Skip to content

Version Packages

Version Packages #9140

Workflow file for this run

name: Node CI
on:
workflow_dispatch:
pull_request:
# edited is needed because that's the trigger when the base branch is
# changed on a PR
# The rest are the defaults.
types: [edited, opened, synchronize, reopened]
# When a new revision is pushed to a PR, cancel all in-progress CI runs for that
# PR. See https://docs.github.com/en/actions/using-jobs/using-concurrency
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
changeset:
name: Check for .changeset entries for all changed files
if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Force Node version
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: yarn
- name: Get changed files
uses: Khan/actions@get-changed-files-v2
id: changed
- name: Filter out files that don't need a changeset
uses: Khan/actions@filter-files-v1
id: match
with:
changed-files: ${{ steps.changed.outputs.files }}
files: "packages/, config/build/" # Only look for changes in packages, build
globs: "!(**/__tests__/*), !(**/__testdata__/*), !(**/__stories__/*), !(**/dist/*), !(**/*.test.ts), !(**/*.test.tsx)" # Ignore test files
matchAllGlobs: true # Default is to match any of the globs, which ends up matching all files
conjunctive: true # Only match files that match all of the above
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.KHAN_ACTIONS_BOT_SSH_PRIVATE_KEY }}
- name: Verify changeset entries
uses: Khan/[email protected]
with:
changed_files: ${{ steps.match.outputs.filtered }}
lint:
name: Lint, Typecheck, Format, and Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- name: Checking out latest commit
uses: actions/checkout@v4
- name: Install & cache node_modules
uses: ./.github/actions/shared-node-cache
with:
node-version: ${{ matrix.node-version }}
- name: Get All Changed Files
uses: Khan/actions@get-changed-files-v2
id: changed
- name: Check formatting
run: |
yarn -s prettier --check .
- id: js-files
name: Find .js(x)/.ts(x) changed files
uses: Khan/actions@filter-files-v1
with:
changed-files: ${{ steps.changed.outputs.files }}
extensions: ".js,.jsx,.ts,.tsx"
files: "yarn.lock"
- id: eslint-reset
uses: Khan/actions@filter-files-v1
name: Files that would trigger a full eslint run
with:
changed-files: ${{ steps.changed.outputs.files }}
files: ".eslintrc.js,package.json,yarn.lock,.eslintignore"
# Linting / type checking
- name: Eslint
uses: Khan/actions@full-or-limited-v0
with:
full-trigger: ${{ steps.eslint-reset.outputs.filtered }}
full: yarn lint packages
limited-trigger: ${{ steps.js-files.outputs.filtered }}
limited: yarn lint {}
- name: Typecheck
if: (success() || failure()) && steps.js-files.outputs.filtered != '[]'
run: yarn typecheck
- name: Build types
if: (success() || failure()) && steps.js-files.outputs.filtered != '[]'
run: yarn build:types
# Run tests for our target matrix
- id: jest-reset
uses: Khan/actions@filter-files-v1
name: Files that would trigger a full jest run
with:
changed-files: ${{ steps.changed.outputs.files }}
files: "jest.config.js,package.json,yarn.lock,test.config.js,test.transform.js"
- name: Jest
uses: Khan/actions@full-or-limited-v0
with:
full-trigger: ${{ steps.jest-reset.outputs.filtered }}
full: yarn jest
limited-trigger: ${{ steps.js-files.outputs.filtered }}
limited: yarn jest --passWithNoTests --findRelatedTests {}
# We use STOPSHIP internally to mark code that's not safe to go live yet.
# We use an if block because we want to return the exact inverse of what
# `git grep` returns (0 on none found, 1 on some found).
- name: Checks that STOPSHIP is not used in any files.
run: ./utils/stopship-check.sh
cypress:
name: Cypress
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- name: Checking out latest commit
uses: actions/checkout@v4
- name: Install & cache node_modules
uses: ./.github/actions/shared-node-cache
with:
node-version: ${{ matrix.node-version }}
- name: Run tests
run: yarn cypress:ci
- name: Upload Screenshots
uses: actions/upload-artifact@v4
if: failure()
with:
name: cypress-screenshots
path: ./cypress/screenshots
check_builds:
name: Check builds for changes in size
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- name: Checking out latest commit
uses: actions/checkout@v4
- name: Install & cache node_modules
uses: ./.github/actions/shared-node-cache
with:
node-version: ${{ matrix.node-version }}
# Make sure our packages aren't growing unexpectedly
# This must come last as it builds the old code last and so leaves the
# wrong code in place for the next job; in other words, it leaves the repo on a base branch.
- name: Check Builds
uses: preactjs/compressed-size-action@v2
with:
# We only care about the ES module size, really:
pattern: "**/dist/es/*.js"
# Always ignore SourceMaps and node_modules:
exclude: "{**/*.map,**/node_modules/**}"
# Clean up before a build
clean-script: "clean"
# Build production
build-script: "build:prodsizecheck"
#
# Do not place any steps after "Check Builds"
#
publish_snapshot:
name: Publish npm snapshot
# We don't publish snapshots on Changeset "Version Packages" PRs
if: |
!startsWith(github.head_ref, 'changeset-release/')
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
# We need to checkout all history, so that the changeseat tool can diff it
- name: Checkout current commit
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Ensure main branch is available
run: |
REF=$(git rev-parse HEAD)
git checkout main
git checkout $REF
- name: Install & cache node_modules
uses: ./.github/actions/shared-node-cache
with:
node-version: ${{ matrix.node-version }}
- name: Publish Snapshot Release to npm
id: publish-snapshot
run: ./utils/publish-snapshot.sh # All config is via Github env vars
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Calculate short SHA for this commit
id: short-sha
# Why not GITHUB_SHA here? Because that is the last merge-commit
# for the PR (ie. the ephemeral commit that Github creates for
# each PR merging the base branch into the pull request HEAD) for
# Github Action runs). We want to reference the commit that was
# pushed, not this ephemeral commit.
run: echo "short_sha=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-8)" >> $GITHUB_OUTPUT
# Note: these two actions are locked to the latest version that were
# published when I created this yml file (just for security).
- name: Find existing comment
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: "github-actions[bot]"
body-includes: "npm Snapshot:"
- name: Create or update npm snapshot comment - success
if: steps.publish-snapshot.outputs.npm_snapshot_tag != ''
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find-comment.outputs.comment-id }}
edit-mode: replace
body: |
# npm Snapshot: Published
Good news!! We've packaged up the latest commit from this PR (${{
steps.short-sha.outputs.short_sha }}) and published it to npm. You
can install it using the tag `${{
steps.publish-snapshot.outputs.npm_snapshot_tag }}`.
Example:
```sh
yarn add @khanacademy/perseus@${{
steps.publish-snapshot.outputs.npm_snapshot_tag }}
```
If you are working in Khan Academy's webapp, you can run:
```sh
./dev/tools/bump_perseus_version.sh -t PR${{ github.event.pull_request.number }}
```
- name: Create or update npm snapshot comment - failure
if: steps.publish-snapshot.outputs.npm_snapshot_tag == ''
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find-comment.outputs.comment-id }}
edit-mode: replace
body: |
# npm Snapshot: **NOT** Published
Oh noes!! We couldn't find any changesets in this PR (${{
steps.short-sha.outputs.short_sha }}). As a result, we did not
publish an npm snapshot for you.