Generate the package list from pkgs/ instead of a sed script - #18
Merged
Conversation
Releases have been landing in pkgs/step-agent/ without a matching
attribute in default.nix since June: 0.68.0, 0.69.0 and every 0.69.x
prerelease were uninstallable by name, and the bare `step-agent`
attribute still pointed at 0.65.0-rc11 behind a repo redirect.
addpkg.sh never learned which release triggered it. It registered
whichever file sorted highest:
ls -1 pkgs/step-agent/step-agent_* | sort -Vr | head -n 1
So once 0.70.0-rc1 existed, every subsequent 0.69.x release found that
file already registered and added nothing, leaving `git commit` to fail
on a clean tree — four red build runs between 07-27 and 08-01. `sort -V`
also ranks 0.68.0-rc1 above 0.68.0, which is why a stable release could
be skipped in favour of its own release candidate. Separately, the
stable-release check matched `_N_N_N$` against a dotted filename and so
could never fire, freezing the default attribute permanently.
default.nix now reads pkgs/<name>/ directly, so the attribute set cannot
drift from what goreleaser committed and the 21 orphaned derivations
register themselves. The unsuffixed attribute resolves to the highest
stable version via builtins.compareVersions.
This removes addpkg.sh and the add-pkg job entirely. With the commit-back
step gone, the release-check gate that guarded it goes too, so the nix
evaluation and build now run on pull requests rather than only on
goreleaser release commits.
Also drops four derivations for nightly and -dev builds whose GitHub
release assets are long deleted; those artifacts belong in nur-dev.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Action CI has failed at workflow-creation time on every run since 2026-05-25, so actionlint and zizmor have not actually examined this repo in three months. smallstep/workflows f47abc3 gave the reusable zizmor job the actions: read permission it needs to read workflow run metadata. A reusable workflow cannot be granted more than its caller has, and this caller grants only contents: read and security-events: write, so the run is rejected before any job is created — which is why it reports startup_failure with no jobs and no annotations, and why it never surfaced as a failing check on a pull request. gateway, inventory and agent all grant the full set; nur was missed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
actionlint has not run against this repo since May, so the unquoted command substitution and $PWD in the evaluation step have gone unreported. Both are carried over unchanged from the previous workflow; quoting them is behaviour-preserving on the runner, where the path contains no spaces. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dopey
approved these changes
Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes EFF-623.
NixOS customers cannot install any release from 0.68.0 through 0.69.1-rc1 by attribute, including current stable 0.69.0. The derivation files are on disk and build fine; they just have no name in
default.nix.Root cause
addpkg.shnever learned which release triggered it. It registered whichever file sorted highest:pkg_with_version=$(basename $(ls -1 pkgs/${pkg}/${pkg}_* | sort -Vr | head -n 1) .nix)Once
0.70.0-rc1landed on 07-25, every subsequent release on the 0.69 line saw it as the max, found it already registered, added nothing, and leftgit add default.nix && git committo fail on a clean tree. From the 0.69.0 run:Four
build.ymlruns are red for exactly this (07-27, 07-30, 07-31, 08-01).Two further faults compounded it:
sort -Vranks0.68.0-rc1above0.68.0, so a stable release could be skipped in favour of its own release candidate — which is whystep-agent_0_68_0-rc1is registered but0.68.0is not._[0-9]+_[0-9]+_[0-9]+$against a dotted filename (step-agent_0.69.0). It can never match, so the script always printed "Non stable release" and returned before touching the default attribute. That branch has never once executed, which is why the barestep-agentattribute is frozen at0.65.0-rc11and only resolves at all because thestep-agent-plugin→step-agentrepo redirect is still up.release-checkgate's regex has no-devalternation, sodev → rcpromotion commits skipped the job outright. Those runs are green, which is why this never looked broken.Fix
default.nixnow readspkgs/<name>/directly. The attribute set cannot drift from what goreleaser committed, so the 21 orphaned derivations register themselves and no future release can be missed. The unsuffixedstep-agentresolves to the highest stable version viabuiltins.compareVersions— currently 0.69.0, sourced fromsmallstep/step-agentdirectly rather than through the old redirect.addpkg.shand theadd-pkgjob are deleted. With the commit-back step gone, therelease-checkgate that guarded it has no remaining purpose, so the nix evaluation and build now run on pull requests instead of only on goreleaser release commits. That is the "fail loudly next time" coverage the ticket asked for, and it is what would catch a broken generator.Four derivations are pruned: two
0.0.0-nightly.*and two0.64.0-dev*. All four point atsmallstep/agentrelease assets that now 404, so registering them would turn CI red. Nightly and dev artifacts go tonur-dev.Verification
Run in a
nixos/nixcontainer against this branch:nix-env -f . -qawith--option restrict-eval true) returns 49 items.builtins.readDirworking under restricted eval was the one real unknown.nix-build ci.nix -A cacheOutputsexits 0 with 48 store paths, including the 17 previously-orphaned derivations CI had never built.0.65.0,0.68.0and0.69.0all build.step-agentevaluates tostep-agent-plugin-0.69.0.Also here
Action CI had failed at workflow-creation time on every run since 2026-05-25, so actionlint and zizmor were not examining this repo at all — including the workflow rewritten above.
smallstep/workflowsf47abc3 gave the reusable zizmor jobactions: read, and a reusable workflow cannot be granted more than its caller has; this caller granted onlycontents: readandsecurity-events: write, so the run was rejected before any job existed. That reports asstartup_failurewith no jobs and no annotations, which is why it never surfaced as a failing check. gateway, inventory and agent all grant the full set.With the linter running again it immediately flagged SC2046 and SC2086 on the evaluation step, both carried over unchanged from the previous workflow. Quoting them is behaviour-preserving on the runner.
Notes for review
modules→nixos-modulesin the same header block. I keptmain's spelling verbatim. Suggest merging this first — Add the step-agent NixOS module, and align with the upstream NUR layout #17'stestscheck is currently SKIPPED, so it would otherwise merge with no nix evaluation at all; after this lands it gets real PR coverage.flake.nixfails withFunction called without required argument "tpm2-openssl". This reproduces identically on unmodifiedmain—flake.lockpins nixpkgs from April 2024, before that package existed. Out of scope here; flake.lock lockstep #13 is aimed at it.🤖 Generated with Claude Code