Skip to content

ci: add multi-artifact build #625

ci: add multi-artifact build

ci: add multi-artifact build #625

Workflow file for this run

name: Package, test and upload core
on:
- push
- pull_request
jobs:
package-core:
name: Build and package cores
runs-on: ubuntu-latest
env:
CCACHE_IGNOREOPTIONS: -specs=*
outputs:
CORE_TAG: ${{ env.CORE_TAG }}
CORE_HASH: ${{ env.CORE_HASH }}
ALL_BOARD_DATA: ${{ env.ALL_BOARD_DATA }}
ARTIFACTS: ${{ env.ARTIFACTS }}
SUB_ARCHES: ${{ env.SUB_ARCHES }}
steps:
- name: Install OS dependencies
working-directory: /opt
run: |
sudo apt-get remove --purge man-db -y # skips the mandb triggers
sudo apt-get update
sudo apt-get install -y --no-install-recommends git cmake wget python3-pip ninja-build ccache
- uses: actions/checkout@v4
with:
submodules: 'recursive'
fetch-depth: 0
persist-credentials: false
fetch-tags: true
- name: Initialize Zephyr environment
run: |
yes | ./extra/bootstrap.sh -o=--filter=tree:0
echo "CORE_HASH=$(git describe --always)" >> "$GITHUB_ENV"
echo "ALL_BOARD_DATA=$(extra/get_board_details.sh | jq -c 'sort_by(.variant)')" >> "$GITHUB_ENV"
echo "## Building \`$(extra/get_core_version.sh)\`" >> "$GITHUB_STEP_SUMMARY"
- name: Map output packages
# needs the above env vars to be usable
run: |
echo "CORE_TAG=$(git describe --tags --exact-match 2>/dev/null || echo $CORE_HASH)" >> "$GITHUB_ENV"
echo "ARTIFACTS=$(jq -c '["zephyr"] + (map(.artifact) | unique)' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV"
echo "SUB_ARCHES=$(jq -c 'map(.subarch) | unique' <<< ${ALL_BOARD_DATA})" >> "$GITHUB_ENV"
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
verbose: 1
- name: Build variants
shell: bash
run: |
./extra/build_all.sh -f
- name: Package cores
run: |
jq -cr '.[]' <<< ${ARTIFACTS} | while read -r artifact; do
ARTIFACT_NAME=ArduinoCore-${artifact}-${CORE_HASH}
./extra/package_core.sh ${artifact} ${CORE_TAG} distrib/${ARTIFACT_NAME}.tar.bz2
done
- name: Archive cores
uses: actions/upload-artifact@v4
with:
name: ArduinoCore-archives-${{ env.CORE_HASH }}
path: distrib/*.tar.bz2
split-core:
name: Split off ${{ matrix.artifact }}
runs-on: ubuntu-latest
needs: package-core
env:
ALL_CORES_ARTIFACT: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
CORE_ARTIFACT: ArduinoCore-${{ matrix.artifact }}-${{ needs.package-core.outputs.CORE_HASH }}
strategy:
matrix:
artifact: ${{ fromJSON( needs.package-core.outputs.ARTIFACTS ) }}
steps:
- uses: actions/download-artifact@v4
with:
name: ${{ env.ALL_CORES_ARTIFACT }}
- uses: actions/upload-artifact@v4
with:
name: ${{ env.CORE_ARTIFACT }}
path: ${{ env.CORE_ARTIFACT }}.tar.bz2
test-core:
name: Test ${{ matrix.subarch }}:${{ matrix.board }}
runs-on: ubuntu-latest
needs:
- package-core
- split-core
strategy:
matrix:
include:
${{ fromJSON( needs.package-core.outputs.ALL_BOARD_DATA ) }}
fail-fast: false
env:
PLAT: arduino:${{ matrix.subarch }}
FQBN: arduino:${{ matrix.subarch }}:${{ matrix.board }}
CORE_ARTIFACT: ArduinoCore-${{ matrix.artifact }}-${{ needs.package-core.outputs.CORE_HASH }}
steps:
- uses: actions/download-artifact@v4
with:
name: ${{ env.CORE_ARTIFACT }}
- name: Set up core
run: |
tar xf ${CORE_ARTIFACT}.tar.bz2 # will create ArduinoCore-zephyr/
echo "REPORT_FILE=$(echo ${FQBN} | tr ':' '-').json" >> $GITHUB_ENV
- name: Create Blink sketch
run: |
mkdir Blink/
wget -nv https://raw.githubusercontent.com/arduino/arduino-examples/refs/heads/main/examples/01.Basics/Blink/Blink.ino -P Blink/
- name: Compile Blink for ${{ matrix.board }}
uses: pillo79/compile-sketches@main
with:
fqbn: ${{ env.FQBN }}
platforms: |
# Use Board Manager to install the latest release of Arduino Zephyr Boards to get the toolchain
- name: "arduino:zephyr"
source-url: "https://downloads.arduino.cc/packages/package_zephyr_index.json"
- name: ${{ env.PLAT }}
source-path: "ArduinoCore-zephyr"
sketch-paths: Blink
cli-compile-flags: |
- '--build-property'
- 'compiler.c.extra_flags=-Wno-type-limits -Wno-missing-field-initializers'
- '--build-property'
- 'compiler.cpp.extra_flags=-Wno-type-limits -Wno-missing-field-initializers'
verbose: 'false'
enable-deltas-report: 'false'
enable-warnings-report: 'true'
enable-warnings-log: 'true'
- name: Get job ID
id: job_id
if: ${{ success() || failure() }}
uses: actions/github-script@main
with:
script: |
const { data: workflow_run } = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.runId
});
const job_name = `Test ${{ matrix.subarch }}:${{ matrix.board }}`
return workflow_run.jobs.find((job) => job.name === job_name).id;
- name: Prepare log
if: ${{ success() || failure() }}
run: |
sed -i -e 's!/home/runner/.arduino15/packages/arduino/hardware/zephyr/[^/]*/!!g' sketches-reports/${REPORT_FILE}
cat sketches-reports/${REPORT_FILE} | jq -cr ".boards[0].sketches[0] += { job_id: ${{ steps.job_id.outputs.result }} }" > ${REPORT_FILE} && mv ${REPORT_FILE} sketches-reports/
- uses: actions/upload-artifact@v4
if: ${{ success() || failure() }}
with:
name: test-report-${{ needs.package-core.outputs.CORE_TAG }}-${{ matrix.board }}
path: sketches-reports/*
collect-logs:
name: Collect logs
runs-on: ubuntu-latest
needs:
- package-core
- test-core
if: ${{ !cancelled() && needs.package-core.result == 'success' }}
env:
ALL_BOARD_DATA: ${{ needs.package-core.outputs.ALL_BOARD_DATA }}
steps:
- uses: actions/download-artifact@v4
with:
path: .
pattern: test-report-*
merge-multiple: true
- run: |
ARTIFACTS=$(jq -cr 'map(.artifact) | unique | .[]' <<< ${ALL_BOARD_DATA})
for artifact in $ARTIFACTS ; do
echo "### \`$artifact\` test results:" >> "$GITHUB_STEP_SUMMARY"
jq -c "map(select(.artifact == \"$artifact\")) | .[]" <<< ${ALL_BOARD_DATA} | while read -r BOARD_DATA; do
BOARD=$(echo $BOARD_DATA | jq -cr '.board')
VARIANT=$(echo $BOARD_DATA | jq -cr '.variant')
SUBARCH=$(echo $BOARD_DATA | jq -cr '.subarch')
FQBN="arduino:$SUBARCH:$BOARD"
REPORT_FILE="$(echo $FQBN | tr ':' '-').json"
if [ ! -f $REPORT_FILE ]; then
echo "* :x: $BOARD (\`$VARIANT\`) - No report found?" >> "$GITHUB_STEP_SUMMARY"
else
REPORT=$(jq -cr '.boards[0].sketches[0]' $REPORT_FILE)
JOB_ID=$(echo $REPORT | jq -cr '.job_id')
JOB_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${JOB_ID}#step:5:2"
if ! $(echo $REPORT | jq -cr '.compilation_success') ; then
echo "* :x: [$BOARD]($JOB_URL) (\`$VARIANT\`) - Build failed" >> "$GITHUB_STEP_SUMMARY"
else
WARNINGS=$(echo $REPORT | jq -cr '.warnings.current.absolute // 0')
if [ $WARNINGS -eq 0 ]; then
echo "* :white_check_mark: $BOARD (\`$VARIANT\`) - Build successful" >> "$GITHUB_STEP_SUMMARY"
else
echo >> "$GITHUB_STEP_SUMMARY"
echo "<details><summary>&nbsp;&nbsp; :warning: <a href=\"$JOB_URL\">$BOARD</a> (<tt>$VARIANT</tt>) - $WARNINGS warnings:</summary>" >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY"
echo $REPORT | jq -cr '.warnings_log[]' >> "$GITHUB_STEP_SUMMARY"
echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
echo "</details>" >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
fi
fi
fi
done
done
- name: Clean up intermediate artifacts
uses: geekyeggo/delete-artifact@v5.1.0
with:
name: test-report-*
failOnError: false
verify-core:
runs-on: ubuntu-latest
if: cancelled() || contains(needs.*.result, 'failure')
needs:
- package-core
- test-core
steps:
- name: Notify failure
run: exit 1
publish-core:
name: Publish core
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && github.repository == 'arduino/ArduinoCore-zephyr' }}
needs:
- package-core
- test-core
environment: production
permissions:
id-token: write
contents: read
env:
ALL_CORES_ARTIFACT: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
steps:
- uses: actions/download-artifact@v4
with:
name: ${{ env.ALL_CORES_ARTIFACT }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.IAM_ROLE }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Upload artifact
run: aws s3 cp ArduinoCore-*.tar.bz2 s3://${{ secrets.S3_BUCKET }}/
publish-json:
name: Publish jsons
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && github.repository == 'arduino/ArduinoCore-zephyr' }}
needs:
- package-core
- test-core
env:
ALL_CORES_ARTIFACT: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
CORE_TAG: ${{ needs.package-core.outputs.CORE_TAG }}
CORE_HASH: ${{ needs.package-core.outputs.CORE_HASH }}
ARTIFACTS: ${{ needs.package-core.outputs.ARTIFACTS }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
sparse-checkout: |
extra/gen_package_index_json.sh
extra/artifacts/*
- uses: actions/download-artifact@v4
with:
name: ${{ env.ALL_CORES_ARTIFACT }}
- name: Prepare package index snippets
run: |
for artifact in $(jq -cr '.[]' <<< ${ARTIFACTS}); do
ARTIFACT_FILE=ArduinoCore-${artifact}-${CORE_HASH}.tar.bz2
PACKAGE_JSON=ArduinoCore-${artifact}-${CORE_TAG}.json
./extra/gen_package_index_json.sh ${artifact} ${CORE_TAG} ${ARTIFACT_FILE} > ${PACKAGE_JSON}
done
- name: Archive package index snippets
uses: actions/upload-artifact@v4
with:
name: ArduinoCore-zephyr-${{ env.CORE_TAG }}-jsons
path: ArduinoCore-*-${{ env.CORE_TAG }}.json
cleanup-artifacts:
runs-on: ubuntu-latest
needs:
- package-core
- publish-core
- publish-json
if: ${{ !cancelled() }}
steps:
- name: Clean up intermediate artifacts
uses: geekyeggo/delete-artifact@v5.1.0
with:
name: ArduinoCore-archives-${{ needs.package-core.outputs.CORE_HASH }}
failOnError: false