ops: add CI boot-image releases and Unifi PXE rollout
This commit is contained in:
parent
043b1730dc
commit
be26313225
9 changed files with 720 additions and 0 deletions
276
.forgejo/workflows/deploy-runner-images.yml
Normal file
276
.forgejo/workflows/deploy-runner-images.yml
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
name: deploy-runner-images
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: [boot-v*]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
description: "Release tag override (manual runs only)"
|
||||
required: false
|
||||
default: ""
|
||||
publish_release:
|
||||
description: "Publish artifacts to Forgejo release (true/false)"
|
||||
required: false
|
||||
default: "true"
|
||||
build_x86_64_netboot:
|
||||
description: "Build x86_64 netboot tarball (true/false)"
|
||||
required: false
|
||||
default: "true"
|
||||
build_x86_64_iso:
|
||||
description: "Build x86_64 installer ISO (true/false)"
|
||||
required: false
|
||||
default: "true"
|
||||
|
||||
concurrency:
|
||||
group: runner-image-deploy-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
if: ${{ github.server_url != 'https://codeberg.org' }}
|
||||
runs-on: codeberg-medium-lazy
|
||||
steps:
|
||||
- name: Fetch source (no git required)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
|
||||
echo "error: missing github.token"
|
||||
exit 2
|
||||
fi
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "error: curl is required"
|
||||
exit 2
|
||||
fi
|
||||
if ! command -v tar >/dev/null 2>&1; then
|
||||
echo "error: tar is required"
|
||||
exit 2
|
||||
fi
|
||||
if [[ -z "${GITHUB_SHA:-}" ]]; then
|
||||
echo "error: missing GITHUB_SHA"
|
||||
exit 2
|
||||
fi
|
||||
if [[ -z "${GITHUB_SERVER_URL:-}" ]]; then
|
||||
echo "error: missing GITHUB_SERVER_URL"
|
||||
exit 2
|
||||
fi
|
||||
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
|
||||
echo "error: missing GITHUB_REPOSITORY"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
rm -rf .repo
|
||||
mkdir -p .repo
|
||||
curl -fsSL -H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz?rev=${GITHUB_SHA}" \
|
||||
-o .repo/src.tgz
|
||||
tar -xzf .repo/src.tgz -C .repo --strip-components=1
|
||||
rm -f .repo/src.tgz
|
||||
|
||||
- name: Bootstrap Nix
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if ! command -v nix >/dev/null 2>&1; then
|
||||
curl -fsSL https://nixos.org/nix/install -o /tmp/install-nix.sh
|
||||
sh /tmp/install-nix.sh --no-daemon --yes
|
||||
fi
|
||||
|
||||
if [[ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
|
||||
fi
|
||||
if [[ -d "$HOME/.nix-profile/bin" ]]; then
|
||||
echo "PATH=$HOME/.nix-profile/bin:$PATH" >> "$GITHUB_ENV"
|
||||
export PATH="$HOME/.nix-profile/bin:$PATH"
|
||||
fi
|
||||
nix --version
|
||||
|
||||
- name: Resolve build plan
|
||||
id: plan
|
||||
env:
|
||||
INPUT_RELEASE_TAG: ${{ github.event.inputs.release_tag }}
|
||||
INPUT_PUBLISH_RELEASE: ${{ github.event.inputs.publish_release }}
|
||||
INPUT_BUILD_X86_64_NETBOOT: ${{ github.event.inputs.build_x86_64_netboot }}
|
||||
INPUT_BUILD_X86_64_ISO: ${{ github.event.inputs.build_x86_64_iso }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
bool_norm() {
|
||||
local raw
|
||||
raw="$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')"
|
||||
case "${raw}" in
|
||||
''|true|1|yes|y|on) echo "true" ;;
|
||||
false|0|no|n|off) echo "false" ;;
|
||||
*)
|
||||
echo "error: invalid boolean value '${1}'" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
short_sha="${GITHUB_SHA:0:12}"
|
||||
if [[ "${GITHUB_REF:-}" == refs/tags/* ]]; then
|
||||
release_tag="${GITHUB_REF#refs/tags/}"
|
||||
else
|
||||
release_tag="${INPUT_RELEASE_TAG:-}"
|
||||
if [[ -z "${release_tag}" ]]; then
|
||||
release_tag="boot-${short_sha}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! "${release_tag}" =~ ^[A-Za-z0-9._-]+$ ]]; then
|
||||
echo "error: release tag contains unsupported characters: ${release_tag}" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
publish_release="$(bool_norm "${INPUT_PUBLISH_RELEASE:-true}")"
|
||||
build_x86_64_netboot="$(bool_norm "${INPUT_BUILD_X86_64_NETBOOT:-true}")"
|
||||
build_x86_64_iso="$(bool_norm "${INPUT_BUILD_X86_64_ISO:-true}")"
|
||||
|
||||
if [[ "${build_x86_64_netboot}" != "true" && "${build_x86_64_iso}" != "true" ]]; then
|
||||
echo "error: at least one image build must be enabled" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
artifact_suffix="${short_sha}-${GITHUB_RUN_NUMBER:-0}-${GITHUB_RUN_ATTEMPT:-1}"
|
||||
|
||||
echo "release_tag=${release_tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "publish_release=${publish_release}" >> "$GITHUB_OUTPUT"
|
||||
echo "build_x86_64_netboot=${build_x86_64_netboot}" >> "$GITHUB_OUTPUT"
|
||||
echo "build_x86_64_iso=${build_x86_64_iso}" >> "$GITHUB_OUTPUT"
|
||||
echo "artifact_suffix=${artifact_suffix}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build runner boot images
|
||||
env:
|
||||
BUILD_X86_64_NETBOOT: ${{ steps.plan.outputs.build_x86_64_netboot }}
|
||||
BUILD_X86_64_ISO: ${{ steps.plan.outputs.build_x86_64_iso }}
|
||||
ARTIFACT_SUFFIX: ${{ steps.plan.outputs.artifact_suffix }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd .repo
|
||||
|
||||
if [[ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
|
||||
fi
|
||||
export PATH="$HOME/.nix-profile/bin:$PATH"
|
||||
|
||||
artifacts_dir="$PWD/.artifacts"
|
||||
rm -rf "${artifacts_dir}"
|
||||
mkdir -p "${artifacts_dir}"
|
||||
|
||||
nix_args=(--accept-flake-config --extra-experimental-features "nix-command flakes")
|
||||
|
||||
if [[ "${BUILD_X86_64_NETBOOT}" == "true" ]]; then
|
||||
nix build "${nix_args[@]}" \
|
||||
.#nixosConfigurations.ec-runner-x86_64-netboot.config.system.build.netboot \
|
||||
-o result-netboot-x86_64
|
||||
tar -C result-netboot-x86_64 \
|
||||
-czf "${artifacts_dir}/ec-runner-x86_64-netboot-${ARTIFACT_SUFFIX}.tar.gz" \
|
||||
kernel initrd netboot.ipxe
|
||||
fi
|
||||
|
||||
if [[ "${BUILD_X86_64_ISO}" == "true" ]]; then
|
||||
nix build "${nix_args[@]}" \
|
||||
.#nixosConfigurations.ec-runner-x86_64-iso.config.system.build.isoImage \
|
||||
-o result-iso-x86_64
|
||||
iso_source=""
|
||||
if [[ -f result-iso-x86_64 ]]; then
|
||||
iso_source="result-iso-x86_64"
|
||||
else
|
||||
iso_source="$(find -L result-iso-x86_64 -type f -name '*.iso' | head -n 1 || true)"
|
||||
fi
|
||||
if [[ -z "${iso_source}" ]]; then
|
||||
echo "error: could not locate ISO output from result-iso-x86_64" >&2
|
||||
exit 2
|
||||
fi
|
||||
cp -f "${iso_source}" "${artifacts_dir}/ec-runner-x86_64-iso-${ARTIFACT_SUFFIX}.iso"
|
||||
fi
|
||||
|
||||
if ! find "${artifacts_dir}" -maxdepth 1 -type f | grep -q .; then
|
||||
echo "error: no image artifacts were produced" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
(
|
||||
cd "${artifacts_dir}"
|
||||
sha256sum -- * > SHA256SUMS.txt
|
||||
ls -lh
|
||||
)
|
||||
|
||||
- name: Publish artifacts to Forgejo release
|
||||
if: ${{ steps.plan.outputs.publish_release == 'true' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
RELEASE_TAG: ${{ steps.plan.outputs.release_tag }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd .repo
|
||||
|
||||
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
|
||||
echo "error: missing github.token"
|
||||
exit 2
|
||||
fi
|
||||
if [[ -z "${GITHUB_SERVER_URL:-}" ]]; then
|
||||
echo "error: missing GITHUB_SERVER_URL"
|
||||
exit 2
|
||||
fi
|
||||
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
|
||||
echo "error: missing GITHUB_REPOSITORY"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
api_base="${GITHUB_SERVER_URL%/}/api/v1/repos/${GITHUB_REPOSITORY}"
|
||||
release_json="$(curl -fsSL \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
"${api_base}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true)"
|
||||
|
||||
if [[ -z "${release_json}" ]]; then
|
||||
payload="$(cat <<JSON
|
||||
{
|
||||
"tag_name": "${RELEASE_TAG}",
|
||||
"name": "Boot images ${RELEASE_TAG}",
|
||||
"body": "Automated runner boot image build from ${GITHUB_SHA}.",
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}
|
||||
JSON
|
||||
)"
|
||||
release_json="$(curl -fsSL -X POST \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-H "content-type: application/json" \
|
||||
"${api_base}/releases" \
|
||||
-d "${payload}")"
|
||||
fi
|
||||
|
||||
release_id=""
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
release_id="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"${release_json}" 2>/dev/null || true)"
|
||||
fi
|
||||
if [[ -z "${release_id}" ]]; then
|
||||
release_id="$(printf '%s' "${release_json}" \
|
||||
| sed -nE 's/.*"id"[[:space:]]*:[[:space:]]*([0-9]+).*/\1/p' \
|
||||
| head -n 1)"
|
||||
fi
|
||||
if [[ -z "${release_id}" ]]; then
|
||||
echo "error: failed to resolve release id for ${RELEASE_TAG}" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
for asset_path in .artifacts/*; do
|
||||
[[ -f "${asset_path}" ]] || continue
|
||||
asset_name="$(basename "${asset_path}")"
|
||||
curl -fsSL -X POST \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-H "content-type: application/octet-stream" \
|
||||
--data-binary @"${asset_path}" \
|
||||
"${api_base}/releases/${release_id}/assets?name=${asset_name}" >/dev/null
|
||||
echo "uploaded: ${asset_name}"
|
||||
done
|
||||
Loading…
Add table
Add a link
Reference in a new issue