From 931f98f4b3920ada582420711ff3afba2dc22c2c Mon Sep 17 00:00:00 2001 From: Dave Hillier Date: Sat, 3 Oct 2026 09:51:59 +0100 Subject: [PATCH] Release 0.1.0 Drop the alpha suffix and the next dist-tag: 0.x already signals an unstable API, so 0.1.0 publishes to latest. The release workflow now checks the tag against package.json, takes the notes from the matching CHANGELOG.md section before publishing, and creates the GitHub release after. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/release.yml | 39 ++++++++++++++++++++++++++++++----- CHANGELOG.md | 2 +- README.md | 6 +++--- docs/getting-started.mdx | 2 +- package.json | 5 ++--- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2a48826..8e5400ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,10 +18,14 @@ # publisher is updated to match. # 3. Keep the npm CLI recent (>= 11.5.1); older versions do not support OIDC. # -# The dist-tag comes from publishConfig.tag in package.json (currently "next"), -# so prereleases do not become `latest`. It is passed to npm explicitly rather -# than left implicit: npm 10 ignores publishConfig.tag and resolves `latest` -# regardless, which would publish a prerelease as the default install. +# The dist-tag comes from publishConfig.tag in package.json, defaulting to +# `latest`. It is passed to npm explicitly rather than left implicit: npm 10 +# ignores publishConfig.tag and resolves `latest` regardless. +# +# After publishing, the workflow creates the GitHub release for the tag, with +# the matching CHANGELOG.md section as its notes. Both the version check and +# the notes are taken before publishing, so a tag that disagrees with +# package.json, or has no changelog section, fails without publishing anything. name: Release @@ -34,7 +38,7 @@ jobs: release: runs-on: ubuntu-latest permissions: - contents: read + contents: write id-token: write steps: - uses: actions/checkout@v4 @@ -48,6 +52,20 @@ jobs: - run: npm install -g npm@latest - run: yarn --frozen-lockfile - run: yarn test + # The release notes are the CHANGELOG.md section headed with the version. + - name: Check the version and extract the release notes + if: startsWith(github.ref, 'refs/tags/') + run: | + version=$(node -p "require('./package.json').version") + if [ "v$version" != "$GITHUB_REF_NAME" ]; then + echo "Tag $GITHUB_REF_NAME does not match package.json version $version" >&2 + exit 1 + fi + awk -v heading="## $version" '$0 == heading {found=1; next} found && /^## / {exit} found' CHANGELOG.md > "$RUNNER_TEMP/release-notes.md" + if ! grep -q '[^[:space:]]' "$RUNNER_TEMP/release-notes.md"; then + echo "CHANGELOG.md has no section headed '## $version'" >&2 + exit 1 + fi # package.json stays the single source of truth for the dist-tag; reading # it here just stops npm from silently falling back to `latest`. - id: disttag @@ -55,3 +73,14 @@ jobs: tag=$(node -p "require('./package.json').publishConfig?.tag || 'latest'") echo "tag=$tag" >> "$GITHUB_OUTPUT" - run: npm publish --tag "${{ steps.disttag.outputs.tag }}" + # A version with a prerelease suffix, such as 1.0.0-rc.1, is marked as a + # prerelease on GitHub too. + - name: Create the GitHub release + if: startsWith(github.ref, 'refs/tags/') + env: + GH_TOKEN: ${{ github.token }} + run: | + version="${GITHUB_REF_NAME#v}" + prerelease="" + case "$version" in *-*) prerelease="--prerelease" ;; esac + gh release create "$GITHUB_REF_NAME" --title "$version" --notes-file "$RUNNER_TEMP/release-notes.md" $prerelease diff --git a/CHANGELOG.md b/CHANGELOG.md index 04523938..f3c4ddeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Replot - Changelog -## Unreleased +## 0.1.0 The pointer transform now reports the focused datum the way Observable Plot does: the plot element (the `
` when there is one, else the ``) carries the focused datum as its `value`, and a bubbling *input* event fires whenever that value changes. The **onValue** prop follows the same contract and is called once per value change, rather than once per pointer-driven mark. diff --git a/README.md b/README.md index 28a207b7..ab41098c 100644 --- a/README.md +++ b/README.md @@ -194,9 +194,9 @@ npm install @dave-hillier/replot ``` Replot is published as a scoped package because the bare name `replot` is taken -on npm by an unrelated project. While the API is still settling, releases are -prereleases published under the `next` dist-tag, so install -`@dave-hillier/replot@next` until 0.1.0 is out. +on npm by an unrelated project. Replot is on 0.x while the API settles, so a +minor version can contain breaking changes; the [changelog](./CHANGELOG.md) lists +them. Then import the React API: diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index b5f68083..642185db 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -4,7 +4,7 @@ Replot is a React component library: charts are built with declarative JSX via t ## Installing from npm -If you’re developing a web application using Node, you can install Replot via yarn, npm, pnpm, or your preferred package manager. Replot is published under the scoped name `@dave-hillier/replot`, because the bare name `replot` belongs to an unrelated package on npm. While the API is still settling, releases are prereleases published under the `next` dist-tag, so add `@next` to the install commands below until 0.1.0 is out. +If you’re developing a web application using Node, you can install Replot via yarn, npm, pnpm, or your preferred package manager. Replot is published under the scoped name `@dave-hillier/replot`, because the bare name `replot` belongs to an unrelated package on npm. Replot is on 0.x while the API settles, so a minor version can contain breaking changes. ```bash [yarn] diff --git a/package.json b/package.json index d0b33f85..d978fd8e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@dave-hillier/replot", "description": "A React port of Observable Plot: grammar-of-graphics charts as JSX components, rendered natively in the React tree.", - "version": "0.1.0-alpha.1", + "version": "0.1.0", "author": { "name": "Dave Hillier" }, @@ -141,7 +141,6 @@ "node": ">=18" }, "publishConfig": { - "access": "public", - "tag": "next" + "access": "public" } }