diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml new file mode 100644 index 00000000..ea06fe35 --- /dev/null +++ b/.github/actions/setup-bun/action.yml @@ -0,0 +1,29 @@ +name: Setup Bun +description: Install Bun, optionally restore dependency cache, and run bun install + +inputs: + cache: + description: > + Cache mode for Bun dependencies. + "none" skips caching, "restore" uses read-only cache restore, + "read-write" populates the cache after install. + default: "none" + +runs: + using: composite + steps: + - uses: oven-sh/setup-bun@v2 + - uses: actions/cache@v5 + if: inputs.cache == 'read-write' + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }} + restore-keys: bun-${{ runner.os }}- + - uses: actions/cache/restore@v5 + if: inputs.cache == 'restore' + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }} + restore-keys: bun-${{ runner.os }}- + - run: bun install --frozen-lockfile + shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8afd3698..de8dee34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,16 @@ name: CI on: pull_request: branches: [main] + workflow_call: + inputs: + ref: + type: string + default: "" + description: Git ref to checkout. Leave empty for default checkout behavior. + run-e2e: + type: boolean + default: true + description: Whether to run E2E tests concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -18,6 +28,8 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref }} - uses: oven-sh/setup-bun@v2 - uses: actions/cache@v5 with: @@ -34,6 +46,8 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref }} - uses: oven-sh/setup-bun@v2 - uses: actions/cache/restore@v5 with: @@ -52,6 +66,8 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref }} - uses: oven-sh/setup-bun@v2 - uses: actions/cache/restore@v5 with: @@ -65,12 +81,14 @@ jobs: test-e2e: name: E2E Test needs: [build] - # Prevent fork PRs from running E2E tests and using this repo's secrets. - # Also skip Dependabot PRs: Dependabot cannot access Actions secrets, so - # CLERK_CLI_TEST_APP_ID would be empty and the run would fail anyway. + # For workflow_call: respect the run-e2e input. + # For pull_request: skip fork PRs (no access to secrets) and Dependabot PRs + # (cannot access Actions secrets, so CLERK_CLI_TEST_APP_ID would be empty). if: >- - github.event.pull_request.head.repo.full_name == github.repository && - github.actor != 'dependabot[bot]' + (github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository && + github.actor != 'dependabot[bot]') || + (github.event_name != 'pull_request' && inputs.run-e2e) runs-on: blacksmith-8vcpu-ubuntu-2404 container: image: mcr.microsoft.com/playwright:v1.59.1-noble @@ -88,6 +106,8 @@ jobs: grep -v '::1.*localhost' /etc/hosts > /tmp/hosts.new cat /tmp/hosts.new > /etc/hosts - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref }} - uses: actions/setup-node@v6 with: node-version: 22 diff --git a/.github/workflows/notify-failure.yml b/.github/workflows/notify-failure.yml index d9889104..a765e5e3 100644 --- a/.github/workflows/notify-failure.yml +++ b/.github/workflows/notify-failure.yml @@ -20,8 +20,7 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v6 - - uses: oven-sh/setup-bun@v2 - - run: bun install --frozen-lockfile + - uses: ./.github/actions/setup-bun - name: Notify Slack run: bun scripts/slack.ts --status failure env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fdc9a551..245818b3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,13 @@ jobs: # Push to main → stable or canary release # ═══════════════════════════════════════════════════════════════════════ + ci: + if: github.event_name == 'push' + uses: ./.github/workflows/ci.yml + secrets: inherit + versioning: + needs: [ci] if: github.event_name == 'push' runs-on: blacksmith-2vcpu-ubuntu-2404 timeout-minutes: 5 @@ -30,8 +36,9 @@ jobs: version: ${{ steps.check.outputs.version }} steps: - uses: actions/checkout@v6 - - uses: oven-sh/setup-bun@v2 - - run: bun install --frozen-lockfile + - uses: ./.github/actions/setup-bun + with: + cache: restore - name: Check if release needed id: check @@ -160,7 +167,7 @@ jobs: if: >- always() && contains(needs.*.result, 'failure') - needs: [versioning, build, sign-macos, smoke-test, publish-npm, publish-github, homebrew] + needs: [ci, versioning, build, sign-macos, smoke-test, publish-npm, publish-github, homebrew] uses: ./.github/workflows/notify-failure.yml with: workflow-name: Stable release @@ -178,8 +185,9 @@ jobs: version: ${{ steps.version.outputs.version }} steps: - uses: actions/checkout@v6 - - uses: oven-sh/setup-bun@v2 - - run: bun install --frozen-lockfile + - uses: ./.github/actions/setup-bun + with: + cache: restore - name: Version packages for canary id: version @@ -298,6 +306,7 @@ jobs: contains(needs.*.result, 'failure') needs: [ + ci, canary-version, canary-build, canary-sign-macos, @@ -378,9 +387,17 @@ jobs: version=$(jq -r '.version' packages/cli/package.json) echo "version=${version}" >> "$GITHUB_OUTPUT" - snapshot-build: + snapshot-ci: needs: snapshot if: needs.snapshot.outputs.is_fork != 'true' + uses: ./.github/workflows/ci.yml + with: + ref: ${{ needs.snapshot.outputs.sha }} + secrets: inherit + + snapshot-build: + needs: [snapshot, snapshot-ci] + if: needs.snapshot.outputs.is_fork != 'true' uses: ./.github/workflows/build-binaries.yml with: version: ${{ needs.snapshot.outputs.version }} @@ -483,7 +500,7 @@ jobs: snapshot-notify-failure: needs: - [snapshot, snapshot-build, snapshot-sign-macos, snapshot-smoke-test, snapshot-publish] + [snapshot, snapshot-ci, snapshot-build, snapshot-sign-macos, snapshot-smoke-test, snapshot-publish] if: >- always() && contains(needs.*.result, 'failure')