diff --git a/.changeset/README.md b/.changeset/README.md index f43091d..193bf35 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -2,7 +2,9 @@ This folder is managed by [Changesets](https://github.com/changesets/changesets). It tracks pending version bumps and changelog entries for the workspace's -publishable packages. +publishable packages — currently just `@makeplane/propel`. + +## Adding a changeset When you make a change that should ship in a release, run: @@ -10,11 +12,118 @@ When you make a change that should ship in a release, run: pnpm changeset ``` -Pick the affected package(s), the bump type (patch / minor / major), and write a -short summary. That creates a markdown file in this folder which is committed -alongside your change. On merge to `main`, the release workflow opens (or -updates) a "Version Packages" PR that consumes these files, bumps versions, -writes `CHANGELOG.md`, and publishes to npm when merged. +Pick the affected package, the bump type, and write a short summary. That writes a +markdown file into this folder — **commit it alongside your change**, in the same PR. + +The generated file is just frontmatter plus prose: + +```markdown +--- +"@makeplane/propel": minor +--- + +Add the `@makeplane/propel/icons` subpath export. +``` + +You can hand-write or edit these files freely; the interactive prompt is a +convenience, not a requirement. + +## Picking a bump type + +**Changesets does not work this out for you.** There is no diff analysis and no API +comparison — whatever you declare is applied verbatim. A `patch` that quietly deletes +an export will ship as a patch. Choosing correctly is on the author and the reviewer. + +propel is **pre-1.0**, and changesets does *not* apply the "0.x major means minor" +convention. From `0.1.0`: + +| Bump | Result | Use for | +| ------- | ------- | ---------------------------------------------------------- | +| `patch` | `0.1.1` | Bug fixes, internal refactors, docs on a published file | +| `minor` | `0.2.0` | New components/exports **and breaking changes** (pre-1.0) | +| `major` | `1.0.0` | Nothing, until we deliberately cut 1.0 | + +While we are on `0.x`, breaking changes go in the **minor** slot. Do not reach for +`major` to signal "this is a big change" — it ships 1.0.0. + +Because propel is a published component library, treat anything that changes the +**public API surface** as at least a minor: a new subpath export, a renamed or removed +prop, a changed default. Those are what consumers feel on upgrade. + +## Multiple changesets + +One PR can add several changesets, and several PRs accumulate before a release. When +they are consumed, the **highest bump wins** and every summary is kept, grouped by type: + +``` +patch + patch + minor -> 0.2.0 +``` + +```markdown +## 0.2.0 + +### Minor Changes + +- feat c + +### Patch Changes + +- fix a +- fix b +``` + +So a small fix riding along with a feature still gets its own changelog line. + +## Writing the summary + +The summary becomes the changelog entry, published to npm and read by consumers. +Write it for someone upgrading the package, not for the reviewer of your diff. + +- Say what changed from the outside: `Add the SplitButton component`, not `refactor button internals` +- Name the export you touched, so it is greppable: `` `Tooltip` now forwards `aria-describedby` `` +- Call out anything that requires action on upgrade: a renamed prop, a removed variant, a new peer requirement +- One line is usually enough; add a second only if there's a real gotcha + +## When you don't need one + +Skip the changeset when nothing about the published package changes: + +- Docs-site work under `apps/docs` +- CI, tooling, or repo config +- Tests, Storybook stories, or lint fixes with no runtime effect + +Everything under `packages/propel/src` that ends up in `dist` needs one. + +## Checking what's pending + +```bash +pnpm changeset status # what would be released right now +pnpm changeset status --since=origin/main # what this branch adds +``` + +"NO packages to be bumped" means a push to `main` will publish nothing. + +## How a release actually happens + +It takes **two merges**, which is the part people miss: + +1. Your PR merges to `main` carrying a changeset file. +2. The Release workflow sees a pending changeset and opens (or updates) a + **"Version Packages"** PR. This PR consumes the changeset files, bumps + `packages/propel/package.json`, and writes `CHANGELOG.md`. +3. Merging *that* PR is what publishes to npm and tags the release. + +A push to `main` with no changesets present is a deliberate no-op: the workflow goes +green, warns `No unpublished projects to publish`, and ships nothing. **A green +Release run is not evidence that anything was released** — check npm or the tags. + +## Common mistakes + +- **Forgetting the changeset entirely** — the PR merges green and the change silently never ships +- **Using `major` pre-1.0** — that cuts 1.0.0; breaking changes belong in `minor` for now +- **Writing the commit message as the summary** — the summary is user-facing changelog copy +- **Adding a changeset for docs-only work** — produces a meaningless version bump +- **Assuming the green Release run published something** — it only publishes when a Version Packages PR merges See the [Changesets docs](https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md) for the full workflow. diff --git a/.changeset/config.json b/.changeset/config.json index 2be13d4..754ef41 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,5 +7,6 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] + "ignore": [], + "privatePackages": false } diff --git a/.changeset/tender-grapes-kneel.md b/.changeset/tender-grapes-kneel.md new file mode 100644 index 0000000..c053599 --- /dev/null +++ b/.changeset/tender-grapes-kneel.md @@ -0,0 +1,27 @@ +--- +"@makeplane/propel": minor +--- + +First installable release. `0.1.0` was published with unresolved pnpm `catalog:` specifiers in +its `dependencies`, so both `npm install` and `pnpm add` fail on it outright +(`EUNSUPPORTEDPROTOCOL: Unsupported URL Type "catalog:"`). This release ships a correct manifest +with real semver ranges. + +**Added** + +- `@makeplane/propel/icons` — a new subpath exporting 737 icons, tree-shakeable per icon. Icons + render as static SVG with no client boundary, so they stay server-rendered in RSC. +- `elements/button-group` and `components/button-group` +- `elements/split-button` and `components/split-button` +- `elements/expandable-search` and `components/expandable-search` +- `components/icon` +- `components/shortcut` + +**Removed** + +- `elements/menubar` and `components/menubar` +- `elements/meter` and `components/meter` +- `elements/toggle-group` and `components/toggle-group` + +Anything importing the removed subpaths must migrate before upgrading. propel is pre-1.0, so +removals ship in the minor slot. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0798080..19200f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,16 +10,26 @@ env: jobs: release: name: Release - runs-on: blacksmith-4vcpu-ubuntu-2404 + # MUST be a GitHub-hosted runner, unlike ci.yml's blacksmith-* ones. Publishing + # authenticates via npm trusted publishing (OIDC) with no NPM_TOKEN fallback, and + # Blacksmith registers as a *self-hosted* runner, so GitHub stamps its OIDC token + # `runner_environment: self-hosted` — which npm rejects ("Trusted publishing + # currently supports only cloud-hosted runners"). Releases are rare; the slower + # runner costs nothing that matters. + runs-on: ubuntu-latest permissions: contents: write # create the "Version Packages" PR, tags and releases pull-requests: write # open/update the release PR - id-token: write # npm provenance (publishConfig.provenance) + id-token: write # OIDC token for npm trusted publishing + provenance steps: - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + # action-setup must precede setup-node so `cache: pnpm` can find the store. + # Keep action-setup current: an outdated one breaks the OIDC token exchange + # (pnpm/pnpm#11513). No `registry-url:` on setup-node — it writes an .npmrc + # pinning `_authToken=${NODE_AUTH_TOKEN}`, which is empty on the OIDC path. + - uses: pnpm/action-setup@v6 + - uses: actions/setup-node@v6 with: node-version-file: .node-version cache: pnpm