Skip to content

ci: add installer ISO build + release workflows #4

ci: add installer ISO build + release workflows

ci: add installer ISO build + release workflows #4

Workflow file for this run

# Build ISO — builds the installer AND appliance ISOs for every supported
# architecture.
#
# Each arch builds on a native runner; the build itself runs inside the
# official `nixos/nix` container via `docker run`. We deliberately do NOT put
# the whole job in `container:` — the nixos/nix image lacks a standard glibc
# loader, so GitHub's bundled Node can't run there and every JS action
# (checkout, upload-artifact) fails with `exec .../node: no such file or
# directory`. So checkout/upload run on the host runner and only `make` runs in
# the container.
#
# Bare `make <target>` resolves to the runner's native `builtins.currentSystem`
# (x86_64-linux or aarch64-linux) and produces
# out/<target>/iso/coder-box-<kind>-<arch>-linux.iso inside the container. The
# container /nix/store is ephemeral, so we copy the ISOs into a host mktemp dir
# bind-mounted at /out and upload from there.
#
# Triggers: builds for PRs only when they're ready for review (not on every
# commit/draft push), on merges to main, and manually for any ref via
# workflow_dispatch. Verification build: artifacts are short-lived (1 day).
name: Build ISO
on:
push:
branches: [main]
pull_request:
# Only ready-for-review PRs: `opened`/`reopened` cover a PR created or
# reopened already non-draft, `ready_for_review` covers a draft promoted to
# ready. Notably absent is `synchronize`, so pushing new commits to an open
# PR does NOT rebuild — the draft guard below also skips draft PRs.
types: [opened, reopened, ready_for_review]
workflow_dispatch:
inputs:
ref:
description: "Git ref/commit to build (defaults to the selected branch)"
required: false
type: string
# Cancel superseded runs on the same ref; a full ISO build is expensive so
# don't waste runners on stale commits.
concurrency:
group: build-${{ github.ref }}-${{ github.event.inputs.ref }}
cancel-in-progress: true
jobs:
iso:
name: ${{ matrix.target }} (${{ matrix.system }})
# Skip draft PRs (opened/reopened fire for drafts too); always run for
# push and manual dispatch.
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
target: [installer/iso, appliance/iso]
include:
- system: x86_64-linux
runner: ubuntu-24.04
- system: aarch64-linux
runner: ubuntu-24.04-arm
steps:
- name: Checkout
uses: actions/checkout@v5
with:
# Empty for push/PR (checks out the event ref); honored for manual
# dispatch to build an arbitrary commit.
ref: ${{ github.event.inputs.ref }}
- name: Build ISO (in nixos/nix container)
id: build
env:
TARGET: ${{ matrix.target }}
run: |
# Host /dist volume, bind-mounted into the container, where the build
# drops the finished ISO (the container's /nix/store is ephemeral, so
# the in-tree out/ symlink would dangle on the host — we dereference
# the built ISO into /dist instead).
dist="$(mktemp -d)"
echo "dist=$dist" >>"$GITHUB_OUTPUT"
# out/<target with / -> -> dir>/... e.g. installer/iso -> out/installer-iso
outlink="out/$(echo "$TARGET" | tr '/' '-')/iso"
docker run --rm \
-v "$PWD":/work -w /work \
-v "$dist":/dist \
-e TARGET \
nixos/nix:latest \
sh -euc "
# The Makefile builds via 'nix build --impure' and needs flakes +
# nix-command, which the nixos/nix image does not enable by default.
export NIX_CONFIG='experimental-features = nix-command flakes'
# Repo is bind-mounted and owned by a different uid; allow git to
# read it so the Makefile can stamp the build rev.
git config --global --add safe.directory /work
# gnumake provides 'make'; git lets the Makefile stamp the rev. The
# ISO targets also emit out/<name>.iso.sha256 sidecar checksums.
nix-shell -p gnumake git --run \"make $TARGET\"
# Dereference the build's store symlink into the /dist volume,
# alongside the make-generated checksum sidecar.
cp -L $outlink/*.iso /dist/
cp out/*.iso.sha256 /dist/
"
ls -lh "$dist"
- name: Upload ISO artifact
uses: actions/upload-artifact@v5
with:
name: coder-box-${{ matrix.target == 'installer/iso' && 'installer' || 'appliance' }}-${{ matrix.system }}
path: ${{ steps.build.outputs.dist }}/*.iso*
# Verification build; keep storage cost minimal.
retention-days: 1
if-no-files-found: error