-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathaction.yml
More file actions
350 lines (349 loc) · 14.3 KB
/
Copy pathaction.yml
File metadata and controls
350 lines (349 loc) · 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
name: 'Build and upload conda packages'
description: 'Automatic conda package compilation and publication in the speficied Anaconda user or organization.'
author: "Diego Prada-Gracia"
branding:
icon: "package"
color: "orange"
inputs:
meta_yaml_dir:
description: Path to the directory in the repository where the meta.yaml file is located.
required: true
mambabuild:
description: Using boa (mambabuild) to build the packages.
required: false
default: false
platform_host:
description: Target host plaform.
required: false
default: true
platform_all:
description: Target all supported platforms.
required: false
default: false
platform_linux-64:
description: Target platform linux-64.
required: false
default: false
platform_linux-32:
description: Target platform linux-32.
required: false
default: false
platform_osx-64:
description: Target platform osx-64.
required: false
default: false
platform_osx-arm64:
description: Target platform osx-arm64.
required: false
default: false
platform_linux-ppc64:
description: Target platform linux-ppc64.
required: false
default: false
platform_linux-ppc64le:
description: Target platform linux-ppc64le.
required: false
default: false
platform_linux-s390x:
description: Target platform linux-s390x.
required: false
default: false
platform_linux-armv6l:
description: Target platform linux-armv6l.
required: false
default: false
platform_linux-armv7l:
description: Target platform linux-armv7l.
required: false
default: false
platform_linux-aarch64:
description: Target platform linux-aarch64.
required: false
default: false
platform_win-32:
description: Target platform win-32.
required: false
default: false
platform_win-64:
description: Target platform win-64.
required: false
default: false
upload:
description: Upload built package to anaconda
required: false
default: true
overwrite:
description: Do not cancel the uploading if a package with the same name is found already in Anaconda.
required: false
default: ''
user:
description: Name of the Anaconda user or organization where the conda package will be published.
required: false
default: ''
label:
description: Label of the published conda package.
required: false
default: ''
token:
description: Token to access to anaconda cloud.
required: false
default: ''
conda_build_args:
description: Optional arguments to pass to the 'conda build' command.
required: false
default: ''
conda_convert_args:
description: Optional arguments to pass to the 'conda convert' command.
required: false
default: ''
anaconda_upload_args:
description: Optional arguments to pass to the 'anaconda upload' command.
required: false
default: ''
github_release:
description: "Automatically create a GitHub release if a tag was pushed."
required: false
default: 'false'
outputs:
paths:
description: Paths for the uploaded packages, in the format 'path1 path2 ... pathN'. Empty when 'upload' is false.
value: ${{steps.packages-uploading.outputs.paths}}
built_paths:
description: Paths for every package built or converted, uploaded or not, in the format 'path1 path2 ... pathN'.
value: ${{steps.packages-compilation.outputs.built_paths}}
runs:
using: "composite"
steps:
- name: Sanity checks on inputs
shell: bash -l {0}
env:
UPLOAD: ${{ inputs.upload }}
TOKEN: ${{ inputs.token }}
ANACONDA_USER: ${{ inputs.user }}
LABEL: ${{ inputs.label }}
OVERWRITE: ${{ inputs.overwrite }}
run: |
set -euo pipefail
echo "::group::Sanity checks on inputs"
if [ "$UPLOAD" == "true" ]; then
if [ -z "$TOKEN" ]; then
echo -e "An Anaconda token is required when the package is to be uploaded.\n"\
"Please specify a 'token', or set 'upload' to 'false'."
exit 1
fi
if [ -z "$ANACONDA_USER" ]; then
echo -e "An Anaconda user or organization is required when the package is to be uploaded.\n"\
"Please specify a 'user', or set 'upload' to 'false'."
exit 1
fi
fi
if ${{ contains(inputs.conda_build_args, '--no-anaconda-upload') }}; then
echo -e "The argument '--no-anaconda-upload' is already used within this action's 'conda build' command and is not allowed in 'conda_build_args'."
exit 1
fi
if ${{ contains(inputs.conda_build_args, '--output-folder') }}; then
echo -e "The destination folder for the built packages is set internally and the '--output-folder' option is not allowed in 'conda_build_args'.\n"\
"To retrieve the paths of the built packages, please refer to this action's 'paths' output."
exit 1
fi
if ${{ contains(inputs.conda_convert_args, '--output-folder') }}; then
echo -e "The destination folder for the converted packages is set internally and the '--output-folder' option is not allowed in 'conda_convert_args'.\n"\
"To retrieve the paths of the built packages, please refer to this action's 'paths' output."
exit 1
fi
if (${{ contains(inputs.anaconda_upload_args, '--label') }} || ${{ contains(inputs.anaconda_upload_args, '-l') }}) && [ -n "$LABEL" ]; then
echo -e "Both the 'label' input and the '--label'/'-l' option within 'anaconda_upload_args' were specified.\n"\
"Please only use one of them."
exit 1
fi
if (${{ contains(inputs.anaconda_upload_args, '--user') }} || ${{ contains(inputs.anaconda_upload_args, '-u') }}) && [ -n "$ANACONDA_USER" ]; then
echo -e "Both the 'user' input and the '--user'/'-u' option within 'anaconda_upload_args' were specified.\n"\
"Please only use one of them."
exit 1
fi
if ${{ contains(inputs.anaconda_upload_args, '--token') }} && [ -n "$TOKEN" ]; then
echo -e "Both the 'token' input and the '--token' option within 'anaconda_upload_args' were specified.\n"\
"Please only use one of them."
exit 1
fi
if ${{ contains(inputs.anaconda_upload_args, '--force') }} && [ -n "$OVERWRITE" ]; then
echo -e "Both the 'overwrite' input and the '--force' option within 'anaconda_upload_args' were specified.\n"\
"Please only use one of them."
exit 1
fi
echo "::endgroup::"
- name: Event trigger data
shell: bash -l {0}
run: |
set -euo pipefail
echo "::group::Information about the trigger event"
echo "Trigger event: $GITHUB_EVENT_NAME"
echo "Associated commit SHA: $GITHUB_SHA"
echo "::endgroup::"
- name: Checking if meta.yaml is in meta_yaml_dir
id: checking-meta_yaml
shell: bash -l {0}
working-directory: ${{ inputs.meta_yaml_dir }}
env:
META_YAML_DIR: ${{ inputs.meta_yaml_dir }}
run: |
set -euo pipefail
echo "::group::Checking if the file meta.yaml exists"
if [ ! -f meta.yaml ]; then
echo "A meta.yaml file with the compilation instructions of the conda package was not found in $META_YAML_DIR."
exit 1
else
echo "A meta.yaml file with the compilation instructions of the conda package was found in $META_YAML_DIR."
fi
echo "::endgroup::"
- name: Packages compilation
id: packages-compilation
shell: bash -l {0}
working-directory: ${{ inputs.meta_yaml_dir }}
env:
MAMBABUILD: ${{ inputs.mambabuild }}
CONDA_BUILD_ARGS: ${{ inputs.conda_build_args }}
CONDA_CONVERT_ARGS: ${{ inputs.conda_convert_args }}
PLATFORM_HOST: ${{ inputs.platform_host }}
PLATFORM_ALL: ${{ inputs.platform_all }}
PLATFORM_LINUX_64: ${{ inputs.platform_linux-64 }}
PLATFORM_LINUX_32: ${{ inputs.platform_linux-32 }}
PLATFORM_OSX_64: ${{ inputs.platform_osx-64 }}
PLATFORM_OSX_ARM64: ${{ inputs.platform_osx-arm64 }}
PLATFORM_LINUX_PPC64: ${{ inputs.platform_linux-ppc64 }}
PLATFORM_LINUX_PPC64LE: ${{ inputs.platform_linux-ppc64le }}
PLATFORM_LINUX_S390X: ${{ inputs.platform_linux-s390x }}
PLATFORM_LINUX_ARMV6L: ${{ inputs.platform_linux-armv6l }}
PLATFORM_LINUX_ARMV7L: ${{ inputs.platform_linux-armv7l }}
PLATFORM_LINUX_AARCH64: ${{ inputs.platform_linux-aarch64 }}
PLATFORM_WIN_32: ${{ inputs.platform_win-32 }}
PLATFORM_WIN_64: ${{ inputs.platform_win-64 }}
run: |
set -euo pipefail
echo "::group::Building conda package for host platform"
out_dir="$(mktemp -d -t compilation-XXXXXXXXXX)"
echo "out_dir=$out_dir" >> "$GITHUB_OUTPUT"
if [ "$MAMBABUILD" = "true" ]; then
build_function="mambabuild"
else
build_function="build"
fi
# $CONDA_BUILD_ARGS and friends are intentionally unquoted so that several
# arguments split into several words. They are read from the environment,
# not interpolated into this script, so their content cannot become shell
# syntax.
echo "conda $build_function . --no-anaconda-upload --output-folder $out_dir $CONDA_BUILD_ARGS"
conda "$build_function" . --no-anaconda-upload --output-folder "$out_dir" $CONDA_BUILD_ARGS
HOST_PACKAGE="$(conda "$build_function" . --no-anaconda-upload --output-folder "$out_dir" $CONDA_BUILD_ARGS --output)"
echo "HOST_PACKAGE=$HOST_PACKAGE" >> "$GITHUB_OUTPUT"
echo "Package for host platform compiled as $HOST_PACKAGE"
du -sh "$HOST_PACKAGE"
echo "::endgroup::"
echo "::group::Converting package for other platforms"
platforms_options=""
for entry in \
"all:PLATFORM_ALL" \
"linux-64:PLATFORM_LINUX_64" \
"linux-32:PLATFORM_LINUX_32" \
"osx-64:PLATFORM_OSX_64" \
"osx-arm64:PLATFORM_OSX_ARM64" \
"linux-ppc64:PLATFORM_LINUX_PPC64" \
"linux-ppc64le:PLATFORM_LINUX_PPC64LE" \
"linux-s390x:PLATFORM_LINUX_S390X" \
"linux-armv6l:PLATFORM_LINUX_ARMV6L" \
"linux-armv7l:PLATFORM_LINUX_ARMV7L" \
"linux-aarch64:PLATFORM_LINUX_AARCH64" \
"win-32:PLATFORM_WIN_32" \
"win-64:PLATFORM_WIN_64" \
; do
platform="${entry%%:*}"
variable="${entry##*:}"
if [ "${!variable}" = "true" ]; then
platforms_options+=" -p $platform"
fi
done
if [ -n "$platforms_options" ]; then
echo "conda convert $HOST_PACKAGE -o $out_dir $CONDA_CONVERT_ARGS$platforms_options"
conda convert "$HOST_PACKAGE" -o "$out_dir" $CONDA_CONVERT_ARGS $platforms_options
fi
if [ "$PLATFORM_HOST" != "true" ]; then
rm "$HOST_PACKAGE"
echo "Package for host platform removed."
fi
built_paths=()
while IFS= read -r line; do
built_paths+=("$line")
done < <(find "$out_dir" -type f -name "$(basename "$HOST_PACKAGE")")
echo "built_paths=${built_paths[*]}" >> "$GITHUB_OUTPUT"
echo "Packages available after compilation and conversion:"
printf ' %s\n' "${built_paths[@]}"
echo "::endgroup::"
- name: Packages uploading
id: packages-uploading
if: inputs.upload == 'true'
shell: bash -l {0}
working-directory: ${{ inputs.meta_yaml_dir }}
env:
LABEL: ${{ inputs.label }}
ANACONDA_USER: ${{ inputs.user }}
OVERWRITE: ${{ inputs.overwrite }}
ANACONDA_API_TOKEN: ${{ inputs.token }}
ANACONDA_UPLOAD_ARGS: ${{ inputs.anaconda_upload_args }}
OUT_DIR: ${{ steps.packages-compilation.outputs.out_dir }}
HOST_PACKAGE: ${{ steps.packages-compilation.outputs.HOST_PACKAGE }}
run: |
set -euo pipefail
echo "::group::Conda packages uploading"
label="${LABEL:-main}" #If label is empty (input not provided), set it to 'main'
force=""
if [ "$OVERWRITE" == "true" ]; then
force="--force"
fi
package_paths=()
while IFS= read -r line; do
package_paths+=("$line")
done < <(find "$OUT_DIR" -type f -name "$(basename "$HOST_PACKAGE")")
if [ "${#package_paths[@]}" -eq 0 ]; then
echo "::endgroup::"
echo "::error::No package was found to upload. Nothing was published."
exit 1
fi
failed=0
paths=()
for package_path in "${package_paths[@]}"; do
# $ANACONDA_UPLOAD_ARGS is intentionally unquoted. See the note above.
echo "anaconda upload --user $ANACONDA_USER $force --label $label $ANACONDA_UPLOAD_ARGS $package_path"
if anaconda upload --user "$ANACONDA_USER" $force --label "$label" $ANACONDA_UPLOAD_ARGS "$package_path"; then
paths+=("$package_path")
else
echo "::error::Upload failed for $(basename "$package_path")"
failed=$((failed + 1))
fi
done
echo "paths=${paths[*]}" >> "$GITHUB_OUTPUT"
echo "::endgroup::"
# `anaconda upload` exits non-zero on failure, but the loop used to discard that,
# and the step's status came from the last echo. An expired token therefore looked
# exactly like a successful publication: green workflow, empty channel.
if [ "$failed" -gt 0 ]; then
echo "::error::$failed of ${#package_paths[@]} uploads failed. Those packages were not published."
exit 1
fi
- name: Create GitHub Release
if: inputs.github_release == 'true' && startsWith(github.ref, 'refs/tags/')
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
echo "::group::Creating GitHub Release"
if ! gh release view "$TAG" > /dev/null 2>&1; then
gh release create "$TAG" \
--title "Release $TAG" \
--notes "Automated release of version $TAG. See commit history for details."
echo "Release created: $TAG"
else
echo "Release already exists: $TAG"
fi
echo "::endgroup::"