Skip to content

chore: adopt the release standard - #31

Open
crcatala-vps wants to merge 3 commits into
mainfrom
chore/release-standard
Open

crcatala-vps wants to merge 3 commits into
mainfrom
chore/release-standard

Conversation

@crcatala-vps

@crcatala-vps crcatala-vps commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Applies the shared release standard to flashlink: the canonical release scripts, a commit-stamped fl --version, a new fl update [--check] [--force], a publish-last release flow, and the standard README Install section. The version stays 0.0.3; nothing is released.

Audit: 0 failing, 0 warnings, 27 checks.

⚠️ Structural change: the npm package now lives at the repository root

The standard's scripts/release.mjs (canonical, byte-identical) publishes the root package. In flashlink, the published package used to be packages/cli. To keep the canonical script unmodified, this PR:

  • renames the root package.json from the private flashlink-monorepo to the public flashlink package. It takes over the metadata, bin (fl, flashlink → ./packages/cli/dist/index.js), files, publishConfig, repository and the runtime dependencies (commander, mime);
  • turns packages/cli into the private @flashlink/cli build-only package (sources and tests stay where they are; it is no longer published, and its LICENSE/README copies are removed in favour of the root ones);
  • root build = pnpm --filter @flashlink/cli build && node scripts/build-info.mjs, so the tarball ships packages/cli/dist/index.js plus dist/build-info.json.

What it means:

  • Users: npm install -g flashlink installs the same fl / flashlink commands. Only the internal file path in the tarball changes (dist/index.js → packages/cli/dist/index.js).
  • Maintainers: publish from the repository root (pnpm release), not from packages/cli. The macOS binary scripts, install.sh, the release workflow and the docs were updated for the new paths.
  • Alternative if you prefer not to restructure: keep packages/cli as the published package and accept a non-canonical release.mjs (the audit would flag it). This was not done because it breaks the standard's byte-identical contract.

What changed

  • Canonical copies (byte for byte from the templates): scripts/prep-release.sh, scripts/check-changelog.sh, scripts/release.mjs, scripts/build-info.mjs, scripts/test-package.sh. They are listed in .prettierignore so formatting cannot change them.
  • Project-specific release steps that used to live in the old scripts/release.mjs moved to scripts/release-local.mjs (preflight, check-version, sync-version, notes, publish-check), wired into the release-it hooks and prepublishOnly. No safeguard was dropped.
  • .release-it.json: before:init = local preflight, changelog check, pnpm run verify; after:bump adds pnpm run test:package; npm.publish stays false and github.release stays false (CI's release workflow still creates the GitHub Release with the macOS binaries).
  • package.json scripts: test:package, prepack (build), prepublishOnly (publish-check + verify).
  • CLI (packages/cli/src/index.ts, src/cli-meta.ts): fl --version prints fl 0.0.3 (sha7 YYYY-MM-DD) (-dirty for uncommitted builds); new fl update [--check] [--force]. A standalone macOS binary prints the manual update steps and exits 1.
  • Package smoke test hook scripts/test-package.local.sh: tarball contents and both bins.
  • Docs: README ## Install gains From source and Updating; RELEASING.md rewritten from the template for pnpm and the root package; docs/CLI.md, docs/DEVELOPMENT.md, docs/ARCHITECTURE.md updated; CHANGELOG.md has Unreleased entries only.
  • Tests: new cli-meta.test.ts; release.test.ts, engines.test.ts and process.test.ts updated for the new layout. Timeouts were raised only on the two real-git release.test.ts tests.

Verification

Command Result
pnpm format:check / pnpm typecheck pass
pnpm test 508 tests pass. Under heavy local load a few tests hit Vitest's 5 s default timeout; the same happens on a clean main checkout.
pnpm build dist/build-info.json stamped with this commit, dirty: false
worker wrangler deploy --dry-run exit 0
pnpm test:package Package smoke test passed. (LICENSE, README, package.json, dist/build-info.json, packages/cli/dist/index.js)
sh scripts/package-release.sh + sha256sum -c all five release assets OK
fl --version (local build) fl 0.0.3 (4f2910b 2026-10-27)
fl update --check exit 0, up to date
pnpm release:dry refused by the canonical preflight: not logged in to npm (expected on the machine where this was prepared)
npx release-it --dry-run --ci --no-npm --no-github --git.requireBranch=chore/release-standard plans chore: release v0.0.4 and annotated tag v0.0.4; tree left clean, no tag created
PR CI check, binaries, GitGuardian, Socket: all pass

No release, tag, publish or GitHub Release was created.

🤖 Generated with Claude Code

crcatala-vps and others added 3 commits October 27, 2026 18:43
Copy the standard's canonical scripts byte for byte (release.mjs, build-info.mjs,
test-package.sh, prep-release.sh, check-changelog.sh) and keep them out of
prettier so format:check cannot rewrite them.

The published npm package is now the repository root (packages/cli becomes the
private @flashlink/cli build package), which is what the standard's release.mjs
needs: it publishes the root package after release-it has committed, tagged and
pushed, so the published build is stamped with the release commit. The tarball
ships packages/cli/dist, dist/build-info.json, the README and the LICENSE, and
prepublishOnly still refuses anything but the tagged, synced, not-yet-published
commit before running verify.

Project-specific release steps move to scripts/release-local.mjs (preflight,
check-version, sync-version, notes, publish-check) and are wired into the
release-it hooks, the release workflow and npm's prepublishOnly; nothing from the
old flow is dropped.

Adds test:package (with project checks in scripts/test-package.local.sh) and
prepack, so a release packs and installs the tarball after the bump.

Co-authored-by: Christian Catalan <crcatala@gmail.com>
`fl --version` (and -V) now prints `fl X.Y.Z (sha7 YYYY-MM-DD)` everywhere: a
build stamps dist/build-info.json (scripts/build-info.mjs) and reports it, a run
from source in a checkout reads git instead, and `-dirty` marks a build from
uncommitted changes. Standalone (Bun) binaries embed the commit and its date at
compile time. The macOS installer and Finder menu strip the new name prefix, so
their "fl X.Y.Z (sha date)" labels are unchanged.

`fl update` updates the way fl was installed: a clone is pulled and rebuilt
(refusing a dirty tree or another branch), a global npm/pnpm/bun install is
reinstalled from npm, mise uses `mise upgrade --bump`, npx explains itself, and
anything else prints the manual steps and exits 1. `--check` only reports
(0 up to date, 1 update available, 2 unknown) and `--force` updates anyway.

The version/update module lives at src/cli-meta.ts in the published package root
and is bundled into packages/cli/dist.

Co-authored-by: Christian Catalan <crcatala@gmail.com>
Rewrite RELEASING.md for the wrapped release-it flow (preflight, changelog
check, verify, bump, smoke test, tag, publish from the tag) and the recovery
steps, note which files are canonical copies, and add the README's Install
section with From source and Updating. Update the CLI reference, DEVELOPMENT and
ARCHITECTURE for the new version line, `fl update` and the one published
package.

Co-authored-by: Christian Catalan <crcatala@gmail.com>
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