Merge pull request #110 from gsd-redux/chore/ci-skip-tests-on-docs
ci: skip full test matrix on doc-only PRs (PR-2 of 4)
This commit is contained in:
49
.github/workflows/test-skip.yml
vendored
Normal file
49
.github/workflows/test-skip.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: Test (skip-noop)
|
||||||
|
|
||||||
|
# Fires on pull_request events that touch NO code paths.
|
||||||
|
# Emits noop jobs with identical names/matrix to test.yml so the required
|
||||||
|
# status checks (lint-tests + 6x test (...)) are satisfied on doc-only PRs.
|
||||||
|
#
|
||||||
|
# IMPORTANT: paths-ignore here must be the exact inverse of the paths: list
|
||||||
|
# in test.yml. Keep both in sync whenever a new code path is added.
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- 'bin/**'
|
||||||
|
- 'get-shit-done/**'
|
||||||
|
- 'agents/**'
|
||||||
|
- 'commands/**'
|
||||||
|
- 'hooks/**'
|
||||||
|
- 'sdk/**'
|
||||||
|
- 'tests/**'
|
||||||
|
- 'scripts/**'
|
||||||
|
- 'package.json'
|
||||||
|
- 'package-lock.json'
|
||||||
|
- 'tsconfig*.json'
|
||||||
|
- '.github/workflows/test.yml'
|
||||||
|
- '.github/workflows/test-skip.yml'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "doc-only PR: skipping lint-tests"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
node-version: [22, 24]
|
||||||
|
steps:
|
||||||
|
- run: echo "doc-only PR: skipping test on node ${{ matrix.node-version }} / ${{ matrix.os }}"
|
||||||
|
shell: bash
|
||||||
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@@ -9,6 +9,20 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
paths:
|
||||||
|
- 'bin/**'
|
||||||
|
- 'get-shit-done/**'
|
||||||
|
- 'agents/**'
|
||||||
|
- 'commands/**'
|
||||||
|
- 'hooks/**'
|
||||||
|
- 'sdk/**'
|
||||||
|
- 'tests/**'
|
||||||
|
- 'scripts/**'
|
||||||
|
- 'package.json'
|
||||||
|
- 'package-lock.json'
|
||||||
|
- 'tsconfig*.json'
|
||||||
|
- '.github/workflows/test.yml'
|
||||||
|
- '.github/workflows/test-skip.yml'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ are permitted on release/hotfix branches).
|
|||||||
Targets all tags (`~ALL`). Blocks tag updates and deletions — tags are
|
Targets all tags (`~ALL`). Blocks tag updates and deletions — tags are
|
||||||
immutable once created. Tag creation is unrestricted.
|
immutable once created. Tag creation is unrestricted.
|
||||||
|
|
||||||
## 3-PR Rollout Plan
|
## 4-PR Rollout Plan
|
||||||
|
|
||||||
| PR | Branch | Action |
|
| PR | Branch | Action |
|
||||||
|----|--------|--------|
|
|----|--------|--------|
|
||||||
| PR-1 (this PR) | `chore/branch-protection-specs` | Check in spec files; `enforcement: disabled` — no effect on repo |
|
| PR-1 | `chore/branch-protection-specs` | Check in spec files; `enforcement: disabled` — no effect on repo |
|
||||||
| PR-2 | `chore/branch-protection-evaluate` | Run `sync-rulesets.sh` with `ENFORCEMENT=evaluate`; 1-week dry-run via rule-suite logs |
|
| PR-2 | `chore/ci-skip-tests-on-docs` | Add path filter to `test.yml` + new `test-skip.yml` noop; doc-only PRs satisfy required checks in <30s |
|
||||||
| PR-3 | `chore/branch-protection-active` | Run `sync-rulesets.sh` with `ENFORCEMENT=active`; protection live |
|
| PR-3 | `chore/branch-protection-evaluate` | Run `sync-rulesets.sh` with `ENFORCEMENT=evaluate`; 1-week dry-run via rule-suite logs |
|
||||||
|
| PR-4 | `chore/branch-protection-active` | Run `sync-rulesets.sh` with `ENFORCEMENT=active`; protection live |
|
||||||
|
|
||||||
## Running `sync-rulesets.sh`
|
## Running `sync-rulesets.sh`
|
||||||
|
|
||||||
@@ -61,6 +62,58 @@ Each entry shows the actor, ref, result (`pass`/`fail`), and which rules
|
|||||||
triggered. Use this to validate no legitimate workflows are broken before
|
triggered. Use this to validate no legitimate workflows are broken before
|
||||||
flipping to `active` in PR-3.
|
flipping to `active` in PR-3.
|
||||||
|
|
||||||
|
|
||||||
|
## Path filters
|
||||||
|
|
||||||
|
The `test.yml` workflow uses a `paths:` filter on its `pull_request:` trigger so
|
||||||
|
the 6-lane matrix only runs when code-touching files change. A companion workflow,
|
||||||
|
`test-skip.yml`, fires on the inverse (`paths-ignore:`) and emits instant noop
|
||||||
|
jobs with **identical job IDs and matrix dimensions**. This ensures the 7 required
|
||||||
|
status checks (`lint-tests` + 6× `test (...)`) are always satisfied — whether the
|
||||||
|
real matrix ran or the noop ran.
|
||||||
|
|
||||||
|
### Why dual workflow instead of paths-ignore alone?
|
||||||
|
|
||||||
|
GitHub required-status-checks expect a specific context string to appear as
|
||||||
|
"passed" on every PR. If `test.yml` is suppressed by `paths-ignore` on a doc-only
|
||||||
|
PR, those contexts never fire and the PR is permanently blocked. The noop workflow
|
||||||
|
produces the same context strings via matching job IDs + matrix, resolving the
|
||||||
|
deadlock.
|
||||||
|
|
||||||
|
### Canonical code-paths list
|
||||||
|
|
||||||
|
Both `test.yml` (`paths:`) and `test-skip.yml` (`paths-ignore:`) use this list:
|
||||||
|
|
||||||
|
```
|
||||||
|
bin/**
|
||||||
|
get-shit-done/**
|
||||||
|
agents/**
|
||||||
|
commands/**
|
||||||
|
hooks/**
|
||||||
|
sdk/**
|
||||||
|
tests/**
|
||||||
|
scripts/**
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
tsconfig*.json
|
||||||
|
.github/workflows/test.yml
|
||||||
|
.github/workflows/test-skip.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This list also mirrors `changeset-required.yml`'s path filter. Keep all three in sync.
|
||||||
|
|
||||||
|
### Adding a new code path
|
||||||
|
|
||||||
|
When adding a directory or file that should trigger real tests:
|
||||||
|
|
||||||
|
1. Add the glob to `paths:` in `.github/workflows/test.yml`
|
||||||
|
2. Add the **same** glob to `paths-ignore:` in `.github/workflows/test-skip.yml`
|
||||||
|
3. Add the same glob to `changeset-required.yml` if changesets should be required
|
||||||
|
for that path
|
||||||
|
|
||||||
|
Failure to update `test-skip.yml` means doc PRs that happen to touch the new
|
||||||
|
path will deadlock (real matrix never fires, noop never fires either).
|
||||||
|
|
||||||
## Phase-2 TODO
|
## Phase-2 TODO
|
||||||
|
|
||||||
Enable the `required_signatures` rule (signed commits) once agent commits sign
|
Enable the `required_signatures` rule (signed commits) once agent commits sign
|
||||||
|
|||||||
Reference in New Issue
Block a user