Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .artifacts.yml

This file was deleted.

7 changes: 7 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Summary

## Test plan

## Todo

- [ ] PR title has a `fix:`/`feat:`/`feat!:` prefix (or intentionally none, for no release)
106 changes: 106 additions & 0 deletions .github/workflows/npm-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: NPM release

on:
push:
branches: ['main']

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be publisher-production? main does not exist unless you are intended to change this but note we still want to publish builds to that branch

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! That's in the post-merge TODO:

-[ ] Rename publisher-production to main; the workflow only runs on 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
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22
24
1 change: 0 additions & 1 deletion .publisher.yml

This file was deleted.

19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
1 change: 0 additions & 1 deletion _config.yml

This file was deleted.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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"
}
}
Loading