Manual Package Publish #99
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: Manual Package Publish | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version to publish (e.g., 1.0.0, patch, minor, major)" | |
| required: true | |
| default: "patch" | |
| type: string | |
| npm_tag: | |
| description: "NPM tag to publish with (e.g., latest, beta, alpha)" | |
| required: true | |
| default: "latest" | |
| type: string | |
| dry_run: | |
| description: "Run in dry-run mode (no actual publish)" | |
| required: false | |
| default: false | |
| type: boolean | |
| notify_skills_repo: | |
| description: "Notify the skills repo about the release" | |
| required: false | |
| default: true | |
| type: boolean | |
| env: | |
| CLI_PACKAGE_DIR: packages/cli | |
| # This workflow deliberately does NOT run the Wix gateway proxy: the gateway | |
| # cannot carry `npm publish` (it rejects `PUT /<package>`), so per secplatform's | |
| # interim policy for OSS repos this job relies on `--frozen-lockfile` plus | |
| # bunfig.toml's minimumReleaseAge instead. It resolves nothing, so dropping the | |
| # gateway does not widen what it can pull. Exemption lives in | |
| # .github/scripts/check_wix_proxy_steps.py. | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| # contents: write for the release commit, tag, and GitHub Release. | |
| # id-token: write for npm trusted publishing (OIDC). | |
| contents: write | |
| id-token: write | |
| steps: | |
| - name: Generate a token | |
| id: generate-token | |
| uses: actions/create-github-app-token@v2 | |
| with: | |
| app-id: ${{ vars.BASE44_GITHUB_ACTIONS_APP_ID }} | |
| private-key: ${{ secrets.BASE44_GITHUB_ACTIONS_APP_PRIVATE_KEY }} | |
| owner: base44 | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ steps.generate-token.outputs.token }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: ".node-version" | |
| registry-url: "https://registry.npmjs.org" | |
| # No `npm install -g npm@latest`: trusted publishing needs npm >= 11.5.1, and | |
| # the npm bundled with .node-version's Node 24 is already newer. | |
| - name: Setup Bun | |
| id: setup-bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ steps.setup-bun.outputs.bun-version }}-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun-${{ steps.setup-bun.outputs.bun-version }}- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Set version | |
| working-directory: ${{ env.CLI_PACKAGE_DIR }} | |
| # `npm version` takes both a keyword (patch/minor/major) and an explicit | |
| # version, so it replaces the old branch. It also replaces `bunx json-bump`, | |
| # which fetched an undeclared package at run time, outside the cooldown. | |
| run: | | |
| npm version "${{ github.event.inputs.version }}" --no-git-tag-version --no-workspaces | |
| echo "NEW_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV | |
| - name: Build package | |
| run: bun run build | |
| working-directory: ${{ env.CLI_PACKAGE_DIR }} | |
| - name: Build standalone binaries | |
| run: bun run build:binaries | |
| working-directory: ${{ env.CLI_PACKAGE_DIR }} | |
| - name: Package binaries for release | |
| run: bun run package:binaries | |
| working-directory: ${{ env.CLI_PACKAGE_DIR }} | |
| - name: Upload sourcemaps to PostHog | |
| if: github.event.inputs.dry_run == 'false' | |
| uses: PostHog/upload-source-maps@v0.4.6 | |
| with: | |
| directory: ./${{ env.CLI_PACKAGE_DIR }}/dist/cli | |
| env-id: ${{ vars.POSTHOG_PROJECT_ID }} | |
| cli-token: ${{ secrets.POSTHOG_CLI_API_KEY }} | |
| version: ${{ env.NEW_VERSION }} | |
| - name: Show package info | |
| working-directory: ${{ env.CLI_PACKAGE_DIR }} | |
| run: | | |
| echo "Package name: $(node -p "require('./package.json').name")" | |
| echo "Version: ${{ env.NEW_VERSION }}" | |
| echo "NPM tag: ${{ github.event.inputs.npm_tag }}" | |
| echo "Dry run: ${{ github.event.inputs.dry_run }}" | |
| - name: Publish to NPM | |
| # Authenticates via npm trusted publishing (OIDC), so no NPM_TOKEN reaches | |
| # the build. Needs a trusted publisher for `base44` on npmjs.com registered | |
| # against this repo and this workflow filename — the registry keys on the | |
| # filename, so each publish workflow needs its own entry. | |
| working-directory: ${{ env.CLI_PACKAGE_DIR }} | |
| run: | | |
| # Remove devDependencies before publish (everything is bundled) | |
| cp package.json package.json.bak | |
| jq 'del(.devDependencies)' package.json > package.json.tmp && mv package.json.tmp package.json | |
| npm publish --tag ${{ github.event.inputs.npm_tag }} ${{ github.event.inputs.dry_run == 'true' && '--dry-run' || '' }} | |
| mv package.json.bak package.json | |
| - name: Create Git tag | |
| if: github.event.inputs.dry_run == 'false' | |
| env: | |
| GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
| run: | | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" | |
| git add ${{ env.CLI_PACKAGE_DIR }}/package.json | |
| git commit -m "chore: release v${{ env.NEW_VERSION }}" | |
| git tag v${{ env.NEW_VERSION }} | |
| git push origin HEAD:${{ github.ref }} | |
| git push origin v${{ env.NEW_VERSION }} | |
| - name: Create GitHub Release and upload binaries | |
| if: github.event.inputs.dry_run == 'false' | |
| env: | |
| GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
| run: | | |
| RELEASE_URL=$(gh release create "v${{ env.NEW_VERSION }}" \ | |
| --title "Release v${{ env.NEW_VERSION }}" \ | |
| --notes "## Installation | |
| **npm:** | |
| \`\`\`bash | |
| npm install -g base44@${{ github.event.inputs.npm_tag }} | |
| \`\`\` | |
| **Homebrew:** | |
| \`\`\`bash | |
| brew install base44/tap/base44 | |
| \`\`\` | |
| **Version:** ${{ env.NEW_VERSION }} | |
| **NPM Tag:** ${{ github.event.inputs.npm_tag }}" \ | |
| ${{ env.CLI_PACKAGE_DIR }}/dist/binaries/base44-*.tar.gz) | |
| echo "RELEASE_URL=$RELEASE_URL" >> $GITHUB_ENV | |
| - name: Update Homebrew Tap | |
| if: github.event.inputs.dry_run == 'false' && github.event.inputs.npm_tag == 'latest' | |
| env: | |
| GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
| run: bash ${{ env.CLI_PACKAGE_DIR }}/infra/homebrew/update-tap.sh "${{ env.NEW_VERSION }}" "${{ env.CLI_PACKAGE_DIR }}/dist/binaries" | |
| - name: Notify skills repo | |
| if: github.event.inputs.dry_run == 'false' && github.event.inputs.notify_skills_repo == 'true' | |
| uses: peter-evans/repository-dispatch@v4 | |
| with: | |
| token: ${{ steps.generate-token.outputs.token }} | |
| repository: base44/skills | |
| event-type: cli-release | |
| client-payload: | | |
| { | |
| "version": "v${{ env.NEW_VERSION }}", | |
| "release_url": "${{ env.RELEASE_URL }}", | |
| "release_name": "Release v${{ env.NEW_VERSION }}" | |
| } |