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
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ jobs:
- name: Create release package
run: npm pack --ignore-scripts --pack-destination release

- name: Publish to npm with provenance
- name: Stage package for npm review
run: |
set -euo pipefail
package_name="$(node -p "require('./package.json').name")"
package_version="$(node -p "require('./package.json').version")"
if npm view "${package_name}@${package_version}" version --silent >/dev/null 2>&1; then
echo "${package_name}@${package_version} is already published; skipping duplicate publish."
else
npm publish --provenance --access public
npm stage publish
fi

- name: Create GitHub Release
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ npm version patch
git push origin main --follow-tags
```

The release workflow accepts only `vMAJOR.MINOR.PATCH` tags and requires the tag to match `package.json`. It builds and tests the tagged source, publishes the package to the public npm registry using npm Trusted Publishing/OIDC, and attaches the same tarball to a GitHub Release.
The release workflow accepts only `vMAJOR.MINOR.PATCH` tags and requires the tag to match `package.json`. It builds and tests the tagged source, stages the package for review using npm Trusted Publishing/OIDC, and attaches the same tarball to a GitHub Release. The package becomes public only after a maintainer approves the staged package on npm.

Repository administrators should protect `main` and `v*.*.*` tags, require the CI, dependency-review, and CodeQL checks, require pull requests and signed commits where applicable, configure npm Trusted Publishing for this repository/workflow, and configure the `release` environment with approval rules. These repository settings cannot be enforced by files in the repository alone.

Expand Down
18 changes: 14 additions & 4 deletions docs/INSTRUCTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ Organization or user: Ohryzon
Repository: apimoq-cli
Workflow filename: release.yml
Environment: release
Permission: allow npm publish
Permission: allow staged publishing only
```

Use only `release.yml` as the workflow filename, not the full path. Trusted Publishing uses short-lived OIDC credentials. Do not create or store an npm publish token in GitHub Actions.
Use only `release.yml` as the workflow filename, not the full path. Trusted Publishing uses short-lived OIDC credentials. Do not create or store an npm publish token in GitHub Actions. Leave direct `npm publish` permission unchecked.

After verifying the configuration, enable:

Expand Down Expand Up @@ -159,7 +159,17 @@ Push the commit and tag together:
git push origin main --follow-tags
```

The release workflow then publishes the new version to npm using Trusted Publishing and generates provenance through GitHub Actions OIDC.
The release workflow then stages the new version on npm using Trusted Publishing and generates provenance through GitHub Actions OIDC. It does not become publicly installable until a maintainer approves the staged package.

Review and approve the staged package:

```bash
npm stage list apimoq-cli
npm stage view <stage-id>
npm stage approve <stage-id>
```

The approval step requires maintainer authentication and two-factor authentication. Review the staged package contents before approving it.

## Release requirements

Expand All @@ -184,7 +194,7 @@ If any requirement fails, npm publication does not occur.
- Do not force-push `main` or release tags.
- Do not reuse a published npm version.
- Do not publish from an unreviewed branch.
- Prefer Trusted Publishing over long-lived npm tokens.
- Prefer Trusted Publishing with staged publishing over long-lived npm tokens.
- Review `npm pack --dry-run` output before the first release and whenever package contents change.

## Useful commands
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 29 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
{
"name": "apimoq-cli",
"version": "0.1.0",
"version": "0.1.1",
"description": "A lightweight, persistent local API simulator for frontend development.",
"license": "MIT",
"repository": { "type": "git", "url": "git+ssh://git@github.com/Ohryzon/apimoq-cli.git" },
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/Ohryzon/apimoq-cli.git"
},
"homepage": "https://github.com/Ohryzon/apimoq-cli#readme",
"bugs": { "url": "https://github.com/Ohryzon/apimoq-cli/issues" },
"keywords": ["api", "mock", "mock-server", "frontend", "cli", "development"],
"publishConfig": { "access": "public" },
"bugs": {
"url": "https://github.com/Ohryzon/apimoq-cli/issues"
},
"keywords": [
"api",
"mock",
"mock-server",
"frontend",
"cli",
"development"
],
"publishConfig": {
"access": "public"
},
"type": "module",
"bin": { "apimoq": "./dist/cli/index.js" },
"files": ["dist", "templates"],
"bin": {
"apimoq": "./dist/cli/index.js"
},
"files": [
"dist",
"templates"
],
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && tsc -p tsconfig.json",
Expand All @@ -22,7 +41,9 @@
"pack:ci": "npm pack --dry-run",
"prepublishOnly": "npm run build"
},
"engines": { "node": ">=20" },
"engines": {
"node": ">=20"
},
"dependencies": {
"@faker-js/faker": "^10.6.0",
"commander": "^12.1.0",
Expand Down
Loading