Skip to content
Draft
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
9 changes: 0 additions & 9 deletions .github/release-please-config.json

This file was deleted.

3 changes: 0 additions & 3 deletions .github/release-please-manifest.json

This file was deleted.

6 changes: 4 additions & 2 deletions .github/workflows/check-pull-request-health.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
name: Check pull request health

on: pull_request
on:
pull_request:
workflow_call:

jobs:
build-and-test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Prepare Node.js environment
uses: actions/setup-node@v6
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/check-semantic-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ jobs:
validate-title:
name: Validate Title
runs-on: ubuntu-latest

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
timeout-minutes: 5

steps:
- name: Validate pull request title
uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017
with:
validateSingleCommit: true
uses: amannn/action-semantic-pull-request@01d5fd8a8ebb9aafe902c40c53f0f4744f7381eb
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
111 changes: 111 additions & 0 deletions .github/workflows/publish-package-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Package Release

on:
push:
branches:
- main

permissions:
# Enable the use of OIDC for trusted publishing and npm provenance
id-token: write
# Enable the use of GitHub Packages registry
packages: write
# Enable semantic-release to publish a GitHub release and push commits
contents: write
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Overly broad workflow permissions (Least Privilege)

The workflow-level GITHUB_TOKEN does not need contents: write, issues: write, or pull-requests: write because the semantic-release step explicitly authenticates via the App Token (GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}) to bypass branch protection rules.

Granting these write permissions to the built-in token violates the principle of least privilege. The workflow token only needs id-token: write (for npm OIDC), packages: write (for GitHub Packages publish), and contents: read (default/checkout). You can safely remove lines 13-18 and replace them with:

    contents: read

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This follows the pattern set out by other repos (Typist, etc.), but we can bring this up in the thread.

# Enable semantic-release to post comments on issues
issues: write
# Enable semantic-release to post comments on pull requests
pull-requests: write

# Release workflow steps must complete fully to avoid inconsistent state (e.g., published to
# npm but not GitHub Packages), so new workflow runs are queued until the previous one finishes.
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

jobs:
ci-validation:
name: CI Validation
uses: ./.github/workflows/check-pull-request-health.yml

release-and-publish:
name: Release & Publish
needs: ci-validation
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Generate bot token
id: generate_token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.DOIST_RELEASE_BOT_ID }}
private-key: ${{ secrets.DOIST_RELEASE_BOT_PRIVATE_KEY }}
permission-contents: write
permission-issues: write
permission-pull-requests: write

- name: Get bot user ID
id: bot_user
run: |
user_id=$(gh api "/users/${{ steps.generate_token.outputs.app-slug }}[bot]" --jq .id)
if [ -z "$user_id" ]; then
echo "Failed to get bot user ID" >&2
exit 1
fi
echo "id=$user_id" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}

- name: Checkout repository
uses: actions/checkout@v6
with:
token: ${{ steps.generate_token.outputs.token }}
fetch-depth: 0

- name: Prepare Node.js environment
uses: actions/setup-node@v6
with:
cache: npm
node-version-file: .node-version
scope: '@doist'
registry-url: 'https://registry.npmjs.org/'

- name: Install project npm dependencies
run: npm ci

- name: Build package
run: npm run build

# The Node.js environment is prepared with the public npm registry and OIDC
# authentication for the initial semantic-release publish, after which we remove
# the Doist registry configuration and prepare the Node.js environment for the
# GitHub Packages registry, providing a predictable release workflow for both.
- name: Release and publish to public npm registry
id: semantic-release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
GIT_AUTHOR_NAME: ${{ steps.generate_token.outputs.app-slug }}[bot]
GIT_AUTHOR_EMAIL: ${{ steps.bot_user.outputs.id }}+${{ steps.generate_token.outputs.app-slug }}[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: ${{ steps.generate_token.outputs.app-slug }}[bot]
GIT_COMMITTER_EMAIL: ${{ steps.bot_user.outputs.id }}+${{ steps.generate_token.outputs.app-slug }}[bot]@users.noreply.github.com

- name: Remove Doist registry configuration from .npmrc
if: ${{ steps.semantic-release.outputs.package-published == 'true' }}
run: npm config delete @doist:registry --location=project

- name: Prepare Node.js environment for GitHub Packages registry
if: ${{ steps.semantic-release.outputs.package-published == 'true' }}
uses: actions/setup-node@v6
with:
cache: npm
node-version-file: .node-version
registry-url: https://npm.pkg.github.com/
scope: '@doist'

- name: Publish package to GitHub Packages registry
if: ${{ steps.semantic-release.outputs.package-published == 'true' }}
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59 changes: 0 additions & 59 deletions .github/workflows/publish.yml

This file was deleted.

44 changes: 0 additions & 44 deletions .github/workflows/release-please.yml

This file was deleted.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ After cloning interaction-trace and installing all dependencies, several command

### Release Process (core team only)

The release process for interaction-trace is automated with [release-please](https://github.com/googleapis/release-please). When commits following the [Conventional Commits](https://www.conventionalcommits.org/) specification are merged to `main`, release-please automatically creates or updates a release PR. When that PR is merged, a new version is published to npm.
The release process for interaction-trace is fully automated with [`semantic-release`](https://github.com/semantic-release/semantic-release). Pushing to `main` (after CI passes) triggers a stable release automatically: semantic-release analyzes commits since the last release, determines the version bump, updates the changelog, publishes to npm and GitHub Packages, and creates a GitHub release.

## Sending a Pull Request

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,11 @@ npm test

## Releasing

This project uses [release-please](https://github.com/googleapis/release-please) to automate releases. Commits merged to `main` with `fix:` trigger patch releases, `feat:` triggers minor releases, and `feat!:` or `fix!:` triggers major releases.
This project uses [`semantic-release`](https://github.com/semantic-release/semantic-release) for fully automated releases. When commits following the [Conventional Commits](https://www.conventionalcommits.org/) specification are pushed to `main`, semantic-release automatically determines the next version, updates the changelog, publishes to npm and GitHub Packages, and creates a GitHub release.

When commits land on `main`, release-please creates a release PR. Merging it publishes to npm and GitHub Packages.
- `fix:` commits trigger a **patch** release
- `feat:` commits trigger a **minor** release
- `feat!:` or `fix!:` commits (or commits with a `BREAKING CHANGE:` footer) trigger a **major** release

## License

Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.9/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
Loading
Loading