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
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [main]
branches: [main, "release/**"]
pull_request:
types: [opened, synchronize, reopened, closed]
workflow_dispatch:
Expand Down Expand Up @@ -92,7 +92,8 @@ jobs:
stage-release:
name: Stage release
needs: [commitlint, lint, typecheck, test]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
# The merged release commit lands on main as a push of its own; staging again from it would open a release for the release.
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && !startsWith(github.event.head_commit.message, 'chore(release):')
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
Expand All @@ -104,6 +105,8 @@ jobs:
with:
# semantic-release analyses the full commit history since the last release.
fetch-depth: 0
# Pushes made with GITHUB_TOKEN never start workflows, so the release branch is pushed over SSH with a deploy key and its CI runs like any other branch's.
ssh-key: ${{ secrets.RELEASE_DEPLOY_KEY }}
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
with:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ const config: Options = {
export default config;
```

Requires a `GITHUB_TOKEN` or `GH_TOKEN` environment variable with permission to push a branch and open pull requests on the repository (the default `GITHUB_TOKEN` in GitHub Actions is sufficient, since the pushed branch is never the protected one).
Requires a `GITHUB_TOKEN` or `GH_TOKEN` environment variable with permission to push a branch and open pull requests on the repository (the default `GITHUB_TOKEN` in GitHub Actions is sufficient to push and open the pull request, since the pushed branch is never the protected one). GitHub does not start workflows for pushes made with that token, so a repository that requires status checks on the release pull request pushes the branch with a deploy key instead (`ssh-key` on `actions/checkout`) and runs CI on `release/**` pushes.

## Options

| Option | Default | Description |
| --------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `assets` | `["CHANGELOG.md", "package.json"]` | Files to stage into the release commit. |
| `branch` | `"release/${version}"` | The branch pushed to and PR'd from. `${version}` is replaced with the release version. |
| `commitMessage` | `"chore(release): ${version} [skip ci]"` | The commit message and PR title. `${version}` and `${notes}` are both available. |
| `commitMessage` | `"chore(release): ${version}"` | The commit message and PR title. `${version}` and `${notes}` are both available. |
| `labels` | `[]` | Labels applied when a new pull request is opened. Never removed from an already-open one. |

## License
Expand Down
2 changes: 1 addition & 1 deletion src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { PluginConfig, PrepareContext } from "./types.js";

const DEFAULT_ASSETS = ["CHANGELOG.md", "package.json"];
const DEFAULT_BRANCH = "release/${version}";
const DEFAULT_COMMIT_MESSAGE = "chore(release): ${version} [skip ci]";
const DEFAULT_COMMIT_MESSAGE = "chore(release): ${version}";

function readGithubToken(env: PrepareContext["env"]): string | undefined {
const token = env["GITHUB_TOKEN"] ?? env["GH_TOKEN"];
Expand Down
4 changes: 2 additions & 2 deletions src/plugin.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ describe("prepare", () => {

expect(gitOperations.checkoutNewBranch).toHaveBeenCalledWith("release/1.2.3");
expect(gitOperations.stage).toHaveBeenCalledWith(["CHANGELOG.md", "package.json"]);
expect(gitOperations.commit).toHaveBeenCalledWith("chore(release): 1.2.3 [skip ci]");
expect(gitOperations.commit).toHaveBeenCalledWith("chore(release): 1.2.3");
expect(gitOperations.push).toHaveBeenCalledWith("release/1.2.3");
expect(vi.mocked(pullRequestOperations.openOrUpdate)).toHaveBeenCalledWith({
branch: "release/1.2.3",
baseBranch: "main",
title: "chore(release): 1.2.3 [skip ci]",
title: "chore(release): 1.2.3",
body: context.nextRelease.notes,
labels: [],
});
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface PluginConfig {
*/
readonly branch?: string;
/**
* The release commit's message, and the pull request's title. `${version}` and `${notes}` are replaced with `nextRelease.version` and `nextRelease.notes`. Defaults to `"chore(release): ${version} [skip ci]"`.
* The release commit's message, and the pull request's title. `${version}` and `${notes}` are replaced with `nextRelease.version` and `nextRelease.notes`. Defaults to `"chore(release): ${version}"`. Avoid `[skip ci]`: GitHub skips `push` and `pull_request` workflows for a head commit that contains it, so the release pull request would never receive its required checks.
*/
readonly commitMessage?: string;
/**
Expand Down
Loading