BC-250 console image: custom GNOME recipe with remote admin
Build Bazzite BC-250 / Check Bazzite channel digests (push) Has been cancelled
Build Bazzite BC-250 / Build Custom Image (push) Has been cancelled
Build Bazzite BC-250 / Build Custom 40CU Image (push) Has been cancelled
Build Bazzite BC-250 / Save Bazzite channel digest cache (push) Has been cancelled
Build Bazzite BC-250 / Publish GitHub Release (push) Has been cancelled

Based on 62fixolab/Latest-Bazzite-AMD-BC-250-Patched-Images @ 347fd4d.

Adds on top of the fork:
- recipes/bc250-console-gnome.yml: governor + gnome-remote-desktop +
  openssh-server, sshd enabled, hhd.service masked, no signing module
  (local build + ISO path)
- files/console/usr/bin/bc250-remote-setup: one-time on-box SSH/RDP setup
- files/console/usr/lib/bootc/kargs.d/50-bc250-ttm.toml: ttm memory kargs
- BUILD-CONSOLE.md: build -> ISO -> validation instructions

files/console/ is separate from files/system/ so the 40-CU unlock tooling
stays out of this stable 24-CU image.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 18:54:30 -04:00
co-authored by Claude Fable 5
commit 4e452acc7d
66 changed files with 13574 additions and 0 deletions
+332
View File
@@ -0,0 +1,332 @@
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<<EOF"
cat .current-base-image-digests/digests.tsv
echo "EOF"
} >> "${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