Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ Pass an existing archive to test the same build CI uses:
`npm run test:package -- /absolute/path/to/package.tgz`. For a final CI candidate,
also pass its `release.json` as the second argument. The supplied package's
name, version, executable mode and manifest are checked before runtime probes.
The README inside the archive must match the checkout, install from npm's
`beta` channel and avoid unpublished or local-archive installation guidance.
`npm run verify` runs lint, typecheck, build and tests; `npm run release:check`
also previews the package contents. Neither publishes or creates a tag.

Expand Down
11 changes: 6 additions & 5 deletions docs/doppler.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ a provider option. `resolve-doppler` and

## Local setup

From the checkout, build and log in:
After [installing resenv](../README.md#install) in your application project, log in:

```sh
npm run build
node dist/bin/resenv.cjs login doppler
npx --no-install resenv login doppler
```

After installing a packed build, the same command is `resenv login doppler`.
The examples below use `resenv` directly in an npm script; from your shell,
prefix it with `npx --no-install` to use the project's installed copy.
For checkout builds and local testing, see [CONTRIBUTING.md](../CONTRIBUTING.md).
If the references are already loaded into the shell environment, `resenv login`
infers Doppler without naming it. No cloud references means no login is needed.
Neither command loads dotenv files; Nx remains responsible for file selection.
Expand All @@ -40,7 +41,7 @@ and build suffixes while the package retains its complete release version.
The user token is saved in the OS credential store under service
`ciqol.envref.doppler`, account `default`. The identifier is retained across
the resenv rename so existing logins continue to work. Nothing is saved in the repository,
dotenv files or worktree. The current prototype stores one workplace login per
dotenv files or worktree. The current beta stores one workplace login per
OS user; logging in again replaces that saved identity. Each developer logs in
separately and receives the permissions of their own Doppler account.

Expand Down
7 changes: 7 additions & 0 deletions docs/maintainer-handoff.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ npm view @ciqol/resenv versions dist-tags --json
npm stage list @ciqol/resenv --json
```

Inspect the tested archive's README as well as the source README before release.
The first public beta shipped obsolete archive-only installation instructions;
later source corrections cannot update an already published archive. Package
checks now enforce npm installation guidance and README equality with the
checkout. Ship documentation corrections in a new tested release through the
same staging and approval workflow.

The first intended version is `0.1.0-beta.1`; npm tags `beta` and `latest` point
to the same tested beta release. The planner uses semantic-release's official
commit-analysis and notes plugins directly;
Expand Down
16 changes: 16 additions & 0 deletions docs/validation.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Validation

## October 13, 2026 — packaged installation documentation

npm lists only `0.1.0-beta.1`, with both `beta` and `latest` pointing to it.
Its public archive still contains the unpublished, archive-only installation
instructions corrected later in the source README. Package checks now compare
the archived README with the checkout and require npm beta installation,
rejecting local archive paths and unpublished claims. The actual published
archive fails the new gate; restoring its README in both source and build also
fails the installation check. The current build passes all 16 packed runtime
checks and both typed consumers. Lint, strict types, build, 101 unit/tooling
tests, the coverage gate and 41 process tests passed on pinned Node 24.19.0.
The package check used a writable temporary npm cache after the sandbox denied
access to the default cache. The Doppler guide now starts with the installed
CLI and links to contributor setup. The existing public archive is unchanged;
publishing corrected documentation requires a new staged, approved release.

## October 13, 2026 — PR review and command shutdown

Review found that forwarding a signal only to the wrapped command could leave
Expand Down
7 changes: 7 additions & 0 deletions test/package-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ try {
if (source.license !== 'UNLICENSED') assert.ok(packed.files.some(file => file.path === 'LICENSE'))
assert.ok(packed.files.find(file => file.path === 'bin/resenv.cjs').mode & 0o111, 'CLI must remain executable')
const archive = suppliedArchive ?? join(directory, packed.filename)
const readme = run('tar', ['-xOf', archive, 'package/README.md'], root).stdout
assert.equal(readme, readFileSync(join(root, 'README.md'), 'utf8'), 'Packed README must match the checked-out documentation')
const install = readme.split(/^## /m).find(section => section.startsWith('Install\n'))
assert.ok(install, 'README must include application installation instructions')
assert.match(install, /npm install --save-exact @ciqol\/resenv@beta/, 'Application installation must use the public npm beta')
assert.doesNotMatch(install, /\.tgz\b|file:|\/path\/to\//, 'Local archive installation belongs in CONTRIBUTING.md')
assert.doesNotMatch(readme, /not (?:yet )?published|has not been published|once .{0,40}published|currently distributed\s+as a package archive/i, 'README must not describe the public package as unpublished')
const packedManifest = JSON.parse(run('tar', ['-xOf', archive, 'package/package.json'], root).stdout)
const dependency = `file:${archive}`
const dependencies = { [source.name]: dependency }
Expand Down
Loading