Skip to content

Commit 9eb88f1

Browse files
authored
Merge pull request #286 from pillo79/parallel-ci
ci: run Zephyr builds in parallel
2 parents 5f5ce5a + 5a55b11 commit 9eb88f1

File tree

3 files changed

+154
-61
lines changed

3 files changed

+154
-61
lines changed

.github/workflows/package_core.yml

Lines changed: 134 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@ on:
66

77
jobs:
88

9-
package-core:
10-
name: Build and package cores
9+
build-env:
10+
name: Prepare build environment
1111
runs-on: ubuntu-latest
12-
env:
13-
CCACHE_IGNOREOPTIONS: -specs=*
1412
outputs:
1513
CORE_TAG: ${{ env.CORE_TAG }}
1614
CORE_HASH: ${{ env.CORE_HASH }}
@@ -46,64 +44,156 @@ jobs:
4644
echo "ARTIFACTS=$(jq -c '["zephyr"] + (map(.artifact) | unique)' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV"
4745
echo "SUB_ARCHES=$(jq -c 'map(.subarch) | unique' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV"
4846
47+
(cd && tar cphf - .cmake work zephyr-sdk-* | zstd > build-env.tar.zstd)
48+
tar cphf - cores/arduino/api | zstd > arduino-api.tar.zstd
49+
50+
- name: Archive build environment
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: build-env
54+
path: ~/build-env.tar.zstd
55+
56+
- name: Archive API snapshot
57+
uses: actions/upload-artifact@v4
58+
with:
59+
name: arduino-api
60+
path: arduino-api.tar.zstd
61+
62+
build-board:
63+
name: Build loader for ${{ matrix.board }}
64+
runs-on: ubuntu-latest
65+
needs:
66+
- build-env
67+
env:
68+
CCACHE_IGNOREOPTIONS: -specs=*
69+
OUTPUT_ARTIFACT: binaries-${{ matrix.board }}-${{ needs.build-env.outputs.CORE_HASH }}
70+
strategy:
71+
matrix:
72+
include:
73+
${{ fromJSON( needs.build-env.outputs.ALL_BOARD_DATA ) }}
74+
fail-fast: false
75+
steps:
76+
- uses: actions/download-artifact@v4
77+
with:
78+
path: /home/runner
79+
name: build-env
80+
81+
- name: Restore build environment
82+
run: |
83+
(cd ~ && tar --use-compress-program=unzstd -xpf build-env.tar.zstd && rm build-env.tar.zstd)
84+
4985
- name: ccache
5086
uses: hendrikmuhs/ccache-action@v1.2
5187
with:
5288
verbose: 1
5389

54-
- name: Build variants
90+
- name: Build loader
5591
shell: bash
5692
run: |
57-
./extra/build_all.sh -f
93+
if ! ./extra/build.sh ${{ matrix.board }} 2> >(tee error.log) ; then
94+
echo "### :x: ${{ matrix.board }} (\`${{ matrix.variant }}\`) build errors" > $GITHUB_STEP_SUMMARY
95+
echo >> $GITHUB_STEP_SUMMARY
96+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
97+
cat error.log >> $GITHUB_STEP_SUMMARY
98+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
99+
exit 1
100+
fi
58101
59-
- name: Package cores
102+
- name: Package board binaries
103+
if: ${{ !cancelled() }}
60104
run: |
61-
jq -cr '.[]' <<< ${ARTIFACTS} | while read -r artifact; do
62-
ARTIFACT_NAME=ArduinoCore-${artifact}-${CORE_HASH}
63-
./extra/package_core.sh ${artifact} ${CORE_TAG} distrib/${ARTIFACT_NAME}.tar.bz2
64-
done
105+
tar chf - \
106+
firmwares/*${{ matrix.variant }}* \
107+
variants/${{ matrix.variant }}/ \
108+
${{ (job.status == 'failure') && format('build/{0}/', matrix.variant) }} \
109+
| zstd > ${OUTPUT_ARTIFACT}.tar.zstd
65110
66-
- name: Archive cores
111+
- name: Archive board binaries
112+
if: ${{ !cancelled() }}
67113
uses: actions/upload-artifact@v4
68114
with:
69-
name: ArduinoCore-archives-${{ env.CORE_HASH }}
70-
path: distrib/*.tar.bz2
115+
name: ${{ format('{0}{1}', (job.status == 'failure') && 'failed-' || '', env.OUTPUT_ARTIFACT) }}
116+
path: ${{ env.OUTPUT_ARTIFACT }}.tar.zstd
71117

72-
split-core:
73-
name: Split off ${{ matrix.artifact }}
118+
package-core:
119+
name: Package ${{ matrix.artifact }}
74120
runs-on: ubuntu-latest
75-
needs: package-core
121+
needs:
122+
- build-env
123+
- build-board
76124
env:
77-
ALL_CORES_ARTIFACT: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
78-
CORE_ARTIFACT: ArduinoCore-${{ matrix.artifact }}-${{ needs.package-core.outputs.CORE_HASH }}
125+
CORE_ARTIFACT: ArduinoCore-${{ matrix.artifact }}-${{ needs.build-env.outputs.CORE_HASH }}
126+
CORE_TAG: ${{ needs.build-env.outputs.CORE_TAG }}
79127
strategy:
80128
matrix:
81-
artifact: ${{ fromJSON( needs.package-core.outputs.ARTIFACTS ) }}
129+
artifact: ${{ fromJSON( needs.build-env.outputs.ARTIFACTS ) }}
130+
fail-fast: false
131+
if: ${{ !cancelled() && needs.build-env.result == 'success' }}
82132
steps:
133+
- uses: actions/checkout@v4
134+
with:
135+
submodules: 'recursive'
136+
fetch-depth: 0
137+
persist-credentials: false
138+
fetch-tags: true
139+
83140
- uses: actions/download-artifact@v4
84141
with:
85-
name: ${{ env.ALL_CORES_ARTIFACT }}
142+
path: .
143+
name: arduino-api
144+
145+
- uses: actions/download-artifact@v4
146+
with:
147+
path: .
148+
pattern: binaries-*
149+
merge-multiple: true
150+
151+
- name: Package core
152+
run: |
153+
rm -f cores/arduino/api # remove broken symlink
154+
tar --use-compress-program=unzstd -xpf arduino-api.tar.zstd
155+
for f in binaries-*.tar.zstd ; do
156+
tar --use-compress-program=unzstd -xpf $f
157+
done
158+
./extra/package_core.sh ${{ matrix.artifact }} ${CORE_TAG} distrib/${CORE_ARTIFACT}.tar.bz2
86159
87160
- uses: actions/upload-artifact@v4
161+
if: ${{ success() || failure() }}
88162
with:
89163
name: ${{ env.CORE_ARTIFACT }}
90-
path: ${{ env.CORE_ARTIFACT }}.tar.bz2
164+
path: distrib/${{ env.CORE_ARTIFACT }}.tar.bz2
165+
166+
cleanup-build:
167+
name: Clean up intermediates
168+
runs-on: ubuntu-latest
169+
needs:
170+
- package-core
171+
if: always()
172+
steps:
173+
- uses: geekyeggo/delete-artifact@v5.1.0
174+
with:
175+
name: |
176+
arduino-api
177+
binaries-*
178+
build-env
179+
failOnError: false
91180

92181
test-core:
93182
name: Test ${{ matrix.subarch }}:${{ matrix.board }}
94183
runs-on: ubuntu-latest
95184
needs:
185+
- build-env
96186
- package-core
97-
- split-core
98187
strategy:
99188
matrix:
100189
include:
101-
${{ fromJSON( needs.package-core.outputs.ALL_BOARD_DATA ) }}
190+
${{ fromJSON( needs.build-env.outputs.ALL_BOARD_DATA ) }}
102191
fail-fast: false
103192
env:
104193
PLAT: arduino:${{ matrix.subarch }}
105194
FQBN: arduino:${{ matrix.subarch }}:${{ matrix.board }}
106-
CORE_ARTIFACT: ArduinoCore-${{ matrix.artifact }}-${{ needs.package-core.outputs.CORE_HASH }}
195+
CORE_ARTIFACT: ArduinoCore-${{ matrix.artifact }}-${{ needs.build-env.outputs.CORE_HASH }}
196+
if: ${{ !cancelled() && needs.build-env.result == 'success' }}
107197
steps:
108198
- uses: actions/download-artifact@v4
109199
with:
@@ -163,18 +253,19 @@ jobs:
163253
- uses: actions/upload-artifact@v4
164254
if: ${{ success() || failure() }}
165255
with:
166-
name: test-report-${{ needs.package-core.outputs.CORE_TAG }}-${{ matrix.board }}
256+
name: test-report-${{ needs.build-env.outputs.CORE_TAG }}-${{ matrix.board }}
167257
path: sketches-reports/*
168258

169259
collect-logs:
170260
name: Collect logs
171261
runs-on: ubuntu-latest
172262
needs:
263+
- build-env
173264
- package-core
174265
- test-core
175-
if: ${{ !cancelled() && needs.package-core.result == 'success' }}
266+
if: ${{ !cancelled() && needs.build-env.result == 'success' }}
176267
env:
177-
ALL_BOARD_DATA: ${{ needs.package-core.outputs.ALL_BOARD_DATA }}
268+
ALL_BOARD_DATA: ${{ needs.build-env.outputs.ALL_BOARD_DATA }}
178269
steps:
179270
- uses: actions/download-artifact@v4
180271
with:
@@ -230,9 +321,10 @@ jobs:
230321
runs-on: ubuntu-latest
231322
if: cancelled() || contains(needs.*.result, 'failure')
232323
needs:
324+
- build-env
233325
- package-core
234326
- test-core
235-
steps:
327+
steps:
236328
- name: Notify failure
237329
run: exit 1
238330

@@ -241,18 +333,19 @@ jobs:
241333
runs-on: ubuntu-latest
242334
if: ${{ github.event_name == 'push' && github.repository == 'arduino/ArduinoCore-zephyr' }}
243335
needs:
336+
- build-env
244337
- package-core
245338
- test-core
246339
environment: production
247340
permissions:
248341
id-token: write
249342
contents: read
250-
env:
251-
ALL_CORES_ARTIFACT: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
252343
steps:
253344
- uses: actions/download-artifact@v4
254345
with:
255-
name: ${{ env.ALL_CORES_ARTIFACT }}
346+
path: .
347+
pattern: ArduinoCore-*
348+
merge-multiple: true
256349

257350
- name: Configure AWS credentials
258351
uses: aws-actions/configure-aws-credentials@v4
@@ -266,18 +359,17 @@ jobs:
266359
aws s3 cp $f s3://${{ secrets.S3_BUCKET }}/
267360
done
268361
269-
publish-json:
270-
name: Publish jsons
362+
prepare-json:
363+
name: Prepare jsons
271364
runs-on: ubuntu-latest
272-
if: ${{ github.repository == 'arduino/ArduinoCore-zephyr' }}
273365
needs:
366+
- build-env
274367
- package-core
275368
- test-core
276369
env:
277-
ALL_CORES_ARTIFACT: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
278-
CORE_TAG: ${{ needs.package-core.outputs.CORE_TAG }}
279-
CORE_HASH: ${{ needs.package-core.outputs.CORE_HASH }}
280-
ARTIFACTS: ${{ needs.package-core.outputs.ARTIFACTS }}
370+
CORE_TAG: ${{ needs.build-env.outputs.CORE_TAG }}
371+
CORE_HASH: ${{ needs.build-env.outputs.CORE_HASH }}
372+
ARTIFACTS: ${{ needs.build-env.outputs.ARTIFACTS }}
281373
steps:
282374
- uses: actions/checkout@v4
283375
with:
@@ -287,7 +379,9 @@ jobs:
287379

288380
- uses: actions/download-artifact@v4
289381
with:
290-
name: ${{ env.ALL_CORES_ARTIFACT }}
382+
path: .
383+
pattern: ArduinoCore-*
384+
merge-multiple: true
291385

292386
- name: Prepare package index snippets
293387
run: |
@@ -302,17 +396,3 @@ jobs:
302396
with:
303397
name: ArduinoCore-zephyr-${{ env.CORE_TAG }}-jsons
304398
path: ArduinoCore-*-${{ env.CORE_TAG }}.json
305-
306-
cleanup-artifacts:
307-
runs-on: ubuntu-latest
308-
needs:
309-
- package-core
310-
- publish-core
311-
- publish-json
312-
if: ${{ !cancelled() }}
313-
steps:
314-
- name: Clean up intermediate artifacts
315-
uses: geekyeggo/delete-artifact@v5.1.0
316-
with:
317-
name: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
318-
failOnError: false

extra/get_variant_name.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,5 @@ set -e
44
source venv/bin/activate
55

66
# Get the variant name (NORMALIZED_BOARD_TARGET in Zephyr)
7-
tmpdir=$(mktemp -d)
87
variant=$(cmake "-DBOARD=$1" -P extra/get_variant_name.cmake 2>/dev/null | grep 'VARIANT=' | cut -d '=' -f 2)
9-
rm -rf ${tmpdir}
10-
118
echo $variant

extra/package_core.sh

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22

33
set -e
4+
RET=0
45

56
if [ -z "$1" ]; then
67
echo "Usage: $0 ARTIFACT VERSION [OUTPUT_FILE]"
@@ -16,6 +17,14 @@ ARTIFACT=$1
1617
VERSION=$2
1718
OUTPUT_FILE=${3:-distrib/${ARTIFACT}-${VERSION}.tar.bz2}
1819

20+
log_msg() {
21+
if [ -n $GITHUB_WORKSPACE ] ; then
22+
echo "::$1::$2"
23+
else
24+
echo "$2"
25+
fi
26+
}
27+
1928
# we use variants for include because we filter on file paths
2029
# and boards for exclude because we want to remove matching lines in boards.txt
2130
BOARD_DETAILS=$(extra/get_board_details.sh)
@@ -31,7 +40,7 @@ else
3140
EXCLUDED_BOARDS=$(echo ${BOARD_DETAILS} | jq -cr "map(select(.artifact != \"$ARTIFACT\")) | .[].board")
3241
fi
3342

34-
[ -n $GITHUB_WORKSPACE ] && echo "::group::Packaging ${ARTIFACT_NAME:-all variants} ($(basename $OUTPUT_FILE))"
43+
log_msg group "Packaging ${ARTIFACT_NAME:-all variants} ($(basename $OUTPUT_FILE))"
3544

3645
# create a temporary boards.txt file with the correct list of boards
3746
TEMP_BOARDS=$(mktemp -p . | sed 's/\.\///')
@@ -50,6 +59,7 @@ cat platform.txt > ${TEMP_PLATFORM}
5059
sed -ie "s/^version=.*/version=$(extra/get_core_version.sh)/" ${TEMP_PLATFORM}
5160

5261
declutter_file() {
62+
# remove comments and empty lines
5363
[ -f "$1" ] || return 0
5464
cat "$1" | sed -e 's/\s*#.*//' | grep -v '^\s*$'
5565
}
@@ -61,9 +71,13 @@ echo ${TEMP_PLATFORM} >> ${TEMP_INC}
6171
declutter_file extra/artifacts/_common.inc >> ${TEMP_INC}
6272
declutter_file extra/artifacts/$ARTIFACT.inc >> ${TEMP_INC}
6373
for variant in $INCLUDED_VARIANTS ; do
64-
echo "::info::\`${variant}\`"
74+
echo "- ${variant}"
6575
echo "variants/${variant}/" >> ${TEMP_INC}
66-
ls firmwares/zephyr-${variant}.* >> ${TEMP_INC}
76+
# add the firmwares, if some are missing notify at end
77+
if ! ls firmwares/zephyr-${variant}.* >> ${TEMP_INC} ; then
78+
log_msg error "No firmware for '${variant}' found."
79+
RET=3
80+
fi
6781
done
6882

6983
# create the list of files and directories to exclude
@@ -78,4 +92,6 @@ tar -cjhf ${OUTPUT_FILE} -X ${TEMP_EXC} -T ${TEMP_INC} \
7892
--transform "s,^,ArduinoCore-zephyr/,"
7993
rm -f ${TEMP_INC} ${TEMP_EXC} ${TEMP_BOARDS} ${TEMP_PLATFORM}
8094

81-
[ -n $GITHUB_WORKSPACE ] && echo "::endgroup::"
95+
log_msg endgroup
96+
97+
exit $RET

0 commit comments

Comments
 (0)