name: Build Bazzite BC-250 on: schedule: - cron: "40 8 * * *" push: paths-ignore: - "**.md" workflow_dispatch: inputs: force_build: description: "Build packages even if Bazzite channel digests did not change" required: false type: boolean default: false concurrency: group: ${{ github.workflow }}-${{ github.ref || github.run_id }} cancel-in-progress: true jobs: base-digests: name: Check Bazzite channel digests runs-on: ubuntu-latest outputs: cache-hit: ${{ steps.base-digest-cache.outputs.cache-hit }} cache-key: ${{ steps.base-digests.outputs.cache-key }} digests-tsv: ${{ steps.base-digests.outputs.digests-tsv }} normal-matrix: ${{ steps.build-plan.outputs.normal-matrix }} normal-count: ${{ steps.build-plan.outputs.normal-count }} fortycu-matrix: ${{ steps.build-plan.outputs.fortycu-matrix }} fortycu-count: ${{ steps.build-plan.outputs.fortycu-count }} should-build: ${{ steps.build-plan.outputs.should-build }} steps: - name: Checkout repository uses: actions/checkout@v6.0.2 with: persist-credentials: false - name: Resolve base image digests id: base-digests run: | mkdir -p .base-image-digests mkdir -p .current-base-image-digests : > .current-base-image-digests/digests.tsv resolve_digest() { docker buildx imagetools inspect "$1" | awk '/Digest:/ {print $2; exit}' } for channel in stable testing unstable; do for variant in deck gnome kde; do case "$variant" in deck) image="ghcr.io/ublue-os/bazzite-deck" ;; gnome) image="ghcr.io/ublue-os/bazzite-gnome" ;; kde) image="ghcr.io/ublue-os/bazzite" ;; esac ref="${image}:${channel}" echo "Resolving ${ref}" if digest="$(resolve_digest "${ref}")"; then printf '%s\t%s\t%s\t%s\n' \ "$channel" \ "$variant" \ "$image" \ "$digest" >> .current-base-image-digests/digests.tsv else echo "::warning::Could not resolve ${ref}; skipping this channel/variant." fi done done cat .current-base-image-digests/digests.tsv cache_key="bazzite-channel-digests-$(sha256sum .current-base-image-digests/digests.tsv | awk '{print $1}')" echo "cache-key=${cache_key}" >> "${GITHUB_OUTPUT}" { echo "digests-tsv<> "${GITHUB_OUTPUT}" - name: Restore base digest cache id: base-digest-cache uses: actions/cache/restore@v5.0.5 with: path: .base-image-digests key: ${{ steps.base-digests.outputs.cache-key }} restore-keys: | bazzite-channel-digests- bazzite-stable-digests- - name: Prepare build matrices id: build-plan run: | force_args=() if [[ "${FORCE_BUILD}" == "true" ]]; then force_args+=(--force) fi previous_file=".base-image-digests/digests.tsv" if [[ ! -f "$previous_file" && -f ".base-image-digests/digests.txt" ]]; then previous_file=".base-image-digests/digests.txt" fi scripts/prepare-build-matrices.py \ --current .current-base-image-digests/digests.tsv \ --previous "$previous_file" \ "${force_args[@]}" env: FORCE_BUILD: ${{ github.event_name == 'workflow_dispatch' && inputs.force_build == true }} bluebuild: name: Build Custom Image needs: base-digests if: needs.base-digests.outputs.normal-count != '0' && github.ref_name != '40cu' runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write strategy: fail-fast: false max-parallel: 1 matrix: ${{ fromJson(needs.base-digests.outputs.normal-matrix) }} steps: - name: Checkout repository uses: actions/checkout@v6.0.2 with: persist-credentials: false - name: Maximize build space uses: hastd/free-disk-space@68572aeaadb7f76bd408246328e95926323402b5 with: skip-if-available: "80G" - name: Set up Docker Buildx run: | docker buildx create --name bluebuild-builder --driver docker-container --use docker buildx inspect --bootstrap - name: Install BlueBuild run: | set -euo pipefail sudo docker create \ --name blue-build-installer \ ghcr.io/blue-build/cli:v0.9-installer sudo docker cp blue-build-installer:/out/bluebuild /usr/bin/bluebuild sudo docker rm blue-build-installer bluebuild --version - name: Install cosign env: COSIGN_VERSION: v3.0.6 run: | set -euo pipefail curl -fsSL \ -o cosign \ "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" sudo install -m 0755 cosign /usr/local/bin/cosign rm cosign cosign version - name: Build Custom Image env: BB_BUILD_PUSH: "true" BB_PASSWORD: ${{ github.token }} BB_USERNAME: ${{ github.repository_owner }} BB_REGISTRY: ghcr.io BB_REGISTRY_NAMESPACE: ${{ github.repository_owner }} COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} COSIGN_PASSWORD: "" GH_TOKEN: ${{ github.token }} GH_PR_EVENT_NUMBER: ${{ github.event.number }} RUST_LOG_STYLE: always CLICOLOR_FORCE: "1" run: | generated_recipe="recipes/.generated-${{ matrix.channel }}-${{ matrix.recipe }}" scripts/render-channel-recipe.py \ --recipe "recipes/${{ matrix.recipe }}" \ --output "$generated_recipe" \ --channel "${{ matrix.channel }}" \ --name "${{ matrix.image_name }}" bluebuild build -v "$generated_recipe" bluebuild_40cu: name: Build Custom 40CU Image needs: base-digests if: needs.base-digests.outputs.fortycu-count != '0' && (github.ref_name == github.event.repository.default_branch || github.ref_name == '40cu') runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write strategy: fail-fast: false max-parallel: 1 matrix: ${{ fromJson(needs.base-digests.outputs.fortycu-matrix) }} steps: - name: Checkout repository uses: actions/checkout@v6.0.2 with: persist-credentials: false - name: Maximize build space uses: hastd/free-disk-space@68572aeaadb7f76bd408246328e95926323402b5 with: skip-if-available: "80G" - name: Set up Docker Buildx run: | docker buildx create --name bluebuild-builder --driver docker-container --use docker buildx inspect --bootstrap - name: Install BlueBuild run: | set -euo pipefail sudo docker create \ --name blue-build-installer \ ghcr.io/blue-build/cli:v0.9-installer sudo docker cp blue-build-installer:/out/bluebuild /usr/bin/bluebuild sudo docker rm blue-build-installer bluebuild --version - name: Install cosign env: COSIGN_VERSION: v3.0.6 run: | set -euo pipefail curl -fsSL \ -o cosign \ "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" sudo install -m 0755 cosign /usr/local/bin/cosign rm cosign cosign version - name: Build Custom 40CU Image env: BB_BUILD_PUSH: "true" BB_PASSWORD: ${{ github.token }} BB_USERNAME: ${{ github.repository_owner }} BB_REGISTRY: ghcr.io BB_REGISTRY_NAMESPACE: ${{ github.repository_owner }} COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} COSIGN_PASSWORD: "" GH_TOKEN: ${{ github.token }} GH_PR_EVENT_NUMBER: ${{ github.event.number }} RUST_LOG_STYLE: always CLICOLOR_FORCE: "1" run: | generated_recipe="recipes/.generated-${{ matrix.channel }}-${{ matrix.recipe }}" scripts/render-channel-recipe.py \ --recipe "recipes/${{ matrix.recipe }}" \ --output "$generated_recipe" \ --channel "${{ matrix.channel }}" \ --name "${{ matrix.image_name }}" bluebuild build -v "$generated_recipe" save-base-digests: name: Save Bazzite channel digest cache needs: - base-digests - bluebuild - bluebuild_40cu if: always() && needs.base-digests.outputs.should-build == 'true' && (needs.bluebuild.result == 'success' || needs.bluebuild.result == 'skipped') && (needs.bluebuild_40cu.result == 'success' || needs.bluebuild_40cu.result == 'skipped') runs-on: ubuntu-latest steps: - name: Record base image digests run: | mkdir -p .base-image-digests cat > .base-image-digests/digests.tsv <<'EOF' ${{ needs.base-digests.outputs.digests-tsv }} EOF sed -i 's/^ //' .base-image-digests/digests.tsv cat .base-image-digests/digests.tsv - name: Save base digest cache uses: actions/cache/save@v5.0.5 with: path: .base-image-digests key: ${{ needs.base-digests.outputs.cache-key }} publish-release: name: Publish GitHub Release needs: - base-digests - bluebuild - bluebuild_40cu if: needs.base-digests.outputs.should-build == 'true' && github.ref_name == github.event.repository.default_branch && (needs.bluebuild.result == 'success' || needs.bluebuild.result == 'skipped') && (needs.bluebuild_40cu.result == 'success' || needs.bluebuild_40cu.result == 'skipped') runs-on: ubuntu-latest permissions: contents: write packages: read steps: - name: Checkout repository uses: actions/checkout@v6.0.2 with: persist-credentials: false - name: Publish grouped release env: GH_TOKEN: ${{ github.token }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | set -euo pipefail release_date="$(date -u +%Y.%m.%d)" scripts/publish-release.sh \ --date "${release_date}" \ --owner "${{ github.repository_owner }}" \ --repo "${{ github.event.repository.name }}" \ --target "${GITHUB_SHA}" \ --run-url "${RUN_URL}" \ --publish