Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft, closed]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
build-and-test:
if: ${{ github.event_name != 'pull_request' || (!github.event.pull_request.draft && github.event.action != 'closed') }}
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
Expand Down Expand Up @@ -51,6 +53,7 @@ jobs:
run: pnpm build:demo

browser-release-evidence:
if: ${{ github.event_name != 'pull_request' || (!github.event.pull_request.draft && github.event.action != 'closed') }}
name: Cross-engine Clipboard / Playwright 1.62.0
runs-on: ubuntu-24.04
timeout-minutes: 60
Expand Down Expand Up @@ -84,6 +87,7 @@ jobs:
run: pnpm --dir tests/browser exec playwright test --config playwright.config.ts

office:
if: ${{ github.event_name != 'pull_request' || (!github.event.pull_request.draft && github.event.action != 'closed') }}
name: Office / Python ${{ matrix.python-version }}
runs-on: ubuntu-24.04
timeout-minutes: 30
Expand Down
16 changes: 14 additions & 2 deletions src/workflowExactHead.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ const officeJob = workflowJob(workflow, 'office');
describe('exact-head CI workflow contract', () => {
it('cancels only superseded runs for the same repository and PR while keeping full main compatibility coverage', () => {
expect(workflow).toContain(
"group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event.pull_request.number || github.ref }}",
"group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event.pull_request.number || github.run_id }}",
);
expect(workflow).toContain(
"cancel-in-progress: ${{ github.event_name == 'pull_request' }}",
);
expect(workflow).toContain('cancel-in-progress: true');
expect(officeJob).toContain(
"python-version: ${{ github.event_name == 'pull_request' && fromJSON('[\"3.14\"]') || fromJSON('[\"3.11\", \"3.12\", \"3.13\", \"3.14\"]') }}",
);
Expand All @@ -82,6 +84,16 @@ describe('exact-head CI workflow contract', () => {
expect(releaseWorkflow).toContain('cancel-in-progress: false');
});

it('cancels stale PR work and skips inactive pull requests', () => {
expect(workflow).toContain(
'types: [opened, synchronize, reopened, ready_for_review, converted_to_draft, closed]',
);
for (const job of [buildJob, browserJob, officeJob]) {
expect(job).toContain('!github.event.pull_request.draft');
expect(job).toContain("github.event.action != 'closed'");
}
});

it('uses a fixed runner and checks out the immutable current PR head in every job', () => {
expect(workflow).not.toContain('ubuntu-latest');
for (const job of [buildJob, browserJob, officeJob]) {
Expand Down
Loading