diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..654c6d4 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets). + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md). diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..de9c04a --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json", + "changelog": [ + "@changesets/changelog-github", + { "repo": "kernel/managed-auth-react" } + ], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": ["@onkernel/managed-auth-react-demo"] +} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a091795..013dcc0 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,26 +1,40 @@ name: Release -# Publishing flow: -# 1. PRs land on main (passing the test workflow) -# 2. Bump `packages/managed-auth-react/package.json` "version" on main -# 3. Tag and push: `git tag v0.1.0-alpha.1 && git push --tags` -# 4. This workflow validates the tag matches package.json, builds, and -# publishes to npm via OIDC trusted publishers (no NPM_TOKEN needed). +# Changesets-driven release flow: +# 1. Contributors include `.changeset/*.md` files in their PRs describing +# the version bump (patch | minor | major) and the change. +# 2. When PRs land on main, this workflow runs and the changesets bot +# either: +# a. Opens (or updates) a single "Version Packages" PR that bumps +# package.json versions, regenerates CHANGELOG.md, and deletes +# the consumed changeset files. Reviewers approve + merge it +# when ready to ship. +# b. If no pending changesets exist (i.e. the Version PR was just +# merged), runs `bun run release` which builds the package and +# runs `changeset publish` — that calls `npm publish` for every +# package version not yet on the registry, then tags + GitHub +# releases each. # -# One-time setup before the first release: -# - On npmjs.com → @onkernel/managed-auth-react → Settings → Trusted Publishers -# add this repository + workflow filename + the `release` job name. -# - The first publish under OIDC requires the package to already exist -# OR the publishing user to have permission to create scoped packages -# under @onkernel. +# No manual git tags, no manual package.json edits, no main-branch +# bypasses. Releases go through the normal PR + status-check + approval +# flow like any other change. +# +# `--provenance` is intentionally omitted from the publish: npm requires +# a public source repository for provenance attestations and this repo +# is `internal`-visibility. Re-add via .changeset/config.json once the +# repo flips public. + on: push: - tags: - - 'v*' + branches: [main] permissions: - contents: write # creating GitHub releases - id-token: write # npm OIDC trusted publishing + contents: write # opening/merging the version PR + tagging releases + pull-requests: write # opening the version PR + id-token: write # npm OIDC trusted publishing + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} jobs: release: @@ -32,7 +46,6 @@ jobs: fetch-depth: 0 - name: Set up Bun - # Pin to package.json `packageManager` — same reason as test.yaml. uses: oven-sh/setup-bun@v2 with: bun-version: "1.2.21" @@ -43,70 +56,22 @@ jobs: node-version: '20' registry-url: 'https://registry.npmjs.org' - # OIDC trusted publishers require npm >= 11.5.1 — the version bundled - # with Node 20 is older. This is the same workaround the CLI uses. + # OIDC trusted publishing requires npm >= 11.5.1; the version + # bundled with Node 20 is older. - name: Ensure latest npm run: npm install -g npm@latest - # Catch the most common release foot-gun: tag pushed before bumping - # package.json. Fail loud here instead of publishing a mismatched - # version that npm can't ever republish under the right tag. - - name: Verify tag matches package.json - run: | - TAG_VERSION="${GITHUB_REF_NAME#v}" - PKG_VERSION="$(node -p "require('./packages/managed-auth-react/package.json').version")" - echo "Tag version: $TAG_VERSION" - echo "package.json version: $PKG_VERSION" - if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then - echo "::error::Tag $GITHUB_REF_NAME does not match package.json version $PKG_VERSION" - exit 1 - fi - - name: Install dependencies run: bun install --frozen-lockfile - # Build before typecheck so the demo workspace can resolve - # `@onkernel/managed-auth-react`'s emitted .d.ts. Same ordering as - # test.yaml. - - name: Build package - run: bun run --filter '@onkernel/managed-auth-react' build - - - name: Typecheck - run: bun run typecheck - - # The package's `files: ["dist", "README.md", "LICENSE"]` references - # a LICENSE that lives at the repo root, not in the package directory. - # Copy it in before publishing so npm includes it in the tarball. - - name: Copy LICENSE into package - run: cp LICENSE packages/managed-auth-react/LICENSE - - # npm requires --tag for any version with a hyphen (alpha/beta/rc). - # Stable releases get the default `latest` tag; prereleases land - # under `alpha` so `npm install @onkernel/managed-auth-react` keeps - # picking up stable versions only. - # - # `--provenance` is intentionally omitted: npm requires a public - # source repository for provenance attestations and this repo is - # `internal`. Re-add `--provenance` if the repo goes public. - - name: Publish to npm - working-directory: packages/managed-auth-react - run: | - NPM_TAG="latest" - if [[ "$GITHUB_REF_NAME" == *-* ]]; then - NPM_TAG="alpha" - fi - npm publish --access public --tag "$NPM_TAG" - - - name: Create GitHub release + - name: Create release PR or publish + uses: changesets/action@v1 + with: + # Runs when there are no pending .changeset/*.md files — + # i.e. immediately after the Version Packages PR is merged. + publish: bun run release + # PR title for the bot's open Version Packages PR. + title: "chore: version packages" + commit: "chore: version packages" env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Mark prerelease for any tag that includes a hyphen (alpha, beta, rc). - PRERELEASE_FLAG="" - if [[ "$GITHUB_REF_NAME" == *-* ]]; then - PRERELEASE_FLAG="--prerelease" - fi - gh release create "$GITHUB_REF_NAME" \ - --title "$GITHUB_REF_NAME" \ - --generate-notes \ - $PRERELEASE_FLAG + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..e6bd350 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,12 @@ +# Bun and Changesets re-serialize package.json on every install / version +# bump and use single-line arrays. Prettier wraps JSON arrays multi-line. +# Letting prettier touch package.json would cause endless format churn, +# so its formatting is owned by bun + changesets, not prettier. +**/package.json + +# Generated build output and lockfiles +**/dist/** +bun.lock + +# Auto-generated changelog (managed by changesets) +**/CHANGELOG.md diff --git a/README.md b/README.md index 8e90ef8..7dc5753 100644 --- a/README.md +++ b/README.md @@ -43,17 +43,31 @@ Every successful build (JS + DTS) replaces the consumer's `dist/`, so refreshing ## CI / releases - `.github/workflows/test.yaml` runs on every PR and push to `main`: `format:check`, `typecheck`, `build`, and a `npm pack --dry-run` to verify publishability. -- `.github/workflows/release.yaml` triggers on `v*` tags. Verifies the tag matches `package.json`, builds, and publishes to npm via OIDC trusted publishing (`--provenance`). Hyphenated tags like `v0.2.0-beta.1` are marked as GitHub prereleases. +- `.github/workflows/release.yaml` runs on every push to `main` and is driven by [Changesets](https://github.com/changesets/changesets). Either opens/updates a "Version Packages" PR, or — when that PR is merged — publishes to npm via OIDC trusted publishing. -To cut a release: +Bun is pinned to `1.2.21` in both workflows (and in `packageManager` at the root) so lockfile-format drift across bun majors doesn't silently break CI. -```bash -# Bump the version in packages/managed-auth-react/package.json on main, then: -git tag v0.2.0 -git push origin v0.2.0 -``` +### Cutting a release -Bun is pinned to `1.2.21` in both workflows (and in `packageManager` at the root) so lockfile-format drift across bun majors doesn't silently break CI. +The release flow is fully PR-driven — no direct `package.json` edits, no manual `git tag`, no main-branch bypasses. + +1. **In any PR that changes published behavior**, add a changeset: + + ```bash + bun run changeset + ``` + + The CLI asks which packages changed and which bump (patch / minor / major), then writes a `.changeset/.md` file describing the change. Commit it alongside your code. + + Skip the changeset for tooling/infra/docs PRs that don't affect what consumers see. + +2. **Merge your PR to `main`.** The Changesets bot runs and either: + - Opens (or updates) a single **"chore: version packages"** PR that bumps `package.json` versions, regenerates `CHANGELOG.md`, and deletes the consumed changeset files. Multiple feature PRs accumulate into the same Version PR. + - If no pending changesets exist (i.e. the Version PR was just merged), runs `bun run release` which builds the package and calls `changeset publish` → `npm publish` for every version not yet on the registry, then tags + creates the GitHub release. + +3. **To ship**, review and merge the open Version PR. The next workflow run publishes. + +That's it. The git tag, npm publish, and GitHub release are all created by the bot on Version-PR merge. ## License diff --git a/bun.lock b/bun.lock index 6d3a85f..6778b3b 100644 --- a/bun.lock +++ b/bun.lock @@ -27,7 +27,7 @@ }, "packages/managed-auth-react": { "name": "@onkernel/managed-auth-react", - "version": "0.1.0-alpha.0", + "version": "0.1.0", "dependencies": { "clsx": "^2.1.1", }, diff --git a/package.json b/package.json index 7926207..10e0af5 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,10 @@ "typecheck": "bun run --filter '*' typecheck", "lint": "bun run --filter '*' lint", "format": "prettier --write \"**/*.{ts,tsx,js,json,md,css}\"", - "format:check": "prettier --check \"**/*.{ts,tsx,js,json,md,css}\"" + "format:check": "prettier --check \"**/*.{ts,tsx,js,json,md,css}\"", + "changeset": "changeset", + "version-packages": "changeset version", + "release": "bun run --filter '@onkernel/managed-auth-react' build && cp LICENSE packages/managed-auth-react/LICENSE && changeset publish" }, "devDependencies": { "@types/node": "^20",