Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Comment thread
jcary741 marked this conversation as resolved.
Outdated

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).
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