Publish to NPM #1694
This file contains 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: | |
release_type: | |
type: choice | |
description: Release Type | |
options: | |
- prerelease | |
- prepatch | |
- preminor | |
- premajor | |
- patch | |
- minor | |
- major | |
required: true | |
default: prerelease | |
dry_run: | |
type: boolean | |
description: "(Optional) Dry run" | |
required: false | |
default: false | |
push: | |
branches: | |
- main | |
env: | |
RELEASE_TYPE: ${{ github.event.inputs.release_type }} | |
DRY_RUN: ${{ github.event.inputs.dry_run || 'false' }} | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.release_type }} | |
cancel-in-progress: false | |
jobs: | |
Publish: | |
name: Publish Workflow | |
runs-on: ubuntu-latest-4-cores | |
env: | |
GH_TOKEN: ${{ secrets.TS_IMMUTABLE_SDK_GITHUB_TOKEN }} | |
NODE_OPTIONS: --max-old-space-size=14366 | |
SDK_PUBLISH_SLACK_WEBHOOK: ${{ secrets.SDK_PUBLISH_SLACK_WEBHOOK }} | |
SDK_PUBLISH_MAJOR_VERSION_ACTORS: ${{ secrets.SDK_PUBLISH_MAJOR_VERSION_ACTORS }} | |
permissions: | |
id-token: write # ! Required for GitHub Attestations, removing will create a Sev 0 incident ! | |
attestations: write # ! Required for GitHub Attestations, removing will create a Sev 0 incident ! | |
steps: | |
- name: Check Public Release Branch | |
if: ${{ !startsWith(env.RELEASE_TYPE, 'pre') && github.ref != 'refs/heads/main' }} | |
run: | | |
echo "Public releases can only be executed from the main branch, current branch ${{ github.ref }}" | |
exit 1 | |
- name: Check User Permission | |
if: ${{ env.RELEASE_TYPE == 'major' }} | |
id: check_user_permission | |
uses: actions-cool/check-user-permission@v2 | |
with: | |
token: ${{ secrets.TS_IMMUTABLE_SDK_GITHUB_TOKEN }} | |
require: admin | |
username: ${{ github.triggering_actor }} | |
check-bot: true | |
- name: Log User Permission | |
if: ${{ env.RELEASE_TYPE == 'major' }} | |
run: | | |
echo "Check user permissions for triggering actor - ${{ github.triggering_actor }}" | |
echo "user-permission = ${{ steps.check_user_permission.outputs.user-permission }}" | |
echo "require-result = ${{ steps.check_user_permission.outputs.require-result }}" | |
- name: Major release Permission Check | |
if: ${{ env.RELEASE_TYPE == 'major' }} | |
run: | | |
if [[ ${{ steps.check_user_permission.outputs.require-result }} != 'true' || !${{ fromJson(env.SDK_PUBLISH_MAJOR_VERSION_ACTORS) }}.includes(${{ github.triggering_actor }}) ]]; then | |
echo "User does not have permission to perform a major release." | |
exit 1 | |
fi | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
token: ${{ secrets.TS_IMMUTABLE_SDK_GITHUB_TOKEN }} | |
- name: Setup | |
uses: ./.github/actions/setup | |
- name: Setup Github | |
run: | | |
git config user.name "platform-sa" | |
git config user.email "[email protected]" | |
- name: Initialize current versions | |
run: pnpm --filter @imtbl/sdk... --filter @imtbl/checkout-widgets... exec sh -c "jq --arg version \"$(npm view @imtbl/metrics versions --json | jq -r '.[-1]')\" '.version = \$version' package.json > package.tmp.json && mv package.tmp.json package.json" | |
- name: Setup new package versions | |
run: pnpm nx release version --specifier ${{ env.RELEASE_TYPE }} $( ${{ env.DRY_RUN }} && echo "--dry-run" || echo "") | |
- name: Build SDK & Checkout Widgets | |
run: pnpm build | |
# ! Do NOT remove - this will cause a Sev 0 incident ! | |
- name: Generate SDK attestations | |
uses: actions/attest-build-provenance@v1 | |
with: | |
subject-path: './sdk, !./sdk/node_modules' | |
- name: Generate version.json | |
if: (env.DRY_RUN) == 'false' | |
run: | | |
echo '{ "version": "$(jq -r '.version' ./sdk/package.json)" }' > ./sdk/version.json | |
cp ./sdk/version.json ./sdk/dist/ | |
- name: Publish Github Release | |
if: ${{ !startsWith(env.RELEASE_TYPE, 'pre') }} | |
run: pnpm nx release changelog $(jq -r '.version' ./sdk/package.json) $( ${{ env.DRY_RUN }} && echo "--dry-run" || echo "") | |
- name: Release to NPM | |
id: npm_release | |
env: | |
NODE_AUTH_TOKEN: ${{ secrets.TS_IMMUTABLE_SDK_NPM_TOKEN }} | |
NPM_CONFIG_PROVENANCE: true | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: pnpm nx release publish $( ${{ env.DRY_RUN }} && echo "--dry-run" || echo "") $( ${{ startsWith(env.RELEASE_TYPE, 'pre') }} && echo "--tag alpha" || echo "") | |
- name: Warm up CDN | |
id: warm_up_cdn | |
if: ${{ !startsWith(env.RELEASE_TYPE, 'pre') }} | |
run: | | |
wget https://cdn.jsdelivr.net/npm/@imtbl/checkout-widgets/dist/widgets.js | |
wget https://cdn.jsdelivr.net/npm/@imtbl/checkout-widgets/dist/index.js | |
# Wait for 30 seconds to make sure the tag is available on GitHub | |
- uses: GuillaumeFalourd/wait-sleep-action@v1 | |
with: | |
time: "30" | |
- name: Get GitHub Release Name and URL | |
if: contains(env.RELEASE_TYPE, 'release') && env.DRY_RUN == 'false' | |
id: release | |
run: | | |
echo "RELEASE_NAME=$(gh release view --json name | jq -r .name)" >> $GITHUB_OUTPUT | |
echo "RELEASE_URL=$(gh release view --json url | jq -r .url)" >> $GITHUB_OUTPUT | |
- name: Notify SDK Slack Publish Success | |
if: ${{ success() && (steps.npm_release.conclusion == 'success') && env.DRY_RUN == 'false' }} | |
uses: ./.github/actions/notify-slack-publish-status | |
with: | |
message: "✅ ${{ github.triggering_actor }} successfully published SDK packages @ version ${{steps.release.outputs.RELEASE_NAME}} to NPM.\n\nhttps://www.npmjs.com/package/@imtbl/sdk/v/${{steps.release.outputs.RELEASE_NAME}}" | |
- name: Notify SDK Slack Publish Failure | |
if: ${{ failure() && (steps.npm_release.conclusion == 'failure') && env.DRY_RUN == 'false' }} | |
uses: ./.github/actions/notify-slack-publish-status | |
with: | |
message: "❌ Failed to publish SDK version ${{steps.release.outputs.RELEASE_NAME}} to NPM. ${{ github.triggering_actor }} please check the logs for more details." | |
- name: Wait for NPM @latest Update | |
id: wait_for_npm_update | |
if: ${{ !startsWith(env.RELEASE_TYPE, 'pre') }} && env.DRY_RUN == 'false' | |
run: | | |
VERSION="$(jq -r '.version' ./sdk/package.json)" | |
echo "Waiting for NPM registry to reflect version: $VERSION" | |
for i in {1..20}; do | |
LATEST_VERSION=$(if [[ "${{ startsWith(env.RELEASE_TYPE, 'pre') }}" == "true" ]]; then npm view @imtbl/sdk@alpha version; else npm view @imtbl/sdk@latest version; fi) | |
if [[ "$LATEST_VERSION" == "$VERSION" ]]; then | |
echo "NPM registry updated to version: $LATEST_VERSION" | |
exit 0 | |
fi | |
echo "NPM registry not updated yet, retrying in 15 seconds..." | |
sleep 15 | |
done | |
echo "NPM registry failed to update after 5 minutes." | |
exit 1 | |
- name: Purge CDN Cache for version.json | |
id: purge_cdn | |
if: ${{ !startsWith(env.RELEASE_TYPE, 'pre') }} && env.DRY_RUN == 'false' | |
run: | | |
curl -X GET https://purge.jsdelivr.net/npm/@imtbl/sdk@latest/dist/version.json | |
echo "CDN cache purged for https://cdn.jsdelivr.net/npm/@imtbl/sdk@latest/dist/version.json" |