Skip to content

Commit cc15240

Browse files
authored
Merge pull request #85 from themashcodee/npm-run-release-script
chore: 🚀 replace changesets with one-command release + PR previews
2 parents 4a9b207 + 734d292 commit cc15240

11 files changed

Lines changed: 1819 additions & 3324 deletions

File tree

.changeset/README.md

Lines changed: 0 additions & 8 deletions
This file was deleted.

.changeset/config.json

Lines changed: 0 additions & 11 deletions
This file was deleted.

.github/workflows/preview.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Preview Release
2+
3+
# Publishes an installable preview build of every PR (and of `main`) to pkg.pr.new,
4+
# so contributors and testers can `npm install` a branch WITHOUT it ever touching the
5+
# real `slack-blocks-to-jsx` npm package or needing your npm token.
6+
#
7+
# Each new commit on a PR republishes and updates the PR comment with a fresh install
8+
# command — no version bumping or cleanup needed. See the "more commits" note in RELEASING.md.
9+
#
10+
# ONE-TIME SETUP: install the pkg.pr.new GitHub App on this repo (only an owner can):
11+
# https://github.com/apps/pkg-pr-new
12+
# No secrets/tokens are required — it works for fork PRs too.
13+
14+
on:
15+
push:
16+
branches: [main]
17+
pull_request:
18+
19+
permissions: {}
20+
21+
jobs:
22+
preview:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v4
26+
- uses: pnpm/action-setup@v4
27+
with:
28+
version: 9
29+
- uses: actions/setup-node@v4
30+
with:
31+
node-version: 22.13
32+
cache: pnpm
33+
- run: pnpm install --frozen-lockfile
34+
- run: pnpm run build
35+
- run: pnpm dlx pkg-pr-new publish

.github/workflows/publish.yml

Lines changed: 0 additions & 35 deletions
This file was deleted.

.npmignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
.changeset
21
.github
2+
scripts
3+
RELEASING.md
34
node_modules
45
src
56
.env

KNOWLEDGE_BASE.md

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,11 @@ Input: `src/style.css`. Output: `dist/style.css` (~40 KB).
612612
| `dev` | tsup watch |
613613
| `dev:css` | PostCSS watch |
614614
| `lint` | `tsc --noEmit` |
615-
| `release` | `pnpm run build && changeset publish` |
616-
| `release-alpha-without-git` | Publish `--tag alpha --no-git-checks` |
615+
| `test` | `tsc --noEmit` (typecheck; no unit tests) |
616+
| `release` | `node scripts/release.mjs` (see Ch. 11) |
617+
| `release:dry` | Preview a release; changes nothing |
618+
| `release:beta` | Publish next `beta` prerelease (tag: beta) |
619+
| `release:alpha` | Publish next `alpha` prerelease (tag: alpha) |
617620

618621
### 10.4 dist/ output
619622

@@ -626,7 +629,7 @@ Input: `src/style.css`. Output: `dist/style.css` (~40 KB).
626629

627630
### 10.5 npm publish hygiene
628631

629-
`.npmignore` excludes: `.changeset`, `.github`, `node_modules`, `src`, `.env`, `.prettierrc`, `CHANGELOG.md`, `pnpm-lock.yaml`, `tailwind.config.js`, `tsconfig.json`, `.DS_Store`, `postcss.config.js`.
632+
`.npmignore` excludes: `.github`, `scripts`, `RELEASING.md`, `node_modules`, `src`, `.env`, `.prettierrc`, `CHANGELOG.md`, `pnpm-lock.yaml`, `tailwind.config.js`, `tsconfig.json`, `.DS_Store`, `postcss.config.js`.
630633

631634
`.npmrc`: `auto-install-peers=true`.
632635

@@ -636,14 +639,37 @@ Input: `src/style.css`. Output: `dist/style.css` (~40 KB).
636639

637640
## Chapter 11 — Release process
638641

639-
From `PUBLISH_GUIDE.md`, in short:
640-
641-
1. Commit source changes.
642-
2. `pnpm changeset` — pick patch / minor / major; write summary.
643-
3. `git push origin main` — triggers GitHub Actions (`.github/workflows/`).
644-
4. CI runs lint + build.
645-
5. Changesets bot opens a "Version Packages" PR (bumps version, updates `CHANGELOG.md`).
646-
6. Merge that PR → publish workflow runs `pnpm run release``pnpm run build && changeset publish`.
642+
Releasing is a single local command: **`pnpm release`** (see `RELEASING.md`). It is driven by
643+
`scripts/release.mjs` — a dependency-free Node script that, in order:
644+
645+
1. **Pre-flight checks** — clean working tree, on `main`, not behind `origin/main`, and authenticated
646+
to both npm (`npm whoami`) and GitHub (`gh auth status`).
647+
2. **Lint / typecheck** (`pnpm run lint`) and **build** (`pnpm run build`).
648+
3. **Bumps the version** in `package.json` (interactive patch/minor/major/custom, or passed as an arg).
649+
4. **Commits** (`chore: release vX.Y.Z`) and **tags** (`vX.Y.Z`).
650+
5. **Publishes to npm** (`pnpm publish --no-git-checks --tag <dist-tag>`).
651+
6. **Pushes** the commit + tag, then **creates a GitHub release** via `gh release create --generate-notes`.
652+
653+
`pnpm release:dry` previews the whole thing (runs checks + build, mutates nothing).
654+
655+
**Prereleases (beta / alpha):** `pnpm release:beta` / `pnpm release:alpha` cut the next prerelease
656+
(`1.0.4``1.0.5-beta.0``-beta.1` …). Each publishes under its own npm dist-tag (`beta`, `alpha`,
657+
`rc`…) so it never becomes `latest`, and is flagged as a pre-release on GitHub — testers opt in with
658+
`npm install slack-blocks-to-jsx@beta`. Bump types `prepatch`/`preminor`/`premajor`/`prerelease` plus
659+
`--preid=<id>` give finer control; a normal `pnpm release patch` on a prerelease graduates it to stable
660+
(`1.0.5-beta.2``1.0.5`). The version maths mirror semver's `inc`. See `RELEASING.md`.
661+
662+
The old Changesets flow (`pnpm changeset` + the `publish.yml` "Version Packages" bot) has been removed
663+
in favour of this. CI (`.github/workflows/main.yml`) still runs lint + build on every push/PR, but no
664+
longer publishes — releasing is now a deliberate local action. There is no `CHANGELOG.md`; release notes
665+
are auto-generated from merged PRs/commits on each GitHub release.
666+
667+
**PR preview releases:** `.github/workflows/preview.yml` publishes every PR (and `main`) to
668+
[pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) so reviewers can `npm install`
669+
a branch (`https://pkg.pr.new/slack-blocks-to-jsx@<commit-or-PR>`) without it ever hitting the
670+
real npm package. It needs no npm token, works for fork PRs, and re-publishes + updates the PR
671+
comment on every new commit. Requires the pkg.pr.new GitHub App installed on the repo. These
672+
previews are distinct from intentional `pnpm release:beta` prereleases (which do go to npm).
647673

648674
`RELEASE_NOTES.md` tells the story of v1.0.1 — the "full Block Kit parity" release — after 80+ iterative releases. Major breaking changes from that version:
649675

@@ -683,8 +709,9 @@ Folder: `test-blocks/`. Used as manual/visual test inputs. Each file is a comple
683709

684710
```
685711
slack blocks to jsx library/
686-
├── .changeset/
687712
├── .github/
713+
├── scripts/
714+
│ └── release.mjs # One-command release (see Ch. 11)
688715
├── dist/
689716
│ ├── index.js index.mjs index.d.ts index.d.mts style.css
690717
├── src/
@@ -751,7 +778,7 @@ slack blocks to jsx library/
751778
│ ├── main.tsx App.tsx fixtures.ts index.css
752779
├── package.json tsconfig.json tsup.config.ts
753780
├── tailwind.config.js postcss.config.js .prettierrc
754-
├── readme.md PUBLISH_GUIDE.md RELEASE_NOTES.md
781+
├── readme.md RELEASING.md KNOWLEDGE_BASE.md
755782
├── .npmignore .npmrc .env .gitignore
756783
└── pnpm-lock.yaml
757784
```
@@ -771,7 +798,7 @@ Rules worth knowing before making changes:
771798
7. **Externalization:** `react-markdown`, `remark-gfm`, `node-emoji` must stay external in tsup config — bundling them again will break Next.js ESM interop.
772799
8. **Accessibility:** preserve the `accessibility_label` prop on buttons; use semantic tags (button, a, input) — this mirrors Slack's own a11y posture.
773800
9. **Type-first:** every block/element addition requires a matching interface in `src/types/` before the component lands.
774-
10. **Changesets:** any user-facing change needs a changeset before merge.
801+
10. **Releasing:** versioning + publishing is a single local command, `pnpm release` (see Ch. 11 / `RELEASING.md`). No changeset files are needed.
775802

776803
---
777804

@@ -856,3 +883,4 @@ The sidebar picks it up automatically on next HMR. Keep fixtures small (≤ 10 b
856883
| 2026-04-17 | Claude + Mash | Added Ch. 0 — How to use this knowledge base (usage, reading strategy, update triggers, update procedure, style rules, ownership). |
857884
| 2026-04-17 | Claude + Mash | v1.1.0 release prep: added three new blocks (`alert`, `card`, `carousel`) matching Slack's 2026-04-16 Block Kit launch. Ch. 4 block count 14 → 17 (new §4.6 "Status & rich-container blocks"). Ch. 6.1 type list updated with `AlertBlock`, `CardBlock`, `CarouselBlock`, `CardImage`, `AlertLevel`. Ch. 12 gained `11-alert-card-carousel.json` fixture. Ch. 13 file tree updated. Changeset: `.changeset/add-alert-card-carousel-blocks.md`. |
858885
| 2026-04-17 | Claude + Mash | Added Ch. 15 — Playground. New `playground/` folder (Vite + React 18) that source-aliases `slack-blocks-to-jsx` to `../src/index.ts` for instant HMR. Committed to git, excluded from npm via `.npmignore`. Ch. 15 renumbered from change log → playground; change log moved to Ch. 16. Root `package.json` gained `playground`, `playground:install`, `playground:build` scripts. Ch. 13 file tree extended. |
886+
| 2026-06-06 | Claude + Mash | Replaced the Changesets release flow with a single local command `pnpm release` (`scripts/release.mjs`): checks → lint → build → bump → commit/tag → npm publish → push → GitHub release. Removed `.changeset/`, `@changesets/cli`, and `.github/workflows/publish.yml`; added `test`/`release`/`release:dry` scripts and `RELEASING.md`. Rewrote Ch. 11, updated §10.3/§10.5 scripts + hygiene, Ch. 13 file tree (`scripts/`), and Ch. 14 rule 10. Added first-class beta/alpha prereleases: `release:beta`/`release:alpha` scripts, `prepatch`/`preminor`/`premajor`/`prerelease` bump types + `--preid`, auto dist-tag per channel, prerelease graduation, and a "Trying a prerelease" section in `readme.md`. Added `.github/workflows/preview.yml` (pkg.pr.new) for automatic per-PR/per-commit preview installs (no npm token, fork-safe). |

RELEASING.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Releasing
2+
3+
Releasing is one command:
4+
5+
```bash
6+
pnpm release
7+
```
8+
9+
It walks you through everything — pick **patch / minor / major** (or a custom version) and confirm. The script then runs the whole pipeline for you:
10+
11+
1. **Pre-flight checks** — clean working tree, on `main`, up to date with the remote, and logged in to both npm and GitHub.
12+
2. **Lint / typecheck** (`pnpm run lint`).
13+
3. **Build** (`pnpm run build`).
14+
4. **Bump the version** in `package.json`.
15+
5. **Commit** (`chore: release vX.Y.Z`) and **tag** (`vX.Y.Z`).
16+
6. **Publish to npm** (`pnpm publish`).
17+
7. **Push** the commit and tag to GitHub.
18+
8. **Create a GitHub release** with auto-generated notes.
19+
20+
## One-time setup
21+
22+
You only need to do these once per machine:
23+
24+
```bash
25+
npm login # so the script can publish to npm
26+
gh auth login # so it can create the GitHub release (you're likely already logged in)
27+
```
28+
29+
## Usage
30+
31+
```bash
32+
pnpm release # interactive — pick patch / minor / major / prerelease / custom
33+
pnpm release patch # 1.0.4 -> 1.0.5
34+
pnpm release minor # 1.0.4 -> 1.1.0
35+
pnpm release major # 1.0.4 -> 2.0.0
36+
pnpm release 1.2.3 # set an exact version
37+
pnpm release patch --yes # skip the confirmation prompt
38+
pnpm release:dry # preview the whole thing, change nothing
39+
```
40+
41+
## Beta / alpha prereleases
42+
43+
Ship a version for people to test **before** it becomes the default `latest`:
44+
45+
```bash
46+
pnpm release:beta # 1.0.4 -> 1.0.5-beta.0 (npm dist-tag: beta)
47+
pnpm release:beta # run again -> 1.0.5-beta.1, 1.0.5-beta.2 …
48+
pnpm release:alpha # same idea on the "alpha" channel -> 1.0.5-alpha.0
49+
```
50+
51+
Each prerelease is published under its own npm **dist-tag** (`beta`, `alpha`, …), so it never
52+
becomes the version people get by default, and it's marked as a *pre-release* on GitHub. Testers opt in:
53+
54+
```bash
55+
npm install slack-blocks-to-jsx@beta # latest beta
56+
npm install slack-blocks-to-jsx@alpha # latest alpha
57+
npm install slack-blocks-to-jsx@1.0.5-beta.2 # an exact prerelease
58+
```
59+
60+
Meanwhile `npm install slack-blocks-to-jsx` keeps installing the stable `latest` release.
61+
62+
When the beta is solid, **graduate it to stable** — a normal release drops the prerelease suffix:
63+
64+
```bash
65+
pnpm release patch # from 1.0.5-beta.2 -> 1.0.5 (dist-tag: latest)
66+
```
67+
68+
More control:
69+
70+
```bash
71+
pnpm release prerelease --preid=rc # release-candidate channel (1.0.5-rc.0, tag: rc)
72+
pnpm release preminor --preid=beta # start a beta off the next minor (1.1.0-beta.0)
73+
pnpm release premajor --preid=beta # start a beta off the next major (2.0.0-beta.0)
74+
pnpm release 1.2.3-beta.0 # any exact prerelease version you want
75+
```
76+
77+
## Dry run
78+
79+
Not sure? Preview first — it runs the checks, lint, and build but changes nothing:
80+
81+
```bash
82+
pnpm release:dry
83+
```
84+
85+
## PR preview releases (pkg.pr.new)
86+
87+
Every pull request automatically gets an **installable preview build** so reviewers and
88+
testers can try the change before it's merged — without it ever touching the real
89+
`slack-blocks-to-jsx` package on npm. This is handled by
90+
[pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) via
91+
`.github/workflows/preview.yml`.
92+
93+
When a PR opens, a bot comments with an install command, e.g.:
94+
95+
```bash
96+
npm install https://pkg.pr.new/slack-blocks-to-jsx@<commit-or-PR>
97+
```
98+
99+
**What about new commits on the PR?** Nothing to do. Every push re-runs the workflow and
100+
republishes; the bot **edits its existing comment** with the fresh command, and the
101+
per-PR URL always resolves to the PR's latest commit. So testers just re-install the same
102+
URL to get the newest build — no version bumping, no cleanup, no npm clutter.
103+
104+
This needs **no npm token** and works for PRs from forks. One-time setup (owner only):
105+
install the **pkg.pr.new GitHub App**<https://github.com/apps/pkg-pr-new>.
106+
107+
> PR previews are **not** the same as `pnpm release:beta`. Previews are automatic, throwaway,
108+
> and never published to npm. A `beta`/`alpha` (via `pnpm release:beta`) is an intentional,
109+
> maintainer-cut prerelease published to the real npm package under the `beta`/`alpha` dist-tag.
110+
111+
## If something fails midway
112+
113+
The script does the irreversible steps (commit → tag → publish → push → GitHub release) in
114+
an order that keeps things recoverable, and prints exact recovery commands if a step fails.
115+
The common cases:
116+
117+
- **Failed before publishing** — nothing was pushed. Undo the local bump:
118+
```bash
119+
git tag -d vX.Y.Z
120+
git reset --hard HEAD~1
121+
```
122+
- **Published, but a later step failed** — the package is already on npm; just finish the rest:
123+
```bash
124+
git push --follow-tags origin main
125+
gh release create vX.Y.Z --title vX.Y.Z --generate-notes
126+
```
127+
128+
## Notes
129+
130+
- **"Tests"** currently means the TypeScript typecheck (`pnpm run lint` / `pnpm test`); there is
131+
no unit-test suite yet. When one is added, wire it into the `test` script and the release will
132+
pick it up.
133+
- CI (`.github/workflows/main.yml`) still runs lint + build on every push and PR. Releasing is now
134+
a deliberate local action rather than an automated CI publish.

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
"build:css": "postcss ./src/style.css -o ./dist/style.css",
2525
"dev:css": "postcss ./src/style.css -o ./dist/style.css --watch",
2626
"dev": "tsup --watch",
27-
"new-version": "pnpm changeset",
2827
"lint": "tsc",
29-
"release": "pnpm run build && changeset publish",
30-
"release-alpha-without-git": "pnpm run build && pnpm publish --tag alpha --no-git-checks",
28+
"test": "tsc",
29+
"release": "node scripts/release.mjs",
30+
"release:dry": "node scripts/release.mjs --dry-run",
31+
"release:beta": "node scripts/release.mjs prerelease --preid=beta",
32+
"release:alpha": "node scripts/release.mjs prerelease --preid=alpha",
3133
"playground:install": "cd playground && npm install",
3234
"playground": "cd playground && npm run dev",
3335
"playground:build": "cd playground && npm run build"
@@ -46,7 +48,6 @@
4648
"@yozora/character": "^2.3.2",
4749
"@yozora/core-tokenizer": "^2.3.2",
4850
"@yozora/parser": "^2.3.2",
49-
"@changesets/cli": "^2.26.2",
5051
"@types/react": "^17 || ^18 || ^19",
5152
"@types/react-dom": "^17 || ^18 || ^19",
5253
"autoprefixer": "^10.4.17",

0 commit comments

Comments
 (0)