mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
ci: skip checks for draft pull requests [skip ci] (#29484)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
@@ -18,8 +18,8 @@ export function verifyRequiredPrContext(parseYaml) {
|
||||
}
|
||||
const gate = providers[0].job
|
||||
const condition = gate.if?.replace(/^\$\{\{\s*|\s*\}\}$/g, '').trim()
|
||||
if (condition !== '!cancelled()') {
|
||||
throw new Error('Required PR aggregate must run unless the workflow is cancelled.')
|
||||
if (condition !== '!cancelled() && github.event.pull_request.draft != true') {
|
||||
throw new Error('Required PR aggregate must run unless cancelled or the PR is a draft.')
|
||||
}
|
||||
if (gate['continue-on-error'] || gate.steps?.some((step) => step['continue-on-error'])) {
|
||||
throw new Error('Required PR aggregate must not ignore failures.')
|
||||
|
||||
@@ -45,6 +45,7 @@ on:
|
||||
- 'config/scripts/windows-rust-executable-build.mjs'
|
||||
- 'resources/build/icon.ico'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- '.github/workflows/ci-cache-warmup-platforms.yml'
|
||||
- '.github/workflows/ci-cache-warmup-platform-jobs.yml'
|
||||
@@ -58,4 +59,5 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
warm-platforms:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
uses: ./.github/workflows/ci-cache-warmup-platform-jobs.yml
|
||||
|
||||
@@ -48,6 +48,7 @@ on:
|
||||
- 'native/windows-registry/**'
|
||||
- 'native/windows-security/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- '.github/workflows/ci-cache-warmup.yml'
|
||||
- '.github/actions/prepare-headless-compiler/**'
|
||||
@@ -63,6 +64,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
warm:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
concurrency:
|
||||
group: ci-cache-warmup-linux-x64-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name != 'schedule' }}
|
||||
|
||||
@@ -2,6 +2,7 @@ name: pnpm verification cache pilot
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths: ['.github/workflows/ci-pnpm-verification-pilot.yml']
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -17,6 +18,7 @@ env:
|
||||
|
||||
jobs:
|
||||
seed:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||
|
||||
@@ -2,6 +2,7 @@ name: Cloud Verify
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- cloud/**
|
||||
- src/packages/process-host/**
|
||||
@@ -29,6 +30,7 @@ defaults:
|
||||
jobs:
|
||||
# Public-repository hosted runners preserve Blacksmith allowance for macOS.
|
||||
security:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
name: Secret scan
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@@ -79,6 +81,7 @@ jobs:
|
||||
# Compiles the workspace. No Postgres service: nothing here reaches a
|
||||
# database, and the service container costs ~13s of startup.
|
||||
build:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -99,6 +102,7 @@ jobs:
|
||||
# packages it needs through pretest hooks, so it does not depend on
|
||||
# `pnpm build` having run.
|
||||
test:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-22.04
|
||||
services:
|
||||
postgres:
|
||||
@@ -135,6 +139,7 @@ jobs:
|
||||
# Fork pull requests reach this job, so it never configures a backend, never plans, and never
|
||||
# holds a credential. Only the relay root ships here; foundation and apps stay private.
|
||||
terraform:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -2,6 +2,7 @@ name: Computer-use e2e
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- '.github/workflows/computer-e2e.yml'
|
||||
- 'config/electron-builder.config.cjs'
|
||||
@@ -65,7 +66,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
native-smoke:
|
||||
if: github.event_name == 'pull_request'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.draft != true
|
||||
permissions:
|
||||
contents: read
|
||||
strategy:
|
||||
@@ -141,6 +142,7 @@ jobs:
|
||||
# Hosted macOS runners cannot receive persistent Accessibility/Screen Recording
|
||||
# grants. Keep the real native build/owner-loss checks on every trigger instead.
|
||||
mac-native-owner-smoke:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: macos-15
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -6,6 +6,7 @@ on:
|
||||
release:
|
||||
types: [published]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'docs/site/**'
|
||||
- '.github/workflows/docs.yml'
|
||||
@@ -36,7 +37,7 @@ jobs:
|
||||
# including forks.
|
||||
check:
|
||||
name: Build and test
|
||||
if: github.event_name == 'pull_request'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Git command termination runtime
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/git/command-runner/spawned-command-tree-kill*'
|
||||
- '.github/workflows/git-command-termination-runtime.yml'
|
||||
@@ -12,6 +13,7 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
jobs:
|
||||
windows-exit:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
|
||||
@@ -2,6 +2,7 @@ name: macOS updater regression tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- '.github/workflows/macos-updater-tests.yml'
|
||||
- 'src/main/macos-update-running-instances*'
|
||||
@@ -24,6 +25,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
updater:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: macos-15
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
|
||||
@@ -6,6 +6,8 @@ on:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
- converted_to_draft
|
||||
paths:
|
||||
- 'mobile/**'
|
||||
# Why all of src/shared: mobile imports hundreds of its modules, directly and through the RPC
|
||||
@@ -94,7 +96,7 @@ concurrency:
|
||||
jobs:
|
||||
verify:
|
||||
name: Mobile verify
|
||||
if: github.event_name == 'pull_request'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.draft != true
|
||||
# Why ARM: 209s of this job is Vitest and nothing here needs x86: no Android SDK, emulator, gradle,
|
||||
# Hermes or Watchman, no docker, and no artifacts. The Gemfile.lock lists the generic `ruby`
|
||||
# platform, so frozen bundler installs without an aarch64-linux entry.
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Headless Node server
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'config/**'
|
||||
|
||||
@@ -5,6 +5,7 @@ on:
|
||||
- cron: '15 9 * * *'
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- '.github/workflows/performance-contracts.yml'
|
||||
- 'config/vitest.performance.config.ts'
|
||||
@@ -40,6 +41,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
contracts:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Pi owner runtime verification
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/pi/**'
|
||||
- '!src/main/pi/**/*.test.ts'
|
||||
@@ -15,6 +16,7 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
jobs:
|
||||
runtime:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Pi extension provider verification
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/shared/commit-message-agent-specs-primary.ts'
|
||||
- 'tests/tools/pi-provider-runtime-smoke.mjs'
|
||||
@@ -12,6 +13,7 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
jobs:
|
||||
runtime:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -8,6 +8,7 @@ on:
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
- converted_to_draft
|
||||
|
||||
concurrency:
|
||||
group: pr-checks-${{ github.event.pull_request.number }}
|
||||
@@ -24,6 +25,7 @@ jobs:
|
||||
# Per-job outputs also skip git-compat/xterm/packaging/shell when those
|
||||
# inputs are unchanged; empty diffs fail closed and run everything.
|
||||
code_paths:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
name: detect changes and check repository guards
|
||||
# Start routing without waiting behind the GitHub-hosted test queue.
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
@@ -1515,7 +1517,7 @@ jobs:
|
||||
verify:
|
||||
name: PR checks passed
|
||||
# Publish an explicit result after every required dependency settles.
|
||||
if: ${{ !cancelled() }}
|
||||
if: ${{ !cancelled() && github.event.pull_request.draft != true }}
|
||||
needs:
|
||||
- code_paths
|
||||
- preflight
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Preflight comparison
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- .github/workflows/preflight-benchmark.yml
|
||||
- config/scripts/benchmark-preflight-*.mjs
|
||||
@@ -15,6 +16,7 @@ env:
|
||||
ORCA_BACKGROUND_LAUNCH: '1'
|
||||
jobs:
|
||||
compilers:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
@@ -37,6 +39,7 @@ jobs:
|
||||
path: .build/preflight-benchmark/
|
||||
retention-days: 30
|
||||
static-analysis:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
@@ -59,6 +62,7 @@ jobs:
|
||||
path: .build/preflight-benchmark/
|
||||
retention-days: 30
|
||||
compatibility-imports:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
@@ -82,6 +86,7 @@ jobs:
|
||||
path: .build/preflight-benchmark/
|
||||
retention-days: 30
|
||||
localization-extraction:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 12
|
||||
steps:
|
||||
|
||||
@@ -2,6 +2,7 @@ name: Preflight CLI platforms
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/ipc/preflight*'
|
||||
- 'src/main/ipc/agent-detection-shell-path.ts'
|
||||
@@ -22,6 +23,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
preflight:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
name: Preflight CLI (${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Preflight critical-path comparison
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- .github/workflows/preflight-critical-path-benchmark.yml
|
||||
- config/scripts/benchmark-ci-preflight-critical-path.mjs
|
||||
@@ -14,6 +15,7 @@ env:
|
||||
ORCA_BACKGROUND_LAUNCH: '1'
|
||||
jobs:
|
||||
compare:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
|
||||
@@ -2,6 +2,7 @@ name: Release JavaScript comparison
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths: ['.github/workflows/release-javascript-benchmark.yml']
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -20,6 +21,7 @@ env:
|
||||
|
||||
jobs:
|
||||
bundle:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
uses: ./.github/workflows/release-javascript.yml
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
|
||||
@@ -2,6 +2,7 @@ name: Release ref validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- '.github/workflows/adhoc-mac-build.yml'
|
||||
- '.github/workflows/dev-channel-win-build.yml'
|
||||
@@ -19,6 +20,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -6,6 +6,7 @@ name: Skill update round trip
|
||||
# run marks the default-branch tip failed, so the repo shows a red X.
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths: &skill-roundtrip-paths
|
||||
- 'skills/**'
|
||||
- 'resources/skills/**'
|
||||
@@ -28,6 +29,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
roundtrip:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -7,7 +7,7 @@ name: SSH hostile hosts
|
||||
# or the slot build changes, and on demand.
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
# The managed deploy still runs on these relay-named install and runtime primitives.
|
||||
- 'src/main/ssh/ssh-relay-*'
|
||||
|
||||
@@ -6,7 +6,7 @@ name: SSH Windows hosts
|
||||
# sessions behind logging shims, and deploys orcad on the pinned node.exe in both DefaultShell cases.
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/ssh/ssh-relay-*'
|
||||
- 'src/main/ssh/*runtime*'
|
||||
|
||||
@@ -8,7 +8,7 @@ name: Windows packaged orcad serve switch E2E
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/daemon/**'
|
||||
- '!src/main/daemon/**/*.test.ts'
|
||||
|
||||
@@ -2,6 +2,7 @@ name: Windows typecheck parity
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
@@ -25,6 +26,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
parity:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
name: Windows compiler diagnostics and file selection
|
||||
runs-on: windows-2022
|
||||
timeout-minutes: 40
|
||||
|
||||
@@ -7,6 +7,7 @@ name: WSL orcad E2E
|
||||
# Hosted WSL2 was proven in #27783: WSL 2.7.14, import 13-18 s, cold boot 8-14 s.
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/wsl/**'
|
||||
- '!src/main/wsl/**/*.test.ts'
|
||||
@@ -38,6 +39,7 @@ env:
|
||||
jobs:
|
||||
# The distro is linux-x64-glibc; its node-pty slot only builds on Linux, and nothing else is needed.
|
||||
template:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
name: Build the linux-x64-glibc orcad template
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Coding Plan credential contract
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/zcode/**'
|
||||
- 'src/shared/node-bounded-file-reader*'
|
||||
@@ -25,6 +26,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
credential-files:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
name: ZCode credentials (${{ matrix.os }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: ZCode transcript contract
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||
paths:
|
||||
- 'src/main/ai-vault/session-scanner-zcode*'
|
||||
- 'src/main/ai-vault/session-scanner-opencode*'
|
||||
@@ -18,6 +19,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
transcript-readers:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { readFileSync, readdirSync } from 'node:fs'
|
||||
import { expect, it } from 'vitest'
|
||||
import { parse } from 'yaml'
|
||||
import { compileAggregateExpression } from './pr-aggregate-gate-context.mjs'
|
||||
|
||||
const workflows = readdirSync('.github/workflows').flatMap((file) => {
|
||||
const workflow = parse(readFileSync(`.github/workflows/${file}`, 'utf8'))
|
||||
// The LoC reporter updates PR metadata rather than running CI.
|
||||
return Object.hasOwn(workflow.on ?? {}, 'pull_request') && file !== 'pr-test-loc.yml'
|
||||
? [{ file, workflow }]
|
||||
: []
|
||||
})
|
||||
|
||||
function admitted(condition, draft, needs = {}, eventName = 'pull_request') {
|
||||
return (
|
||||
compileAggregateExpression(condition ?? 'true', ['github', 'needs', 'inputs'])({
|
||||
github: {
|
||||
event_name: eventName,
|
||||
repository: 'stablyai/orca',
|
||||
event: { pull_request: { draft } }
|
||||
},
|
||||
needs,
|
||||
inputs: {}
|
||||
}).coerceString() === 'true'
|
||||
)
|
||||
}
|
||||
|
||||
it.each(workflows)('$file starts no CI jobs for a draft PR', ({ workflow }) => {
|
||||
const needs = Object.fromEntries(
|
||||
Object.keys(workflow.jobs).map((id) => [id, { result: 'skipped', outputs: {} }])
|
||||
)
|
||||
for (const [id, job] of Object.entries(workflow.jobs)) {
|
||||
// Jobs without a status function inherit success(), so skipped parents block them.
|
||||
if (job.needs && !/\b(?:cancelled|always|success|failure)\(/.test(job.if ?? '')) {
|
||||
continue
|
||||
}
|
||||
expect(admitted(job.if, true, needs), id).toBe(false)
|
||||
}
|
||||
})
|
||||
|
||||
it.each(workflows)('$file starts CI when ready and cancels it when drafted', ({ workflow }) => {
|
||||
const types = workflow.on.pull_request.types
|
||||
expect(types).toEqual(
|
||||
expect.arrayContaining([
|
||||
'opened',
|
||||
'synchronize',
|
||||
'reopened',
|
||||
'ready_for_review',
|
||||
'converted_to_draft'
|
||||
])
|
||||
)
|
||||
expect(Object.values(workflow.jobs).some((job) => !job.needs && admitted(job.if, false))).toBe(
|
||||
true
|
||||
)
|
||||
const concurrency = workflow.concurrency['cancel-in-progress']
|
||||
expect(typeof concurrency === 'boolean' ? concurrency : admitted(concurrency, true)).toBe(true)
|
||||
})
|
||||
|
||||
it.each(workflows)('$file keeps its non-PR entry points eligible', ({ workflow }) => {
|
||||
const needs = Object.fromEntries(
|
||||
Object.keys(workflow.jobs).map((id) => [id, { result: 'success', outputs: {} }])
|
||||
)
|
||||
for (const event of Object.keys(workflow.on).filter((name) => name !== 'pull_request')) {
|
||||
for (const [id, job] of Object.entries(workflow.jobs)) {
|
||||
expect(admitted(job.if, true, needs, event), `${event}/${id}`).toBe(
|
||||
admitted(job.if, false, needs, event)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -24,7 +24,7 @@ export function compileAggregateExpression(expression, contexts = ['needs']) {
|
||||
).evaluate()
|
||||
}
|
||||
|
||||
export const aggregateShouldRun = compileAggregateExpression(aggregateJob.if)
|
||||
export const aggregateShouldRun = compileAggregateExpression(aggregateJob.if, ['needs', 'github'])
|
||||
const aggregateEnvironmentExpressions = Object.fromEntries(
|
||||
Object.entries(aggregateShell.env).map(([name, expression]) => [
|
||||
name,
|
||||
|
||||
@@ -12,7 +12,10 @@ import {
|
||||
|
||||
const results = ['success', 'failure', 'cancelled', 'skipped', '', 'unknown', undefined, null]
|
||||
const admitted = (needs, cancelled = false) =>
|
||||
aggregateShouldRun({ needs }, cancelled).coerceString() === 'true'
|
||||
aggregateShouldRun(
|
||||
{ needs, github: { event: { pull_request: { draft: false } } } },
|
||||
cancelled
|
||||
).coerceString() === 'true'
|
||||
|
||||
describe('explicit PR aggregate result', () => {
|
||||
it('keeps every required dependency and the existing failure reporter', () => {
|
||||
@@ -27,7 +30,6 @@ describe('explicit PR aggregate result', () => {
|
||||
}
|
||||
expect(aggregateJob['continue-on-error']).toBeUndefined()
|
||||
expect(aggregateShell['continue-on-error']).toBeUndefined()
|
||||
expect(aggregateJob.if).toBe('${{ !cancelled() }}')
|
||||
expect(aggregateShell.run).toContain('"$CODE_PATHS" != "success"')
|
||||
const checked = [...aggregateShell.run.matchAll(/^check_job (\S+) /gm)].map((match) => match[1])
|
||||
expect(checked).toEqual(aggregateRequiredJobs)
|
||||
|
||||
@@ -151,7 +151,6 @@ describe('ready-for-review required check reuse', () => {
|
||||
expect(detector.steps.find((step) => step.id === 'e2e_filter').if).toBe(
|
||||
"github.event.pull_request.draft != true && steps.filter.outputs.should_run == 'true'"
|
||||
)
|
||||
expect(workflow.jobs.verify.if).toBe('${{ !cancelled() }}')
|
||||
expect(workflow.jobs.verify.needs).toEqual([
|
||||
'code_paths',
|
||||
'preflight',
|
||||
@@ -163,7 +162,7 @@ describe('ready-for-review required check reuse', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it.each(['pr-test-loc.yml', 'mobile.yml'])(
|
||||
it.each(['pr-test-loc.yml'])(
|
||||
'does not rerun draft-independent %s on readiness changes',
|
||||
(file) => {
|
||||
const source = readFileSync(`.github/workflows/${file}`, 'utf8')
|
||||
|
||||
@@ -22,7 +22,6 @@ it('checks context names even when workflow-only changes skip root tests', () =>
|
||||
(candidate) => candidate.run === 'bun .github/scripts/check-required-pr-context.mjs'
|
||||
)
|
||||
expect(step).toBeDefined()
|
||||
expect(job.if).toBeUndefined()
|
||||
expect(step.if).toBeUndefined()
|
||||
expect(step['continue-on-error']).toBeUndefined()
|
||||
const checkout = job.steps.find((candidate) => candidate.uses?.startsWith('actions/checkout@'))
|
||||
@@ -45,7 +44,7 @@ it('rejects aggregate conditions that hide a successful result', () => {
|
||||
return workflow
|
||||
}
|
||||
expect(() => verifyRequiredPrContext(parseChanged), String(condition)).toThrow(
|
||||
'Required PR aggregate must run unless the workflow is cancelled.'
|
||||
'Required PR aggregate must run unless cancelled or the PR is a draft.'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user