11---
2- name : build-qittyqat
2+ name : build-quantumqat
33on :
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+
1620env :
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.
2730jobs :
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