Skip to content

Commit 3f1ca8d

Browse files
authored
Merge pull request #170 from linearis-oss/chore/ci-release-ruleset-refactor
ci: refactor CI/release trigger model and dedupe branch automation
2 parents 318e08d + 0b358b1 commit 3f1ca8d

7 files changed

Lines changed: 158 additions & 37 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: CI Post-merge Sentinel
2+
3+
on:
4+
push:
5+
branches:
6+
- next
7+
- main
8+
9+
permissions:
10+
contents: read
11+
12+
concurrency:
13+
group: post-merge-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
sentinel:
18+
name: Post-merge sentinel (node v22)
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v6
24+
25+
- name: Setup node v22
26+
uses: actions/setup-node@v6
27+
with:
28+
node-version: 22
29+
cache: npm
30+
31+
- name: Install deps
32+
run: npm ci
33+
34+
- name: Build project
35+
run: npm run build
36+
37+
- name: Verify packed binaries
38+
run: npm run verify:packed-binaries

.github/workflows/ci.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
name: CI
22

33
on:
4-
push:
5-
branches:
6-
- main
74
pull_request:
8-
types:
5+
branches:
6+
- next
7+
- main
8+
types:
99
- opened
1010
- synchronize
1111
- ready_for_review
@@ -25,7 +25,7 @@ jobs:
2525

2626
strategy:
2727
matrix:
28-
node-version: [22, 24]
28+
node-version: [22]
2929

3030
steps:
3131
- name: Checkout code
@@ -49,7 +49,7 @@ jobs:
4949
lint:
5050
strategy:
5151
matrix:
52-
node-version: [22, 24]
52+
node-version: [22]
5353

5454
name: Code checks on node v${{ matrix.node-version }}
5555
runs-on: ubuntu-latest

.github/workflows/promote-next-to-main.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,32 @@ jobs:
3131
- name: Fetch main and next refs
3232
run: git fetch origin main next
3333

34+
- name: No-op when next has no commits ahead of main
35+
id: commits-check
36+
shell: bash
37+
run: |
38+
set -euo pipefail
39+
40+
commit_ahead=$(git rev-list --max-count=1 origin/main..origin/next)
41+
42+
if [ -z "$commit_ahead" ]; then
43+
echo "No commits to promote (origin/main..origin/next is empty)."
44+
echo "has_commits=false" >> "$GITHUB_OUTPUT"
45+
exit 0
46+
fi
47+
48+
echo "has_commits=true" >> "$GITHUB_OUTPUT"
49+
3450
- name: Generate linearis-bot app token
51+
if: ${{ steps.commits-check.outputs.has_commits == 'true' }}
3552
id: app-token
3653
uses: actions/create-github-app-token@v2
3754
with:
3855
app-id: ${{ secrets.RELEASE_APP_ID }}
3956
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
4057

4158
- name: Build PR metadata
59+
if: ${{ steps.commits-check.outputs.has_commits == 'true' }}
4260
id: meta
4361
env:
4462
GH_TOKEN: ${{ steps.app-token.outputs.token }}
@@ -112,6 +130,7 @@ jobs:
112130
} >> "$GITHUB_OUTPUT"
113131
114132
- name: Upsert promotion PR
133+
if: ${{ steps.commits-check.outputs.has_commits == 'true' }}
115134
env:
116135
GH_TOKEN: ${{ steps.app-token.outputs.token }}
117136
PROMOTION_PR_TITLE: ${{ steps.meta.outputs.title }}

.github/workflows/release-check.yml

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ on:
44
push:
55
branches:
66
- next
7-
schedule:
8-
- cron: "0 9 * * 1"
7+
- main
98
workflow_dispatch:
109

1110
permissions:
1211
contents: write
1312
id-token: write
1413

1514
concurrency:
16-
group: release-${{ github.event_name == 'schedule' && 'main' || github.ref_name }}
15+
group: release-${{ github.ref_name }}
1716
cancel-in-progress: false
1817

1918
jobs:
@@ -50,11 +49,7 @@ jobs:
5049
id: target
5150
shell: bash
5251
run: |
53-
if [ "${{ github.event_name }}" = "schedule" ]; then
54-
branch="main"
55-
else
56-
branch="${{ github.ref_name }}"
57-
fi
52+
branch="${{ github.ref_name }}"
5853
5954
case "$branch" in
6055
main|next) ;;
@@ -114,15 +109,6 @@ jobs:
114109
- name: Build
115110
run: npm run build
116111

117-
- name: Unit tests
118-
run: npm test
119-
120-
- name: Lint and format check
121-
run: npm run check:ci
122-
123-
- name: Type check
124-
run: npx tsc --noEmit
125-
126112
- name: Verify npm auth
127113
env:
128114
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

CONTRIBUTING.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ Integration tests (`tests/integration/`) require `LINEAR_API_TOKEN` in your envi
4343

4444
## Publishing
4545

46-
Publishing is fully automated by the `Release` workflow (`.github/workflows/release-check.yml`).
47-
48-
- `next` (default branch): releases run on every push (prerelease channel)
49-
- `main` (stable branch): releases run on weekly schedule
50-
- Can be started manually with `workflow_dispatch` for either branch
51-
- Executes build/test/lint/type-check gates before release
52-
- Uses semantic-release to decide if a release is required
53-
- Publishes npm package, creates tag, and creates GitHub release when releasable commits exist
46+
Publishing is automated by GitHub Actions, primarily via the `Release` workflow (`.github/workflows/release-check.yml`).
47+
48+
At a high level:
49+
50+
- PR quality gates run in `ci.yml`
51+
- Post-merge sentinel validation runs in `ci-post-merge.yml`
52+
- Releases run in `release-check.yml` (semantic-release decides whether to publish)
53+
54+
For the authoritative workflow trigger matrix, required check names, and verification commands, see [`docs/ci-run-model.md`](docs/ci-run-model.md) (source of truth).
5455

5556
### Changelog ownership
5657

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,15 @@ Add this (or a version adapted to your workflow) to your `AGENTS.md` or `CLAUDE.
125125

126126
## Release Automation Policy
127127

128-
Releases are automated by GitHub Actions via `.github/workflows/release-check.yml`.
128+
Linearis uses three CI/release workflows:
129129

130-
- `next` (default branch): release runs on every push (prerelease channel)
131-
- `main` (stable branch): release runs on weekly schedule
132-
- Manual `workflow_dispatch` supports releasing from either `main` or `next`
133-
- `CHANGELOG.md` is automation-owned and must not be edited in pull requests
130+
- `ci.yml` for required pull request checks
131+
- `ci-post-merge.yml` for post-merge sentinel validation on `main`/`next` pushes
132+
- `release-check.yml` for push-driven and manual releases
134133

135-
If a pull request branch contains `CHANGELOG.md` changes anywhere in `main...HEAD` history, CI fails and posts rebase instructions.
134+
For the authoritative trigger matrix, required checks, and operational verification commands, see [`docs/ci-run-model.md`](docs/ci-run-model.md) (source of truth).
135+
136+
`CHANGELOG.md` is automation-owned and must not be edited in pull requests. If a pull request branch contains `CHANGELOG.md` changes anywhere in `main...HEAD` history, CI fails and posts rebase instructions.
136137

137138
## Contributing
138139

docs/ci-run-model.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# CI Run Model
2+
3+
This document defines how pull request checks and release runs are wired together.
4+
5+
## Workflow purpose
6+
7+
| Workflow | Purpose |
8+
| --- | --- |
9+
| `ci.yml` | Runs required pull request checks used by branch protection/rulesets. |
10+
| `ci-post-merge.yml` | Runs post-merge sentinel validation on `main`/`next` pushes. |
11+
| `release-check.yml` | Performs semantic-release on release branches after required checks have already passed in PR. |
12+
13+
## Trigger matrix
14+
15+
| Event | Branch | `ci.yml` | `ci-post-merge.yml` | `release-check.yml` |
16+
| --- | --- | --- | --- | --- |
17+
| `pull_request` | `main`, `next` | ✅ required checks |||
18+
| `push` | `main`, `next` || ✅ post-merge sentinel | ✅ release run |
19+
| `workflow_dispatch` | selected ref (only `main`/`next` accepted by job validation) ||| ✅ manual release run (main/next only) |
20+
21+
> **Constraint:** Although GitHub UI lets you choose any ref for `workflow_dispatch`, `release-check.yml` enforces `main` or `next` only and fails early for other refs.
22+
23+
## Required checks for repository ruleset
24+
25+
The repository ruleset must require exactly these check names:
26+
27+
- Unit tests on node v22
28+
- Code checks on node v22
29+
30+
These checks are produced by `ci.yml` and must be green before merging to `main` or `next`.
31+
32+
## Release model (no schedule)
33+
34+
Release workflow is lean and intentionally does not run a weekly schedule:
35+
36+
- Push to `next` → prerelease channel
37+
- Push to `main` → stable release channel
38+
- Manual `workflow_dispatch` → ad-hoc release from `main` or `next` only (validated in the release job)
39+
40+
Because release runs happen only after merges, quality gates live in PR required checks, not duplicated release-time full matrices.
41+
42+
## Operational verification
43+
44+
Use GitHub CLI to confirm the run model:
45+
46+
```bash
47+
# CI required checks from PRs
48+
49+
gh run list --workflow ci.yml --event pull_request --limit 20
50+
51+
# Post-merge sentinel runs on push (next)
52+
53+
gh run list --workflow ci-post-merge.yml --event push --branch next --limit 20
54+
55+
# Post-merge sentinel runs on push (main)
56+
57+
gh run list --workflow ci-post-merge.yml --event push --branch main --limit 20
58+
59+
# Release runs on push (main + next)
60+
61+
gh run list --workflow release-check.yml --event push --limit 20
62+
63+
# Optional manual release runs
64+
65+
gh run list --workflow release-check.yml --event workflow_dispatch --limit 20
66+
```
67+
68+
## Rollback guidance
69+
70+
If the model needs to be reverted quickly:
71+
72+
1. Revert the workflow/ruleset refactor commit.
73+
2. Confirm ruleset required checks point to existing check names.
74+
3. Re-run a PR and confirm both required checks appear and pass.
75+
4. Verify push-based release on `next` and `main` with `gh run list` filters above.
76+
5. If release is blocked, run `workflow_dispatch` once as a temporary bridge while fixing ruleset/workflow drift.

0 commit comments

Comments
 (0)