diff --git a/astro.config.js b/astro.config.js
index 1b43c8a..490893e 100644
--- a/astro.config.js
+++ b/astro.config.js
@@ -78,11 +78,14 @@ export default defineConfig({
{
label: "CI Configurations",
items: [
- { slug: "recipes/ci-configurations" },
- { slug: "recipes/ci-configurations/circleci-workflows" },
- { slug: "recipes/ci-configurations/travis" },
- { slug: "recipes/ci-configurations/gitlab-ci" },
+ { slug: "recipes/ci-configurations", label: "Overview" },
{ slug: "recipes/ci-configurations/github-actions" },
+ { slug: "recipes/ci-configurations/gitlab-ci" },
+ {
+ slug: "recipes/ci-configurations/circleci-workflows",
+ label: "CircleCI Workflows",
+ },
+ { slug: "recipes/ci-configurations/travis" },
{ slug: "recipes/ci-configurations/jenkins-ci" },
],
},
diff --git a/src/content/docs/foundation/considerations.md b/src/content/docs/foundation/considerations.md
index a59e118..77f9745 100644
--- a/src/content/docs/foundation/considerations.md
+++ b/src/content/docs/foundation/considerations.md
@@ -12,7 +12,7 @@ title: Considerations
If your primary attraction is for automatic release note generation rather than semantic versioning, you may want to reconsider if **semantic-release** is the right fit for your goals.
-:::tip[Recommendation]
+:::tip[Recommendation]
Adopt **semantic-release** when semantic versioning is your primary objective, with release-step automation as a secondary benefit.
:::
@@ -29,7 +29,7 @@ Applications that are deployed directly to a runtime environment lack an audienc
Docker images that are published to a registry only for the purpose of deploying directly to a runtime environment fall into this category, even though they are a published asset.
Often, using the git SHA as the version for such assets is a better choice than versioning them semantically.
-:::tip[Recommendation]
+:::tip[Recommendation]
Prioritize semantic versioning for artifacts consumed as dependencies; for directly deployed artifacts, consider using git SHAs instead.
:::
@@ -43,7 +43,7 @@ and [making commits during the release process adds significant complexity](/sup
Please consider the trade-offs of adding those plugins to your release configuration for potentially unnecessary goals.
-:::tip[Recommendation]
+:::tip[Recommendation]
Keep your configuration minimal and only add release-time commits when there is a clear, justified need.
:::
diff --git a/src/content/docs/foundation/plugins.md b/src/content/docs/foundation/plugins.md
index bfa1173..b01dcf6 100644
--- a/src/content/docs/foundation/plugins.md
+++ b/src/content/docs/foundation/plugins.md
@@ -8,17 +8,17 @@ This enables support for different [commit message conventions](/foundation/how-
A plugin is a npm module that can implement one or more lifecycle methods for the following hooks:
-| Lifecycle Hook | Related Release Step | Required | Description |
-| ------------------ | --------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `verifyConditions` | Verify Conditions | No | Verify conditions necessary to proceed with the release: configuration is correct, authentication tokens are valid, and so on. |
-| `analyzeCommits` | Analyze Commits | Yes | Determine the type of the next release (`major`, `minor`, or `patch`). This hook is required to decide the next release type. If multiple plugins implement `analyzeCommits`, the highest release type returned wins. |
-| `verifyRelease` | Verify Release | No | Verify the parameters of the release that is about to be published, such as version, type, or distribution tag. |
-| `generateNotes` | Generate Notes | No | Generate the content of the release note. If multiple plugins implement `generateNotes`, the release notes will be the concatenation of each plugin output. |
-| `prepare` | Prepare | No | Prepare the release, for example by creating or updating files such as `package.json`, `CHANGELOG.md`, documentation, or compiled assets and pushing a commit. |
-| `publish` | Publish | No | Publish the release. |
-| `addChannel` | Add Channel (optional) | No | Assign the release to a distribution channel when channel management is needed, for example by adding an npm dist-tag. |
-| `success` | Notify | No | Notify consumers or maintainers after a successful release. |
-| `fail` | Notify | No | Notify consumers or maintainers after a failed release. |
+| Lifecycle Hook | Related Release Step | Required | Description |
+| ------------------ | ---------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `verifyConditions` | Verify Conditions | No | Verify conditions necessary to proceed with the release: configuration is correct, authentication tokens are valid, and so on. |
+| `analyzeCommits` | Analyze Commits | Yes | Determine the type of the next release (`major`, `minor`, or `patch`). This hook is required to decide the next release type. If multiple plugins implement `analyzeCommits`, the highest release type returned wins. |
+| `verifyRelease` | Verify Release | No | Verify the parameters of the release that is about to be published, such as version, type, or distribution tag. |
+| `generateNotes` | Generate Notes | No | Generate the content of the release note. If multiple plugins implement `generateNotes`, the release notes will be the concatenation of each plugin output. |
+| `prepare` | Prepare | No | Prepare the release, for example by creating or updating files such as `package.json`, `CHANGELOG.md`, documentation, or compiled assets and pushing a commit. |
+| `publish` | Publish | No | Publish the release. |
+| `addChannel` | Add Channel (optional) | No | Assign the release to a distribution channel when channel management is needed, for example by adding an npm dist-tag. |
+| `success` | Notify | No | Notify consumers or maintainers after a successful release. |
+| `fail` | Notify | No | Notify consumers or maintainers after a failed release. |
For each [release step](/foundation/steps/), **semantic-release** runs every plugin in the [`plugins` array](plugins.md#plugins-declaration-and-execution-order) that implements the hook for that step.
diff --git a/src/content/docs/foundation/shareable-configurations.md b/src/content/docs/foundation/shareable-configurations.md
index 877ee12..e876ebf 100644
--- a/src/content/docs/foundation/shareable-configurations.md
+++ b/src/content/docs/foundation/shareable-configurations.md
@@ -16,7 +16,7 @@ The shareable configurations to use can be set with the [extends](/usage/configu
```json
{
- "extends": "@semantic-release/gitlab-config"
+ "extends": "@semantic-release/gitlab-config"
}
```
@@ -24,8 +24,8 @@ For example, a project can extend a shared base config and still override its ow
```json
{
- "extends": "@semantic-release/gitlab-config",
- "branches": ["main", "next"]
+ "extends": "@semantic-release/gitlab-config",
+ "branches": ["main", "next"]
}
```
@@ -36,4 +36,3 @@ If multiple shareable configurations are defined, they are loaded in order. Loca
See the [shareable configurations list](/extending/shareable-configurations-list) for official and community-maintained packages you can extend.
If you want to build your own shareable configuration, see [Shareable configuration development](/developer-guide/shareable-configuration/).
-
diff --git a/src/content/docs/foundation/supported-branching.md b/src/content/docs/foundation/supported-branching.md
index 397ebcb..2dbe060 100644
--- a/src/content/docs/foundation/supported-branching.md
+++ b/src/content/docs/foundation/supported-branching.md
@@ -4,7 +4,7 @@ title: Supported Branching Models
This page summarizes branching models that align well with **semantic-release** and those that are officially unsupported.
-:::tip[Recommendation]
+:::tip[Recommendation]
Default to workflows that keep changes flowing to a stable trunk quickly and continuously.
:::
@@ -35,7 +35,7 @@ These models align with the delivery and release assumptions built into **semant
- [Continuous Deployment](https://trunkbaseddevelopment.com/continuous-delivery/#continuous-deployment)
-:::tip[Recommendation]
+:::tip[Recommendation]
Choose a trunk-based workflow that keeps branch lifetime short and integration frequent.
:::
@@ -44,7 +44,7 @@ Choose a trunk-based workflow that keeps branch lifetime short and integration f
- [GitHub Docs: GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow)
- [GitHub Flow](https://githubflow.github.io/)
-:::tip[Recommendation]
+:::tip[Recommendation]
GitHub Flow is a practical fit when pull requests are short-lived and releases are frequent.
:::
@@ -73,7 +73,7 @@ While the [same reflection](https://nvie.com/posts/a-successful-git-branching-mo
While some have found that the [Pre-release workflow](/foundation/workflow-configuration/#prerelease) enabled by **semantic-release** can be used to _simulate_ a git-flow-like workflow,
it is also worth noting that this orchestration pattern is not an intended use case and requests for support when attempting to use it that way will be closed by our team.
-:::tip[Recommendation]
+:::tip[Recommendation]
Avoid Git flow-style long-lived branch orchestration when using **semantic-release**.
:::
@@ -81,7 +81,7 @@ Avoid Git flow-style long-lived branch orchestration when using **semantic-relea
- [The Importance of a Local Build](https://trunkbaseddevelopment.com/styles/#the-importance-of-a-local-build)
-:::tip[Recommendation]
+:::tip[Recommendation]
Prefer workflows where confidence comes from CI quality signals, with production release as the promotion event.
:::
diff --git a/src/content/docs/foundation/workflow-configuration.md b/src/content/docs/foundation/workflow-configuration.md
index 699cabd..260157e 100644
--- a/src/content/docs/foundation/workflow-configuration.md
+++ b/src/content/docs/foundation/workflow-configuration.md
@@ -23,10 +23,10 @@ The type of the branch is automatically determined based on naming conventions a
## Branch Properties
-| Property | Branch type | Description | Default |
-| ------------ | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
-| `name` | All | **Required.** The Git branch holding the commits to analyze and the code to release. See [name](#name). | - The value itself if defined as a `String` or the matching branches name if defined as a glob. |
-| `channel` | All | The distribution channel on which to publish releases from this branch. Set to `false` to force the default distribution channel instead of using the default. See [channel](#channel). | `undefined` for the first release branch, the value of `name` for subsequent ones. |
+| Property | Branch type | Description | Default |
+| ------------ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| `name` | All | **Required.** The Git branch holding the commits to analyze and the code to release. See [name](#name). | - The value itself if defined as a `String` or the matching branches name if defined as a glob. |
+| `channel` | All | The distribution channel on which to publish releases from this branch. Set to `false` to force the default distribution channel instead of using the default. See [channel](#channel). | `undefined` for the first release branch, the value of `name` for subsequent ones. |
| `range` | [maintenance](#maintenance-branches) only | **Required unless `name` is formatted like `N.N.x` or `N.x` (`N` is a number).** The range of [semantic versions](https://semver.org) to support on this branch. See [range](#range). | The value of `name`. |
| `prerelease` | [pre-release](#pre-release-branches) only | **Required.** The pre-release denotation to append to [semantic versions](https://semver.org) released from this branch. See [prerelease](#prerelease). | - |
diff --git a/src/content/docs/recipes/ci-configurations/github-actions.md b/src/content/docs/recipes/ci-configurations/github-actions.md
deleted file mode 100644
index 44e9cdc..0000000
--- a/src/content/docs/recipes/ci-configurations/github-actions.md
+++ /dev/null
@@ -1,129 +0,0 @@
----
-title: "GitHub Actions"
----
-
-## Environment variables
-
-The [Authentication](../../usage/ci-configuration.md#authentication) environment variables can be configured with [Secret Variables](https://docs.github.com/en/actions/reference/encrypted-secrets).
-
-In this example a publish type [`NPM_TOKEN`](https://docs.npmjs.com/creating-and-viewing-authentication-tokens) is required to publish a package to the npm registry. GitHub Actions [automatically populate](https://docs.github.com/en/actions/security-guides/automatic-token-authentication) a [`GITHUB_TOKEN`](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) environment variable which can be used in Workflows.
-
-## Trusted publishing and npm provenance
-
-For improved security and automation, it is recommended to leverage [trusted publishing](https://docs.npmjs.com/trusted-publishers) through [OpenID Connect (OIDC)](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) when publishing to npm from GitHub Actions. GitHub Actions is a [trusted identity provider](https://docs.npmjs.com/trusted-publishers#identity-providers) for npm, enabling configuration of a trust relationship between your GitHub repository and npm so that no long-lived secret (like an `NPM_TOKEN`) is required to publish packages to npm from GitHub Actions. The npm registry [recently increased restrictions for use of long-lived access tokens](https://github.blog/changelog/2025-09-29-strengthening-npm-security-important-changes-to-authentication-and-token-management/), further encouraging trusted publishing as the preferred approach for publishing to npm from GitHub Actions. Enabling trusted publishing requires granting the `id-token: write` permission to the job performing the publish step and [configuring a trust relationship](https://docs.npmjs.com/trusted-publishers#step-1-add-a-trusted-publisher-on-npmjscom) between your GitHub repository and npm.
-
-**Note**: When setting up a Trusted Publisher on npmjs for GitHub Actions, it's crucial to specify the workflow file that triggers the release process, not necessarily the one that contains the release logic itself.\
-If your release job is encapsulated in a [reusable workflow](https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows), the workflow file you must reference is the caller workflow—typically the one triggered by events like `push` or `workflow_dispatch` on your main branch.\
-This is because npm's Trusted Publisher mechanism authorizes the workflow that initiates the run, not any downstream workflows it invokes.
-
-[npm provenance](https://docs.npmjs.com/generating-provenance-statements) is valuable for increasing supply-chain security for your npm packages. Before trusted publishing was available, generating provenance attestations required configuring your project to enable publishing with provenance. With trusted publishing, npm provenance is automatically generated for packages published to npm from GitHub Actions without any additional configuration.
-
-## Important: Avoid `registry-url` in `setup-node`
-
-**Do not** set the `registry-url` option in the `actions/setup-node` step when using semantic-release for npm publishing. The `registry-url` option causes `setup-node` to create an `.npmrc` file that can conflict with semantic-release's npm authentication mechanism, leading to `EINVALIDNPMTOKEN` errors even when your token is valid.
-
-```yaml
-# ❌ Don't do this - can cause conflicts with semantic-release
-- name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: "lts/*"
- registry-url: "https://registry.npmjs.org"
-
-# ✅ Do this instead - let semantic-release handle npm authentication
-- name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: "lts/*"
-```
-
-If you need to specify a custom registry, configure it in your project's `.npmrc` file instead. This ensures consistent behavior between local development and CI environments, and avoids conflicts with semantic-release.
-
-## Node project configuration
-
-[GitHub Actions](https://github.com/features/actions) support [Workflows](https://help.github.com/en/articles/configuring-workflows), allowing to run tests on multiple Node versions and publish a release only when all test pass.
-
-**Note**: The publish pipeline must run on a [Node version that meets our version requirement](../../support/node-version.md).
-
-### `.github/workflows/release.yml` configuration for Node projects
-
-The following is a minimal configuration for [`semantic-release`](https://github.com/semantic-release/semantic-release) with a build running on the latest LTS version of Node when a new commit is pushed to a `master/main` branch. See the [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions) for additional configuration options.
-
-```yaml
-name: Release
-on:
- push:
- branches:
- - master # or main
-
-permissions:
- contents: read # for checkout
-
-jobs:
- release:
- name: Release
- runs-on: ubuntu-latest
- permissions:
- contents: write # to be able to publish a GitHub release
- issues: write # to be able to comment on released issues
- pull-requests: write # to be able to comment on released pull requests
- id-token: write # to enable use of OIDC for trusted publishing and npm provenance
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: "lts/*"
- - name: Install dependencies
- run: npm clean-install
- - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
- run: npm audit signatures
- - name: Release
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: npx semantic-release
-```
-
-## Pushing `package.json` changes to your repository
-
-If you choose to commit changes to your `package.json` [against our recommendation](../../support/FAQ.md#making-commits-during-the-release-process-adds-significant-complexity), the [`@semantic-release/git`](https://github.com/semantic-release/git) plugin can be used.
-
-**Note**: Automatically populated `GITHUB_TOKEN` cannot be used if branch protection is enabled for the target branch. It is **not** advised to mitigate this limitation by overriding an automatically populated `GITHUB_TOKEN` variable with a [Personal Access Tokens](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line), as it poses a security risk. Since Secret Variables are available for Workflows triggered by any branch, it becomes a potential vector of attack, where a Workflow triggered from a non-protected branch can expose and use a token with elevated permissions, yielding branch protection insignificant. One can use Personal Access Tokens in trusted environments, where all developers should have the ability to perform administrative actions in the given repository and branch protection is enabled solely for convenience purposes, to remind about required reviews or CI checks.
-
-If the risk is acceptable, some extra configuration is needed. The [actions/checkout `persist-credentials`](https://github.com/marketplace/actions/checkout#usage) option needs to be `false`, otherwise the generated `GITHUB_TOKEN` will interfere with the custom one. Example:
-
-```yaml
-- name: Checkout
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
- persist-credentials: false # <--- this
-```
-
-## Trigger semantic-release on demand
-
-### Using GUI:
-
-You can use [Manual Triggers](https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/) for GitHub Actions.
-
-### Using HTTP:
-
-Use [`repository_dispatch`](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch) event to have control on when to generate a release by making an HTTP request, e.g.:
-
-```yaml
-name: Release
-on:
- repository_dispatch:
- types: [semantic-release]
-jobs:
-# ...
-```
-
-To trigger a release, call (with a [Personal Access Tokens](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) stored in `GITHUB_TOKEN` environment variable):
-
-```
-$ curl -v -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/[org-name-or-username]/[repository]/dispatches -d '{ "event_type": "semantic-release" }'
-```
diff --git a/src/content/docs/recipes/ci-configurations/github-actions.mdx b/src/content/docs/recipes/ci-configurations/github-actions.mdx
new file mode 100644
index 0000000..9d00364
--- /dev/null
+++ b/src/content/docs/recipes/ci-configurations/github-actions.mdx
@@ -0,0 +1,247 @@
+---
+title: "GitHub Actions"
+---
+
+import { Steps } from "@astrojs/starlight/components";
+
+Use this recipe to run semantic-release on GitHub Actions with a secure default setup. It covers authentication options, trusted publishing with OIDC and npm provenance, a minimal release workflow for Node projects, and common pitfalls to avoid when configuring npm and GitHub tokens.
+
+## Quick start
+
+
+
+1. Create `.github/workflows/verify-and-release.yml` using the [verify-and-release workflow configuration](#githubworkflowsverify-and-releaseyml-configuration-for-node-projects).
+2. [Choose a publishing path](#choose-a-publishing-path).
+ - Use **trusted publishing** (recommended): follow [Path A](#path-a-recommended-trusted-publishing-oidc), then review [Trusted publishing and npm provenance](#trusted-publishing-and-npm-provenance).
+ - If you cannot use trusted publishing, add `NPM_TOKEN` as a GitHub Actions secret as described in [Environment variables](#environment-variables) and follow [Path B](#path-b-fallback-npm_token).
+3. Push a commit to `main`/`master` (or run `workflow_dispatch`) and verify with the [Release readiness checklist](#release-readiness-checklist). For manual runs, see [Trigger semantic-release on demand](#trigger-semantic-release-on-demand).
+
+
+
+## Choose a publishing path
+
+### Path A (recommended): Trusted publishing (OIDC)
+
+- No long-lived npm token in GitHub secrets.
+- npm provenance is generated automatically.
+- Requires `id-token: write` permission in the job that runs semantic-release.
+- Requires an npm [Trusted Publisher](https://docs.npmjs.com/trusted-publishers#for-github-actions) configured for the workflow that triggers the run.
+
+### Path B (fallback): `NPM_TOKEN`
+
+- Add `NPM_TOKEN` to repository or organization secrets.
+- Keep `GITHUB_TOKEN` for GitHub release notes, issue comments, and pull request comments.
+- Use this only when trusted publishing is not available for your setup.
+
+## Node project configuration
+
+[GitHub Actions](https://github.com/features/actions) supports [workflows](https://docs.github.com/en/actions/writing-workflows), allowing you to run tests on multiple Node versions and publish a release only when all tests pass.
+
+### `.github/workflows/verify-and-release.yml` configuration for Node projects
+
+Use this as a starting point for `.github/workflows/verify-and-release.yml`. This example runs verification first and only runs semantic-release if verification succeeds. Make sure to adjust the trigger and branch name as needed. The example below is configured for trusted publishing with OIDC, but it can be easily adapted to use `NPM_TOKEN` instead by removing the `id-token: write` permission and ensuring `NPM_TOKEN` is available in secrets.
+
+:::note
+The publish pipeline must run on a [Node version that meets our version requirement](/support/node-version), but can be different than the Node version used in your verification job(s).
+:::
+
+```yaml
+name: Verify and Release
+on:
+ push:
+ branches:
+ - main # or master
+
+permissions:
+ contents: read # for checkout
+
+jobs:
+ verify:
+ name: Verify
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: .nvmrc
+ - name: Install dependencies
+ run: npm clean-install
+ - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
+ run: npm audit signatures
+ - name: Run lint, tests, and other verification
+ run: npm test
+
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ needs: verify
+ permissions:
+ contents: write # to be able to publish a GitHub release
+ issues: write # to be able to comment on released issues
+ pull-requests: write # to be able to comment on released pull requests
+ id-token: write # to enable use of OIDC for trusted publishing and npm provenance
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "lts/*"
+ - name: Install dependencies
+ run: npm clean-install
+ - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
+ run: npm audit signatures
+ - name: Release
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: npx semantic-release # <- The Run Commnand
+```
+
+The workflow above shows a verify-then-release setup with the default semantic-release flow. If your release process needs a different invocation style or non-default behavior (for example, plugins or shareable configurations), refer to [Running semantic-release](/usage/running).
+
+## Environment variables
+
+The [Authentication](/usage/ci-configuration#authentication) environment variables can be configured with [GitHub Actions secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions).
+
+If you are not using trusted publishing, an [`NPM_TOKEN`](https://docs.npmjs.com/creating-and-viewing-authentication-tokens) is required to publish a package to the npm registry. GitHub Actions [automatically populates](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication) a [`GITHUB_TOKEN`](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication) environment variable that can be used in workflows.
+
+## Trusted publishing and npm provenance
+
+For improved security and automation, it is recommended to leverage [trusted publishing](https://docs.npmjs.com/trusted-publishers) through [OpenID Connect (OIDC)](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) when publishing to npm from GitHub Actions. GitHub Actions is a [trusted identity provider](https://docs.npmjs.com/trusted-publishers#identity-providers) for npm, enabling configuration of a trust relationship between your GitHub repository and npm so that no long-lived secret (like an `NPM_TOKEN`) is required to publish packages to npm from GitHub Actions. The npm registry [recently increased restrictions for use of long-lived access tokens](https://github.blog/changelog/2025-09-29-strengthening-npm-security-important-changes-to-authentication-and-token-management/), further encouraging trusted publishing as the preferred approach for publishing to npm from GitHub Actions. Enabling trusted publishing requires granting the `id-token: write` permission to the job performing the publish step and [configuring a trust relationship](https://docs.npmjs.com/trusted-publishers#step-1-add-a-trusted-publisher-on-npmjscom) between your GitHub repository and npm.
+
+:::note
+When setting up a Trusted Publisher on npmjs for GitHub Actions, it's crucial to specify the workflow file that triggers the release process, not necessarily the one that contains the release logic itself.
+
+If your release job is encapsulated in a [reusable workflow](https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows), the workflow file you must reference is the caller workflow—typically the one triggered by events like `push` or `workflow_dispatch` on your main branch.
+
+This is because npm's Trusted Publisher mechanism authorizes the workflow that initiates the run, not any downstream workflows it invokes.
+:::
+
+[npm provenance](https://docs.npmjs.com/generating-provenance-statements) is valuable for increasing supply-chain security for your npm packages. Before trusted publishing was available, generating provenance attestations required configuring your project to enable publishing with provenance. With trusted publishing, npm provenance is automatically generated for packages published to npm from GitHub Actions without any additional configuration.
+
+## Common pitfalls checklist
+
+- Do not set `registry-url` in `actions/setup-node` when using semantic-release for npm publishing. It creates an `.npmrc` that can conflict with semantic-release auth and lead to `EINVALIDNPMTOKEN` errors.
+- If you need a custom npm registry, set it in your project `.npmrc`.
+- If using npm trusted publishing, keep `id-token: write` permission in the release job.
+- If using `NPM_TOKEN`, ensure it is configured as a repository or organization secret.
+
+```yaml
+# ❌ Don't do this - can cause conflicts with semantic-release
+- name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "lts/*"
+ registry-url: "https://registry.npmjs.org"
+
+# ✅ Do this instead - let semantic-release handle registry configuration through normal npm conventions
+- name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "lts/*"
+```
+
+## Pushing `package.json` changes to your repository
+
+If you choose to commit changes to your `package.json` [against our recommendation](/support/faq#making-commits-during-the-release-process-adds-significant-complexity), the [`@semantic-release/git`](https://github.com/semantic-release/git) plugin can be used.
+
+:::note
+The automatically populated `GITHUB_TOKEN` cannot be used if branch protection is enabled for the target branch. In that case, prefer [GitHub App authentication](https://github.com/actions/create-github-app-token) so the release job can create commits without relying on a long-lived secret.
+
+Personal Access Tokens are not recommended here. They create a broader security risk because a secret exposed to any workflow run can be reused with elevated permissions, which makes branch protection much less effective. Only consider a PAT in tightly controlled environments where the security tradeoff is acceptable.
+:::
+
+Example release job using GitHub App authentication with `@semantic-release/git` (assuming a preceding `verify` job):
+
+```yaml
+# verify:
+# # ... your existing verify job
+
+release:
+ name: Release
+ runs-on: ubuntu-latest
+ needs: verify
+ permissions:
+ contents: write
+ issues: write
+ pull-requests: write
+ id-token: write
+ steps:
+ - name: Create GitHub App token
+ id: app-token
+ uses: actions/create-github-app-token@v1
+ with:
+ app-id: ${{ vars.RELEASE_APP_ID }}
+ private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ token: ${{ steps.app-token.outputs.token }}
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "lts/*"
+ - name: Install dependencies
+ run: npm clean-install
+ - name: Release
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
+ run: npx semantic-release
+```
+
+## Release readiness checklist
+
+- Your workflow triggers on the branch you release from (`main` or `master`).
+- `fetch-depth: 0` is enabled in checkout.
+- `GITHUB_TOKEN` is available to semantic-release for the default release flow.
+- If you commit files during release on a protected branch (for example with `@semantic-release/git`), GitHub App auth is configured and checkout uses the app token.
+- You chose one npm auth path: trusted publishing (`id-token: write`) or `NPM_TOKEN` secret.
+- `registry-url` is not set in `actions/setup-node`.
+- Your runtime meets the [supported Node version policy](/support/node-version).
+
+## Trigger semantic-release on demand
+
+Use these options when you want to trigger a release outside the normal push-based workflow.
+
+:::caution[Discouraged in most setups]
+Manual or API-triggered releases are generally **not recommended** with semantic-release.
+
+semantic-release is designed for continuous delivery: once changes are merged to your primary release branch, releases should happen automatically and predictably from CI. Adding ad-hoc triggers increases operational complexity, weakens release consistency, and can bypass the normal branch-based release flow your team relies on.
+
+Use the options below only for exceptional operational scenarios.
+:::
+
+### Using GUI
+
+You can use [`workflow_dispatch`](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onworkflow_dispatch) to run the release workflow manually from the GitHub UI.
+
+### Using HTTP
+
+Use the [`repository_dispatch`](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#repository_dispatch) event to control when to generate a release by making an HTTP request, for example:
+
+```yaml
+name: Release
+on:
+ repository_dispatch:
+ types: [semantic-release]
+jobs:
+# ...
+```
+
+To trigger a release, call the GitHub API with a [Personal Access Token](https://docs.github.com/en/rest/authentication/authenticating-to-the-rest-api) stored in the `GITHUB_TOKEN` environment variable:
+
+```
+$ curl -v -X POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${GITHUB_TOKEN}" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/[org-name-or-username]/[repository]/dispatches \
+ -d '{ "event_type": "semantic-release" }'
+```
diff --git a/src/content/docs/recipes/ci-configurations/index.md b/src/content/docs/recipes/ci-configurations/index.md
deleted file mode 100644
index 618045f..0000000
--- a/src/content/docs/recipes/ci-configurations/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: "CI configurations"
----
-
-- [CircleCI 2.0 workflows](circleci-workflows.md)
-- [Travis CI](travis.md)
-- [GitLab CI](gitlab-ci.md)
-- [GitHub Actions](github-actions.md)
-- [Jenkins CI](jenkins-ci.md)
diff --git a/src/content/docs/recipes/ci-configurations/index.mdx b/src/content/docs/recipes/ci-configurations/index.mdx
new file mode 100644
index 0000000..075543b
--- /dev/null
+++ b/src/content/docs/recipes/ci-configurations/index.mdx
@@ -0,0 +1,37 @@
+---
+title: "CI configurations"
+---
+
+import { CardGrid, LinkCard } from "@astrojs/starlight/components";
+
+
+
+
+
+
+
+
+
+
+
+