diff --git a/ auto.config.ts b/ auto.config.ts index df2296010..062ced8e0 100644 --- a/ auto.config.ts +++ b/ auto.config.ts @@ -7,7 +7,7 @@ import type { AutoRc } from 'auto'; export default function rc(): AutoRc { return { baseBranch: 'main', - plugins: ['npm', 'released', ['exec', { afterShipIt: 'yarn publish-action' }]], + plugins: ['npm', 'released'], shipit: { onlyGraduateWithReleaseLabel: true, prerelease: true, diff --git a/.github/workflows/chromatic-main-and-prs.yml b/.github/workflows/chromatic-main-and-prs.yml index 638a7af14..22fd9950b 100644 --- a/.github/workflows/chromatic-main-and-prs.yml +++ b/.github/workflows/chromatic-main-and-prs.yml @@ -10,7 +10,7 @@ jobs: chromatic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/chromatic-prod.yml b/.github/workflows/chromatic-prod.yml index 9bb29196f..3bfc22033 100644 --- a/.github/workflows/chromatic-prod.yml +++ b/.github/workflows/chromatic-prod.yml @@ -5,7 +5,7 @@ jobs: chromatic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/chromatic-staging.yml b/.github/workflows/chromatic-staging.yml index 5b5d5ee52..51048634f 100644 --- a/.github/workflows/chromatic-staging.yml +++ b/.github/workflows/chromatic-staging.yml @@ -5,7 +5,7 @@ jobs: chromatic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8a8e877b6..3a4f32e43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,13 +1,32 @@ name: Release -on: [push] +on: + # PRs have their own canary releases which always run but don't publish the GitHub Action. + # To allow debugging the release process, this does not have a paths filter. + pull_request: + branches: + - main + + # Pushes to main trigger a release and publish the GitHub Action. To allow the occasional update + # to markdown and config files, only changes to actual source code trigger a release. + push: + branches: + - main + paths: + - action-src/** + - bin-src/** + - node-src/** + - action.yml + - isChromatic.* + - package.json + - storybook-addon.* jobs: release: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: token: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/smoke-test-action.yml b/.github/workflows/smoke-test-action.yml index 87f1bc57c..f78d97704 100755 --- a/.github/workflows/smoke-test-action.yml +++ b/.github/workflows/smoke-test-action.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-node-api.yml b/.github/workflows/smoke-test-node-api.yml index 193e4ac25..fb973841e 100755 --- a/.github/workflows/smoke-test-node-api.yml +++ b/.github/workflows/smoke-test-node-api.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-node14.yml b/.github/workflows/smoke-test-node14.yml index db328798d..abc86eb81 100755 --- a/.github/workflows/smoke-test-node14.yml +++ b/.github/workflows/smoke-test-node14.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-node16.yml b/.github/workflows/smoke-test-node16.yml index 5a838d3fe..b490689da 100755 --- a/.github/workflows/smoke-test-node16.yml +++ b/.github/workflows/smoke-test-node16.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-node18.yml b/.github/workflows/smoke-test-node18.yml index 81f066a20..47e1de525 100755 --- a/.github/workflows/smoke-test-node18.yml +++ b/.github/workflows/smoke-test-node18.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-node20.yml b/.github/workflows/smoke-test-node20.yml index a021b2b5d..d372cbfcd 100755 --- a/.github/workflows/smoke-test-node20.yml +++ b/.github/workflows/smoke-test-node20.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-npx.yml b/.github/workflows/smoke-test-npx.yml index d993d4855..84eb06bd0 100644 --- a/.github/workflows/smoke-test-npx.yml +++ b/.github/workflows/smoke-test-npx.yml @@ -5,7 +5,7 @@ jobs: chromatic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-windows.yml b/.github/workflows/smoke-test-windows.yml index 7840ba681..0ca192e89 100644 --- a/.github/workflows/smoke-test-windows.yml +++ b/.github/workflows/smoke-test-windows.yml @@ -5,7 +5,7 @@ jobs: chromatic: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-yarn-canary.yml b/.github/workflows/smoke-test-yarn-canary.yml index d26cf1230..53153cf39 100644 --- a/.github/workflows/smoke-test-yarn-canary.yml +++ b/.github/workflows/smoke-test-yarn-canary.yml @@ -5,7 +5,7 @@ jobs: chromatic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-yarn-classic.yml b/.github/workflows/smoke-test-yarn-classic.yml index 0ec41fe58..b8028c03c 100644 --- a/.github/workflows/smoke-test-yarn-classic.yml +++ b/.github/workflows/smoke-test-yarn-classic.yml @@ -5,7 +5,7 @@ jobs: chromatic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/.github/workflows/smoke-test-yarn.yml b/.github/workflows/smoke-test-yarn.yml index e0aaa67f6..9628472d4 100755 --- a/.github/workflows/smoke-test-yarn.yml +++ b/.github/workflows/smoke-test-yarn.yml @@ -5,7 +5,7 @@ jobs: self-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 diff --git a/README.md b/README.md index ca7db64f1..dde433d48 100644 --- a/README.md +++ b/README.md @@ -17,38 +17,6 @@ Publishes your Storybook to Chromatic and kicks off tests if they're enabled. 📝 View the [Changelog](https://github.com/chromaui/chromatic-cli/blob/main/CHANGELOG.md#readme) -## Using a `next` version - -From time to time we pre-publish a `next` version of the package to test new features. To use the -next branch you can either: - -### Using `npx` - -Change your script to use the `next` dist-tag: - -```bash -npx chromatic@next --project-token ... -``` - -### Using a dependency in `package.json` - -Update to the latest `next` version with: - -```bash -yarn add --dev chromatic@next - -# or -npm i --save-dev chromatic@next -``` - -### Using the github action - -Use our `chromatic-next` action: - -```yaml -- uses: chromaui/action-next@v1 -``` - ## Contributing Contributions of any kind are welcome! We're available to chat via the Intercom widget on the documentation site. @@ -58,7 +26,7 @@ Contributions of any kind are welcome! We're available to chat via the Intercom Compatibility is guaranteed between this package and Chromatic like so: - Production Chromatic ensures it’s compatible with what’s on npm -- What's on the main branch is equal to what's published on npm +- What's on the Git tag is equal to what's published on npm for that version - This package ensures it’s compatible with production Chromatic To facilitate upgrading in the future, removing and adding features, this is the process: @@ -76,7 +44,7 @@ To facilitate upgrading in the future, removing and adding features, this is the #### Running against staging ```bash -CHROMATIC_INDEX_URL=https://index.staging-chromatic.com yarn chromatic -t 253df72b53d2 +CHROMATIC_INDEX_URL=https://index.staging-chromatic.com yarn chromatic -t ``` #### Running against development @@ -93,41 +61,29 @@ To only test a small number of test stories as a smoke test, use: SMOKE_TEST=1 CHROMATIC_INDEX_URL=https://index.dev-chromatic.com yarn chromatic -t ``` -### Publishing a new version to npm +### Publishing a new version -Before publishing, make sure you've done the following: +We use `auto` to automate the release process. Versions are bumped, tags are created and the changelog is updated automatically. A new release goes out whenever a PR is merged to `main`. A PR **must** have **exactly one** of the following labels before merging: -- Updated CHANGELOG.md -- Committed and pushed everything (clean working directory) -- Decide on the proper semver bump (major/minor/patch) -- Decide on the proper tag (canary/next/latest) +- `major` triggers a major version bump +- `minor` triggers a minor version bump +- `patch` triggers a patch version bump -We have three types of releases: +Additionally, a PR **may** have exactly one of these labels: -- `canary` releases are intended for testing purposes and should not be used in production, as they may only work against a staging or dev environment. -- `next` releases should be valid, working releases that can potentially be used by early adopters of new features, for example to handle a support request. -- `latest` releases are the general audience production releases, used by most people. +- `release` creates a `latest` rather than a `next` release (see below) +- `skip-release` does not create a release at all -> For GitHub Actions, we publish `chromaui/action-canary` and `chromaui/action-next`, which contain the latest `canary` or `next` release, respectively. A `latest` release will also automatically update `chromaui/action-next` (besides `chromaui/action`), in order to keep users who happen to depend on `chromaui/action-next` up to date with the `latest` release. - -A script is provided to create new releases: - -```sh -yarn release [--dry-run] -``` - -This script ensures the version is bumped properly, the tag is set correctly and the corresponding GitHub Action is updated. +We have three types of releases: -#### Examples: +- `latest` releases are the general audience production releases, used by most people. Automatically created when merging a PR with the `release` label. +- `next` releases should be valid, working releases that can potentially be used by early adopters of new features, for example to handle a support request. Automatically created when merging a PR without the `release` and `skip-release` labels. +- `canary` releases are intended for testing purposes and should not be used in production, as they may only work against a staging or dev environment. Automatically created on every PR, but does not auto-publush the GitHub Action. -```sh -yarn release patch canary -``` +> For GitHub Actions, we publish `chromaui/action-next` and `chromaui/action-canary`. The latter is only published manually, rather than for every PR. -Releases e.g. `6.6.1-canary.0`. +A script is provided to manually publish the GitHub Action, though it's typically only necessary for `action-canary` releases: ```sh -yarn release major latest +yarn publish-action ``` - -Releases e.g. `7.0.0`. diff --git a/action.yml b/action.yml index aec2a081a..1f4e2bc7a 100755 --- a/action.yml +++ b/action.yml @@ -61,8 +61,8 @@ inputs: description: 'Deprecated, use onlyChanged, onlyStoryNames or onlyStoryFiles instead' required: false projectToken: - description: 'Your chromatic project token' - required: true + description: 'Your chromatic project token (best provided via env.CHROMATIC_PROJECT_TOKEN)' + required: false repositorySlug: description: 'Override the repository slug (e.g. ownerName/repositoryName)' required: false diff --git a/package.json b/package.json index 8e6e24ca0..c70e1461d 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "lint": "yarn lint:js .storybook bin-src node-src test-stories ./isChromatic.js ./isChromatic.mjs", "lint:js": "cross-env NODE_ENV=production eslint --fix --cache --cache-location=.cache/eslint --ext .js,.json,.mjs,.ts,.cjs --report-unused-disable-directives", "lint:package": "sort-package-json", - "release": "yarn run build && auto shipit", + "release": "yarn run build && auto shipit && yarn run publish-action", "publish-action": "./scripts/publish-action.mjs", "trace": "./dist/bin.js trace", "trim-stats": "./dist/bin.js trim-stats-file", @@ -108,7 +108,6 @@ "@actions/core": "^1.10.0", "@actions/github": "^5.0.0", "@antfu/ni": "^0.21.5", - "@auto-it/exec": "^11.0.4", "@babel/cli": "^7.14.8", "@babel/core": "^7.15.0", "@babel/node": "^7.15.4", diff --git a/scripts/publish-action.mjs b/scripts/publish-action.mjs index 8abdbce26..8e0a340d8 100755 --- a/scripts/publish-action.mjs +++ b/scripts/publish-action.mjs @@ -6,11 +6,10 @@ import tmp from 'tmp-promise'; const command = (cmd, opts) => execaCommand(cmd, { stdio: 'inherit', ...opts }); -const publishAction = async ({ context, newVersion, repo }) => { - console.info(`✅ Publishing ${newVersion} as ${context} action to https://github.com/${repo}`); +const publishAction = async ({ version, repo }) => { + const dryRun = process.argv.includes('--dry-run'); - const [major, minor, patch] = newVersion.replace(/^(\d+\.\d+\.\d+).*/, '$1').split('.'); - if (!major || !minor || !patch) throw new Error(`Invalid version: ${newVersion}`); + console.info(`✅ Publishing ${version} to ${repo} ${dryRun ? '(dry run)' : ''}`); const { path, cleanup } = await tmp.dir({ unsafeCleanup: true, prefix: `chromatic-action-` }); const run = (cmd) => command(cmd, { cwd: path }); @@ -21,14 +20,20 @@ const publishAction = async ({ context, newVersion, repo }) => { await cpy(['action-src/CHANGELOG.md', 'action-src/LICENSE', 'action-src/README.md'], path); await run('git init -b main'); - await run('git config --global user.name "Chromatic"'); - await run('git config --global user.email "support@chromatic.com"'); + await run('git config user.name "Chromatic"'); + await run('git config user.email "support@chromatic.com"'); await run(`git remote add origin https://${process.env.GH_TOKEN}@github.com/${repo}.git`); await run('git add .'); - await run(`git commit -m "${newVersion}"`); - await run('git tag -f v1'); - await run('git push origin HEAD:main --force'); - await run('git push --tags --force'); + await run(`git commit -m ${version}`); + await run('git tag -f v1'); // For backwards compatibility + await run('git tag -f latest'); + + if (dryRun) { + console.info('✅ Skipping git push due to --dry-run'); + } else { + await run('git push origin HEAD:main --force'); + await run('git push --tags --force'); + } return cleanup(); }; @@ -37,28 +42,47 @@ const publishAction = async ({ context, newVersion, repo }) => { * Generally, this script is invoked by auto's `afterShipIt` hook. * * For manual (local) use: - * yarn publish-action + * yarn publish-action [context] [--dry-run] * e.g. yarn publish-action canary + * or yarn publish-action --dry-run + * + * Make sure to build the action before publishing manually. */ (async () => { + const { stdout: status } = await execaCommand('git status --porcelain'); + if (status) { + console.error(`❗️ Working directory is not clean:\n${status}`); + return; + } + const { default: pkg } = await import('../package.json', { assert: { type: 'json' } }); - const { context, newVersion } = process.env.ARG_0 - ? JSON.parse(process.env.ARG_0) - : { newVersion: pkg.version, context: process.argv[2] }; + const [, major, minor, patch, tag] = pkg.version.match(/(\d+)\.(\d+)\.(\d+)-?(\w+)?/) || []; + if (!major || !minor || !patch) { + console.error(`❗️ Invalid version: ${pkg.version}`); + return; + } + + const context = ['canary', 'next', 'latest'].includes(process.argv[2]) + ? process.argv[2] + : tag || 'latest'; switch (context) { case 'canary': - await publishAction({ context, newVersion, repo: 'chromaui/action-canary' }); + if (process.argv[2] !== 'canary') { + console.info('Skipping automatic publish of action-canary.'); + console.info('Run `yarn publish-action canary` to publish a canary action.'); + return; + } + await publishAction({ version: pkg.version, repo: 'chromaui/action-canary' }); break; case 'next': - await publishAction({ context, newVersion, repo: 'chromaui/action-next' }); + await publishAction({ version: pkg.version, repo: 'chromaui/action-next' }); break; case 'latest': - await publishAction({ context, newVersion, repo: 'chromaui/action-next' }); - await publishAction({ context, newVersion, repo: 'chromaui/action' }); + await publishAction({ version: pkg.version, repo: 'chromaui/action' }); break; default: - console.warn(`Unknown context: ${context}`); + console.error(`❗️ Unknown tag: ${tag}`); } })(); diff --git a/yarn.lock b/yarn.lock index b6fafab01..39e81f5db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -97,18 +97,6 @@ typescript-memoize "^1.0.0-alpha.3" url-join "^4.0.0" -"@auto-it/exec@^11.0.4": - version "11.0.4" - resolved "https://registry.yarnpkg.com/@auto-it/exec/-/exec-11.0.4.tgz#97efbc9fbc14f2b777ef874c029a40fda8be7a3e" - integrity sha512-n/kB8k/dwci9UeTsLCs8mig8ZQuS2dMHcHlsKXBeM18EmcbGHxDxyaPeMHJsnSlfKNmGtCXhHBHBhGVP18Ia+w== - dependencies: - "@auto-it/core" "11.0.4" - endent "^2.1.0" - fp-ts "^2.5.3" - fromentries "^1.2.0" - io-ts "^2.1.2" - tslib "2.1.0" - "@auto-it/npm@11.0.4": version "11.0.4" resolved "https://registry.yarnpkg.com/@auto-it/npm/-/npm-11.0.4.tgz#67b6bf78fb6d3f814365796f15541b014db73fcb"