Skip to content

agent: clean identity on dispatch failure #66

agent: clean identity on dispatch failure

agent: clean identity on dispatch failure #66

name: Katl Release Artifacts
on:
push:
branches:
- "release/**"
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: CalVer embedded in artifacts (for example 2026.7.0-beta.1)
required: true
type: string
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
identity:
name: Resolve Release Identity
runs-on: ubuntu-24.04
outputs:
artifact-name: ${{ steps.release.outputs.artifact-name }}
version: ${{ steps.release.outputs.version }}
env:
KATL_ARCHITECTURE: x86_64
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Resolve release identity
id: release
shell: bash
env:
MANUAL_VERSION: ${{ inputs.version }}
run: |
version="$(scripts/katl-release-artifacts version \
"$GITHUB_EVENT_NAME" "$GITHUB_REF_TYPE" "$GITHUB_REF_NAME" \
"$MANUAL_VERSION")"
short_sha="${GITHUB_SHA:0:12}"
artifact_name="katl-${version}-${KATL_ARCHITECTURE}-${short_sha}"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "artifact-name=$artifact_name" >> "$GITHUB_OUTPUT"
runtime:
name: Build And Verify Runtime
needs: identity
runs-on: ubuntu-24.04
timeout-minutes: 90
outputs:
mkosi-version: ${{ steps.mkosi-version.outputs.version }}
env:
GOTOOLCHAIN: auto
KATL_ARCHITECTURE: x86_64
KATL_BUILD_COMMIT: ${{ github.sha }}
KATL_CONTAINER_RUNTIME: docker
KATL_MKOSI_IMAGE: localhost/katl-mkosi-builder:fedora-44-go-squashfs
KATL_VERSION: ${{ needs.identity.outputs.version }}
KATL_VMTEST_IMAGE_SUPPORT: "0"
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- name: Restore Katl Go build caches
uses: actions/cache@v6
with:
path: |
_build/go-mod
_build/go-cache
key: katl-go-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-${{ hashFiles('go.mod', 'go.sum') }}
restore-keys: |
katl-go-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-
- name: Resolve mkosi cache identity
id: mkosi-cache
shell: bash
run: |
digest="$({
sha256sum \
Containerfile.mkosi \
mkosi.conf \
mkosi.profiles/installer-image/mkosi.conf \
mkosi.profiles/kubernetes-sysext/kubernetes.env \
mkosi.profiles/kubernetes-sysext/mkosi.conf \
mkosi.profiles/runtime/mkosi.conf
} | sha256sum | cut -d ' ' -f 1)"
echo "key=$digest" >> "$GITHUB_OUTPUT"
- name: Restore mkosi package cache
uses: actions/cache@v6
with:
path: _build/mkosi/package-cache
key: katl-mkosi-packages-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-fedora-44-${{ steps.mkosi-cache.outputs.key }}
restore-keys: |
katl-mkosi-packages-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-fedora-44-
- name: Build runtime
shell: bash
run: scripts/mkosi build-runtime
- name: Resolve mkosi version
id: mkosi-version
shell: bash
run: |
version="$(docker run --rm "$KATL_MKOSI_IMAGE" mkosi --version)"
version="${version#mkosi }"
if [[ ! "$version" =~ ^[0-9]+([.][0-9]+)*$ ]]; then
echo "unexpected mkosi version from builder: $version" >&2
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Verify runtime
shell: bash
run: |
docker run --rm \
--volume "$GITHUB_WORKSPACE:/work" \
--workdir /work \
"$KATL_MKOSI_IMAGE" \
bash -euo pipefail -c '
scripts/check-runtime-root
scripts/check-runtime-boot-asset
'
- name: Build endpoint advertiser sysext
shell: bash
run: scripts/build-endpoint-advertiser-sysext
- name: Package install and upgrade images concurrently
shell: bash
run: |
install_status=0
upgrade_status=0
scripts/build-katlos-install-image &
install_pid=$!
KATL_KATLOS_IMAGE_ROLE=upgrade scripts/build-katlos-install-image &
upgrade_pid=$!
wait "$install_pid" || install_status=$?
wait "$upgrade_pid" || upgrade_status=$?
((install_status == 0 && upgrade_status == 0))
- name: Verify KatlOS images
shell: bash
run: |
scripts/check-katlos-install-image
KATL_KATLOS_IMAGE_ROLE=upgrade scripts/check-katlos-install-image
- name: Upload runtime and KatlOS image intermediates
uses: actions/upload-artifact@v7
with:
name: katl-runtime-images-${{ github.sha }}
path: |
_build/mkosi/katl-runtime-root.squashfs
_build/mkosi/katl-runtime-root.squashfs.json
_build/mkosi/katl-runtime-root.squashfs.sha256
_build/mkosi/katl-runtime.efi
_build/mkosi/katl-runtime.efi.json
_build/mkosi/katl-runtime.efi.sha256
_build/mkosi/katl-runtime.packages.tsv
_build/mkosi/katlos-install-*.squashfs
_build/mkosi/katlos-install-*.squashfs.json
_build/mkosi/katlos-install-*.squashfs.sha256
_build/mkosi/katlos-upgrade-*.squashfs
_build/mkosi/katlos-upgrade-*.squashfs.json
_build/mkosi/katlos-upgrade-*.squashfs.sha256
if-no-files-found: error
retention-days: 1
compression-level: 0
installer:
name: Build And Verify Installer
needs: identity
runs-on: ubuntu-24.04
timeout-minutes: 90
env:
GOTOOLCHAIN: auto
KATL_ARCHITECTURE: x86_64
KATL_BUILD_COMMIT: ${{ github.sha }}
KATL_CONTAINER_RUNTIME: docker
KATL_MKOSI_IMAGE: localhost/katl-mkosi-builder:fedora-44-go-squashfs
KATL_VERSION: ${{ needs.identity.outputs.version }}
KATL_VMTEST_IMAGE_SUPPORT: "0"
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- name: Restore Katl Go build caches
uses: actions/cache@v6
with:
path: |
_build/go-mod
_build/go-cache
key: katl-go-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-${{ hashFiles('go.mod', 'go.sum') }}
restore-keys: |
katl-go-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-
- name: Resolve mkosi cache identity
id: mkosi-cache
shell: bash
run: |
digest="$({
sha256sum \
Containerfile.mkosi \
mkosi.conf \
mkosi.profiles/installer-image/mkosi.conf \
mkosi.profiles/kubernetes-sysext/kubernetes.env \
mkosi.profiles/kubernetes-sysext/mkosi.conf \
mkosi.profiles/runtime/mkosi.conf
} | sha256sum | cut -d ' ' -f 1)"
echo "key=$digest" >> "$GITHUB_OUTPUT"
- name: Restore mkosi package cache
uses: actions/cache@v6
with:
path: _build/mkosi/package-cache
key: katl-mkosi-packages-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-fedora-44-${{ steps.mkosi-cache.outputs.key }}
restore-keys: |
katl-mkosi-packages-${{ runner.os }}-${{ env.KATL_ARCHITECTURE }}-fedora-44-
- name: Build installer
shell: bash
run: scripts/mkosi build-installer
- name: Verify installer
shell: bash
run: |
docker run --rm \
--volume "$GITHUB_WORKSPACE:/work" \
--workdir /work \
"$KATL_MKOSI_IMAGE" \
scripts/check-installer-image
- name: Upload installer intermediates
uses: actions/upload-artifact@v7
with:
name: katl-installer-${{ github.sha }}
path: |
_build/mkosi/katl-installer.efi
_build/mkosi/katl-installer.efi.json
_build/mkosi/katl-installer.efi.sha256
_build/mkosi/katl-installer.initrd
_build/mkosi/katl-installer.initrd.json
_build/mkosi/katl-installer.initrd.sha256
_build/mkosi/katl-installer.packages.tsv
_build/mkosi/katl-installer.vmlinuz
_build/mkosi/katl-installer.vmlinuz.json
_build/mkosi/katl-installer.vmlinuz.sha256
if-no-files-found: error
retention-days: 1
compression-level: 0
katlctl:
name: Build And Verify katlctl
needs: identity
runs-on: ubuntu-24.04
env:
KATL_ARCHITECTURE: x86_64
KATL_BUILD_COMMIT: ${{ github.sha }}
KATL_VERSION: ${{ needs.identity.outputs.version }}
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- name: Build katlctl
shell: bash
run: scripts/katl-release-artifacts build-katlctl "$KATL_VERSION"
- name: Upload katlctl intermediate
uses: actions/upload-artifact@v7
with:
name: katlctl-${{ github.sha }}
path: _build/mkosi/katlctl-*
if-no-files-found: error
retention-days: 1
compression-level: 0
assemble:
name: Assemble And Verify Katl Release
needs:
- identity
- runtime
- installer
- katlctl
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
attestations: write
contents: read
id-token: write
env:
GOTOOLCHAIN: auto
KATL_ARCHITECTURE: x86_64
KATL_BUILD_COMMIT: ${{ github.sha }}
KATL_VERSION: ${{ needs.identity.outputs.version }}
steps:
- name: Check out repository
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- name: Download runtime and KatlOS image intermediates
uses: actions/download-artifact@v8
with:
name: katl-runtime-images-${{ github.sha }}
path: _build/mkosi
- name: Download installer intermediates
uses: actions/download-artifact@v8
with:
name: katl-installer-${{ github.sha }}
path: _build/mkosi
- name: Download katlctl intermediate
uses: actions/download-artifact@v8
with:
name: katlctl-${{ github.sha }}
path: _build/mkosi
- name: Install ISO assembly tools
shell: bash
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends --yes dosfstools mtools xorriso
- name: Assemble and verify installer ISO
shell: bash
run: |
scripts/build-installer-iso >/dev/null
go run ./cmd/katl-mkosi-artifacts write-installer-artifacts >/dev/null
scripts/check-installer-iso
- name: Record release build inputs
shell: bash
env:
MKOSI_VERSION: ${{ needs.runtime.outputs.mkosi-version }}
run: |
go run ./cmd/katl-resource-lock prepare-mkosi \
-manifest _build/mkosi/katl-release-build-inputs.json \
-mode record \
-run-id "release-${KATL_VERSION}-${GITHUB_SHA:0:12}" \
-git-revision "$GITHUB_SHA" \
-mkosi-version "$MKOSI_VERSION" \
-package-set installer-image \
-package-set runtime \
-package-set katlos-install-image
- name: Stage supported publication artifacts
shell: bash
run: scripts/katl-release-artifacts stage "$KATL_VERSION" dist
- name: Attest staged release artifacts
if: github.event_name == 'push' && github.ref_type == 'tag'
uses: actions/attest@v4
with:
subject-path: dist/*
- name: Upload GitHub Actions artifact
uses: actions/upload-artifact@v7
with:
name: ${{ needs.identity.outputs.artifact-name }}
path: dist/
if-no-files-found: error
retention-days: 30
compression-level: 0
publish-tag:
name: Publish GitHub Release Assets
if: github.event_name == 'push' && github.ref_type == 'tag'
needs:
- identity
- assemble
runs-on: ubuntu-24.04
permissions:
attestations: read
contents: write
steps:
- name: Download verified artifacts
uses: actions/download-artifact@v8
with:
name: ${{ needs.identity.outputs.artifact-name }}
path: dist
- name: Publish tag release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
KATL_VERSION: ${{ needs.identity.outputs.version }}
run: |
prerelease=()
if [[ "$KATL_VERSION" == *-* ]]; then
prerelease+=(--prerelease)
fi
if gh release view --repo "$GITHUB_REPOSITORY" \
"$GITHUB_REF_NAME" >/dev/null 2>&1; then
gh release upload --repo "$GITHUB_REPOSITORY" \
"$GITHUB_REF_NAME" dist/*
else
gh release create --repo "$GITHUB_REPOSITORY" \
"$GITHUB_REF_NAME" \
--verify-tag \
--title "KatlOS $KATL_VERSION" \
--notes-file dist/RELEASE_NOTES.md \
"${prerelease[@]}" \
dist/*
fi
- name: Verify published release provenance
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
# The inner shell expands its positional artifact argument.
# shellcheck disable=SC2016
find dist -mindepth 1 -maxdepth 1 -type f -print0 | \
xargs -0 -r -n1 -P4 bash -euo pipefail -c '
artifact="$1"
gh attestation verify "$artifact" \
--repo "$GITHUB_REPOSITORY" \
--signer-workflow "$GITHUB_REPOSITORY/.github/workflows/release-artifacts.yml" \
--source-ref "$GITHUB_REF" \
--source-digest "$GITHUB_SHA" >/dev/null
' _