Skip to content
Draft
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
127 changes: 127 additions & 0 deletions .github/actions/prerelease-publish/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: PR prerelease npm publish
description: Checkout, setup, build publish targets, gamut-release, and sticky PR comment

inputs:
node-auth-token:
description: NPM token value (pass secrets.NODE_AUTH_TOKEN)
required: true
gh-token:
description: GitHub token for release tooling (pass secrets.ACTIONS_GITHUB_TOKEN)
required: true
ignore-commit-message:
description: Commit message prefix to skip (chore release commits)
required: true
manifest-path:
description: JSON manifest path written by gamut-release
required: true
comment-path:
description: Markdown file path for the PR comment body
required: true
comment-title:
description: Title line after the emoji (e.g. Published Alpha Packages)
required: true
sticky-header:
description: Sticky comment header key
required: true
publish-run:
description: Bash to set PREID and run gamut-release:pre-release
required: true

runs:
using: composite
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
filter: tree:0
ref: ${{ github.event.pull_request.head.ref }}

- name: Setup and Build
id: setup
uses: ./.github/actions/yarn

- name: Set git user
uses: ./.github/actions/set-git-user

- name: Set npm token
uses: ./.github/actions/set-npm-token
with:
token-secret: ${{ inputs.node-auth-token }}

- name: Ensure workflow is associated with a pull request
uses: ./.github/actions/validate-pr-context

- name: Skip build from automated commit
uses: ./.github/actions/skip-automated-commits
with:
ignore-commit-message: ${{ inputs.ignore-commit-message }}

- run: npx nx run-many --target=publish-build --parallel=3
shell: bash

- name: Publish prerelease packages
id: publish-prerelease
shell: bash
env:
GH_TOKEN: ${{ inputs.gh-token }}
NODE_AUTH_TOKEN: ${{ inputs.node-auth-token }}
run: |
${{ inputs.publish-run }}

- name: Build prerelease packages comment
id: build-comment
continue-on-error: true
uses: actions/github-script@v7
env:
MANIFEST_PATH: ${{ inputs.manifest-path }}
OUTPUT_PATH: ${{ inputs.comment-path }}
COMMENT_TITLE: ${{ inputs.comment-title }}
with:
script: |
const fs = require('fs');
const core = require('@actions/core');
const manifestPath = process.env.MANIFEST_PATH;
const outputPath = process.env.OUTPUT_PATH;
const commentTitle = process.env.COMMENT_TITLE;
if (!fs.existsSync(manifestPath)) {
fs.writeFileSync(outputPath, '');
core.setOutput('has_comment', 'false');
return;
}

const entries = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
if (!Array.isArray(entries) || entries.length === 0) {
fs.writeFileSync(outputPath, '');
core.setOutput('has_comment', 'false');
return;
}

const tableLines = [
'| Package | Version | npm | Diff |',
'| --- | --- | --- | --- |',
...entries.map((entry) => {
const pkgUrl = `https://www.npmjs.com/package/${entry.name}`;
const versionUrl = `${pkgUrl}/v/${entry.version}`;
const baseVersion = entry.previousVersion || null;
const diffUrl = baseVersion
? `https://npmdiff.dev/${encodeURIComponent(
entry.name
)}/${baseVersion}/${entry.version}/`
: null;
const npmLink = `[npm](${versionUrl})`;
const diffLink = diffUrl ? `[diff](${diffUrl})` : 'N/A';

return `| \`${entry.name}\` | \`${entry.version}\` | ${npmLink} | ${diffLink} |`;
}),
];
const comment = `📬 ${commentTitle}\n\n${tableLines.join('\n')}\n`;
fs.writeFileSync(outputPath, comment);
core.setOutput('has_comment', 'true');

- name: Comment with published packages
uses: ./.github/actions/sticky-comment
if: ${{ !cancelled() && steps.build-comment.outputs.has_comment == 'true' }}
with:
github-token: ${{ inputs.gh-token }}
header: ${{ inputs.sticky-header }}
message-path: ${{ inputs.comment-path }}
102 changes: 17 additions & 85 deletions .github/workflows/publish-alpha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,94 +17,26 @@ permissions:
issues: write
actions: write

concurrency:
group: npm-prerelease-${{ github.event.pull_request.number }}
cancel-in-progress: false

jobs:
publish-alpha:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'beta') }}
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}

- name: Setup and Build
id: setup
uses: ./.github/actions/yarn

- name: Set git user
uses: ./.github/actions/set-git-user

- name: Set npm token
uses: ./.github/actions/set-npm-token
with:
token-secret: ${{ secrets.NODE_AUTH_TOKEN }}

- name: Ensure workflow is associated with a pull request
uses: ./.github/actions/validate-pr-context

- name: Skip build from automated commit
uses: ./.github/actions/skip-automated-commits
- uses: ./.github/actions/prerelease-publish
with:
node-auth-token: ${{ secrets.NODE_AUTH_TOKEN }}
gh-token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }}

- run: npx nx run-many --target=publish-build --parallel=3

- name: Publish alpha packages
id: publish-alpha
run: |
SHORT_SHA=${GITHUB_SHA:0:6}
PREID="alpha.${SHORT_SHA}"
npx nx run gamut-release:alpha --preid="${PREID}" --manifest
env:
GH_TOKEN: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

- name: List alpha packages versions
id: published
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const manifestPath = 'alpha-publish-manifest.json';
const outputPath = 'alpha-publish-comment.md';
if (!fs.existsSync(manifestPath)) {
fs.writeFileSync(outputPath, '');
return;
}

const entries = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
if (!Array.isArray(entries) || entries.length === 0) {
fs.writeFileSync(outputPath, '');
return;
}

const tableLines = [
'| Package | Version | npm | Diff |',
'| --- | --- | --- | --- |',
...entries.map((entry) => {
const pkgUrl = `https://www.npmjs.com/package/${entry.name}`;
const versionUrl = `${pkgUrl}/v/${entry.version}`;
const baseVersion = entry.previousVersion || null;
const diffUrl = baseVersion
? `https://npmdiff.dev/${encodeURIComponent(
entry.name
)}/${baseVersion}/${entry.version}/`
: null;
const npmLink = `[npm](${versionUrl})`;
const diffLink = diffUrl ? `[diff](${diffUrl})` : 'N/A';

return `| \`${entry.name}\` | \`${entry.version}\` | ${npmLink} | ${diffLink} |`;
}),
];
const comment = `📬 Published Alpha Packages:\n\n${tableLines.join(
'\n'
)}\n`;
fs.writeFileSync(outputPath, comment);

- name: Comment with published alpha packages
uses: ./.github/actions/sticky-comment
if: ${{ !cancelled() && hashFiles('alpha-publish-comment.md') != '' }}
with:
github-token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
header: Alpha Packages
message-path: alpha-publish-comment.md
manifest-path: alpha-publish-manifest.json
comment-path: alpha-publish-comment.md
comment-title: Published Alpha Packages
sticky-header: Alpha Packages
publish-run: |
SHORT_SHA=${GITHUB_SHA:0:6}
PREID="alpha.${SHORT_SHA}"
npx nx run gamut-release:pre-release --preid="${PREID}" --manifest
43 changes: 43 additions & 0 deletions .github/workflows/publish-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Publish Beta

on:
pull_request:
types: [labeled]

env:
NODE_VERSION: '22.13.1'
NODE_OPTIONS: '--max_old_space_size=8196'
NX_CLOUD: false
IGNORE_COMMIT_MESSAGE: 'chore(release): publish'

permissions:
id-token: write
contents: read
pull-requests: write
issues: write
actions: write

concurrency:
group: npm-prerelease-${{ github.event.pull_request.number }}
cancel-in-progress: false

jobs:
publish-beta:
if: github.event.label.name == 'beta' && github.event.pull_request.head.ref == 'cass-gmt-1607-publish'
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/prerelease-publish
with:
node-auth-token: ${{ secrets.NODE_AUTH_TOKEN }}
gh-token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }}
manifest-path: beta-publish-manifest.json
comment-path: beta-publish-comment.md
comment-title: 'Published Beta Packages (install with `@beta`):'
sticky-header: Beta Packages
publish-run: |
PREID="beta.pr${{ github.event.pull_request.number }}.${{ github.run_id }}"
npx nx run gamut-release:pre-release --preid="${PREID}" --publish-tag=beta --manifest=beta-publish-manifest.json
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,21 @@ Add new Button variant and fix spacing issues
- It will create git tags and GitHub releases
1. You can find the new version number on npmjs.com/package/<package-name>, or find it in that package's `package.json` on the `main` branch

### Publishing an alpha version of a module
### Publishing an pre-release version of a module

Every PR that changes files in a package publishes alpha releases that you can use to test your changes across applications.
You can consume prerelease packages from npm before your PR merges. Two flows are available; **alpha** and **beta** are mutually exclusive on a PR.

**Alpha (default):** On each push to the PR branch, CI publishes alpha releases (per-commit prerelease versions on npm). This does **not** run while the PR has the **`beta`** label.

**Beta:** Add the **`beta`** label to the PR (create the label in the repo if it does not exist). That triggers a one-time publish to npm under the **`beta`** dist-tag (install with e.g. `yarn add @codecademy/gamut@beta`). Pushing new commits does **not** republish beta automatically; remove the **`beta`** label and add it again after your changes to trigger another publish.

> NOTE: in case an alpha build is not published upon opening of the PR or Draft PR, re-run the `build-test` check and that will re-run the alpha build publishing flows

1. Create a PR or Draft PR.
- This will kickoff a Github Action workflow which will publish an alpha build. (This will appear in Github as the "Deploy")
1. After the alpha build is published, the `codecademydev` bot should comment on your PR with the names of the published alpha packages. <br/>
- Without the **`beta`** label, each push kicks off the workflow that publishes an alpha build. (This will appear in Github as the "Deploy")
1. After packages are published, the `codecademydev` bot should comment on your PR with the names of the published packages (separate comments for alpha vs beta). <br/>
<img width="290" height="auto" src="https://user-images.githubusercontent.com/4298857/114948632-3fa88a80-9e04-11eb-89ef-d016a1c9c572.png">
1. Install this version of the package in your application you wish to test your changes on.
1. Install that version in the application where you want to test your changes (alpha by exact version from the table, or beta via `@beta` when using the beta flow).

### Working with pre-published changes

Expand Down
18 changes: 12 additions & 6 deletions tools/gamut-release/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
# Gamut Release

A CLI tool for publishing alpha versions of packages in the gamut repo using Nx release.
A CLI tool for publishing prerelease versions of packages in the gamut repo using Nx release.

Mainly meant to be run in CI.

## Overview

This tool automates the process of publishing alpha versions of packages in the gamut repo. This is mainly meant to be run in CI for pull requests, but can be run manually using the same Nx target.
This tool automates publishing alpha or beta prereleases of packages. It is run in CI on pull requests via the Nx target `gamut-release:pre-release`, which injects the required Node experimental flags.

CI is responsible for validating the presence of a version plan before running alpha publishes.
The Release Plan workflow (`release-plan-check.yml`) enforces version plans on PRs separately from these prerelease publishes.

## Usage

### Alpha Release
### Prerelease publish

```bash
npx nx run gamut-release:alpha --preid=alpha.abc123
npx nx run gamut-release:pre-release --preid=alpha.abc123
```

By default, the **npm dist-tag** is the same as `--preid`. To publish under a standard tag such as `beta` while using a unique semver prerelease id, pass **`--publish-tag`**:

```bash
npx nx run gamut-release:pre-release --preid=beta.pr123.456789 --publish-tag=beta
```

### Manifest output (optional)

```bash
npx nx run gamut-release:alpha --preid=alpha.abc123 --manifest[=path]
npx nx run gamut-release:pre-release --preid=alpha.abc123 --manifest[=path]
```
2 changes: 1 addition & 1 deletion tools/gamut-release/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"projectType": "library",
"tags": ["scope:nx"],
"targets": {
"alpha": {
"pre-release": {
"executor": "nx:run-commands",
"options": {
"commands": ["node tools/gamut-release/src/main.ts"],
Expand Down
Loading
Loading