Publish to npm #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish to npm | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| npm_tag: | |
| description: npm dist-tag to publish | |
| required: true | |
| default: next | |
| type: choice | |
| options: | |
| - next | |
| - beta | |
| - latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify release branch | |
| run: | | |
| if [ "${GITHUB_REF_NAME}" != "next" ]; then | |
| echo "This workflow publishes the rebuild package and must be run from the next branch." | |
| exit 1 | |
| fi | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Node | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - name: Verify npm publish access | |
| run: | | |
| if [ -z "${NODE_AUTH_TOKEN:-}" ]; then | |
| echo "NPM_TOKEN is not configured for this repository or environment." | |
| echo "Add a GitHub Actions secret named NPM_TOKEN with npm publish access before rerunning." | |
| exit 1 | |
| fi | |
| if ! NPM_USER=$(npm whoami 2>&1); then | |
| echo "NPM_TOKEN could not authenticate with npm." | |
| echo "${NPM_USER}" | |
| exit 1 | |
| fi | |
| echo "Authenticated to npm as ${NPM_USER}." | |
| if ! npm access list packages @chart-kit --json >/dev/null; then | |
| echo "NPM_TOKEN cannot access the @chart-kit npm scope." | |
| echo "Create or claim the @chart-kit scope and grant this token publish rights before rerunning." | |
| exit 1 | |
| fi | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Install dependencies | |
| run: npm install --ignore-scripts | |
| - name: Install Playwright browsers | |
| run: npx playwright install --with-deps chromium | |
| - name: Build | |
| run: npm run build | |
| - name: Typecheck | |
| run: npm run typecheck | |
| - name: Test | |
| run: npm run test | |
| - name: E2E | |
| run: npm run test:e2e | |
| - name: Surface | |
| run: npm run surface:check | |
| - name: Package pack check | |
| run: npm run pack:check | |
| - name: Docs | |
| run: npm run docs:build | |
| - name: React Native CLI example | |
| run: npm run example:rn-cli:typecheck | |
| - name: Verify package publish state | |
| id: package | |
| run: | | |
| PACKAGE_NAME=$(node -p "require('./package.json').name") | |
| PACKAGE_VERSION=$(node -p "require('./package.json').version") | |
| NPM_TAG="${{ inputs.npm_tag }}" | |
| TAG_NAME="v${PACKAGE_VERSION}" | |
| echo "name=${PACKAGE_NAME}" >> "$GITHUB_OUTPUT" | |
| echo "version=${PACKAGE_VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "npm_tag=${NPM_TAG}" >> "$GITHUB_OUTPUT" | |
| echo "tag=${TAG_NAME}" >> "$GITHUB_OUTPUT" | |
| if [ "${NPM_TAG}" = "latest" ] && [[ "${PACKAGE_VERSION}" == *-* ]]; then | |
| echo "Refusing to publish prerelease version ${PACKAGE_VERSION} with npm dist-tag latest" | |
| exit 1 | |
| fi | |
| for PACKAGE_DIR in $(node scripts/list-release-packages.mjs --publishable); do | |
| PACKAGE_JSON="${PACKAGE_DIR}/package.json" | |
| if [ "${PACKAGE_DIR}" = "." ]; then | |
| PACKAGE_JSON="package.json" | |
| fi | |
| WORKSPACE_NAME=$(node -p "require('./${PACKAGE_JSON}').name") | |
| WORKSPACE_VERSION=$(node -p "require('./${PACKAGE_JSON}').version") | |
| if npm view "${WORKSPACE_NAME}@${WORKSPACE_VERSION}" version >/dev/null 2>&1; then | |
| echo "${WORKSPACE_NAME}@${WORKSPACE_VERSION} is already published and will be skipped" | |
| fi | |
| done | |
| if git ls-remote --exit-code --tags origin "refs/tags/${TAG_NAME}" >/dev/null 2>&1; then | |
| echo "${TAG_NAME} already exists" | |
| exit 1 | |
| fi | |
| - name: Publish | |
| run: | | |
| for PACKAGE_DIR in $(node scripts/list-release-packages.mjs --publishable); do | |
| PACKAGE_JSON="${PACKAGE_DIR}/package.json" | |
| PUBLISH_TARGET="./${PACKAGE_DIR}" | |
| if [ "${PACKAGE_DIR}" = "." ]; then | |
| PACKAGE_JSON="package.json" | |
| PUBLISH_TARGET="." | |
| fi | |
| WORKSPACE_NAME=$(node -p "require('./${PACKAGE_JSON}').name") | |
| WORKSPACE_VERSION=$(node -p "require('./${PACKAGE_JSON}').version") | |
| if npm view "${WORKSPACE_NAME}@${WORKSPACE_VERSION}" version >/dev/null 2>&1; then | |
| echo "Skipping ${WORKSPACE_NAME}@${WORKSPACE_VERSION}; already published" | |
| continue | |
| fi | |
| npm publish "${PUBLISH_TARGET}" --ignore-scripts --access public --provenance --tag "${NPM_TAG}" | |
| done | |
| env: | |
| NPM_TAG: ${{ steps.package.outputs.npm_tag }} | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Verify npm registry publish state | |
| run: npm run release:publish:status -- --strict | |
| - name: Create GitHub release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PACKAGE_NAME: ${{ steps.package.outputs.name }} | |
| PACKAGE_VERSION: ${{ steps.package.outputs.version }} | |
| TAG_NAME: ${{ steps.package.outputs.tag }} | |
| run: | | |
| awk "/^## v${PACKAGE_VERSION}$/{flag=1; next} /^## /{flag=0} flag" CHANGELOG.md > release-notes.md | |
| if [ ! -s release-notes.md ]; then | |
| echo "Published ${PACKAGE_NAME}@${PACKAGE_VERSION} to npm." > release-notes.md | |
| fi | |
| if [[ "${PACKAGE_VERSION}" == *-* ]]; then | |
| gh release create "${TAG_NAME}" \ | |
| --target "${GITHUB_SHA}" \ | |
| --title "${TAG_NAME}" \ | |
| --notes-file release-notes.md \ | |
| --prerelease | |
| else | |
| gh release create "${TAG_NAME}" \ | |
| --target "${GITHUB_SHA}" \ | |
| --title "${TAG_NAME}" \ | |
| --notes-file release-notes.md | |
| fi |