Skip to content

Commit 33f8a44

Browse files
authored
feat: refactor to use blue-build (#41)
* feat: refactor to use blue-build * ci: only build ISO on non-PR events (image isn't published on PRs)
1 parent f7861dc commit 33f8a44

44 files changed

Lines changed: 559 additions & 391 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
version: 2
77
updates:
8+
# Tracks the SHA-pinned GitHub Actions in .github/workflows/. Dependabot reads
9+
# the "# vX" comment beside each pinned SHA and opens a PR that bumps both the
10+
# SHA and the comment when a newer release is published.
811
- package-ecosystem: "github-actions"
912
directory: "/"
1013
schedule:

.github/release-watch.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"name": "winboat",
4+
"repo": "TibixDev/winboat",
5+
"pin_file": "files/scripts/20-install-winboat.sh",
6+
"pin_key": "WINBOAT_VERSION"
7+
}
8+
]

.github/workflows/build.yml

Lines changed: 52 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
name: build-qittyqat
2+
name: build-quantumqat
33
on:
44
pull_request:
55
branches:
@@ -13,231 +13,110 @@ on:
1313
- '**/README.md'
1414
workflow_dispatch:
1515

16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
18+
cancel-in-progress: true
19+
1620
env:
17-
# The tag used in the image from which we base of.
18-
# ex.: ghcr.io/org/image:IMAGE_SOURCE_TAG
19-
IMAGE_SOURCE_TAG: "latest"
2021
SOURCE_ORG: "ublue-os"
2122
SOURCE_REPO: "bazzite"
22-
# Custom
23-
MY_IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names
24-
MY_IMAGE_DESC: "Custom Bazzite image tailored for hackers."
25-
IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit
23+
IMAGE_SOURCE_TAG: "stable"
24+
MY_IMAGE_NAME: "quantumqat"
25+
IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}"
2626

27+
# Actions are pinned to full commit SHAs for supply-chain safety. The trailing
28+
# "# vX" comment lets Dependabot (.github/dependabot.yml) bump the SHA + comment
29+
# when a new release is published.
2730
jobs:
2831
build_push:
2932
name: Build and push image
3033
runs-on: ubuntu-24.04
31-
3234
permissions:
3335
contents: read
3436
packages: write
3537
id-token: write
36-
3738
steps:
38-
# Checkout push-to-registry action GitHub repository
39-
- name: Checkout Push to Registry action
40-
uses: actions/checkout@v7
41-
42-
- name: Maximize build space
43-
uses: ublue-os/remove-unwanted-software@v9
39+
# The entire build/sign/push is handled by the reusable BlueBuild action.
40+
# It reads recipes/recipe.yml, builds the image, signs it with cosign
41+
# (SIGNING_SECRET), and pushes to ghcr.io/<owner>/quantumqat.
42+
- name: Build Custom Image
43+
uses: blue-build/github-action@24d146df25adc2cf579e918efe2d9bff6adea408 # v1.11
44+
with:
45+
recipe: recipe.yml
46+
cosign_private_key: ${{ secrets.SIGNING_SECRET }}
47+
registry_token: ${{ github.token }}
48+
pr_event_number: ${{ github.event.number }}
49+
maximize_build_space: true
50+
51+
build_iso:
52+
name: Build ISO
53+
runs-on: ubuntu-24.04
54+
needs: build_push
55+
# The BlueBuild action does not publish a pullable image on pull_request
56+
# events, so build the ISO only on push/schedule/manual runs where the
57+
# `latest` image exists. PRs still validate that the image builds.
58+
if: github.event_name != 'pull_request'
59+
permissions:
60+
contents: read
61+
packages: read
62+
steps:
63+
- name: Checkout
64+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
4465

4566
# OUTPUTS:
46-
# - SOURCE_VERSION: version of the source image. Ex.: testing-41.20250312
47-
# - SOURCE_VERSION_MAJOR: major version. Used to identify big releases. Ex.: 41
67+
# - SOURCE_VERSION_MAJOR: Fedora major version of the base image (e.g. 43)
4868
- name: Get image major version
4969
id: fetch_source_meta
5070
env:
5171
org: ${{ env.SOURCE_ORG }}
5272
BASE_IMAGE: ${{ env.SOURCE_REPO }}
53-
IMAGE_SOURCE_TAG: ${{ env.IMAGE_SOURCE_TAG || 'latest' }}
73+
IMAGE_SOURCE_TAG: ${{ env.IMAGE_SOURCE_TAG }}
5474
run: |
5575
set -x
56-
# SOURCE_VERSION_MAJOR must be a number
5776
declare -i SOURCE_VERSION_MAJOR=0
5877
59-
# There are some ways to get the major release from an image.
60-
# First method: `skopeo inspect` and annotations.
61-
6278
SOURCE_VERSION=$(
6379
skopeo inspect --no-tags --raw --config \
6480
"docker://ghcr.io/${org}/${BASE_IMAGE}:${IMAGE_SOURCE_TAG}" | \
6581
jq -r '.config.Labels["org.opencontainers.image.version"]'
6682
)
6783
if [[ -z $SOURCE_VERSION ]]; then
68-
echo "::error::$SOURCE_VERSION was not fetched correctly: $SOURCE_VERSION=${$SOURCE_VERSION}"
84+
echo "::error::SOURCE_VERSION was not fetched correctly"
6985
exit 1
7086
fi
71-
echo "SOURCE_VERSION=$SOURCE_VERSION" >>$GITHUB_OUTPUT
7287
7388
SOURCE_VERSION_MAJOR=$([[ ${SOURCE_VERSION} =~ ^(.*-)?([[:digit:]]+) ]] && echo "${BASH_REMATCH[-1]}")
74-
_status=$?
75-
unset -v _tag
76-
77-
if [[ $_status -ne 0 ]] || [[ -z ${SOURCE_VERSION_MAJOR} ]] || (( SOURCE_VERSION_MAJOR <= 0 )); then
78-
echo "::error::SOURCE_VERSION_MAJOR was not fetched correctly: SOURCE_VERSION_MAJOR=${SOURCE_VERSION_MAJOR}"
89+
if [[ -z ${SOURCE_VERSION_MAJOR} ]] || (( SOURCE_VERSION_MAJOR <= 0 )); then
90+
echo "::error::SOURCE_VERSION_MAJOR was not fetched correctly: ${SOURCE_VERSION_MAJOR}"
7991
exit 1
8092
fi
8193
82-
echo "SOURCE_VERSION_MAJOR=$SOURCE_VERSION_MAJOR" >>$GITHUB_OUTPUT
83-
84-
- name: Generate tags
85-
id: generate-tags
86-
shell: bash
87-
run: |
88-
# Generate a timestamp for creating an image version history
89-
TIMESTAMP="$(date +%Y%m%d)"
90-
COMMIT_TAGS=()
91-
BUILD_TAGS=()
92-
93-
# Have tags for tracking builds during pull request
94-
SHA_SHORT="${GITHUB_SHA::7}"
95-
echo "tag=${SHA_SHORT}" >> $GITHUB_OUTPUT
96-
97-
COMMIT_TAGS+=("pr-${{ github.event.number }}")
98-
COMMIT_TAGS+=("${SHA_SHORT}")
99-
100-
# Append matching timestamp tags to keep a version history
101-
for TAG in "${BUILD_TAGS[@]}"; do
102-
BUILD_TAGS+=("${TAG}-${TIMESTAMP}")
103-
done
104-
105-
BUILD_TAGS+=("${TIMESTAMP}")
106-
BUILD_TAGS+=("latest")
107-
108-
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
109-
echo "Generated the following commit tags: "
110-
for TAG in "${COMMIT_TAGS[@]}"; do
111-
echo "${TAG}"
112-
done
113-
114-
alias_tags=("${COMMIT_TAGS[@]}")
115-
116-
PRETTY="PR (${{ github.event.pull_request.number }})"
117-
else
118-
alias_tags=("${BUILD_TAGS[@]}")
119-
PRETTY="Stable (${SHA_SHORT})"
120-
fi
121-
122-
echo "pretty=${PRETTY}" >> $GITHUB_OUTPUT
94+
echo "SOURCE_VERSION_MAJOR=$SOURCE_VERSION_MAJOR" >>$GITHUB_OUTPUT
12395
124-
echo "Generated the following build tags: "
125-
for TAG in "${BUILD_TAGS[@]}"; do
126-
echo "${TAG}"
127-
done
128-
129-
echo "alias_tags=${alias_tags[*]}" >> $GITHUB_OUTPUT
130-
131-
# Build metadata
132-
- name: Image Metadata
133-
uses: docker/metadata-action@v6
134-
id: meta
135-
with:
136-
images: |
137-
${{ env.MY_IMAGE_NAME }}
138-
139-
labels: |
140-
io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository }}/main/README.md
141-
io.artifacthub.package.logo-url=https://raw.githubusercontent.com/${{ github.repository }}/main/assets/logo.jpg
142-
org.opencontainers.image.description=${{ env.MY_IMAGE_DESC }}
143-
org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }}
144-
145-
# Build image using Buildah action
146-
- name: Build Image
147-
id: build_image
148-
uses: redhat-actions/buildah-build@v2
149-
with:
150-
containerfiles: |
151-
./Containerfile
152-
# Postfix image name with -custom to make it a little more descriptive
153-
# Syntax: https://docs.github.com/en/actions/learn-github-actions/expressions#format
154-
image: ${{ env.MY_IMAGE_NAME }}
155-
tags: |
156-
${{ steps.generate-tags.outputs.alias_tags }}
157-
build-args: |
158-
VERSION_TAG=${{ steps.generate-tags.outputs.tag }}
159-
VERSION_PRETTY=${{ steps.generate-tags.outputs.pretty }}
160-
labels: ${{ steps.meta.outputs.labels }}
161-
oci: false
162-
163-
# Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR.
164-
# https://github.com/macbre/push-to-ghcr/issues/12
96+
# GitHub usernames may contain uppercase letters which GHCR rejects.
16597
- name: Lowercase Registry
16698
id: registry_case
167-
uses: ASzc/change-string-case-action@v8
99+
uses: ASzc/change-string-case-action@ecd1412d078f2e06e9eedcbaa6fcd988151c3f82 # v8
168100
with:
169101
string: ${{ env.IMAGE_REGISTRY }}
170102

171-
- name: Login to GitHub Container Registry
172-
uses: docker/login-action@v4
173-
with:
174-
registry: ghcr.io
175-
username: ${{ github.actor }}
176-
password: ${{ secrets.GITHUB_TOKEN }}
177-
178-
- name: Push Image to GHCR
179-
uses: redhat-actions/push-to-registry@v2
180-
id: push
181-
env:
182-
REGISTRY_USER: ${{ github.actor }}
183-
REGISTRY_PASSWORD: ${{ github.token }}
184-
with:
185-
image: ${{ steps.build_image.outputs.image }}
186-
tags: ${{ steps.build_image.outputs.tags }}
187-
registry: ${{ steps.registry_case.outputs.lowercase }}
188-
username: ${{ env.REGISTRY_USER }}
189-
password: ${{ env.REGISTRY_PASSWORD }}
190-
extra-args: |
191-
--disable-content-trust
192-
193-
# This section is optional and only needs to be enabled in you plan on distributing
194-
# your project to others to consume. You will need to create a public and private key
195-
# using Cosign and save the private key as a repository secret in Github for this workflow
196-
# to consume. For more details, review the image signing section of the README.
197-
198-
# Sign container
199-
- uses: sigstore/cosign-installer@v4.1.2
200-
if: github.event_name != 'pull_request'
201-
202-
- name: Sign container image
203-
if: github.event_name != 'pull_request'
204-
run: |
205-
cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS}
206-
env:
207-
TAGS: ${{ steps.push.outputs.digest }}
208-
COSIGN_EXPERIMENTAL: false
209-
COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}
210-
211-
# Build the ISO
212-
- name: Set Image Tag
213-
id: generate_iso_tag
214-
shell: bash
215-
run: |
216-
TAG="latest"
217-
218-
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
219-
TAG="pr-${{ github.event.number }}"
220-
fi
221-
222-
echo "tag=${TAG}" >> $GITHUB_OUTPUT
223-
224103
- name: Build ISO
225-
uses: jasonn3/build-container-installer@main
104+
uses: jasonn3/build-container-installer@c9ef3de33236e66781ec37bd0485e8009eaefe24 # v1.4.0
226105
id: build_iso
227106
with:
228-
image_name: ${{ env.MY_IMAGE_NAME}}
229-
image_repo: ${{ env.IMAGE_REGISTRY}}
230-
image_tag: ${{ steps.generate_iso_tag.outputs.tag }}
107+
image_name: ${{ env.MY_IMAGE_NAME }}
108+
image_repo: ${{ steps.registry_case.outputs.lowercase }}
109+
image_tag: latest
231110
variant: Kinoite
232111
version: ${{ steps.fetch_source_meta.outputs.SOURCE_VERSION_MAJOR }}
233112
secure_boot_key_url: 'https://github.com/ublue-os/bazzite/raw/main/secure_boot.der'
234113
enrollment_password: 'universalblue'
235114
additional_templates: '/github/workspace/installer/lorax_templates/remove_root_password_prompt.tmpl /github/workspace/installer/lorax_templates/set_default_user.tmpl'
236-
iso_name: build/${{ env.MY_IMAGE_NAME }}-${{ steps.generate_iso_tag.outputs.tag }}.iso
115+
iso_name: build/${{ env.MY_IMAGE_NAME }}-latest.iso
237116

238117
- name: Upload ISO as artifact
239118
id: upload
240-
uses: actions/upload-artifact@v7
119+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
241120
with:
242121
name: ${{ steps.build_iso.outputs.iso_name }}
243122
path: |
@@ -251,7 +130,7 @@ jobs:
251130
name: Check all builds successful
252131
if: always()
253132
runs-on: ubuntu-latest
254-
needs: [build_push]
133+
needs: [build_push, build_iso]
255134
steps:
256135
- name: Check Jobs
257136
env:

0 commit comments

Comments
 (0)