Skip to content

fix(release): support aube-only checkouts without package-lock.json#101

Merged
ThomasK33 merged 1 commit into
mainfrom
release-tooling/aube-lockfile-support
May 13, 2026
Merged

fix(release): support aube-only checkouts without package-lock.json#101
ThomasK33 merged 1 commit into
mainfrom
release-tooling/aube-lockfile-support

Conversation

@ThomasK33
Copy link
Copy Markdown
Member

@ThomasK33 ThomasK33 commented May 13, 2026

Summary

After the aube migration in #91 the repo no longer ships a package-lock.json, but the release-prep tooling still required one. The net effect was that npm run release:prep (and npm run release:finalize, which calls the same helpers) failed end-to-end on the current main, blocking the documented release flow:

$ npm run release:prep -- --version 0.2.0 --changelog ci
error: ENOENT: no such file or directory, open '/path/to/agent-tty/package-lock.json'

This PR makes the lockfile path optional so the scripts work on aube-only checkouts while still supporting the npm-lockfile path for downstream consumers that re-introduce one.

Why this blocks v0.2.0

I hit this while running the release:prep step of the v0.2.0 release sequence (Step 3 of plan tracked in #99). Without this fix the documented release:prep / release:finalize flow is broken on main, so it needs to land before the version-bump PR.

Changes

scripts/release-helpers.mjs

  • readPackageVersions checks existsSync('package-lock.json'). When present it still parses + returns the lockfile version fields; otherwise it returns hasPackageLock: false with null lockfile versions and only validates package.json.
  • assertPackageVersionsMatch only runs the lockfile-coherence assertions when hasPackageLock is true.

scripts/release-prep.mjs

  • Replaces the module-scope VERSION_FILE_PATHS constant with resolveVersionFilePaths(root) computed at runtime. On an aube-only checkout this resolves to ['package.json']; on a checkout that still carries package-lock.json it stays at ['package.json', 'package-lock.json'], preserving the prior behavior.

scripts/release-finalize.mjs

  • No direct changes — it consumes assertPackageVersionsMatch and inherits the fix.

test/integration/release-scripts.test.ts

  • createTempRepo / writePackageFiles gain an includePackageLock option (default `true`).
  • New: `prepares a release on an aube-only checkout (no package-lock.json)` — asserts the prep commit's diff is exactly `['package.json']` and that `package.json.version` matches the requested release version.
  • New: `finalizes on an aube-only checkout (no package-lock.json)` — asserts the annotated tag is created and pushed.
  • The pre-existing npm-lockfile test cases are unchanged and continue to assert the two-file diff + readVersions triple.

docs/RELEASE-PROCESS.md

  • Updated the `--changelog ci` prose and the manual-prep fallback so they no longer claim `package-lock.json` is always part of the prep commit; manual snippets stage `package-lock.json` only when it actually exists.

`CHANGELOG.md`

  • Added a Fixed entry under Unreleased.

Test plan

  • `npx vitest run test/integration/release-scripts.test.ts` — 27/27 pass (existing 25 + 2 new)
  • `npm run format:check` (oxfmt) — clean
  • `npm run lint` (oxlint) — 0 warnings / 0 errors
  • `npm run typecheck` — clean
  • CI on this PR
  • After this lands, verify `npm run release:prep -- --version 0.2.0 --changelog ci` succeeds on a fresh main checkout (the v0.2.0 release-prep PR is the real-world smoke test)

🤖 Generated with Claude Code

After the aube migration in #91 the repo no longer ships a
`package-lock.json`, but `scripts/release-helpers.mjs` and
`scripts/release-prep.mjs` still hardcoded it as a required file:

- `readPackageVersions` did `readJsonFile('package-lock.json')`
  unconditionally and failed with ENOENT on the current main.
- `assertPackageVersionsMatch` then asserted the lockfile's `version`
  and `packages[""].version` matched `package.json.version`.
- `release-prep.mjs` froze `VERSION_FILE_PATHS` as
  `['package.json', 'package-lock.json']` at module scope and staged
  both, so even if the version-match assertion were relaxed, the
  staging step would still fail because `package-lock.json` does not
  exist.

The net effect was that `npm run release:prep` (and, by inheritance,
`npm run release:finalize`) failed end-to-end on `main`, blocking the
documented release flow. This change makes the lockfile path optional:

- `readPackageVersions` checks `existsSync('package-lock.json')`. When
  present it still parses + returns the lockfile version fields;
  otherwise it returns `hasPackageLock: false` with null lockfile
  versions and only validates `package.json`.
- `assertPackageVersionsMatch` only runs the lockfile-coherence
  assertions when `hasPackageLock` is true.
- `release-prep.mjs` computes the version-file allowlist at runtime
  via `resolveVersionFilePaths(root)`. On an aube-only checkout this
  resolves to `['package.json']`; on a checkout that still carries
  `package-lock.json` it stays at `['package.json', 'package-lock.json']`,
  preserving the prior behavior for downstream consumers that
  re-introduce an npm lockfile.

`release-finalize.mjs` consumes `assertPackageVersionsMatch` and
inherits the fix without changes.

Tests
-----

`createTempRepo` / `writePackageFiles` gain an `includePackageLock`
option (default `true`), and two new integration test cases cover the
aube-only path:

- `prepares a release on an aube-only checkout (no package-lock.json)`
  asserts the prep commit's diff is exactly `['package.json']` and
  that `package.json.version` matches the requested release version.
- `finalizes on an aube-only checkout (no package-lock.json)` asserts
  the annotated tag is created and pushed.

The pre-existing npm-lockfile test cases are unchanged and continue
to assert the two-file diff + readVersions triple.

All 27 release-scripts tests pass. Format, lint, and typecheck are
clean.

Docs
----

`docs/RELEASE-PROCESS.md` is updated so the changelog-mode prose and
the manual-prep fallback no longer claim that `package-lock.json` is
always part of the prep commit; the fallback snippets now stage
`package-lock.json` only when it actually exists.

Change-Id: Idfb4bbdde5d222c4f0f9096d650bbbc2f6d5f9c9
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33 ThomasK33 merged commit ffc1728 into main May 13, 2026
12 checks passed
@ThomasK33 ThomasK33 deleted the release-tooling/aube-lockfile-support branch May 13, 2026 10:56
@ThomasK33 ThomasK33 mentioned this pull request May 13, 2026
6 tasks
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.

1 participant