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
43 changes: 43 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Publish

on:
push:
branches:
- main

concurrency:
group: publish
cancel-in-progress: false

jobs:
publish:
name: Version and publish
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.2

- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
registry-url: https://registry.npmjs.org

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Version and publish packages
run: bun run tegami ci
env:
GITHUB_TOKEN: ${{ github.token }}
48 changes: 48 additions & 0 deletions .github/workflows/tegami-pr-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Tegami PR Comment

on:
workflow_run:
workflows: ["Tegami PR"]
types: [completed]

permissions:
actions: read
contents: read
pull-requests: write

jobs:
comment:
name: Post preview comment
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.2

- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Download preview
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: tegami-pr-preview
path: ${{ runner.temp }}/tegami-pr-preview
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
Comment thread
aryasaatvik marked this conversation as resolved.

- name: Post preview comment
run: bun run tegami pr comment "$RUNNER_TEMP/tegami-pr-preview/tegami-pr-preview.md"
env:
GITHUB_TOKEN: ${{ github.token }}
40 changes: 40 additions & 0 deletions .github/workflows/tegami-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Tegami PR

on:
pull_request:
types: [opened, synchronize, reopened]

permissions:
contents: read

jobs:
preview:
name: Release preview
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.2

- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Release preview
run: bun run tegami pr preview --artifact tegami-pr-preview.md

- name: Upload preview
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: tegami-pr-preview
path: tegami-pr-preview.md
49 changes: 0 additions & 49 deletions .tegami/publish-lock.yaml

This file was deleted.

2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ User-visible package changes also need a pending Tegami changelog under
`.tegami/`. See [the release guide](./docs/releases.md) for the file format and
package names. Commit the changelog with the implementation it describes; do
not edit package `CHANGELOG.md` files or `.tegami/publish-lock.yaml` directly.
After the changelog reaches `main`, GitHub Actions opens the Version Packages
pull request.

## Proposing a new integration

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ bun run format:check

Contributions are welcome — see [CONTRIBUTING.md](./CONTRIBUTING.md) for local
setup, package conventions, and how to propose a new integration. Maintainers
use the attended [Tegami release flow](./docs/releases.md) for package versions,
changelogs, npm publication, tags, and GitHub Releases.
use the [Tegami release flow](./docs/releases.md) for package versions,
changelogs, npm publication, tags, and GitHub Releases. GitHub Actions
publishes; merging the Version Packages pull request is the human gate.

## Security

Expand Down
74 changes: 44 additions & 30 deletions docs/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,33 @@

This repository uses [Tegami](https://tegami.fuma-nama.dev) for changelogs,
version pull requests, npm publication, Git tags, and GitHub Releases.
Releases are attended local sessions; GitHub Actions does not publish packages.

GitHub Actions publishes the public packages. `.github/workflows/publish.yml`
runs `bun run tegami ci` on every push to `main`. That command versions first:
if `.tegami/` has pending changelog files, it opens or updates a Version
Packages pull request. If there is nothing to version, it publishes from
`.tegami/publish-lock.yaml`. Merging the Version Packages PR is the human gate;
the following `main` push publishes. Do not auto-merge that PR with
`GITHUB_TOKEN` — GitHub will not re-run workflows for commits created by that
token, so publish would never start.

Authentication is npm trusted publishing (OIDC). The workflow sets
`id-token: write` and does not use an `NPM_TOKEN`. Each public package on
npmjs.com must list GitHub Actions trusted publisher
`AryaLabsHQ/samva-integrations` with workflow filename `publish.yml` and no
environment name. Do not rename `publish.yml`; npm pins that filename.

This repository is public, so npm attaches provenance attestations to trusted
publishes. Current `0.1.1` tarballs were attended local publishes and have none.

The public packages version independently:

- `@samva/better-auth` — release group `better-auth`
- `@samva/email-sdk` — release group `email-sdk`

Pull requests that add Tegami changelog files get a release preview comment
from the split `tegami-pr.yml` / `tegami-pr-comment.yml` workflows.

## Queue a change

Run `bun run tegami` to create a pending file under `.tegami/`, or write one as
Expand All @@ -29,45 +49,39 @@ Use `@samva/better-auth`, `@samva/email-sdk`, `group:better-auth`, or
`group:email-sdk` as the package key, with a `patch`, `minor`, or `major` bump.
Commit the pending changelog with the user-visible change it describes. Do not
edit package `CHANGELOG.md` files or `.tegami/publish-lock.yaml` directly.
After the changelog reaches `main`, Actions opens the Version Packages pull
request.

## Prepare the version pull request
## Version Packages pull request

Start from a clean, current `main` with GitHub CLI authentication:
Review the generated version bump, changelog aggregation, lockfile, and
`.tegami/publish-lock.yaml`. Merge it in the GitHub UI (or with a
non-`GITHUB_TOKEN` actor). The next `publish.yml` run publishes and creates
GitHub Releases.

```sh
bun install --frozen-lockfile
bun run version:packages
```

The version command passes the authenticated `gh` token to Tegami. Tegami
consumes pending changelogs, updates package versions and changelogs, refreshes
`bun.lock`, writes `.tegami/publish-lock.yaml`, pushes `tegami/version-packages`,
and opens or updates a pull request against `main`. Review and merge that pull
request before publishing.
`afterPreflight` still runs `bun run release:packages:check`: it builds each
canonical package root and audits the npm tarball.

## Publish

From the clean, current merged `main`, authenticate npm and run the attended
release:
## Verify a publish

```sh
npm whoami
gh auth status
bun run release
gh run list --workflow=publish.yml --branch main --limit 5
npm view @samva/better-auth version dist-tags --json
npm view @samva/email-sdk version dist-tags --json
gh release list --limit 10
```

The release command runs the full repository gates, passes the authenticated
`gh` token to Tegami, audits each canonical npm tarball, publishes planned
packages, then pushes group tags and creates matching GitHub Releases.
If a publish job fails partway through, fix the cause and re-run the same
workflow. The publish lock makes retries safe.

## Emergency local publish

Verify the result for each affected package:
Use laptop publish only when Actions cannot. From a clean, current `main` with
npm 2FA:

```sh
npm view @samva/better-auth version dist-tags --json
npm view @samva/email-sdk version dist-tags --json
gh release list --limit 10
npm whoami
GH_TOKEN="$(gh auth token)" bun run release
```

Do not publish from a dirty worktree. If a release stops partway through, check
npm versions, Git tags, GitHub Releases, and Tegami publish status before
resuming or cleaning up the publish lock.
Restore CI as the default path after that emergency succeeds.
8 changes: 6 additions & 2 deletions scripts/tegami.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bun

/**
* Attended release configuration for Samva integration packages.
* CI and local release config for Samva integration packages.
*
* Tegami owns changelogs, version pull requests, npm registry preflight,
* dependency ordering, publication, Git tags, and GitHub Releases. Repository
Expand Down Expand Up @@ -48,6 +48,10 @@ const paper = tegami({
npm: {
client: "bun",
updateLockFile: true,
trustedPublish: {
provider: "github",
workflow: "publish.yml",
},
onBreakPeerDep: "error",
bumpDep: ({ dependent, kind }) => {
if (dependent.manifest.private === true) return false;
Expand Down Expand Up @@ -77,7 +81,7 @@ const paper = tegami({
versionPr: {
branch: "tegami/version-packages",
base: "main",
forceCreate: true,
forceCreate: false,
create() {
return { title: "chore(release): prepare integration packages" };
},
Expand Down
Loading