Skip to content

ci(infra): build installer ISO on PRs + main + release publish#4905

Merged
AceHack merged 8 commits into
mainfrom
feat/ci-build-installer-iso-workflow-2026-05-24
May 25, 2026
Merged

ci(infra): build installer ISO on PRs + main + release publish#4905
AceHack merged 8 commits into
mainfrom
feat/ci-build-installer-iso-workflow-2026-05-24

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 25, 2026

Summary

Adds `.github/workflows/build-installer-iso.yml` — Linux runner builds the `.#installer-iso` flake output on every PR touching the flake/infra, every push to main, manual dispatch, and release publish. Removes the local-Nix-required dependency for testing changes to the ISO.

Why a CI build path

The installer ISO target is `x86_64-linux`. On Apple Silicon Macs (most maintainers' workstations), building it requires the nix-darwin `linux-builder` VM setup. CI on ubuntu-24.04 builds it directly — no cross-compile, no local Nix install, no APFS-volume gymnastics.

Anyone reviewing a flake-touching PR can now grab the rebuilt ISO from the workflow artifact and `dd` it to a USB stick without any local toolchain.

Pipeline

Step What
Checkout Full history (reproducible flake.lock pinning)
Install Nix `DeterminateSystems/nix-installer-action@v22`
Cache `magic-nix-cache-action@v13` for /nix/store reuse
Eval check `nix flake check --no-build` fail-fast
Build `nix build .#installer-iso --print-build-logs`
Metadata path/name/size/sha256 → step summary
Upload Workflow artifact, 90d retention, no re-compression

A second job (`attach-to-release`) fires only on release-publish events: rebuilds the ISO at the tag and uploads it + its SHA256 to the release assets.

Security

  • Runner pinned to `ubuntu-24.04` (not `-latest`); matches `gate.yml` convention
  • Third-party actions SHA-pinned with trailing `# vX.Y.Z` comments
  • Workflow-level `permissions: contents: read`; only `attach-to-release` elevates to `contents: write` and only for the upload step
  • `github.event.release.tag_name` (attacker-controllable) passed via `env: RELEASE_TAG` not interpolated into shell — per the GH Actions injection guide flagged by the security-reminder PreToolUse hook

Test plan

  • Workflow triggers on this PR (flake.nix isn't touched, but the workflow file path is)
  • First green run produces a downloadable `zeta-installer-24.11.iso` artifact
  • SHA256 in the step summary matches the artifact

Composes with

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Adds .github/workflows/build-installer-iso.yml — Linux runner builds
the .#installer-iso flake output on every PR touching flake.nix /
flake.lock / infra/nixos/**, every push to main hitting those paths,
manual workflow_dispatch, and release publish.

Why on a Linux runner (not the existing macos-26 gate matrix):
the ISO target is x86_64-linux. Building on macOS requires the
nix-darwin linux-builder VM. Ubuntu-24.04 builds directly — faster,
cheaper, no cross-compile path.

Pipeline:
  1. Checkout (full history for reproducible flake.lock pinning)
  2. Install Nix via DeterminateSystems/nix-installer-action@v22
     (SHA-pinned ef8a148080ab6020fd15196c2084a2eea5ff2d25)
  3. Magic Nix cache action@v13 for /nix/store reuse across runs
  4. nix flake metadata for the run summary
  5. nix flake check --no-build (cheap eval-only fail-fast)
  6. nix build .#installer-iso
  7. Capture iso path/name/size/sha256, write to GITHUB_STEP_SUMMARY
  8. Upload as workflow artifact (90-day retention, no re-compression)

Second job (attach-to-release) runs only on release events:
  - Re-builds the ISO at the tag for build-from-source reproducibility
  - Uploads ISO + .sha256 to the release assets
  - permissions: contents: write scoped to this job only

Security discipline:
  - Runner pinned to ubuntu-24.04 (not -latest), matches gate.yml
  - Third-party actions SHA-pinned with # vX.Y.Z trailing comments
  - Workflow-level permissions: contents: read; only attach-to-release
    elevates to write
  - github.event.release.tag_name (attacker-controllable) passed via
    env: RELEASE_TAG, never interpolated into run: shell — per the
    GitHub Actions injection guide flagged by the security-reminder
    PreToolUse hook
  - Concurrency cancel-in-progress only for PR events (main + release
    queue so every event gets a record)

Benefits:
  - Maintainers can review a PR and grab the rebuilt ISO from the
    workflow run page — no local Nix required
  - flake.nix can't go stale silently; CI catches breakage
  - Releases automatically ship a downloadable ISO + checksum

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 03:23
@AceHack AceHack enabled auto-merge (squash) May 25, 2026 03:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated GitHub Actions workflow to build the Nix flake .#installer-iso output on Ubuntu CI for PRs/pushes, with an additional release-only path intended to attach the built ISO to GitHub Releases.

Changes:

  • Introduces .github/workflows/build-installer-iso.yml to build the installer ISO on PRs (path-filtered), pushes to main, manual dispatch, and release publish.
  • Uploads the ISO as a workflow artifact for PR/main runs.
  • Adds a release-only job intended to rebuild and upload the ISO + SHA256 as release assets.

Comment thread .github/workflows/build-installer-iso.yml Outdated
Comment thread .github/workflows/build-installer-iso.yml
Comment thread .github/workflows/build-installer-iso.yml
Comment thread .github/workflows/build-installer-iso.yml Outdated
Lior and others added 2 commits May 24, 2026 23:27
…nix-cache FlakeHub-auth dep)

Two CI failures on PR #4905, both fixable in place.

actionlint SC2129 (lint job): the metadata-capture step at line ~96
had 4 sequential `echo ... >> "$GITHUB_OUTPUT"` redirects. shellcheck
flagged the pattern and recommends `{ ...; } >> file`. Grouped the
4 echoes accordingly. Matches the style already used for the
GITHUB_STEP_SUMMARY block lower in the same step.

build-iso job: failed with
  "Unable to authenticate to FlakeHub. Individuals must register at
   FlakeHub.com; Organizations must create an organization at
   FlakeHub.com."

This came from `DeterminateSystems/magic-nix-cache-action@v13`,
which now requires a FlakeHub account/org that the project doesn't
have set up. The auth failure propagates into the substituter chain
nix uses during `nix flake check`, causing the eval-only step to
fail before the build can even start.

Removed the magic-nix-cache step from both jobs (build + attach-
to-release). Builds will be uncached (~10-15 min cold) instead of
~3 min warm — acceptable trade-off vs requiring contributors to
set up FlakeHub. Follow-up to wire `actions/cache` on /nix/store or
swap to `nix-community/cache-nix-action` (no FlakeHub auth needed)
is tracked in the comment block left in place of the removed step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e predicate

The newly-added build-installer-iso workflow's `nix flake check` step
surfaced two real bugs in the substrate landed via PR #4898. These
went undetected before because no CI ever ran `nix flake check` on
this repo until now.

Bug 1: services.openssh.enable conflict in installer config
  Upstream `installation-cd-minimal.nix` (imported on line 24) sets
  services.openssh.enable = true. Our installer config set it to false
  for the no-credentials-in-Git security posture. NixOS module merge
  fails eval:

    error: The option `services.openssh.enable' has conflicting
    definition values:
      - In `<nixpkgs>/nixos/modules/profiles/installation-device.nix': true
      - In `infra/nixos/hosts/installer/configuration.nix': false

  Fix: `lib.mkForce false` so our value wins the merge. Documented
  the WHY in a comment block so the next reader knows why mkForce
  is necessary.

Bug 2: cuda_cuobjdump unfree license in gpu.nix
  `nixpkgs.config.allowUnfreePredicate` enumerated a hand-picked
  list (cuda_cudart, cuda_nvcc, cuda-merged, libcublas, libcudnn).
  CUDA's transitive dependency cuda_cuobjdump-12.4.99 wasn't in
  the list, so flake-check refused to evaluate:

    error: Package 'cuda_cuobjdump-12.4.99' has an unfree license
    ('CUDA EULA'), refusing to evaluate.

  Fix: switched from explicit enumeration to prefix-based matching:
    - hard-list nvidia-x11, nvidia-settings, nvidia-persistenced,
      nvidia-docker, nvidia-container-toolkit
    - prefix-allow cuda*  (covers cuda_cudart, cuda_nvcc,
      cuda_cuobjdump, cuda_nvprune, cuda_cccl, cuda_nvtx,
      cuda_profiler_api, etc)
    - prefix-allow libcu*, libnv*, libnp* (libcublas, libcurand,
      libcusolver, libcusparse, libcufft, libcudnn, libnpp,
      libnvjpeg, libnvjitlink, ...)
    - explicit allow for cuda-merged umbrella package
  Comments name what each pattern covers so future-readers know
  what's being permitted.

This is exactly what the CI workflow added in this PR is supposed
to catch — it's catching two bugs on its first real run. Both fixes
land in this PR so reviewers see the workflow + the bugs it caught
together.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 03:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/build-installer-iso.yml
Comment thread .github/workflows/build-installer-iso.yml
Comment thread .github/workflows/build-installer-iso.yml Outdated
AceHack pushed a commit that referenced this pull request May 25, 2026
Codex P1 — installer-iso not buildable on Apple Silicon
  The whole point of this PR was that nix-darwin's linux-builder
  lets Apple Silicon Macs run `nix build .#installer-iso`. But the
  flake gated installer-iso to system == "x86_64-linux" only,
  meaning on aarch64-darwin the attribute lookup fails BEFORE the
  linux-builder can be invoked.

  Fix: introduced isoBuildSystems = [ x86_64-linux, aarch64-darwin,
  x86_64-darwin ] and gate the package set on `elem system
  isoBuildSystems`. Darwin systems get the same isoImage derivation;
  Nix dispatches the actual build via the linux-builder VM when
  the derivation's system attribute (x86_64-linux) doesn't match
  the host. aarch64-linux stays excluded (no cross-build use case).

  Also extended supportedSystems to include aarch64-darwin +
  x86_64-darwin so flake-utils.eachSystem produces devShells +
  formatter for maintainer Macs too.

Copilot P1 — wheel vs admin troubleshooting row
  README troubleshooting said "You're not in the `wheel` group" but
  the config trusts `@admin` (macOS admin group). Updated to "admin
  group (macOS)" so the guidance matches the actual setting.

Copilot P1 — install-command pointer in configuration.nix
  Comment claimed the macOS Nix install command was in
  /etc/zeta-install.md or infra/README.md — neither true. Updated
  to point at the actual Determinate .pkg URL (dtr.mn/determinate-nix)
  and at infra/nix-darwin/README.md (same dir) which has the
  prerequisites + walkthrough.

Copilot P2 — sizing comment "8 GB / 8 cores" vs cores = 6
  Comment said 8 cores but config set 6. Rewrote the comment to
  reference the actual closure size (~8 GB working set) and let
  the inline `# 6 vCPU` annotation on the config line carry the
  cores value. No magic-number duplication.

Outdated-but-true findings resolved without code change:

Copilot (line ~50): wrapped line starting with `+` — already fixed
  in commit 51453d6 (the markdownlint MD032 fix). Thread was
  filed against the pre-fix line content.

Copilot (line 82): README links to .github/workflows/build-installer-iso.yml
  which doesn't exist on main yet. It DOES exist on
  feat/ci-build-installer-iso-workflow-2026-05-24 (PR #4905) and
  will land alongside this PR. Forward-ref will resolve as soon as
  #4905 merges; no fix needed in this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AceHack pushed a commit that referenced this pull request May 25, 2026
…in + line wrap)

Copilot caught 5 follow-up issues from the prior review-fix commit.

P1 — Intel Mac confusion (flake.nix lines 60 + 76):
  Comment implied x86_64-darwin also used Rosetta 2 (it's Apple-
  Silicon-only); isoBuildSystems exposed installer-iso on
  x86_64-darwin but there's no darwinConfiguration.zeta-mac-intel
  to actually set up the linux-builder there.

  Resolution: dropped x86_64-darwin from BOTH supportedSystems
  and isoBuildSystems. The whole local-build story is M-series-
  only by design (Apple Virtualization.framework + Rosetta is
  required). Intel Mac maintainers use the CI workflow (PR #4905)
  to build the ISO. Comments updated to call this out explicitly.

P1 — wheel vs admin (configuration.nix line 29, README line 33):
  Both surfaces still said "wheel group (admin users on macOS)"
  but config trusts `@admin`, not @wheel. On macOS the relevant
  group is `admin` and `wheel` is a separate (rarely-used) group.

  Resolution: rewrote both comments to name `admin` directly and
  explain that `@admin` is nix.settings.trusted-users group-
  reference syntax. README bullet now also names the actual
  setting (`trusted-users = @admin`) so the doc and the config
  agree byte-for-byte.

P2 — broken line wrap (configuration.nix line 18):
  Header comment wrapped "Virtualization.framework" as
  "Virtualization\n.framework", leaving a stray leading dot on
  the next line. Hard to scan.

  Resolution: kept "Virtualization.framework" on a single line.

Composes with the prior fix commit; takes the substrate from
"five Copilot threads ago" to no-outstanding-comment state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 25, 2026
…ds on Apple Silicon (#4906)

* feat(infra): nix-darwin linux-builder config for local x86_64-linux ISO builds on Apple Silicon

Adds infra/nix-darwin/ + wires darwinConfigurations.zeta-mac into
flake.nix. After this lands, any maintainer with Nix installed on
an Apple Silicon Mac runs one command:

  nix run nix-darwin/master#darwin-rebuild -- switch \
    --flake /path/to/Zeta#zeta-mac

…and gets a working linux-builder VM. From then on
`nix build .#installer-iso` from the repo root builds the
x86_64-linux ISO locally via Apple Virtualization.framework +
Rosetta 2 — no Parallels, Lima, Docker, or remote builders.

infra/nix-darwin/configuration.nix:
  - nix.linux-builder.enable = true with maxJobs=4, 8GB RAM,
    40GB disk, 6 cores (sized for the installer ISO closure)
  - ephemeral = false to keep VM warm across reboots
  - nix.settings.extra-platforms = [ "x86_64-linux" ] so Nix
    routes x86_64-linux derivations to the VM
  - nix.linux-builder.supportedFeatures = [ kvm benchmark
    big-parallel ] so heavy builds dispatch correctly
  - experimental-features = nix-command + flakes
  - trusted-users = @admin (wheel group on macOS)
  - cache.nixos.org + nix-community substituters trusted
  - Baseline package set mirrors a subset of the installer USB
    (kubectl, helm, k9s, argocd, age, sops, jq, yq, ripgrep,
    fd, htop, gh, git, nix-output-monitor, nvd, nh)
  - system.stateVersion = 5 (current nix-darwin module API)

infra/nix-darwin/README.md:
  - Prerequisites (Apple Silicon, macOS 13+, Nix, Rosetta 2)
  - One-command setup
  - Build the ISO post-setup
  - Update procedure
  - Troubleshooting table
  - Explicit "what this is NOT" — not a NixOS host config,
    not required for cluster operation, not a replacement for
    the CI build (workflow at .github/workflows/build-installer-iso.yml
    stays source of truth for "this PR's ISO")

flake.nix:
  - Adds inputs.nix-darwin pinned to master (project has no
    stable release channel as of 2026-05; matches nix-darwin
    team's recommendation)
  - inputs.nix-darwin.inputs.nixpkgs.follows = "nixpkgs" to
    keep one nixpkgs revision across the whole flake
  - darwinConfigurations.zeta-mac wired with
    specialArgs = { inherit inputs; }

Composes with #4905 (CI workflow that builds the ISO without
needing local Nix). Local linux-builder is the iteration path;
CI is the source-of-truth path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(infra): markdownlint MD032 — wrapped line starting with '+' read as list

infra/nix-darwin/README.md line 50 wrapped a sentence as:

  First build takes ~10-15 min (downloads + boots the linux-builder VM
  + compiles the Linux closure). Subsequent builds reuse the warm VM
  and the /nix/store cache — typically 1-3 min.

markdownlint reads the line starting with "+ compiles" as a list
item (CommonMark unordered-list marker), then complains the list
isn't surrounded by blank lines (MD032).

Rewrote the sentence so no wrapped line starts with `+` (or `-` or
`*`). No content change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(infra): address 5 Copilot/Codex review threads on PR #4906

Codex P1 — installer-iso not buildable on Apple Silicon
  The whole point of this PR was that nix-darwin's linux-builder
  lets Apple Silicon Macs run `nix build .#installer-iso`. But the
  flake gated installer-iso to system == "x86_64-linux" only,
  meaning on aarch64-darwin the attribute lookup fails BEFORE the
  linux-builder can be invoked.

  Fix: introduced isoBuildSystems = [ x86_64-linux, aarch64-darwin,
  x86_64-darwin ] and gate the package set on `elem system
  isoBuildSystems`. Darwin systems get the same isoImage derivation;
  Nix dispatches the actual build via the linux-builder VM when
  the derivation's system attribute (x86_64-linux) doesn't match
  the host. aarch64-linux stays excluded (no cross-build use case).

  Also extended supportedSystems to include aarch64-darwin +
  x86_64-darwin so flake-utils.eachSystem produces devShells +
  formatter for maintainer Macs too.

Copilot P1 — wheel vs admin troubleshooting row
  README troubleshooting said "You're not in the `wheel` group" but
  the config trusts `@admin` (macOS admin group). Updated to "admin
  group (macOS)" so the guidance matches the actual setting.

Copilot P1 — install-command pointer in configuration.nix
  Comment claimed the macOS Nix install command was in
  /etc/zeta-install.md or infra/README.md — neither true. Updated
  to point at the actual Determinate .pkg URL (dtr.mn/determinate-nix)
  and at infra/nix-darwin/README.md (same dir) which has the
  prerequisites + walkthrough.

Copilot P2 — sizing comment "8 GB / 8 cores" vs cores = 6
  Comment said 8 cores but config set 6. Rewrote the comment to
  reference the actual closure size (~8 GB working set) and let
  the inline `# 6 vCPU` annotation on the config line carry the
  cores value. No magic-number duplication.

Outdated-but-true findings resolved without code change:

Copilot (line ~50): wrapped line starting with `+` — already fixed
  in commit 51453d6 (the markdownlint MD032 fix). Thread was
  filed against the pre-fix line content.

Copilot (line 82): README links to .github/workflows/build-installer-iso.yml
  which doesn't exist on main yet. It DOES exist on
  feat/ci-build-installer-iso-workflow-2026-05-24 (PR #4905) and
  will land alongside this PR. Forward-ref will resolve as soon as
  #4905 merges; no fix needed in this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(infra): 3rd Copilot wave on PR #4906 (Intel Mac scope + wheel→admin + line wrap)

Copilot caught 5 follow-up issues from the prior review-fix commit.

P1 — Intel Mac confusion (flake.nix lines 60 + 76):
  Comment implied x86_64-darwin also used Rosetta 2 (it's Apple-
  Silicon-only); isoBuildSystems exposed installer-iso on
  x86_64-darwin but there's no darwinConfiguration.zeta-mac-intel
  to actually set up the linux-builder there.

  Resolution: dropped x86_64-darwin from BOTH supportedSystems
  and isoBuildSystems. The whole local-build story is M-series-
  only by design (Apple Virtualization.framework + Rosetta is
  required). Intel Mac maintainers use the CI workflow (PR #4905)
  to build the ISO. Comments updated to call this out explicitly.

P1 — wheel vs admin (configuration.nix line 29, README line 33):
  Both surfaces still said "wheel group (admin users on macOS)"
  but config trusts `@admin`, not @wheel. On macOS the relevant
  group is `admin` and `wheel` is a separate (rarely-used) group.

  Resolution: rewrote both comments to name `admin` directly and
  explain that `@admin` is nix.settings.trusted-users group-
  reference syntax. README bullet now also names the actual
  setting (`trusted-users = @admin`) so the doc and the config
  agree byte-for-byte.

P2 — broken line wrap (configuration.nix line 18):
  Header comment wrapped "Virtualization.framework" as
  "Virtualization\n.framework", leaving a stray leading dot on
  the next line. Hard to scan.

  Resolution: kept "Virtualization.framework" on a single line.

Composes with the prior fix commit; takes the substrate from
"five Copilot threads ago" to no-outstanding-comment state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Lior <lior@zeta.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five fixes raised on PR 4905:

P0 — sha256 sidecar to /nix/store (read-only EROFS)
  attach-to-release wrote ${iso_path}.sha256 next to the nix-store
  iso path; the parent dir is read-only on the runner so the
  upload step would EROFS. Write sidecar to $RUNNER_TEMP and
  upload that file instead.

P1 — attach-to-release checkout missing fetch-depth: 0
  Build job pins fetch-depth: 0 for reproducible flake.lock +
  git-describe; release job inherited default depth 1. Match
  the build job so tag builds can't silently drift.

P2 — header comment said "tag push"; actual trigger is
  release: published. Updated to match.

P2 — find ... | head -1 is non-deterministic on multi-match
  and silent on no-match. Switched to find -print -quit + an
  explicit ::error:: + exit 1 if nothing found. Applied at
  both call sites (build + attach-to-release).

P2 — release events ran build then attach-to-release, building
  the ISO twice. Skip build on release events (attach-to-release
  rebuilds at the tag — the verification on PR/main already ran).

actionlint clean; yaml-valid.

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 920b691fb8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/build-installer-iso.yml Outdated
Two follow-up findings on top of peer Otto's review-fix commit
920b691. Both real.

Codex P1 — needs:build short-circuits attach-to-release on release events
  Peer Otto kept `needs: build` on attach-to-release. Build is now
  skipped on release events (`if: github.event_name != 'release'`).
  When a needed job is skipped via `if:`, downstream jobs depending
  on it via `needs:` are ALSO skipped by default — meaning
  attach-to-release would never run.

  Fix: removed `needs: build`. The two jobs are independent:
  attach-to-release does its own checkout + build at the release tag.

Copilot P1 — explicit ref pinning on attach-to-release checkout
  Peer Otto fixed fetch-depth: 0 but didn't add `ref:` to pin the
  checkout to the release tag. On release events GITHUB_REF
  defaults to the tag, so the implicit behavior is correct today.
  Explicit pinning is defense in depth against future payload
  variation + reads clearer at the call site.

  Fix: `ref: ${{ github.event.release.tag_name }}` (also renamed
  the step from "Checkout" to "Checkout at the release tag" for
  matching clarity).

My own larger refactor commit (f0775d999) was dropped — it
overlapped substantively with peer Otto's 920b691 (same root
findings, slightly different approach). Honoring peer Otto's
work per the honor-those-that-came-before discipline; this
commit lands only the residual gaps Codex + Copilot still flagged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 03:47
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/build-installer-iso.yml Outdated
Comment thread .github/workflows/build-installer-iso.yml Outdated
Comment thread .github/workflows/build-installer-iso.yml Outdated
AceHack added a commit that referenced this pull request May 25, 2026
* fix(infra): pin nix-darwin to nix-darwin-24.11 release branch (match nixpkgs)

nix-darwin > 25.x added an assertion that fails eval when the
nix-darwin and nixpkgs branches don't match:

  error:
    nix-darwin and Nixpkgs branches in use must match, but you are
    currently using nix-darwin master with Nixpkgs nixos-24.11

PR #4906 (which added the nix-darwin input) pinned it to `master`
based on stale guidance from the nix-darwin README. Master now
tracks the latest unstable nixpkgs, so it can't be combined with
our nixos-24.11 pin.

Fix: pin nix-darwin to the nix-darwin-24.11 release branch that
matches nixpkgs.url. Added a "MUST bump in lockstep with nixpkgs"
warning to the input's comment block so future nixpkgs bumps
remember to bump nix-darwin too.

Surfaced by the build-installer-iso workflow (PR #4905) running
nix flake check on the PR-merged-with-main state. Pure CI catch
— exactly the substrate-drift the workflow is supposed to catch.
Unblocks PR #4905 + restores `nix flake check` on main.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docs): chase nix-darwin/master refs to match the new pin

Copilot P1: the prior commit pinned the flake input to
`nix-darwin-24.11`, but 4 usage examples elsewhere still said
`nix-darwin/master`:
  - flake.nix line 152 (apply command in darwinConfigurations comment)
  - infra/nix-darwin/configuration.nix line 13 (apply command in
    header comment)
  - infra/nix-darwin/README.md line 24 (one-command setup)
  - infra/nix-darwin/README.md line 58 (update procedure)

A maintainer following any of these would invoke
`nix run nix-darwin/master#darwin-rebuild` and hit the same
branch-mismatch eval error the prior commit fixed for the flake.

Fix: rewrote all 4 to `nix-darwin/nix-darwin-24.11#darwin-rebuild`
to match the input pin. Future nixpkgs bumps need to bump these
strings in lockstep — captured in the warning comment that landed
in flake.nix in the prior commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Lior <lior@zeta.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lior and others added 2 commits May 24, 2026 23:59
…leanup

3 findings on PR #4905 after the prior nix-darwin-pin retrigger.

P0 (security) — gh release upload tag-as-positional-arg flag injection
  `gh release upload "$RELEASE_TAG" ...` parses `$RELEASE_TAG`
  positionally; git tag names can legally start with `-`, which
  would make gh treat the tag as a flag. If a release is ever
  created with such a tag, the upload step could be coerced into
  unintended gh-CLI behavior.

  Two-layer defense:
    1. Hard-fail if RELEASE_TAG starts with `-` (case match)
    2. Add `--` separator before positional args (belt + suspenders
       against any future argv-injection vector)
  Also re-ordered the call to put `--clobber` before the `--` so
  the trailing args are unambiguously positional.

P1 — .sha256 file format
  Was writing just the hash:  `<hash>\n`
  Standard sha256sum format:  `<hash>  <filename>\n`
  The standard format lets consumers verify with `sha256sum --check`
  out of the box. Switched to `( cd dir && sha256sum name )` so the
  filename in the sidecar matches the ISO basename (not the full
  /nix/store path).

P2 — header comment "tag-push job" stale
  Header still said "tag-push job elevates to contents: write" but
  the actual job is `attach-to-release` (triggered by
  `release: published`, not tag push). Renamed accordingly in the
  comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 04:10
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread infra/nixos/modules/gpu.nix Outdated
Comment thread .github/workflows/build-installer-iso.yml Outdated
Comment thread .github/workflows/build-installer-iso.yml Outdated
3 Copilot findings on PR #4905.

P1 — gpu.nix cuda predicate comment mismatch
  Comment said "`cuda_*` covers ..." but the actual predicate is
  `lib.hasPrefix "cuda" name` (no underscore). The broader form is
  intentional — nixpkgs uses both spellings (cuda_cudart with
  underscore + cudatoolkit + cudaPackages.* aliases without).
  Updated comment to document this explicitly so it matches the
  code.

P1 — find -print -quit silently picks first match (build job)
P1 — find -print -quit silently picks first match (attach-to-release job)
  Peer Otto's prior fix switched from `find ... | head -1` to
  `find ... -print -quit` for determinism, but both are silent on
  multi-match. Multiple ISOs under result/iso/ would be a substrate
  surprise (build layout changed, leftover artifact, etc.) and
  silently picking one is worse than failing loudly — especially
  for release-asset upload where the wrong ISO would ship to the
  public.

  Switched both sites to mapfile + explicit count check:
    - 0 matches → fail loudly with directory listing
    - >1 matches → fail loudly with all candidates printed
    - 1 match  → proceed
  Same pattern, same error format in both jobs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AceHack AceHack merged commit 44bcaff into main May 25, 2026
33 checks passed
@AceHack AceHack deleted the feat/ci-build-installer-iso-workflow-2026-05-24 branch May 25, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants