diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b4a285..4e0efb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,9 @@ name: CI on: - push: - branches: [main] pull_request: workflow_dispatch: + workflow_call: permissions: contents: read diff --git a/.github/workflows/release-gate.yml b/.github/workflows/release-gate.yml index 7c00d57..41a71c8 100644 --- a/.github/workflows/release-gate.yml +++ b/.github/workflows/release-gate.yml @@ -12,6 +12,9 @@ concurrency: cancel-in-progress: false jobs: + ci: + uses: ./.github/workflows/ci.yml + plan: name: plan · mutation shards runs-on: ubuntu-latest @@ -33,7 +36,6 @@ jobs: mutation: name: mutation · ${{ matrix.package }} needs: [plan] - if: ${{ needs.plan.outputs.packages != '[]' }} runs-on: ubuntu-latest timeout-minutes: 75 strategy: @@ -68,8 +70,8 @@ jobs: deploy: name: deploy · production - needs: [plan, mutation] - if: ${{ !cancelled() && needs.plan.result == 'success' && (needs.mutation.result == 'success' || needs.mutation.result == 'skipped') && !github.event.repository.is_template }} + needs: [ci, plan, mutation] + if: ${{ !github.event.repository.is_template }} runs-on: ubuntu-latest timeout-minutes: 45 env: diff --git a/scripts/mutation-shards.test.ts b/scripts/mutation-shards.test.ts index bf97051..3770ecf 100644 --- a/scripts/mutation-shards.test.ts +++ b/scripts/mutation-shards.test.ts @@ -68,12 +68,16 @@ Deno.test('a mutation script without declared mutate globs is refused', async () }) }) -Deno.test('a workspace without a single *.workflow.ts file has no decisions to mutate', async () => { +Deno.test('a workspace without a single *.workflow.ts file is refused as an empty set', async () => { const root = await workspaceOf([ { name: 'site', mutate: ['src/**/*.workflow.ts'], files: ['src/page.tsx'] }, { name: 'tools', mutation: false, files: ['src/cli.ts'] }, ]) - assertEquals(await planMutationShards(root), { packages: [], refusals: [], decisions: 0 }) + assertEquals(await planMutationShards(root), { + packages: [], + refusals: ['no workspace package has a *.workflow.ts file; the release gate refuses an empty set'], + decisions: 0, + }) }) Deno.test('decisions that no package mutates are refused as an empty set', async () => { diff --git a/scripts/mutation-shards.ts b/scripts/mutation-shards.ts index bda3043..a3531ac 100755 --- a/scripts/mutation-shards.ts +++ b/scripts/mutation-shards.ts @@ -42,7 +42,13 @@ export const planMutationShards = async (root: string): Promise => { } } } - if (decisions === 0) return { packages: [], refusals: [], decisions } + if (decisions === 0) { + return { + packages: [], + refusals: ['no workspace package has a *.workflow.ts file; the release gate refuses an empty set'], + decisions, + } + } if (packages.length === 0 && refusals.length === 0) { refusals.push( `${decisions} *.workflow.ts file(s) but no workspace package declares a \`mutation\` script; the release gate refuses an empty set`, @@ -58,9 +64,6 @@ if (import.meta.main) { for (const refusal of plan.refusals) console.error(`mutation-shards: ${refusal}`) Deno.exit(1) } - if (plan.decisions === 0) { - console.log('::notice title=Release gate::No decisions to mutate: no workspace package has a *.workflow.ts file.') - } const line = `packages=${JSON.stringify(plan.packages)}` console.error(`mutation-shards: ${line}`) if (output) await Deno.writeTextFile(output, `${line}\n`, { append: true })