From 5b9e69d42ce35b4df7d7e407cfcf09c9a4bf3d2c Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Wed, 23 Oct 2024 18:03:53 -0500 Subject: [PATCH] refactor: adopt m2giles workflow --- .github/workflows/build-desktop.yml | 257 ++++++++++++++++++++++++++++ .github/workflows/build.yml | 179 ++++--------------- Containerfile | 11 +- build.sh | 2 +- build_files/desktop-changes.sh | 2 +- build_files/server-changes.sh | 2 +- 6 files changed, 300 insertions(+), 153 deletions(-) create mode 100644 .github/workflows/build-desktop.yml diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml new file mode 100644 index 0000000..94ac2d3 --- /dev/null +++ b/.github/workflows/build-desktop.yml @@ -0,0 +1,257 @@ +name: Build bOS-desktops +on: + workflow_call: + inputs: + tag_version: + description: "The Tag Version for the Build" + required: true + type: string + +env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_NAME: bos + IMAGE_STYLED: bOS + +jobs: + push-ublue: + name: Build Desktop Images + runs-on: ubuntu-24.04 + continue-on-error: false + permissions: + contents: read + packages: write + id-token: write + strategy: + fail-fast: false + matrix: + image: + #- bazzite-deck-gnome + #- bazzite-gnome + #- bazzite-gnome-nvidia + - bluefin + - bluefin-nvidia + tag_version: + - ${{ inputs.tag_version }} + + steps: + - name: Build Variables + id: build-vars + uses: Wandalen/wretry.action@v3.5.0 + with: + attempt_limit: 3 + attempt_delay: 15000 + command: | + set -eoux pipefail + image="${{ matrix.image }}" + base_image=${{ matrix.image }} + tag_version=${{ matrix.tag_version }} + + if [[ "$tag_version" == "stable" && ! "${image}" =~ bazzite ]]; then + tag_version="${tag_version}-daily" + fi + + if [[ "$tag_version" == "beta" && ${image} =~ bazzite ]]; then + tag_version="unstable" + fi + + if [[ ! "${image}" =~ cosmic ]]; then + KERNEL_RELEASE=$(skopeo inspect docker://ghcr.io/ublue-os/"${base_image}:${tag_version}" | jq -r '.Labels["ostree.linux"]') + fedora_version=$(echo $KERNEL_RELEASE | grep -oP 'fc\K[0-9]+') + ver=$(skopeo inspect docker://ghcr.io/ublue-os/"${base_image}:$tag_version" | jq -r '.Labels["org.opencontainers.image.version"]') + fi + + case "${image}" in + "bluefin"*|"aurora"*) + upstream_repo=bluefin + ;; + "bazzite"*) + upstream_repo=bazzite + ;; + *) + echo "Invalid Choice. Exiting..." + exit 1 + ;; + esac + + if [ -z "$ver" ] || [ "null" = "$ver" ]; then + echo "inspected image version must not be empty or null" + exit 1 + fi + + echo "version=$ver" >> $GITHUB_ENV + echo "tag_version=$tag_version" >> $GITHUB_ENV + echo "kernel_release=${KERNEL_RELEASE}" >> $GITHUB_ENV + echo "fedora_version=${fedora_version}" >> $GITHUB_ENV + echo "upstream_repo=${upstream_repo}" >> $GITHUB_ENV + echo "image=${image}" >> $GITHUB_ENV + echo "base_image=${base_image}" >> $GITHUB_ENV + + - name: Verify Base Image + uses: EyeCantCU/cosign-action/verify@v0.2.2 + with: + containers: ${{ env.base_image }}:${{ env.tag_version }} + pubkey: https://raw.githubusercontent.com/ublue-os/${{ env.upstream_repo }}/main/cosign.pub + registry: ghcr.io/ublue-os + + - name: Pull Images + uses: Wandalen/wretry.action@v3.5.0 + id: pull + with: + attempt_limit: 3 + attempt_delay: 15000 + command: | + set -eoux pipefail + sudo podman pull ghcr.io/ublue-os/${{ env.base_image }}:${{ env.tag_version }} + sudo podman pull ghcr.io/hhd-dev/rechunk:v0.8.6 + + - name: Checkout Push to Registry Action + uses: actions/checkout@v4 + + - name: Generate Tags + id: generate_tags + shell: bash + run: | + TIMESTAMP="$(date +%Y%m%d)" + case "${{ env.image }}" in + "bazzite-deck"*) + tag="bazzite-deck" + ;; + "bazzite-gnome-nvidia"*) + tag="bazzite-nvidia" + ;; + "bazzite"*) + tag="bazzite" + ;; + *) + tag="${{ env.image }}" + esac + + if [[ "${{ matrix.tag_version }}" == "beta" ]]; then + tag=${tag}-beta + fi + + BUILD_TAGS+=("${tag}" "${tag}-${TIMESTAMP}") + + for TAG in "${BUILD_TAGS[@]}"; do + echo "${TAG}" + done + + echo "default_tag=${tag}" >> "$GITHUB_OUTPUT" + echo "build_tags=${BUILD_TAGS[*]}" >> "$GITHUB_OUTPUT" + + - name: Maximize Build Space + uses: ublue-os/remove-unwanted-software@v7 + + - name: Build Image + id: build_image + shell: bash + run: | + sudo buildah build \ + --format "docker" \ + --build-arg IMAGE=${{ env.image }} \ + --build-arg BASE_IMAGE=${{ env.base_image }} \ + --build-arg TAG_VERSION=${{ env.tag_version }} \ + --tag raw-img . + + - name: Remove old Images + run: | + set -eoux pipefail + sudo podman image rm ghcr.io/ublue-os/${{ env.base_image }}:${{ env.tag_version }} + + - name: Rechunk Image + id: rechunk + uses: hhd-dev/rechunk@v0.8.6 + with: + ref: "raw-img" + prev-ref: "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tags.outputs.default_tag }}" + version: "${{ env.version }}" + rechunk: "ghcr.io/hhd-dev/rechunk:v0.8.6" + labels: | + org.opencontainers.image.title=${{ env.IMAGE_STYLED }} + org.opencontainers.image.description=${{ env.IMAGE_STYLED }} is my customized image of various ublue projects + org.opencontainers.image.version=${{ env.version }} + # ostree.linux should already be set on our upstream + # ostree.linux=${{ env.kernel_release }} + + - name: Load into Podman and Tag + shell: bash + run: | + set -eoux pipefail + IMAGE=$(podman pull ${{ steps.rechunk.outputs.ref }}) + sudo rm -rf ${{ steps.rechunk.outputs.output }} + for tag in ${{ steps.generate_tags.outputs.build_tags }}; do + podman tag $IMAGE ${{ env.IMAGE_NAME }}:$tag + done + podman tag $IMAGE rechunked-img + + - name: Check Secureboot + id: secureboot + shell: bash + run: | + set -x + if [[ ! $(command -v sbverify) || ! $(command -v curl) || ! $(command -v openssl) ]]; then + sudo apt update + sudo apt install sbsigntool curl openssl + fi + TMP=$(podman create rechunked-img bash) + podman cp $TMP:/usr/lib/modules/${{ env.kernel_release }}/vmlinuz . + podman rm $TMP + # podman run --rm rechunked-img /bin/bash -c "cat /usr/lib/modules/*/vmlinuz" > vmlinuz + sbverify --list vmlinuz + curl --retry 3 -Lo kernel-sign.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key.der + curl --retry 3 -Lo akmods.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key_2.der + openssl x509 -in kernel-sign.der -out kernel-sign.crt + openssl x509 -in akmods.der -out akmods.crt + sbverify --cert kernel-sign.crt vmlinuz || exit 1 + sbverify --cert akmods.crt vmlinuz || exit 1 + + - name: Lowercase Registry + id: registry_case + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ env.IMAGE_REGISTRY }} + + - name: Push to GHCR + uses: Wandalen/wretry.action@v3.5.0 + id: push + if: github.event_name != 'pull_request' + env: + REGISTRY_USER: ${{ github.actor }} + REGISTRY_PASSWORD: ${{ github.token }} + with: + action: redhat-actions/push-to-registry@v2 + attempt_limit: 3 + attempt_delay: 15000 + with: | + image: ${{ env.IMAGE_NAME }} + tags: ${{ steps.generate_tags.outputs.build_tags }} + registry: ${{ steps.registry_case.outputs.lowercase }} + username: ${{ env.REGISTRY_USER }} + password: ${{ env.REGISTRY_PASSWORD }} + extra-args: | + --disable-content-trust + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: github.event_name != 'pull_request' + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: sigstore/cosign-installer@v3.5.0 + if: github.event_name != 'pull_request' + + - name: Sign Container Image + if: github.event_name != 'pull_request' + run: | + cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ env.IMAGE_NAME }}@${TAGS} + env: + TAGS: ${{ steps.push.outputs.outputs && fromJSON(steps.push.outputs.outputs).digest }} + COSIGN_EXPERIMENTAL: false + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + + - name: Echo Outputs + if: github.event_name != 'pull_request' + run: | + echo "${{ toJSON(steps.push.outputs) }}" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86a3ade..0286b94 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,153 +1,42 @@ ---- -name: build-ublue-custom +name: Build bOS on: - pull_request: - branches: - - main - schedule: - - cron: '05 10 * * *' # 10:05am UTC everyday +# schedule: +# - cron: "41 6 * * 0" # 6:41 UTC Sunday +# - cron: "41 6 * * 1,2,3,4,5,6" # 6:41 UTC Monday-Saturday push: branches: - main - paths-ignore: - - '**/README.md' + merge_group: workflow_dispatch: -env: - MY_IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names - MY_IMAGE_DESC: "My Customized Universal Blue Image" - IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit - -jobs: - build_push: - name: Build and push image - runs-on: ubuntu-24.04 - - permissions: - contents: read - packages: write - id-token: write - - steps: - # Checkout push-to-registry action GitHub repository - - name: Checkout Push to Registry action - uses: actions/checkout@v4 - - - name: Maximize build space - uses: ublue-os/remove-unwanted-software@v7 - - - name: Generate tags - id: generate-tags - shell: bash - run: | - # Generate a timestamp for creating an image version history - TIMESTAMP="$(date +%Y%m%d)" - COMMIT_TAGS=() - BUILD_TAGS=() - - # Have tags for tracking builds during pull request - SHA_SHORT="${GITHUB_SHA::7}" - COMMIT_TAGS+=("pr-${{ github.event.number }}") - COMMIT_TAGS+=("${SHA_SHORT}") - - # Append matching timestamp tags to keep a version history - for TAG in "${BUILD_TAGS[@]}"; do - BUILD_TAGS+=("${TAG}-${TIMESTAMP}") - done - - BUILD_TAGS+=("${TIMESTAMP}") - BUILD_TAGS+=("latest") - - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - echo "Generated the following commit tags: " - for TAG in "${COMMIT_TAGS[@]}"; do - echo "${TAG}" - done +permissions: + contents: read + packages: write + id-token: write - alias_tags=("${COMMIT_TAGS[@]}") - else - alias_tags=("${BUILD_TAGS[@]}") - fi +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true - echo "Generated the following build tags: " - for TAG in "${BUILD_TAGS[@]}"; do - echo "${TAG}" - done - - echo "alias_tags=${alias_tags[*]}" >> $GITHUB_OUTPUT - - # Build metadata - - name: Image Metadata - uses: docker/metadata-action@v5 - id: meta - with: - images: | - ${{ env.MY_IMAGE_NAME }} - - labels: | - io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository }}/main/README.md - org.opencontainers.image.description=${{ env.MY_IMAGE_DESC }} - org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }} - - # Build image using Buildah action - - name: Build Image - id: build_image - uses: redhat-actions/buildah-build@v2 - with: - containerfiles: | - ./Containerfile - # Postfix image name with -custom to make it a little more descriptive - # Syntax: https://docs.github.com/en/actions/learn-github-actions/expressions#format - image: ${{ env.MY_IMAGE_NAME }} - tags: | - ${{ steps.generate-tags.outputs.alias_tags }} - labels: ${{ steps.meta.outputs.labels }} - oci: false - - # Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. - # https://github.com/macbre/push-to-ghcr/issues/12 - - name: Lowercase Registry - id: registry_case - uses: ASzc/change-string-case-action@v6 - with: - string: ${{ env.IMAGE_REGISTRY }} - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Image to GHCR - uses: redhat-actions/push-to-registry@v2 - id: push - env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ github.token }} - with: - image: ${{ steps.build_image.outputs.image }} - tags: ${{ steps.build_image.outputs.tags }} - registry: ${{ steps.registry_case.outputs.lowercase }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_PASSWORD }} - extra-args: | - --disable-content-trust - - # This section is optional and only needs to be enabled if you plan on distributing - # your project for others to consume. You will need to create a public and private key - # using Cosign and save the private key as a repository secret in Github for this workflow - # to consume. For more details, review the image signing section of the README. - - # Sign container - - uses: sigstore/cosign-installer@v3.7.0 - if: github.event_name != 'pull_request' - - - name: Sign container image - if: github.event_name != 'pull_request' - run: | - cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} - env: - TAGS: ${{ steps.push.outputs.digest }} - COSIGN_EXPERIMENTAL: false - COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} +jobs: + push-desktop-stable: + uses: ./.github/workflows/build-desktop.yml + secrets: inherit + with: + tag_version: stable + +# push-desktop-beta: +# uses: ./.github/workflows/build-desktop.yml +# secrets: inherit +# with: +# tag_version: beta + +# push-server: +# uses: ./.github/workflows/build-server.yml +# secrets: inherit + +# build-iso: +# uses: ./.github/workflows/build-iso.yml +# secrets: inherit +# needs: push-desktop-stable +# if: (github.event_name == 'schedule' && github.event.schedule != '41 6 * * 1,2,3,4,5,6') || github.event_name == 'workflow_dispatch' \ No newline at end of file diff --git a/Containerfile b/Containerfile index 58435ed..abeb28d 100644 --- a/Containerfile +++ b/Containerfile @@ -1,13 +1,14 @@ -ARG SOURCE_IMAGE="bluefin" -ARG SOURCE_SUFFIX="" -ARG SOURCE_TAG="stable-daily" +ARG BASE_IMAGE="bluefin" +ARG IMAGE="bluefin" +ARG TAG_VERSION="stable-daily" FROM scratch AS ctx COPY / / -FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${SOURCE_TAG} +FROM ghcr.io/ublue-os/${BASE_IMAGE}:${TAG_VERSION} -ARG SOURCE_IMAGE="bluefin" +ARG BASE_IMAGE="bluefin" +ARG IMAGE="bluefin" RUN --mount=type=cache,dst=/var/cache/rpm-ostree \ --mount=type=bind,from=ctx,src=/,dst=/ctx \ diff --git a/build.sh b/build.sh index e57739d..ab9916b 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ set -ouex pipefail -case "${SOURCE_IMAGE}" in +case "${IMAGE}" in "bluefin"*) /ctx/build_files/desktop-changes.sh /ctx/build_files/desktop-packages.sh diff --git a/build_files/desktop-changes.sh b/build_files/desktop-changes.sh index 8e4e2b5..3269c98 100755 --- a/build_files/desktop-changes.sh +++ b/build_files/desktop-changes.sh @@ -4,7 +4,7 @@ set -euox pipefail echo "Tweaking existing desktop config..." -if [[ ${SOURCE_IMAGE} =~ bluefin ]] || [[ ${SOURCE_IMAGE} =~ bazzite-gnome ]]; then +if [[ ${IMAGE} =~ bluefin ]] || [[ ${IMAGE} =~ bazzite ]]; then rsync -rvK /ctx/system_files/silverblue/ / # custom gnome overrides mkdir -p /tmp/ublue-schema-test && \ diff --git a/build_files/server-changes.sh b/build_files/server-changes.sh index 41fac00..8d51395 100755 --- a/build_files/server-changes.sh +++ b/build_files/server-changes.sh @@ -4,7 +4,7 @@ set -euox pipefail echo "Tweaking existing server config..." -if [[ ${SOURCE_IMAGE} =~ ucore ]]; then +if [[ ${IMAGE} =~ ucore ]]; then # moby-engine packages on uCore conflict with docker-ce rpm-ostree override remove \ containerd moby-engine runc