From 147909049dd3fb5761e220b6c012f5bb311aacd2 Mon Sep 17 00:00:00 2001 From: Jay Cary Date: Tue, 20 Oct 2026 13:45:49 -0400 Subject: [PATCH 1/2] feat: update CI with auto-deploy and auto-incrementing versions --- .artifacts.yml | 3 - .github/PULL_REQUEST_TEMPLATE.md | 7 ++ .github/workflows/npm-release.yml | 106 ++++++++++++++++++++++++++++++ .nvmrc | 2 +- .publisher.yml | 1 - README.md | 19 ++++++ package.json | 11 +++- 7 files changed, 142 insertions(+), 7 deletions(-) delete mode 100644 .artifacts.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/npm-release.yml delete mode 100644 .publisher.yml diff --git a/.artifacts.yml b/.artifacts.yml deleted file mode 100644 index 200f219..0000000 --- a/.artifacts.yml +++ /dev/null @@ -1,3 +0,0 @@ -version: v1 -defaults: - - publisher diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..644a0d0 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +## Summary + +## Test plan + +## Todo + +- [ ] PR title has a `fix:`/`feat:`/`feat!:` prefix (or intentionally none, for no release) diff --git a/.github/workflows/npm-release.yml b/.github/workflows/npm-release.yml new file mode 100644 index 0000000..2df5d7c --- /dev/null +++ b/.github/workflows/npm-release.yml @@ -0,0 +1,106 @@ +name: NPM release + +on: + push: + branches: ['main'] + workflow_dispatch: {} + +concurrency: + group: npm-release-${{ github.ref_name }} + cancel-in-progress: false + +env: + CI: true + bucket: '{ "staging": "labs.mapbox.com-staging/to-color", "production": "labs.mapbox.com/to-color" }' + +permissions: + id-token: write + contents: write + pull-requests: write + +jobs: + publish: + name: "Publish ${{ github.ref_name }}" + runs-on: ubuntu-latest + # npm's Trusted Publisher config for @mapbox/to-color is bound to this workflow file and environment. + environment: npm-release + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: false + + - uses: actions/setup-node@v6 + with: + node-version-file: .nvmrc + cache: npm + + - name: Upgrade npm for OIDC trusted publishing support + run: npm install -g npm@^11.5.1 + + - name: Install npm dependencies + run: npm ci --no-fund --no-audit --prefer-offline + + # Runs eslint and jest + - name: Lint and test + run: npm test + + # Reads the current version from public npmjs and git history + - id: version + uses: mapbox/gha@action-conventional-commit-version-v0 + with: + before-sha: ${{ github.event.before }} + after-sha: ${{ github.event.after }} + + # prepublishOnly builds dist/ + - name: Publish + if: steps.version.outputs.skip != 'true' + run: | + npm version ${{ steps.version.outputs.version }} --no-git-tag-version + npm publish --tag ${{ steps.version.outputs.npm_publish_tag }} + + # The demo site at https://labs.mapbox.com/to-color/ (previously deployed by Publisher). + - name: Build demo site + run: npm run build + + - name: Configure AWS credentials + uses: mapbox/gha@action-configure-aws-credentials-v5 + with: + target-account-id: ${{ vars.AWS_ACCOUNT_ID_DEFAULT }} + role-to-assume: to-color-s3 + + - name: Deploy demo site to staging + run: | + aws s3 sync _site "s3://${{ fromJson(env.bucket).staging }}" --exclude "*.html" --cache-control "max-age=120" + aws s3 sync _site "s3://${{ fromJson(env.bucket).staging }}" --exclude "*" --include "*.html" --cache-control "max-age=0" + + - name: Deploy demo site to production + if: github.ref_name == 'main' + run: | + aws s3 sync _site "s3://${{ fromJson(env.bucket).production }}" --exclude "*.html" --cache-control "max-age=120" + aws s3 sync _site "s3://${{ fromJson(env.bucket).production }}" --exclude "*" --include "*.html" --cache-control "max-age=0" + + - id: release + name: Create GitHub Release + continue-on-error: true + if: steps.version.outputs.skip != 'true' && steps.version.outputs.npm_publish_tag == 'latest' + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ steps.version.outputs.version }} + run: gh release create "v$VERSION" --target "$GITHUB_SHA" --title "v$VERSION" --generate-notes + + - name: Comment released version on PRs + continue-on-error: true + if: steps.release.outcome == 'success' + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ steps.version.outputs.version }} + BEFORE_SHA: ${{ github.event.before }} + run: | + set -o pipefail + package_name="$(node -p 'require("./package.json").name')" + for sha in $(git rev-list "$BEFORE_SHA..$GITHUB_SHA"); do + gh api "repos/$GITHUB_REPOSITORY/commits/$sha/pulls" --jq '.[].number' + done | sort -u | while read -r pr; do + gh pr comment "$pr" --body "Released in \`$package_name@$VERSION\` (release [\`v$VERSION\`](https://github.com/$GITHUB_REPOSITORY/releases/tag/v$VERSION))." + done diff --git a/.nvmrc b/.nvmrc index 2bd5a0a..a45fd52 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22 +24 diff --git a/.publisher.yml b/.publisher.yml deleted file mode 100644 index f2b5b4a..0000000 --- a/.publisher.yml +++ /dev/null @@ -1 +0,0 @@ -subdomain: labs diff --git a/README.md b/README.md index 9233c21..356ec07 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,25 @@ npm install & npm start npm run test ``` +### Publishing + +Pull Requests merged to `main` with conventional commit prefixes are automatically published to npm by the `NPM release` GitHub Actions workflow, as new major/minor/patch versions (`feat!:`/`feat:`/`fix:` respectively). When using "Squash and merge", ensure your PR title includes the conventional commit prefix; a `BREAKING CHANGE:` footer only counts if it ends up in the squash commit's body. Other prefixes (`chore:`, `docs:`, etc.) or no prefix don't trigger a release. + +Examples: +- `fix: resolved issue with seeded colors` -> patch +- `feat: added a new option` -> minor +- `feat!: changed the default palette` (requires consumer changes) -> major + +The workflow publishes via [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers/) (OIDC), so no npm token is needed. This requires an npm org admin to configure a trusted publisher for `@mapbox/to-color` (GitHub Actions, workflow `npm-release.yml`, environment `npm-release`), and the `npm-release` GitHub Environment to exist in this repository. After publishing, the workflow creates a [GitHub Release](https://github.com/mapbox/to-color/releases) with generated notes and comments the released version on the merged PRs. + +Every push to `main` also deploys the demo site, including changes that don't release a new version: first to labs staging, then to https://labs.mapbox.com/to-color/. A manual run of the workflow on another branch publishes a prerelease and deploys the demo to labs staging only. + +`package.json`'s `version` may be incremented manually if needed (for example, to skip a minor version), but you shouldn't normally need to touch it; the published npm version, not `package.json`, is the source of truth for what gets released next. + +#### Pre-release versions on other branches + +For testing in downstream projects, you can manually trigger the "NPM release" workflow on a branch to publish a pre-release tagged with the short commit sha (e.g. `2.3.0-aa79c6a`) under the npm `prerelease` dist-tag, without affecting `latest`. Check the workflow results for the published version. + --- **Credit** v2 is adapted from [randomColor](https://github.com/davidmerfield/randomColor). diff --git a/package.json b/package.json index d8eaad7..9d11164 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "2.3.0", "description": "Procedurally generate a deterministic, perceptually distributed color palette.", "main": "dist/to-color.js", + "files": [ + "dist" + ], "scripts": { "start:server": "serve demo", "start": "run-p start:server watch", @@ -11,7 +14,8 @@ "build": "npm run compile && rm -rf _site && mkdir -p _site && cp -R demo/ _site/", "test": "eslint src && jest", "jest-watch": "jest --watch", - "prepare": "husky" + "prepare": "husky", + "prepublishOnly": "npm run compile" }, "keywords": [ "color", @@ -66,10 +70,13 @@ }, "repository": { "type": "git", - "url": "git@github.com:mapbox/to-color.git" + "url": "git+https://github.com/mapbox/to-color.git" }, "dependencies": { "d3-color": "^3.1.0", "hsluv": "^1.0.1" + }, + "publishConfig": { + "access": "public" } } From d9ac362878e2d42054dbf5ab0ccc2a38fdf39d47 Mon Sep 17 00:00:00 2001 From: Jay Cary Date: Thu, 22 Oct 2026 14:40:29 -0400 Subject: [PATCH 2/2] remove _config.yml --- _config.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 _config.yml diff --git a/_config.yml b/_config.yml deleted file mode 100644 index ba6a122..0000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -source: demo