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
5 changes: 5 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a tool to manage versioning and changelogs. Read the full documentation at https://changesets.dev.

We also have a quick list of common questions to get you started engaging with this project in our [FAQ](https://changesets.dev/faq).
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@4.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [["@devicekit/devices", "@devicekit/frame"]],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
73 changes: 0 additions & 73 deletions .github/workflows/publish.yml

This file was deleted.

43 changes: 43 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Release

on:
push:
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}

permissions:
contents: write
pull-requests: write
id-token: write

jobs:
release:
runs-on: ubuntu-latest
# Must match the "Environment name" configured on each package's npm
# trusted publisher entry, or OIDC-based publishing is refused.
environment: npm-release
# push: already only fires on main. workflow_dispatch: restrict to main so
# a feature branch can't be manually dispatched into a publish.
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0

- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version-file: .node-version
cache: pnpm
registry-url: https://registry.npmjs.org

- name: Check npm CLI version
run: npm -v

- run: pnpm install --frozen-lockfile

- uses: changesets/action@ae32849d5ba541f9ae29e40e22a623bc13562f51 # v2.1.2
with:
publish-script: pnpm release
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
Changes after 0.4.0 are recorded per package by Changesets, in
[`packages/devices/CHANGELOG.md`](packages/devices/CHANGELOG.md) and
[`packages/frame/CHANGELOG.md`](packages/frame/CHANGELOG.md).

## [0.4.0] - 2026-09-14

Expand Down
53 changes: 24 additions & 29 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pnpm --filter @devicekit/frame demo
- `pnpm lint` must report zero warnings.
- Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/):
`feat: ...`, `fix: ...`, `docs: ...`, `chore: ...`, etc.
- Any user-facing change to `@devicekit/devices` or `@devicekit/frame` needs a
changeset: run `pnpm changeset` and follow the prompts. It writes a small
Markdown file describing the change and its semver bump; CI checks it in
along with the PR.

## Adding a new device

Expand All @@ -39,35 +43,26 @@ entry, so run `pnpm --filter @devicekit/devices test` after adding one.

- Keep a PR focused on one change.
- CI must be green (build, test, lint, check-types) before merge.
- Update `CHANGELOG.md` under `## [Unreleased]` for user-facing changes.
- Include a changeset (see above) for any user-facing change.

## Releasing

Bump `version` in the package's `package.json`, then turn the accumulated
`## [Unreleased]` section of `CHANGELOG.md` into `## [x.y.z] - YYYY-MM-DD` and
open a fresh, empty `## [Unreleased]` above it. Merge to main and publish a
GitHub Release; the Publish workflow does the rest.

The dist-tag a version publishes under is decided by the version strings
themselves, not just the Release's pre-release checkbox or a manual dispatch
input: any version with a semver prerelease segment (`1.2.0-beta.1`) always
goes out as `next`, a Release marked pre-release goes out as `next` even for
a stable version number, and asking for `latest` on a prerelease version
fails the workflow instead of publishing it. See `scripts/npm-dist-tag.mjs`
for the exact rule and `scripts/npm-dist-tag.test.mjs` for the cases it
covers.

Before publishing, the workflow also runs `pnpm run verify:pack`: it builds
every package, packs it the way `pnpm publish` would, unpacks the tarball,
and loads it from a directory outside the workspace — catching an `exports`
map that points at a file the build never produced, which `pnpm test` alone
would not, since the workspace's own `exports` point straight at `src/*.ts`.

A Release pointing at a commit that isn't on `main` (e.g. cut from a feature
branch or an old commit) is refused before anything is published.

A manual `workflow_dispatch` run of Publish only does anything on `main` —
the job is a no-op on any other branch, so a dispatch from a feature branch
can't push a build to npm. Every `uses:` in the workflows is pinned to a
commit SHA rather than a mutable tag; Dependabot opens the PRs that move
those pins forward.
Releases are automated with [Changesets](https://github.com/changesets/changesets)
— there's nothing to bump or publish by hand. Merging a PR with changesets
into `main` makes the Release workflow open (or update) a "Version Packages"
PR that applies the accumulated changesets: bumping `@devicekit/devices` and
`@devicekit/frame` together (they're a fixed group, so they always ship the
same version) and writing each package's own `CHANGELOG.md`. Merging that PR
is what actually publishes to npm.

Before publishing, the same `pnpm release` script the workflow runs also runs
`pnpm run verify:pack`: it builds every package, packs it the way `pnpm
publish` would, unpacks the tarball, and loads it from a directory outside
the workspace — catching an `exports` map that points at a file the build
never produced, which `pnpm test` alone would not, since the workspace's own
`exports` point straight at `src/*.ts`.

The Release workflow only does anything on `main` — a manual
`workflow_dispatch` run is a no-op on any other branch. Every `uses:` in the
workflows is pinned to a commit SHA rather than a mutable tag; Dependabot
opens the PRs that move those pins forward.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
"test:coverage": "pnpm -r test:coverage",
"lint": "oxlint .",
"verify:pack": "pnpm -r build && node scripts/verify-pack.mjs",
"images": "node scripts/render-readme-images.mjs"
"images": "node scripts/render-readme-images.mjs",
"release": "pnpm build && pnpm test && pnpm run verify:pack && changeset publish"
},
"devDependencies": {
"@changesets/cli": "^3.0.2",
"oxfmt": "0.67.0",
"oxlint": "1.82.0",
"typescript": "5.9.2"
Expand Down
Loading
Loading