Build #1192
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| skip_linter_check: | |
| type: boolean | |
| default: true | |
| description: 'Skip waiting for the Linter workflow (default true for manual runs)' | |
| branch: | |
| type: string | |
| default: '' | |
| description: 'MTL branch, tag or full 40-char SHA to build; CI stays from the workflow branch (empty = workflow branch)' | |
| push: | |
| branches: | |
| - main | |
| - 'maint-**' | |
| pull_request: | |
| branches: | |
| - main | |
| - 'maint-**' | |
| workflow_call: | |
| inputs: | |
| skip_linter_check: | |
| type: boolean | |
| default: false | |
| description: 'Skip waiting for the Linter workflow (use for schedule/nightly triggers)' | |
| branch: | |
| type: string | |
| default: '' | |
| description: 'MTL branch, tag or full 40-char SHA to build; CI and tests stay from the workflow commit (empty = workflow ref)' | |
| outputs: | |
| mtl_commit: | |
| description: 'Commit the MTL sources were hashed and built from' | |
| value: ${{ jobs.checksums.outputs.commit }} | |
| mtl_hash: | |
| description: 'MTL source checksum' | |
| value: ${{ jobs.checksums.outputs.mtl }} | |
| jpegxs_hash: | |
| description: 'JPEG XS source checksum' | |
| value: ${{ jobs.checksums.outputs.jpegxs }} | |
| ice_hash: | |
| description: 'ICE source checksum' | |
| value: ${{ jobs.checksums.outputs.ice }} | |
| jpegxs_cache_key: | |
| description: 'Exact JPEG XS cache key produced by the build runner' | |
| value: ${{ jobs.build.outputs.jpegxs_cache_key }} | |
| ice_cache_key: | |
| description: 'Exact kernel-specific ICE cache key produced by the build runner' | |
| value: ${{ jobs.build.outputs.ice_cache_key }} | |
| ffmpeg_hash: | |
| description: 'ffmpeg source checksum' | |
| value: ${{ jobs.checksums.outputs.ffmpeg }} | |
| gstreamer_hash: | |
| description: 'gstreamer source checksum' | |
| value: ${{ jobs.checksums.outputs.gstreamer }} | |
| plugins_hash: | |
| description: 'st22 avcodec plugin source checksum' | |
| value: ${{ jobs.checksums.outputs.plugins }} | |
| # One build per pull request at a time. The build job runs on the e835 host, so | |
| # a superseded run is not just wasted minutes: it sits in front of the newest | |
| # commit in the queue for a runner the whole hardware fleet shares. Five runs of | |
| # this workflow queued behind one nightly is what prompted this. | |
| # | |
| # Keyed on the run id rather than the sha outside a pull request, because this | |
| # workflow is also called by the nightly and custom pytest workflows, where | |
| # github.workflow is the caller's name: two dispatches of the same commit are | |
| # two separate intents and must not cancel each other. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| checks: read | |
| jobs: | |
| # ── Gate: skip the build when no artifact input changed ── | |
| # Only a pull request or a push is filtered. A caller (nightly, custom pytest) | |
| # always gets a build. build_workflow holds each filter that pr-gate.yml gets, | |
| # so a test job never waits for a build that this gate skipped. | |
| changes: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| run: ${{ (github.event_name != 'pull_request' && github.event_name != 'push') || steps.filter.outputs.build_workflow == 'true' }} | |
| steps: | |
| - name: Harden Runner | |
| uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| if: ${{ github.event_name == 'pull_request' || github.event_name == 'push' }} | |
| with: | |
| filters: .github/path_filters.yml | |
| # ── Gate: wait for every Linter check on this commit ── | |
| # The names below are the *check run* names produced by linter.yml, which is the | |
| # matrix job name and the residual job's `name:`. They are a contract between the | |
| # two workflows: renaming a job there without renaming it here does not fail the | |
| # gate, it makes the gate wait for something that never arrives and then time out. | |
| # That is exactly how this broke once -- it still asked for super-linter's old | |
| # "Lint Code Base" check, which stopped existing when checkpatch replaced it. | |
| wait-for-linter: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.run == 'true' && !inputs.skip_linter_check && github.ref_name != 'main' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Harden Runner | |
| uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Wait for Linter | |
| uses: ./.github/actions/wait-for-workflow | |
| with: | |
| check_name: | | |
| checkpatch (ubuntu-latest) | |
| checkpatch (macos-latest) | |
| checkpatch (windows-latest) | |
| Lint checks not yet in checkpatch | |
| timeout: '900' | |
| # ── Compute source checksums ── | |
| checksums: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.run == 'true' }} | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 10 | |
| outputs: | |
| dpdk: ${{ steps.sums.outputs.dpdk }} | |
| mtl: ${{ steps.sums.outputs.mtl }} | |
| jpegxs: ${{ steps.sums.outputs.jpegxs }} | |
| ice: ${{ steps.sums.outputs.ice }} | |
| ffmpeg: ${{ steps.sums.outputs.ffmpeg }} | |
| gstreamer: ${{ steps.sums.outputs.gstreamer }} | |
| plugins: ${{ steps.sums.outputs.plugins }} | |
| commit: ${{ steps.checkout.outputs.commit }} | |
| steps: | |
| - name: Harden Runner | |
| uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1 | |
| with: | |
| egress-policy: audit | |
| # The branch is resolved to a commit here, once. The build job and the | |
| # caller's test jobs check out that commit, never the branch again: the | |
| # hashes below include .github/ files, so all of them must hash and | |
| # build the same source commit with the same overlay, or the test jobs' | |
| # fail-on-cache-miss restore finds nothing. | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| id: checkout | |
| with: | |
| ref: ${{ inputs.branch }} | |
| fetch-depth: ${{ inputs.branch && '0' || '1' }} | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0 | |
| # Twice: the branch's own overlay-tests may be older than the workflow | |
| # commit's. The first run checks out the workflow commit's copy, the | |
| # second runs it. | |
| - name: Overlay CI and tests from the workflow commit | |
| if: inputs.branch != '' | |
| env: | |
| MTL_SOURCE: ${{ inputs.branch }} | |
| TEST_SHA: ${{ github.sha }} | |
| TEST_REF: ${{ github.ref_name }} | |
| run: task ci:workflow -- overlay-tests && task ci:workflow -- overlay-tests | |
| - id: sums | |
| uses: ./.github/actions/source-checksums | |
| build: | |
| needs: [wait-for-linter, checksums] | |
| if: ${{ !cancelled() && needs.checksums.result == 'success' && (needs.wait-for-linter.result == 'success' || needs.wait-for-linter.result == 'skipped') }} | |
| runs-on: dpdk | |
| timeout-minutes: 60 | |
| outputs: | |
| jpegxs_cache_key: ${{ steps.keys.outputs.jpegxs_key }} | |
| ice_cache_key: ${{ steps.keys.outputs.ice_key }} | |
| steps: | |
| - name: Harden Runner | |
| uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout MTL | |
| uses: OpenVisualCloud/Media-Transport-Library/.github/actions/checkout-clean@2f540b33d05ab93541c816182b791c0fb6b5d143 | |
| with: | |
| ref: ${{ needs.checksums.outputs.commit }} | |
| fetch-depth: ${{ inputs.branch && '0' || '1' }} | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0 | |
| # Twice: the branch's own overlay-tests may be older than the workflow | |
| # commit's. The first run checks out the workflow commit's copy, the | |
| # second runs it. | |
| - name: Overlay CI and tests from the workflow commit | |
| if: inputs.branch != '' | |
| env: | |
| MTL_SOURCE: ${{ inputs.branch }} | |
| TEST_SHA: ${{ github.sha }} | |
| TEST_REF: ${{ github.ref_name }} | |
| run: task ci:workflow -- overlay-tests && task ci:workflow -- overlay-tests | |
| # Before anything expensive: this runner is long-lived, and a missing | |
| # libelf otherwise surfaces as a pkg-config failure deep inside the build. | |
| # The build scope, because that is what this job consumes -- it builds no | |
| # eBPF, so holding it to xdp-tools' prerequisites fails it on headers | |
| # nothing it compiles includes. | |
| - name: 'system: Check host prerequisites' | |
| shell: bash | |
| run: task ebpf:check-build | |
| - name: Compute exact cache keys | |
| id: keys | |
| shell: bash | |
| env: | |
| HASH_DPDK: ${{ needs.checksums.outputs.dpdk }} | |
| HASH_MTL: ${{ needs.checksums.outputs.mtl }} | |
| HASH_JPEGXS: ${{ needs.checksums.outputs.jpegxs }} | |
| HASH_ICE: ${{ needs.checksums.outputs.ice }} | |
| HASH_FFMPEG: ${{ needs.checksums.outputs.ffmpeg }} | |
| HASH_GSTREAMER: ${{ needs.checksums.outputs.gstreamer }} | |
| HASH_PLUGINS: ${{ needs.checksums.outputs.plugins }} | |
| run: task ci:cache-keys | |
| - name: 'stash: Restore DPDK cache' | |
| id: dpdk-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.dpdk_key }} | |
| path: .local_install/dpdk | |
| - name: 'stash: Restore MTL cache' | |
| id: mtl-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.mtl_key }} | |
| path: .local_install/mtl | |
| - name: 'stash: Restore JPEG XS cache' | |
| id: jpegxs-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.jpegxs_key }} | |
| path: .local_install/jpegxs | |
| - name: 'stash: Restore FFmpeg cache' | |
| id: ffmpeg-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.ffmpeg_key }} | |
| path: .local_install/ffmpeg | |
| - name: 'stash: Restore GStreamer cache' | |
| id: gstreamer-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.gstreamer_key }} | |
| path: .local_install/gstreamer | |
| - name: 'stash: Restore plugins cache' | |
| id: plugins-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.plugins_key }} | |
| path: .local_install/plugins | |
| - name: 'stash: Restore ICE cache' | |
| id: ice-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ steps.keys.outputs.ice_key }} | |
| path: .local_install/ice | |
| - name: Evaluate cache results | |
| id: cache-state | |
| shell: bash | |
| env: | |
| CACHE_HIT_DPDK: ${{ steps.dpdk-cache.outputs.cache-hit }} | |
| CACHE_HIT_MTL: ${{ steps.mtl-cache.outputs.cache-hit }} | |
| CACHE_HIT_JPEGXS: ${{ steps.jpegxs-cache.outputs.cache-hit }} | |
| CACHE_HIT_FFMPEG: ${{ steps.ffmpeg-cache.outputs.cache-hit }} | |
| CACHE_HIT_GSTREAMER: ${{ steps.gstreamer-cache.outputs.cache-hit }} | |
| CACHE_HIT_PLUGINS: ${{ steps.plugins-cache.outputs.cache-hit }} | |
| CACHE_HIT_ICE: ${{ steps.ice-cache.outputs.cache-hit }} | |
| run: task ci:evaluate-caches | |
| - name: Build missing dependencies | |
| if: steps.cache-state.outputs.any_miss == '1' | |
| shell: bash | |
| run: task ci:build-dependencies | |
| - name: Validate dependency outputs | |
| shell: bash | |
| run: task ci:validate-dependencies | |
| - name: 'stash: Save DPDK cache' | |
| if: success() && steps.cache-state.outputs.dpdk_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.dpdk_key }} | |
| path: .local_install/dpdk | |
| - name: 'stash: Save MTL cache' | |
| if: success() && steps.cache-state.outputs.mtl_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.mtl_key }} | |
| path: .local_install/mtl | |
| - name: 'stash: Save JPEG XS cache' | |
| if: success() && steps.cache-state.outputs.jpegxs_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.jpegxs_key }} | |
| path: .local_install/jpegxs | |
| - name: 'stash: Save FFmpeg cache' | |
| if: success() && steps.cache-state.outputs.ffmpeg_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.ffmpeg_key }} | |
| path: .local_install/ffmpeg | |
| - name: 'stash: Save GStreamer cache' | |
| if: success() && steps.cache-state.outputs.gstreamer_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.gstreamer_key }} | |
| path: .local_install/gstreamer | |
| - name: 'stash: Save plugins cache' | |
| if: success() && steps.cache-state.outputs.plugins_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.plugins_key }} | |
| path: .local_install/plugins | |
| - name: 'stash: Save ICE cache' | |
| if: success() && steps.cache-state.outputs.ice_miss == '1' | |
| uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| key: ${{ steps.keys.outputs.ice_key }} | |
| path: .local_install/ice | |
| # The one check to require in branch protection. It always runs, so it | |
| # reports even when the path filter skips build jobs, and it fails only if a | |
| # job it needs failed or was cancelled. | |
| build-result: | |
| name: build-result | |
| needs: [changes, wait-for-linter, checksums, build] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: All build jobs ok | |
| if: ${{ !(contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }} | |
| run: exit 0 | |
| - name: Some build jobs failed | |
| if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} | |
| run: exit 1 |