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
48 changes: 46 additions & 2 deletions skills/setup-simple-release-action/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ By default set up only the **main flow** (release pull request → release on me
2. **Snapshot release** — publish a temporary timestamped prerelease from any branch under its own npm dist-tag, without committing anything.
3. **Maintenance branches** — when a release crosses a major boundary, create a branch for the previous major so fixes for it keep releasing under their own dist-tag.

If the user has already said which add-ons they want — including "just the default" — do not ask. Otherwise ask once, in a single concise question listing the three add-ons with one-line explanations, with "none" as the default.
Projects publishing to the npm registry have one more choice: authenticate with an **`NPM_TOKEN` secret** (the default, works for any package) or with **trusted publishing** (no secret — OIDC with automatic provenance; see the npm authentication point in the toolchain section for its prerequisites).

If the user has already said which add-ons they want — including "just the default" — do not ask. Otherwise ask once, in a single concise question listing the three add-ons with one-line explanations, with "none" as the default, plus the token-or-trusted-publishing choice when the project publishes to npm.

The user may also name the project type or addon explicitly (for example "this is a pnpm monorepo with independent versions"). An explicit statement always wins over detection.

Expand Down Expand Up @@ -105,6 +107,7 @@ Fill the workflow from the repository, not from assumptions:
- **Node.js version** — in priority order: `.nvmrc` or `.node-version` file (then prefer `node-version-file` over a hardcoded `node-version` in `actions/setup-node`), the minimum major satisfying `engines.node`, `volta.node`, existing CI workflows. Fall back to the current LTS major.
- **Package manager version** — if `package.json` has a `packageManager` field, use `pnpm/action-setup` **without** a `version` input — it reads the field. Otherwise infer the major from `pnpm-lock.yaml`'s `lockfileVersion` (`'6.0'` → pnpm 8, `'9.0'` → pnpm 9 or 10 — prefer the latest and tell the user what you assumed). npm needs no setup beyond `actions/setup-node`.
- **Registry** — default `https://registry.npmjs.org`. If `publishConfig.registry` or `.npmrc` points to GitHub Packages (`npm.pkg.github.com`): set that `registry-url` plus `scope: '@owner'` in `actions/setup-node`, pass `npm-token: ${{ secrets.GITHUB_TOKEN }}`, and add `packages: write` to the release job permissions. GitHub Packages requires the package scope to match the repository owner — flag a mismatch instead of publishing into the void.
- **npm authentication** — an `NPM_TOKEN` secret by default. Trusted publishing when the user chose it, or when the repository's existing workflows already publish that way (`id-token: write` on the publishing job and no npm token). Its prerequisites, per the npm docs: the public npm registry (not GitHub Packages), GitHub-hosted runners, npm CLI 11.5.1 or later — use `node-version: 24` in the publishing jobs, Node.js 22 ships npm 10 — and packages that already exist on npm, because the trusted publisher is registered in the package settings. Check every published package with `npm view <name> version`; a 404 means its first version has to be published with a token or by hand, tell the user. Documentation: <https://simple-release.js.org/github-action/trusted-publishing/>.
- **Existing workflows** — reuse the action versions and conventions the repository already has where they don't conflict with this setup.

## Generate the Config
Expand Down Expand Up @@ -237,6 +240,7 @@ Variations:
- **npm project** — drop the `Install pnpm` step, use `cache: 'npm'` and `run: npm ci`.
- **Node.js GitHub Action project** — keep the package manager and Node.js setup and the install step in the `release` job (the configured `build` command needs them), but drop `registry-url` and `npm-token`: publishing pushes git refs, not registry packages.
- **No publishing** (`publish.skip` in the config) — drop `registry-url` and `npm-token` from the `release` job.
- **Trusted publishing** — in the `release` job add `id-token: write` to `permissions`, drop `registry-url` from `actions/setup-node` and `npm-token` from the action step, and use `node-version: 24`; the config needs nothing. The snapshot flow then lives in the same workflow file — see the snapshot add-on.
- **GitHub Packages** — see the registry point in the toolchain section.

### Manual release add-on
Expand Down Expand Up @@ -337,6 +341,40 @@ jobs:

The package manager, Node.js, and registry setup follows the same detection as the release job. Snapshots publish to a registry — skip this add-on for project types that do not (a Node.js GitHub Action).

With trusted publishing the trusted publisher is registered per workflow file, so put the snapshot flow into `release.yml` instead of a second workflow: a `snapshot` input on the `workflow_dispatch` trigger, a guard on the `check` job so a snapshot dispatch does not run the pull request flow, and a `snapshot` job with the same `id-token: write` permission:

```yaml
on:
workflow_dispatch:
inputs:
# ...the manual release inputs, if any
snapshot:
description: Snapshot tag — publish a snapshot under this npm dist-tag instead of a release (leave other inputs empty)
type: string
# ...the issue_comment and push triggers stay as they are
jobs:
check:
if: inputs.snapshot == ''
# ...the rest of the check job stays as it is
snapshot:
runs-on: ubuntu-latest
name: Snapshot
if: inputs.snapshot != ''
permissions:
contents: read
id-token: write
steps:
# ...the same checkout, package manager, Node.js 24, and install steps as the release job, without registry-url
- name: Publish snapshot
uses: TrigenSoftware/simple-release-action@v2
with:
workflow: snapshot
github-token: ${{ secrets.GITHUB_TOKEN }}
bump-snapshot: ${{ inputs.snapshot }}
```

On push and comment events `inputs.snapshot` is empty, so `check` runs as usual and `snapshot` is skipped. This layout needs the `workflow_dispatch` trigger even without the manual release add-on.

## Validate

- The config must be valid JSON and the workflows valid YAML — parse them (for example with `node -e` or a YAML-aware tool). Run `actionlint` on the workflows if it is available.
Expand All @@ -353,7 +391,13 @@ Finish with a checklist of the steps that cannot be automated:
-F can_approve_pull_request_reviews=true
```

2. **`NPM_TOKEN` secret** — required when publishing to the npm registry: an npm automation (granular) token with publish permission for the packages. Not needed for GitHub Packages (the workflow token is used) or for non-publishing projects.
2. **npm authentication** — with the token flow, an `NPM_TOKEN` secret: an npm automation (granular) token with publish permission for the packages. With trusted publishing, no secret; instead register the trusted publisher for every published package on npmjs.com — package **Settings → Trusted Publisher → GitHub Actions**: the organization or user, the repository, the workflow filename `release.yml`, and optionally an environment — or with the npm CLI (11.15 or later, two-factor authentication required):

```bash
npm trust github <package> --repository <owner>/<repo> --file release.yml --allow-publish
```

A package that was never published has no settings to register on: publish its first version with a token first. Neither is needed for GitHub Packages (the workflow token is used) or for non-publishing projects.
3. **Squash-merge release pull requests** — the release is recognized by the `chore(release): ...` commit title on the branch head. A regular merge commit hides it and the release job will not run. Recommend enabling squash merging for the repository.
4. **The first release** — after the setup is merged, the next push of a releasable commit (or the setup push itself) opens a release pull request. When no release tags exist yet, the version is taken from the manifest as is and the changelog covers the whole history.
5. **Reshaping a pending release** — a comment on the release pull request starting with `!simple-release/set-options` followed by a JSON code block (for example `{"bump": {"as": "major"}}`) rebuilds it with those options. A `!simple-release/set-preamble` comment (optionally followed by a full package name to target one package in a monorepo) inserts the markdown after it into the changelog. Both are documented in the cheatsheet included in every release pull request body.
Expand Down
14 changes: 11 additions & 3 deletions skills/simple-release-action/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ From the release workflow — usually `.github/workflows/release.yml` — note:
- `on.push.branches`: the flow runs only for pushes to these branches.
- A `workflow_dispatch` trigger with `version`, `as`, `prerelease` (and `by-project`) inputs forwarded to the `bump-*` action inputs: the **manual release** add-on.
- A `branch` input on the action steps: the release branch name. It defaults to `simple-release`; the `gh pr list --head` commands below use it.
- A separate workflow running `workflow: snapshot` — usually `.github/workflows/snapshot.yml`: the **snapshot** add-on.
- Whether the release job publishes to a registry (`registry-url`, `npm-token`). Node.js GitHub Action projects publish built git refs instead (the `latest` and `v{major}` branches and the `v{version}` tag), and projects with `publish.skip` only tag and create the GitHub release.
- A job running `workflow: snapshot` — a separate `.github/workflows/snapshot.yml`, or a `snapshot` job in `release.yml` guarded by a `snapshot` dispatch input: the **snapshot** add-on.
- How the release job publishes: `npm-token` and `registry-url` mean the token flow; `id-token: write` in the job permissions and no token mean [trusted publishing](https://simple-release.js.org/github-action/trusted-publishing/), where the trusted publisher on npmjs.com is bound to the workflow file — that is why the snapshot job then usually sits in `release.yml`. Node.js GitHub Action projects publish built git refs instead (the `latest` and `v{major}` branches and the `v{version}` tag), and projects with `publish.skip` only tag and create the GitHub release.

A single job running `workflow: full` (the default) behaves like the three-job layout with `check`, `pull-request`, and `release` — the action picks the flow from the event, so everything below applies to both.

Expand Down Expand Up @@ -235,7 +235,7 @@ Notes:

## Snapshot from Any Branch

Requires the snapshot workflow. A snapshot publishes the current state of a branch as a timestamped prerelease under its own npm dist-tag — nothing is committed, tagged, or written to the changelog. Not applicable to projects that publish nothing (Node.js GitHub Action projects, `publish.skip`).
Requires the snapshot add-on. A snapshot publishes the current state of a branch as a timestamped prerelease under its own npm dist-tag — nothing is committed, tagged, or written to the changelog. Not applicable to projects that publish nothing (Node.js GitHub Action projects, `publish.skip`).

```bash
git push -u origin my-feature
Expand All @@ -245,6 +245,13 @@ gh run watch <run-id>
npm view <package> dist-tags
```

When the snapshot job lives in `release.yml` (the trusted publishing layout), dispatch that workflow with its `snapshot` input instead — the `check` job and the release flow are skipped for such a run:

```bash
gh workflow run release.yml --ref my-feature -f snapshot=canary
gh run list --workflow release.yml --event workflow_dispatch --limit 1
```

The branch must exist on the remote — `--ref` names the branch to check out and to take the workflow file from. The `tag` input is both the prerelease identifier and the dist-tag: a repository released as `1.1.0` with a `feat` on the branch publishes `1.2.0-canary.20260707111020`, installable with `npm i <package>@canary`. Without new commits the version falls back to a patch bump, so a snapshot never collides with a real release. In a monorepo every package is snapshotted in one run, each from its own version.

## Maintenance Branches
Expand Down Expand Up @@ -294,6 +301,7 @@ gh api repos/{owner}/{repo}/actions/permissions/workflow
| | The run happened but the options were not applied: invalid JSON, no `json` fence, or the author is not an owner, member, or collaborator | Fix and post again; with `releaser.verbose` the log says "Failed to parse parameters comment" for invalid JSON |
| | The comment was edited — edits do not trigger runs | Post a new comment, or delete and re-post |
| `gh workflow run` fails | "Workflow does not have 'workflow_dispatch' trigger", or unexpected inputs | The manual release or snapshot add-on is not set up — offer the setup skill |
| Publish fails with `ENEEDAUTH` or "Unable to authenticate" | Trusted publishing: the workflow filename or repository does not match the trusted publisher registered on npmjs.com, the job lacks `id-token: write`, npm is older than 11.5.1 (Node.js below 24), or the package was never published, so no publisher could be registered. In the token flow: `NPM_TOKEN` missing or expired | Compare the registration with the workflow file name and repository, check the job permissions and Node.js version; publish a brand-new package's first version with a token; rotate the secret in the token flow |
| Prerelease produced no pull request | An older action version: `as: prerelease` with an identifier on a stable version used to yield nothing | Update simple-release-action, or use the identifier alone or with `as` set to `major`, `minor`, or `patch` |
| Renovate or Dependabot commits do not release a monorepo package | The `deps` scope is not a package name | `bump.extraScopes: ["deps"]` in the config |
| Fixed monorepo: unchanged packages kept their version | By design — only changed packages are bumped | `bump.force: true` in the config |
Expand Down
4 changes: 2 additions & 2 deletions website/src/content/docs/getting-started/agent-skills.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ The repository ships **universal agent skills** — instructions that teach an A
The [`setup-simple-release-action`](https://github.com/TrigenSoftware/simple-release/tree/main/skills/setup-simple-release-action) skill sets up the [GitHub Action](/github-action/) in a repository end to end. Rather than pasting a template, the skill guides the agent to:

- **Detect the project type from the repository** — lock files, workspace manifests, `action.yml` — and describe it in the [config](/getting-started/configuration/) with a version-pinned addon [query](/getting-started/configuration/#project-query). You can also just tell the agent what to use.
- **Fill the workflow from your toolchain** — the Node.js version, the package manager and its version, the default branch, and the npm registry are read from the repository, not assumed.
- **Fill the workflow from your toolchain** — the Node.js version, the package manager and its version, the default branch, and the npm registry are read from the repository, not assumed; the release job publishes with an npm token or through [trusted publishing](/github-action/trusted-publishing/), as you choose.
- **Add the optional flows on request** — [manual release](/github-action/manual-release/), [snapshot release](/github-action/snapshot-release/), and [maintenance branches](/github-action/maintenance-branches/). By default only the main [release automation](/github-action/release-automation/) flow is set up; if you have not said what you need, the agent asks once.
- **Finish with a checklist** of the settings only you can change — allowing GitHub Actions to create pull requests, the `NPM_TOKEN` secret, squash merging for release pull requests.
- **Finish with a checklist** of the settings only you can change — allowing GitHub Actions to create pull requests, the `NPM_TOKEN` secret or the trusted publisher registration, squash merging for release pull requests.

Install the skill into your project with either package runner:

Expand Down
2 changes: 1 addition & 1 deletion website/src/content/docs/github-action/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The `workflow` input selects what the action does in the current job:
| --- | --- |
| `workflow` | Workflow to run. Defaults to `full`. |
| `github-token` | GitHub token to authenticate with the GitHub API. Required. |
| `npm-token` | npm token for publishing. Passed to the `NODE_AUTH_TOKEN` environment variable. |
| `npm-token` | npm token for publishing. Passed to the `NODE_AUTH_TOKEN` environment variable. Not needed with [trusted publishing](/github-action/trusted-publishing/). |
| `publish-token` | Generic token for the config file. Passed to the `PUBLISH_TOKEN` environment variable. |
| `branch` | Branch to store release changes and create the pull request from. Defaults to `simple-release`. |
| `bump-version` | Force a specific version. |
Expand Down
2 changes: 2 additions & 0 deletions website/src/content/docs/github-action/release-automation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ The main flow keeps a **release pull request** up to date and releases it on mer

The three jobs map to the action [workflows](/github-action/#workflows): `check` decides what should run for the current event, `pull-request` maintains the release pull request, and `release` runs on the merged release commit — it creates the tags, publishes the packages, and creates the GitHub release.

The `release` job publishes with the `NPM_TOKEN` secret — an npm automation token with publish permission for the packages. To publish without any secret, switch the job to [trusted publishing](/github-action/trusted-publishing/).

3. Allow the action to create pull requests: in the repository **Settings → Actions → General**, enable **Allow GitHub Actions to create and approve pull requests**. Without it the `pull-request` job fails with a "GitHub Actions is not permitted to create or approve pull requests" error.

4. Push a `feat: ...` or `fix: ...` commit to `main` — the release pull request appears. Merge it with **squash** to release.
Expand Down
2 changes: 2 additions & 0 deletions website/src/content/docs/github-action/snapshot-release.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ jobs:

The `tag` input doubles as the prerelease identifier and the npm dist-tag the snapshot is published under.

With [trusted publishing](/github-action/trusted-publishing/#snapshots) the snapshot job moves into the release workflow instead, because the trusted publisher is registered per workflow file.

## Running it

Go to **Actions → Snapshot → Run workflow**, pick the branch and the tag, and run — or from the CLI:
Expand Down
Loading