fix(ci): add workflow_dispatch to execute-release; fix if guard #1140
Workflow file for this run
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 Bluefin dakota | |
| on: | |
| pull_request: | |
| branches: [main, next, testing] | |
| merge_group: | |
| branches: [main, next, testing] | |
| push: | |
| branches: [main, next] | |
| workflow_dispatch: | |
| # WARNING: Do not manually dispatch immediately after auto/track-* ref bumps | |
| # (e.g. Renovate PRs updating gnome-build-meta.bst). Cold builds of GNOME | |
| # require gbm.gnome.org to have built the new ref first — dispatch too early | |
| # and you get a cold build that times out. | |
| permissions: read-all | |
| env: | |
| IMAGE_NAME: dakota | |
| IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} | |
| # Concurrency: per-ref isolation for all events. | |
| # - PRs: cancel-in-progress: true drops stale validate runs when a new | |
| # push arrives. Safe for other events — merge_group/schedule/dispatch | |
| # each use distinct refs and are unaffected by this flag. | |
| # - merge_group / schedule / dispatch: per-ref queuing, never cancelled. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| # ── Fast PR validation ─────────────────────────────────────────────────── | |
| # Fires only on pull_request. Runs bst show on the full element graph for | |
| # both variants. Zero remote-execution — does not touch cache.projectbluefin.io. | |
| # Expected runtime: <15 min (BST cache hit), <30 min (cold start). | |
| validate: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-validate-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Check bst2 image pin consistency | |
| uses: ./.github/actions/check-bst2-pin | |
| - name: Setup Just | |
| uses: taiki-e/install-action@873c7452cadb7c034694a1282227095d93fbdf92 # v2 | |
| with: | |
| tool: just | |
| # Cache the BST workspace (junction git sources + bst2 container layers). | |
| # Key includes junction element refs so junction bumps start fresh. | |
| # Without this, bst show must clone gnome-build-meta + freedesktop-sdk | |
| # from scratch on every PR run (~15-25 min extra). | |
| - name: Restore BST cache | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 | |
| with: | |
| path: ~/.cache/buildstream | |
| key: bst-show-${{ github.base_ref || github.ref_name }}-${{ hashFiles('elements/gnome-build-meta.bst', 'elements/freedesktop-sdk.bst', 'Justfile') }} | |
| restore-keys: | | |
| bst-show-${{ github.base_ref || github.ref_name }}- | |
| bst-show- | |
| - name: Validate BST element graph (default) | |
| env: | |
| BST_FLAGS: -o x86_64_v3 true --no-interactive | |
| run: just bst show --deps all oci/bluefin.bst | |
| - name: Validate BST element graph (nvidia) | |
| env: | |
| BST_FLAGS: -o x86_64_v3 true --no-interactive | |
| run: just bst show --deps all oci/bluefin-nvidia.bst | |
| # ── Full OCI build ──────────────────────────────────────────────────────── | |
| # Fires on merge_group, schedule, and workflow_dispatch — NOT on pull_request. | |
| # PRs are validated by the validate job above; the full build is the | |
| # merge-queue gate. This keeps cache.projectbluefin.io free from PR traffic. | |
| build: | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 360 | |
| # Both variants build in parallel. NVIDIA is continue-on-error so its | |
| # failure does not block the default image's merge or publication. | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 2 | |
| matrix: | |
| include: | |
| - variant: default | |
| element: oci/bluefin.bst | |
| image_suffix: '' | |
| publish: true | |
| continue: false | |
| - variant: nvidia | |
| element: oci/bluefin-nvidia.bst | |
| image_suffix: '-nvidia' | |
| publish: true | |
| continue: true | |
| continue-on-error: ${{ matrix.continue }} | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Check bst2 image pin consistency | |
| uses: ./.github/actions/check-bst2-pin | |
| # FIXME: Make the build with JWT work | |
| # - name: Get JWT token | |
| # previously used actions/github-script (kept disabled) | |
| # with: | |
| # script: | | |
| # const fs = require('fs'); | |
| # const token = await core.getIDToken('cache.projectbluefin.io') | |
| # fs.writeFileSync('bluefin.token', token, { mode: 0o600 }); | |
| - name: Capture build timestamp | |
| id: timestamp | |
| run: echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" | |
| # ── Disk and storage setup ──────────────────────────────────────── | |
| # Runs before any podman call (BST uses rootful podman to pull bst2; | |
| # storage backend must be stable before first use). | |
| # update-podman: true — newer podman from Ubuntu resolute for bst2 pull. | |
| # Note: setup-runner btrfs does not pass loopback-free; watch for disk | |
| # pressure and upstream the option if needed. | |
| - name: Setup runner | |
| uses: projectbluefin/actions/bootc-build/setup-runner@2a09e72e9be15b137392dde15f8587f35587e8eb # v1.1.0 | |
| with: | |
| storage-backend: btrfs | |
| update-podman: true | |
| install-tools: '["just"]' | |
| # ── Generate CI-specific BuildStream config ─────────────────────── | |
| # Tuned per gnome-build-meta CI patterns: | |
| # - on-error: continue -> find ALL failures, don't stop at first | |
| # - fetchers: 32 -> parallel downloads from upstream caches | |
| # - builders: 4 -> Concurrent builds are controlled in the casd server | |
| # - retry-failed: True -> auto-retry flaky builds | |
| # - error-lines: 80 -> generous error context in logs | |
| # - cache-buildtrees: never -> save disk (we only need final artifacts) | |
| # | |
| - name: Generate BuildStream CI config | |
| env: | |
| CASD_CLIENT_CERT: ${{ vars.CASD_CLIENT_CERT }} | |
| CASD_CLIENT_KEY: ${{ secrets.CASD_CLIENT_KEY }} | |
| uses: ./.github/actions/generate-bst-ci-config | |
| with: | |
| enable-remote-execution: 'true' | |
| # ── BuildStream build ───────────────────────────────────────────── | |
| # Uses the Justfile's `bst` wrapper to run BuildStream inside the | |
| # bst2 container. CI-specific flags (--no-interactive, --config) | |
| # are injected via BST_FLAGS env var. | |
| - name: Build OCI image with BuildStream | |
| env: | |
| BST_FLAGS: -o x86_64_v3 true --no-interactive --config /src/buildstream-ci.conf | |
| run: | | |
| just bst build ${{ matrix.element }} | |
| timeout-minutes: 330 | |
| # Push the built artifact to the remote CAS so the export job can pull it. | |
| # Remote execution may populate the artifact cache implicitly, but an | |
| # explicit push guarantees the artifact is there regardless of BST internals. | |
| # Push both variants so publish.yml can fetch each from CAS. | |
| - name: Push OCI artifact to remote CAS | |
| env: | |
| BST_FLAGS: -o x86_64_v3 true --no-interactive --config /src/buildstream-ci.conf | |
| run: | | |
| just bst artifact push --deps none ${{ matrix.element }} | |
| # ── Upload build logs ───────────────────────────────────────────── | |
| # Always upload, even on failure, so build failures can be diagnosed. | |
| - name: Upload build logs | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: buildstream-logs-x86_64-${{ matrix.variant }} | |
| path: logs/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| # ── aarch64 native build ────────────────────────────────────────────────── | |
| # Mirrors the x86_64 build job. ARM failures do not fail the workflow or | |
| # block x86_64 publication — this is an experimental parallel build. | |
| # Only runs on the daily cron and manual dispatch — not on PRs or merge | |
| # queue — to avoid burning ARM runner time on code that nobody is using yet. | |
| # WebKit aarch64 artifacts are available from gbm.gnome.org (gnome-build-meta | |
| # builds aarch64 natively), so cold-build OOM/timeout should no longer occur. | |
| build-aarch64: | |
| if: false # temporarily disabled — aarch64 needs further investigation | |
| runs-on: ubuntu-24.04-arm | |
| continue-on-error: true | |
| outputs: | |
| pushed: ${{ steps.push-aarch64.outputs.pushed }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Setup runner | |
| uses: projectbluefin/actions/bootc-build/setup-runner@2a09e72e9be15b137392dde15f8587f35587e8eb # v1.1.0 | |
| with: | |
| storage-backend: btrfs | |
| update-podman: true | |
| install-tools: '["just"]' | |
| - name: Capture build timestamp | |
| id: timestamp | |
| run: echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" | |
| - name: Generate BuildStream CI config | |
| env: | |
| CASD_CLIENT_CERT: ${{ vars.CASD_CLIENT_CERT }} | |
| CASD_CLIENT_KEY: ${{ secrets.CASD_CLIENT_KEY }} | |
| uses: ./.github/actions/generate-bst-ci-config | |
| with: | |
| enable-remote-execution: 'false' | |
| - name: Build OCI image with BuildStream (aarch64) | |
| env: | |
| BST_FLAGS: --no-interactive --config /src/buildstream-ci.conf --option arch aarch64 | |
| run: | | |
| just bst build oci/bluefin.bst | |
| timeout-minutes: 420 | |
| - name: Export OCI image from BuildStream | |
| id: export | |
| env: | |
| BST_FLAGS: --no-interactive --config /src/buildstream-ci.conf --option arch aarch64 | |
| BUILD_IMAGE_NAME: ${{ env.IMAGE_NAME }} | |
| OCI_IMAGE_CREATED: ${{ steps.timestamp.outputs.created }} | |
| OCI_IMAGE_REVISION: ${{ github.sha }} | |
| OCI_IMAGE_VERSION: aarch64 | |
| run: | | |
| just export | |
| echo "image_ref=${{ env.IMAGE_NAME }}:aarch64" >> "$GITHUB_OUTPUT" | |
| - name: Verify image loaded | |
| run: sudo podman images | |
| - name: Validate with bootc container lint | |
| run: | | |
| just lint | |
| - name: Upload build logs | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: buildstream-logs-aarch64 | |
| path: logs/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| - name: Login to GHCR | |
| if: >- | |
| github.event_name == 'merge_group' || | |
| github.event_name == 'schedule' || | |
| github.event_name == 'workflow_dispatch' | |
| run: | | |
| echo "${{ secrets.GITHUB_TOKEN }}" | \ | |
| sudo podman login ghcr.io --username ${{ github.actor }} --password-stdin | |
| - name: Tag image for GHCR | |
| if: >- | |
| github.event_name == 'merge_group' || | |
| github.event_name == 'schedule' || | |
| github.event_name == 'workflow_dispatch' | |
| run: | | |
| sudo podman tag "localhost/${{ steps.export.outputs.image_ref }}" \ | |
| "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:aarch64" | |
| sudo podman tag "localhost/${{ steps.export.outputs.image_ref }}" \ | |
| "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:aarch64-${{ github.sha }}" | |
| - name: Push to GHCR | |
| id: push-aarch64 | |
| if: >- | |
| github.event_name == 'merge_group' || | |
| github.event_name == 'schedule' || | |
| github.event_name == 'workflow_dispatch' | |
| run: | | |
| for tag in aarch64 "aarch64-${{ github.sha }}"; do | |
| for i in 1 2 3; do | |
| # Plain zstd required — see x86_64 push step comment above. | |
| sudo podman push --compression-format=zstd \ | |
| "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${tag}" && break | |
| echo "Push attempt $i failed for tag ${tag}, retrying..." | |
| sleep 5 | |
| done | |
| done | |
| echo "pushed=true" >> "$GITHUB_OUTPUT" | |
| # ── Multi-arch manifest ─────────────────────────────────────────────────── | |
| # Combines :latest (x86_64) and :aarch64 into a single multi-arch manifest. | |
| # Only runs when :aarch64 was actually pushed this run (not just when the | |
| # job completed — continue-on-error makes needs.result == 'success' even on | |
| # failure, so we gate on the step output instead). | |
| # ARM failures skip this job without affecting x86_64 publication. | |
| create-manifest: | |
| runs-on: ubuntu-24.04 | |
| needs: [build, build-aarch64] | |
| if: >- | |
| (github.event_name == 'merge_group' || | |
| github.event_name == 'schedule' || | |
| github.event_name == 'workflow_dispatch') && | |
| needs.build-aarch64.outputs.pushed == 'true' | |
| permissions: | |
| packages: write | |
| steps: | |
| - name: Login to GHCR | |
| run: | | |
| echo "${{ secrets.GITHUB_TOKEN }}" | \ | |
| sudo podman login ghcr.io --username ${{ github.actor }} --password-stdin | |
| - name: Create and push multi-arch manifest | |
| run: | | |
| sudo podman manifest create "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:latest" \ | |
| "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:latest" \ | |
| "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:aarch64" | |
| sudo podman manifest push "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:latest" |