Skip to content

Commit 01e91c8

Browse files
committed
Step 1: Fix build process
1 parent 2e71b3a commit 01e91c8

File tree

15 files changed

+622
-344
lines changed

15 files changed

+622
-344
lines changed

.github/workflows/build-disk.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
fail-fast: false
3131
matrix:
3232
variant:
33-
- name: "regular"
33+
- name: "main"
3434
tag: "latest"
3535
- name: "nvidia"
3636
tag: "latest-nvidia"
@@ -46,10 +46,10 @@ jobs:
4646
echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
4747
4848
- name: Maximize build space
49-
uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6 # v10
49+
uses: ublue-os/remove-unwanted-software@v10
5050

5151
- name: Checkout
52-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
52+
uses: actions/checkout@v4
5353

5454
- name: Build ISO
5555
id: build
@@ -71,7 +71,7 @@ jobs:
7171
echo "iso-name=$NEW_NAME" >> $GITHUB_OUTPUT
7272
7373
- name: Upload ISO as artifact
74-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
74+
uses: actions/upload-artifact@v4
7575
with:
7676
name: ${{ env.IMAGE_NAME }}-${{ matrix.variant.name }}-iso
7777
path: output/
@@ -81,7 +81,7 @@ jobs:
8181

8282
- name: Upload ISO to release
8383
if: inputs.create-release == true && inputs.release-tag != ''
84-
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2
84+
uses: softprops/action-gh-release@v2
8585
with:
8686
tag_name: ${{ inputs.release-tag }}
8787
files: |

.github/workflows/build.yml

Lines changed: 48 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ on:
1616
env:
1717
IMAGE_DESC: "Hypercube - A Hyprland-focused bootc image built on Bluefin-DX"
1818
IMAGE_KEYWORDS: "bootc,ublue,universal-blue,hyprland,hypercube,wayland"
19-
IMAGE_LOGO_URL: "https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/main/branding/hypercube-logo.png" # Hypercube logo
20-
IMAGE_NAME: "${{ github.event.repository.name }}" # output image name, usually same as repo name
21-
IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit
19+
IMAGE_LOGO_URL: "https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/main/branding/hypercube-logo.png"
20+
IMAGE_NAME: "${{ github.event.repository.name }}"
21+
IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}"
2222
DEFAULT_TAG: "latest"
2323

2424
concurrency:
@@ -28,7 +28,7 @@ concurrency:
2828
jobs:
2929
build_push:
3030
name: Build and push image
31-
runs-on: ubuntu-latest-m
31+
runs-on: ubuntu-24.04
3232

3333
permissions:
3434
contents: read
@@ -39,9 +39,11 @@ jobs:
3939
fail-fast: false
4040
matrix:
4141
variant:
42-
- base_image: "ghcr.io/ublue-os/bluefin-dx:stable-daily"
42+
- flavor: "main"
43+
base_image: "ghcr.io/ublue-os/bluefin-dx:stable-daily"
4344
tag_suffix: ""
44-
- base_image: "ghcr.io/ublue-os/bluefin-dx-nvidia:stable-daily"
45+
- flavor: "nvidia"
46+
base_image: "ghcr.io/ublue-os/bluefin-dx-nvidia:stable-daily"
4547
tag_suffix: "-nvidia"
4648

4749
steps:
@@ -51,22 +53,15 @@ jobs:
5153
echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV}
5254
echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
5355
54-
# These stage versions are pinned by https://github.com/renovatebot/renovate
5556
- name: Checkout
56-
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5
57+
uses: actions/checkout@v4
5758

58-
# This is optional, but if you see that your builds are way too big for the runners, you can enable this by uncommenting the following lines:
59-
# - name: Maximize build space
60-
# uses: ublue-os/remove-unwanted-software@517622d6452028f266b7ba4cc9a123b5f58a6b53 # v7
61-
# with:
62-
# remove-codeql: true
59+
- name: Maximize build space
60+
uses: ublue-os/remove-unwanted-software@v10
6361

6462
- name: Mount BTRFS for podman storage
6563
id: container-storage-action
66-
uses: ublue-os/container-storage-action@911baca08baf30c8654933e9e9723cb399892140
67-
68-
# Fallback to the remove-unwanted-software-action if github doesn't allocate enough space
69-
# See: https://github.com/ublue-os/container-storage-action/pull/11
64+
uses: ublue-os/container-storage-action@main
7065
continue-on-error: true
7166
with:
7267
target-dir: /var/lib/containers
@@ -75,21 +70,13 @@ jobs:
7570
- name: Get current date
7671
id: date
7772
run: |
78-
# This generates a timestamp like what is defined on the ArtifactHub documentation
79-
# E.G: 2022-02-08T15:38:15Z'
80-
# https://artifacthub.io/docs/topics/repositories/container-images/
81-
# https://linux.die.net/man/1/date
8273
echo "date=$(date -u +%Y\-%m\-%d\T%H\:%M\:%S\Z)" >> $GITHUB_OUTPUT
74+
echo "version=$(date +%Y%m%d)" >> $GITHUB_OUTPUT
8375
84-
# Image metadata for https://artifacthub.io/ - This is optional but is highly recommended so we all can get a index of all the custom images
85-
# The metadata by itself is not going to do anything, you choose if you want your image to be on ArtifactHub or not.
8676
- name: Image Metadata
87-
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
77+
uses: docker/metadata-action@v5
8878
id: metadata
8979
with:
90-
# This generates all the tags for your image, you can add custom tags here too!
91-
# Default tags are "$DEFAULT_TAG" and "$DEFAULT_TAG.$date".
92-
# Matrix tag_suffix is appended to differentiate variants (e.g., latest vs latest-nvidia)
9380
tags: |
9481
type=raw,value=${{ env.DEFAULT_TAG }}${{ matrix.variant.tag_suffix }}
9582
type=raw,value=${{ env.DEFAULT_TAG }}${{ matrix.variant.tag_suffix }}.{{date 'YYYYMMDD'}}
@@ -105,7 +92,7 @@ jobs:
10592
org.opencontainers.image.title=${{ env.IMAGE_NAME }}
10693
org.opencontainers.image.url=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
10794
org.opencontainers.image.vendor=${{ github.repository_owner }}
108-
org.opencontainers.image.version=${{ env.DEFAULT_TAG }}.{{date 'YYYYMMDD'}}
95+
org.opencontainers.image.version=${{ env.DEFAULT_TAG }}.${{ steps.date.outputs.version }}
10996
io.artifacthub.package.deprecated=false
11097
io.artifacthub.package.keywords=${{ env.IMAGE_KEYWORDS }}
11198
io.artifacthub.package.license=Apache-2.0
@@ -117,55 +104,50 @@ jobs:
117104

118105
- name: Build Image
119106
id: build_image
120-
uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2
107+
uses: redhat-actions/buildah-build@v2
121108
with:
122109
containerfiles: |
123110
./Containerfile
124-
# Postfix image name with -custom to make it a little more descriptive
125-
# Syntax: https://docs.github.com/en/actions/learn-github-actions/expressions#format
126111
image: ${{ env.IMAGE_NAME }}
127112
tags: ${{ steps.metadata.outputs.tags }}
128113
labels: ${{ steps.metadata.outputs.labels }}
129114
build-args: |
130115
BASE_IMAGE=${{ matrix.variant.base_image }}
116+
IMAGE_NAME=${{ env.IMAGE_NAME }}
117+
IMAGE_VENDOR=${{ github.repository_owner }}
131118
oci: false
132119

133-
# Rechunk is a script that we use on Universal Blue to make sure there isnt a single huge layer when your image gets published.
134-
# This does not make your image faster to download, just provides better resumability and fixes a few errors.
135-
# Documentation for Rechunk is provided on their github repository at https://github.com/hhd-dev/rechunk
136-
# You can enable it by uncommenting the following lines:
137-
# - name: Run Rechunker
138-
# id: rechunk
139-
# uses: hhd-dev/rechunk@f153348d8100c1f504dec435460a0d7baf11a9d2 # v1.1.1
140-
# with:
141-
# rechunk: 'ghcr.io/hhd-dev/rechunk:v1.0.1'
142-
# ref: "localhost/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}"
143-
# prev-ref: "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}"
144-
# skip_compression: true
145-
# version: ${{ env.CENTOS_VERSION }}
146-
# labels: ${{ steps.metadata.outputs.labels }} # Rechunk strips out all the labels during build, this needs to be reapplied here with newline separator
147-
148-
# This is necessary so that the podman socket can find the rechunked image on its storage
149-
# - name: Load in podman and tag
150-
# run: |
151-
# IMAGE=$(podman pull ${{ steps.rechunk.outputs.ref }})
152-
# sudo rm -rf ${{ steps.rechunk.outputs.output }}
153-
# for tag in ${{ steps.metadata.outputs.tags }}; do
154-
# podman tag $IMAGE ${{ env.IMAGE_NAME }}:$tag
155-
# done
156-
157-
# These `if` statements are so that pull requests for your custom images do not make it publish any packages under your name without you knowing
158-
# They also check if the runner is on the default branch so that things like the merge queue (if you enable it), are going to work
120+
# Rechunk for optimized OCI layers
121+
- name: Run Rechunker
122+
id: rechunk
123+
uses: hhd-dev/[email protected]
124+
if: github.event_name != 'pull_request'
125+
with:
126+
rechunk: 'ghcr.io/hhd-dev/rechunk:v1.0.3'
127+
ref: "localhost/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}${{ matrix.variant.tag_suffix }}"
128+
prev-ref: "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}${{ matrix.variant.tag_suffix }}"
129+
skip_compression: true
130+
labels: ${{ steps.metadata.outputs.labels }}
131+
132+
- name: Load rechunked image and tag
133+
if: github.event_name != 'pull_request'
134+
run: |
135+
IMAGE=$(podman pull ${{ steps.rechunk.outputs.ref }})
136+
sudo rm -rf ${{ steps.rechunk.outputs.output }}
137+
for tag in ${{ steps.metadata.outputs.tags }}; do
138+
podman tag $IMAGE ${{ env.IMAGE_NAME }}:$tag
139+
done
140+
159141
- name: Login to GitHub Container Registry
160-
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
142+
uses: docker/login-action@v3
161143
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
162144
with:
163145
registry: ghcr.io
164146
username: ${{ github.actor }}
165147
password: ${{ secrets.GITHUB_TOKEN }}
166148

167149
- name: Push To GHCR
168-
uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2
150+
uses: redhat-actions/push-to-registry@v2
169151
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
170152
id: push
171153
env:
@@ -178,22 +160,19 @@ jobs:
178160
username: ${{ env.REGISTRY_USER }}
179161
password: ${{ env.REGISTRY_PASSWORD }}
180162

181-
# This section is optional and only needs to be enabled if you plan on distributing
182-
# your project for others to consume. You will need to create a public and private key
183-
# using Cosign and save the private key as a repository secret in Github for this workflow
184-
# to consume. For more details, review the image signing section of the README.
185163
- name: Install Cosign
186-
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
164+
uses: sigstore/cosign-installer@v3
187165
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
188166

189167
- name: Sign container image
190168
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
191169
run: |
192-
IMAGE_FULL="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}"
193-
for tag in ${{ steps.metadata.outputs.tags }}; do
194-
cosign sign -y --key env://COSIGN_PRIVATE_KEY $IMAGE_FULL:$tag
195-
done
170+
# Sign by digest for better security
171+
IMAGE_DIGEST="${{ steps.push.outputs.digest }}"
172+
IMAGE_REF="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST}"
173+
174+
echo "Signing image: ${IMAGE_REF}"
175+
cosign sign -y --key env://COSIGN_PRIVATE_KEY "${IMAGE_REF}"
196176
env:
197-
TAGS: ${{ steps.push.outputs.digest }}
198177
COSIGN_EXPERIMENTAL: false
199178
COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}

.gitignore

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1+
# Secrets
12
cosign.key
2-
_build_*
3-
output
4-
_build-*/**
3+
4+
# Build artifacts
5+
_build*
6+
_rechunk_output/
7+
output/
8+
output.env
9+
previous.manifest.json
10+
changelog.md
11+
12+
# Titanoboa ISO builder
513
_titanoboa/
14+
15+
# VM testing
616
_vm_build/
17+
18+
# ISO files
719
*.iso
20+
result-iso/

Containerfile

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,52 @@
1-
# This build argument allows building different variants (regular vs NVIDIA)
2-
ARG BASE_IMAGE=ghcr.io/ublue-os/bluefin-dx:stable-daily
1+
# Hypercube Container Build
2+
# Aligned with Bluefin patterns
33

4-
# Allow build scripts to be referenced without being copied into the final image
4+
# ============================================
5+
# Build Arguments
6+
# ============================================
7+
ARG BASE_IMAGE=ghcr.io/ublue-os/bluefin-dx:stable-daily
8+
ARG IMAGE_NAME=hypercube
9+
ARG IMAGE_VENDOR=binarypie-dev
10+
ARG SHA_HEAD_SHORT=""
11+
12+
# ============================================
13+
# Stage 1: Context Aggregation
14+
# ============================================
15+
# Aggregate all build context into a single layer for mounting
516
FROM scratch AS ctx
6-
COPY build_files /
7-
COPY branding /branding
17+
COPY system_files /system_files
18+
COPY build_files /build_files
819

9-
# Base Image
20+
# ============================================
21+
# Stage 2: Main Build
22+
# ============================================
1023
FROM ${BASE_IMAGE}
1124

12-
# Copy dot_files into the image at /usr/share/hypercube/config
25+
# Re-declare ARGs after FROM (they don't persist across stages)
26+
ARG IMAGE_NAME
27+
ARG IMAGE_VENDOR
28+
ARG SHA_HEAD_SHORT
29+
30+
# Export build-time environment variables
31+
ENV IMAGE_NAME=${IMAGE_NAME}
32+
ENV IMAGE_VENDOR=${IMAGE_VENDOR}
33+
34+
# Copy dot_files (config templates) into the image
1335
COPY dot_files /usr/share/hypercube/config
1436

1537
# Ensure all config files are readable by everyone
1638
RUN chmod -R a+rX /usr/share/hypercube/config
1739

18-
## Other possible base images include:
19-
# FROM ghcr.io/ublue-os/bazzite:latest
20-
# FROM ghcr.io/ublue-os/bluefin-dx-nvidia:stable-daily
21-
#
22-
# ... and so on, here are more base images
23-
# Universal Blue Images: https://github.com/orgs/ublue-os/packages
24-
# Fedora base image: quay.io/fedora/fedora-bootc:41
25-
# CentOS base images: quay.io/centos-bootc/centos-bootc:stream10
26-
27-
### MODIFICATIONS
28-
## make modifications desired in your image and install packages by modifying the build.sh script
29-
## the following RUN directive does all the things required to run "build.sh" as recommended.
30-
40+
# Build with mounted context and caches
41+
# - Bind mount from ctx stage for build scripts and system files
42+
# - Cache mounts for DNF and rpm-ostree to speed up rebuilds
43+
# - Tmpfs for /tmp to avoid polluting the image
3144
RUN --mount=type=bind,from=ctx,source=/,target=/ctx \
32-
--mount=type=cache,dst=/var/cache \
33-
--mount=type=cache,dst=/var/log \
34-
--mount=type=tmpfs,dst=/tmp \
35-
/ctx/build.sh && \
36-
ostree container commit
37-
38-
### LINTING
39-
## Verify final image and contents are correct.
45+
--mount=type=cache,dst=/var/cache/libdnf5 \
46+
--mount=type=cache,dst=/var/cache/rpm-ostree \
47+
--mount=type=tmpfs,dst=/tmp \
48+
/ctx/build_files/shared/build.sh && \
49+
ostree container commit
50+
51+
# Final validation
4052
RUN bootc container lint

0 commit comments

Comments
 (0)