bluebuild (159): 'type: files' module fails 'chmod: Operation not permitted' inside its own bind-mounted /tmp/modules/files/files.sh under buildah + privileged-podman in our runner. Switch all four `type: files` modules to `type: copy` (low-level COPY, no chmod, no helper script needed). installer-iso (160): livemedia-creator refused build/out which checkout had already created (Forgejo runner reuses workspace dir between runs). rm -rf build/out before invocation; mkdir not needed, livemedia-creator creates the dir itself.
167 lines
6.3 KiB
YAML
167 lines
6.3 KiB
YAML
name: Build veilor-os Installer ISO
|
|
|
|
# v0.7+ — produces a small Anaconda installer ISO that consumes
|
|
# kickstart/install-ostreecontainer-installer.ks. The ISO boots
|
|
# Anaconda, asks for LUKS pw + admin pw interactively, then
|
|
# `ostreecontainer` populates / from the v0.7 OCI image at
|
|
# ghcr.io/veilor-org/veilor-os:43.
|
|
|
|
on:
|
|
push:
|
|
branches: [v0.7-bluebuild-spike]
|
|
paths:
|
|
- 'kickstart/install-ostreecontainer.ks'
|
|
- 'kickstart/install-ostreecontainer-installer.ks'
|
|
- 'bluebuild/recipe.yml'
|
|
- '.github/workflows/build-installer-iso.yml'
|
|
workflow_dispatch:
|
|
inputs:
|
|
releasever:
|
|
description: 'Fedora release version'
|
|
required: false
|
|
default: '43'
|
|
|
|
permissions:
|
|
contents: write # needed to create+update installer-latest release
|
|
|
|
jobs:
|
|
build:
|
|
name: Build installer ISO
|
|
runs-on: nullstone
|
|
timeout-minutes: 120
|
|
|
|
env:
|
|
RELEASEVER: ${{ github.event.inputs.releasever || '43' }}
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4.1.7
|
|
|
|
- name: Install build tooling (Fedora)
|
|
run: |
|
|
set -euxo pipefail
|
|
dnf -y upgrade --refresh
|
|
dnf -y install --skip-unavailable \
|
|
lorax \
|
|
pykickstart \
|
|
anaconda-tui \
|
|
syslinux \
|
|
xorriso \
|
|
grub2-efi-x64 \
|
|
grub2-efi-x64-modules \
|
|
grub2-pc \
|
|
grub2-pc-modules \
|
|
shim-x64 \
|
|
efibootmgr
|
|
|
|
- name: Validate installer kickstart
|
|
run: |
|
|
set -euxo pipefail
|
|
ksvalidator kickstart/install-ostreecontainer-installer.ks
|
|
|
|
- name: Build installer ISO with livemedia-creator
|
|
run: |
|
|
set -euxo pipefail
|
|
# livemedia-creator refuses an existing non-empty resultdir.
|
|
rm -rf build/out
|
|
mkdir -p /var/lmc
|
|
ln -sfn "$GITHUB_WORKSPACE" /work
|
|
# livemedia-creator does NOT support --title (that's livecd-creator).
|
|
# --volid replaces it for the ISO volume label.
|
|
livemedia-creator \
|
|
--make-iso \
|
|
--no-virt \
|
|
--ks kickstart/install-ostreecontainer-installer.ks \
|
|
--resultdir build/out \
|
|
--tmp /var/lmc \
|
|
--volid "veilor-os-installer-${RELEASEVER}" \
|
|
--project "veilor-os" \
|
|
--releasever "$RELEASEVER" \
|
|
--logfile build/out/build.log \
|
|
2>&1 | tee -a build/out/build.log
|
|
|
|
- name: Rename ISO + sha256
|
|
run: |
|
|
set -euxo pipefail
|
|
ISO_FILE=$(ls build/out/*.iso 2>/dev/null | head -1)
|
|
[ -n "$ISO_FILE" ] || { echo "[ERR] no ISO produced"; exit 1; }
|
|
ISO_NAME="veilor-os-installer-${RELEASEVER}-$(date +%Y%m%d-%H%M%S).iso"
|
|
mv "$ISO_FILE" "build/out/$ISO_NAME"
|
|
cd build/out
|
|
sha256sum "$ISO_NAME" > "$ISO_NAME.sha256"
|
|
ls -lh "$ISO_NAME"
|
|
|
|
- name: Split ISO into 1900M chunks
|
|
if: success() && github.ref == 'refs/heads/v0.7-bluebuild-spike'
|
|
run: |
|
|
set -euo pipefail
|
|
cd build/out
|
|
ISO=$(ls *.iso | head -1)
|
|
[ -n "$ISO" ] || { echo "[ERR] no ISO"; exit 1; }
|
|
split -b 1900M -d --suffix-length=2 "$ISO" "${ISO}.part-"
|
|
rm -f "$ISO"
|
|
sha256sum *.part-* > "${ISO}.parts.sha256"
|
|
ls "${ISO}".part-*
|
|
|
|
- name: Publish to installer-latest rolling prerelease (Forgejo)
|
|
if: success() && github.ref == 'refs/heads/v0.7-bluebuild-spike' && github.server_url != 'https://github.com'
|
|
env:
|
|
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
FORGEJO_API: ${{ github.server_url }}/api/v1
|
|
REPO: ${{ github.repository }}
|
|
GIT_SHA: ${{ github.sha }}
|
|
run: |
|
|
set -euo pipefail
|
|
TAG="installer-latest"
|
|
REL_JSON=$(curl -fsSL -H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
"${FORGEJO_API}/repos/${REPO}/releases/tags/${TAG}" 2>/dev/null || echo "")
|
|
if [ -n "$REL_JSON" ]; then
|
|
REL_ID=$(echo "$REL_JSON" | grep -oE '"id":\s*[0-9]+' | head -1 | grep -oE '[0-9]+')
|
|
if [ -n "$REL_ID" ]; then
|
|
curl -fsSL -X DELETE -H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
"${FORGEJO_API}/repos/${REPO}/releases/${REL_ID}" || true
|
|
curl -fsSL -X DELETE -H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
"${FORGEJO_API}/repos/${REPO}/git/refs/tags/${TAG}" || true
|
|
fi
|
|
fi
|
|
BODY="Rolling auto-build from v0.7-bluebuild-spike. Latest commit: ${GIT_SHA}.
|
|
|
|
Installer ISO — boots Anaconda, prompts for LUKS pw + admin pw,
|
|
then ostreecontainer-pulls / from ghcr.io/veilor-org/veilor-os:43.
|
|
|
|
Reassemble:
|
|
cat veilor-os-installer-*.iso.part-* > veilor-os-installer.iso
|
|
sha256sum -c veilor-os-installer-*.iso.parts.sha256
|
|
|
|
Not a stable release — for testing only."
|
|
PAYLOAD=$(BODY="$BODY" TAG="$TAG" python3 -c "
|
|
import json,os
|
|
print(json.dumps({
|
|
'tag_name': os.environ['TAG'],
|
|
'target_commitish': 'v0.7-bluebuild-spike',
|
|
'name': 'installer-latest (auto)',
|
|
'body': os.environ['BODY'],
|
|
'prerelease': True,
|
|
'draft': False,
|
|
}))")
|
|
REL_ID=$(curl -fsSL -X POST -H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$PAYLOAD" \
|
|
"${FORGEJO_API}/repos/${REPO}/releases" | \
|
|
grep -oE '"id":\s*[0-9]+' | head -1 | grep -oE '[0-9]+')
|
|
[ -n "$REL_ID" ] || { echo "[ERR] failed to create release"; exit 1; }
|
|
cd build/out
|
|
for f in *.iso.part-* *.sha256; do
|
|
[ -f "$f" ] || continue
|
|
curl -fsSL -X POST -H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
-F "attachment=@${f}" \
|
|
"${FORGEJO_API}/repos/${REPO}/releases/${REL_ID}/assets?name=${f}"
|
|
done
|
|
|
|
- name: Print build log on failure
|
|
if: failure()
|
|
run: |
|
|
echo "─── build/out/build.log ───"
|
|
tail -200 build/out/build.log 2>/dev/null || echo "(no build.log)"
|
|
find build/out -name 'program.log' -exec tail -100 {} \; 2>/dev/null || true
|
|
find /var/lmc -name '*.log' -exec tail -50 {} \; 2>/dev/null || true
|