| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- name: CI Build Major Branch Keymap
- permissions:
- contents: read
- actions: write
- on:
- workflow_call:
- inputs:
- branch:
- type: string
- required: true
- keymap:
- type: string
- required: true
- slice_length:
- type: string
- required: true
- jobs:
- generate_targets:
- name: "Generate targets (${{ inputs.keymap }})"
- runs-on: ubuntu-latest
- container: ghcr.io/qmk/qmk_cli
- outputs:
- targets: ${{ steps.generate_targets.outputs.targets }}
- steps:
- - name: Disable safe.directory check
- run: |
- git config --global --add safe.directory '*'
- - name: Checkout QMK Firmware
- uses: actions/checkout@v7
- - name: Install dependencies
- run: pip3 install -r requirements-dev.txt
- - name: Generate build targets
- shell: 'bash {0}'
- id: generate_targets
- run: |
- { # Intentionally use `shuf` here so that we share manufacturers across all build groups -- some have a lot of ARM-based boards which inherently take longer
- counter=0
- echo -n '{'
- qmk find -km ${{ inputs.keymap }} 2>/dev/null | sort | uniq | shuf --random-source=<(openssl enc -aes-256-ctr -pass pass:qmk -nosalt </dev/zero 2>/dev/null) | xargs -L${{ inputs.slice_length }} | while IFS=$'\n' read target ; do
- if [ $counter -gt 0 ]; then
- echo -n ','
- fi
- counter=$((counter+1))
- printf "\"group-%02d\":{" $counter
- echo -n '"targets":"'
- echo $target | tr ' ' '\n' | sort | uniq | xargs echo -n
- echo -n '"}'
- done
- echo -n '}'
- } | sed -e 's@\n@@g' > targets.json
- # Output the target keys as a variable
- echo "targets=$(jq -c 'keys' targets.json)" >> $GITHUB_OUTPUT
- - name: Upload targets json
- uses: actions/upload-artifact@v7
- with:
- name: targets-${{ inputs.keymap }}
- path: targets.json
- build_targets:
- name: "Compile ${{ matrix.target }} (${{ inputs.keymap }})"
- needs: generate_targets
- runs-on: ubuntu-latest
- container: ghcr.io/qmk/qmk_cli
- continue-on-error: true
- env:
- CCACHE_CONFIGPATH: ~/.cache
- strategy:
- matrix:
- target: ${{ fromJson(needs.generate_targets.outputs.targets) }}
- steps:
- - name: Disable safe.directory check
- run: |
- git config --global --add safe.directory '*'
- - name: Checkout QMK Firmware
- uses: actions/checkout@v7
- with:
- submodules: recursive
- - name: Install dependencies
- run: pip3 install -r requirements-dev.txt
- - name: Get target definitions
- uses: actions/download-artifact@v8
- with:
- name: targets-${{ inputs.keymap }}
- path: .
- - name: Dump targets
- run: |
- jq -r '.["${{ matrix.target }}"].targets' targets.json | tr ' ' '\n' | sort
- - name: Restore Cache
- id: cache
- uses: actions/cache/restore@v6
- with:
- path: ${{ env.CCACHE_CONFIGPATH }}
- key: compile-${{ inputs.keymap }}-${{ matrix.target }}
- - name: Build targets
- continue-on-error: true
- run: |
- targets=$(jq -r '.["${{ matrix.target }}"].targets' targets.json | tr ' ' '\n' | sort)
- if [ -z "${targets}" ]; then
- echo "Zero build targets detected"
- exit 0
- fi
- qmk mass-compile -t -j $(nproc) -e DUMP_CI_METADATA=yes -e USE_CCACHE=yes $targets || touch .failed
- - name: Dump ccache stats
- run: |
- ccache -s
- # Delete the old cache on hit to emulate a cache update. See https://github.com/actions/cache/issues/342.
- - name: Delete old cache
- env:
- GH_TOKEN: ${{ github.token }}
- if: steps.cache.outputs.cache-hit
- run: |
- count=$(gh cache list --ref ${{ github.ref }} --key ${{ steps.cache.outputs.cache-primary-key }} --json id | jq length)
- if [ $count -gt 0 ]; then
- gh cache delete --ref ${{ github.ref }} ${{ steps.cache.outputs.cache-primary-key }}
- fi
- - name: Save Cache
- uses: actions/cache/save@v6
- with:
- path: ${{ env.CCACHE_CONFIGPATH }}
- key: compile-${{ inputs.keymap }}-${{ matrix.target }}
- - name: Upload binaries
- uses: actions/upload-artifact@v7
- with:
- name: firmware-${{ inputs.keymap }}-${{ matrix.target }}
- if-no-files-found: ignore
- path: |
- *.bin
- *.hex
- *.uf2
- .build/failed.*
- .failed
- - name: Fail build if any group failed
- run: |
- # Exit with failure if the compilation stage failed
- [ ! -f .failed ] || exit 1
- repack_firmware:
- if: always()
- name: "Repack artifacts"
- needs: build_targets
- runs-on: ubuntu-latest
- steps:
- - name: Checkout QMK Firmware
- uses: actions/checkout@v7
- - name: Download firmwares
- uses: actions/download-artifact@v8
- with:
- pattern: firmware-${{ inputs.keymap }}-*
- path: .
- merge-multiple: true
- - name: Upload all firmwares
- uses: actions/upload-artifact@v7
- with:
- name: firmware-${{ inputs.keymap }}
- if-no-files-found: ignore
- path: |
- *.bin
- *.hex
- *.uf2
- .build/failed.*
- .failed
- - name: Generate output logs
- run: |
- # Generate the step summary markdown
- ./util/ci/generate_failure_markdown.sh > $GITHUB_STEP_SUMMARY || true
- # Truncate to a maximum of 1MB to deal with GitHub workflow limit
- truncate --size='<960K' $GITHUB_STEP_SUMMARY || true
- - name: Delete temporary build artifacts
- uses: geekyeggo/delete-artifact@v6
- with:
- name: |
- firmware-${{ inputs.keymap }}-*
- targets-${{ inputs.keymap }}
- - name: 'CI Discord Notification'
- if: always() && !cancelled()
- working-directory: util/ci/
- env:
- DISCORD_WEBHOOK: ${{ secrets.CI_DISCORD_WEBHOOK }}
- run: |
- python3 -m pip install -r requirements.txt
- python3 ./discord-results.py --branch ${{ inputs.branch || github.ref_name }} --sha $(git rev-parse HEAD) --keymap ${{ inputs.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|