Skip to content

Commit f07ab8c

Browse files
authored
fix: preserve invalidation across chained retargets (#165)
Co-authored-by: Franz Hemmer <8227352+HemSoft@users.noreply.github.com>
1 parent 104648b commit f07ab8c

7 files changed

Lines changed: 32 additions & 7 deletions

File tree

‎.github/workflows/sfl-pr-review-auto.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ jobs:
14251425
runs-on: ubuntu-latest
14261426
timeout-minutes: 5
14271427
concurrency:
1428-
group: sfl-codex-review-pull-context-${{ github.repository }}-${{ github.event.pull_request.number }}
1428+
group: sfl-codex-review-pull-context-${{ github.repository }}-${{ github.event.pull_request.number }}-${{ github.event.pull_request.base.ref == github.event.repository.default_branch || github.event.changes.base.ref.from == github.event.repository.default_branch }}
14291429
cancel-in-progress: true
14301430
permissions:
14311431
actions: read

‎VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.0-rc.28
1+
2.1.0-rc.29

‎deployment/infrastructure/sfl-pr-review-auto.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ jobs:
14251425
runs-on: ubuntu-latest
14261426
timeout-minutes: 5
14271427
concurrency:
1428-
group: sfl-codex-review-pull-context-${{ github.repository }}-${{ github.event.pull_request.number }}
1428+
group: sfl-codex-review-pull-context-${{ github.repository }}-${{ github.event.pull_request.number }}-${{ github.event.pull_request.base.ref == github.event.repository.default_branch || github.event.changes.base.ref.from == github.event.repository.default_branch }}
14291429
cancel-in-progress: true
14301430
permissions:
14311431
actions: read

‎deployment/release-metadata.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
"reviewedAt": "2026-10-08",
44
"distribution": {
55
"repository": "hemsoft-dev/set-it-free-loop",
6-
"version": "2.1.0-rc.28",
6+
"version": "2.1.0-rc.29",
77
"visibility": "private",
8-
"tag": "v2.1.0-rc.28",
8+
"tag": "v2.1.0-rc.29",
99
"prerelease": true
1010
},
1111
"reviewerRuntime": {

‎deployment/tests/test-final-review-history.cjs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,31 @@ function retargetCases() {
211211
assert.equal(event('main','release'),true,'retarget to default remains supported');
212212
assert.equal(event('release',undefined),false,'missing original base cannot grant admission');
213213
assert.equal(event('release','main','fork/fixture'),false,'fork remains unsupported');
214+
215+
const job = source.slice(source.indexOf('\n invalidate-pull-context:'),
216+
source.indexOf('\n invalidate-base-advance:'));
217+
const group = /^ group: (.+)$/m.exec(job);
218+
assert(group, 'pull-context invalidation concurrency group');
219+
assert.match(job, /cancel-in-progress: true/);
220+
const evaluateGroup = (ref, from, number=42) => {
221+
const github = {repository:'hemsoft-dev/fixture',event:{
222+
repository:{default_branch:'main'},pull_request:{number,base:{ref}},
223+
changes:{base:{ref:{from}}}}};
224+
return group[1].replace(/\$\{\{\s*(.*?)\s*\}\}/g, (_, expression) =>
225+
String(new Function('github', `return (${expression});`)(github)));
226+
};
227+
const departure = evaluateGroup('release','main');
228+
// Both running and pending jobs can be canceled by another event in their
229+
// group. A chain returning to the same nondefault target must stay separate.
230+
for (const [ref, from] of [['other','release'],['release','other']]) {
231+
assert.equal(event(ref,from),false,'unsupported chained retarget stays read-only');
232+
assert.notEqual(evaluateGroup(ref,from),departure,
233+
'unsupported chained retarget cannot cancel default-departure invalidation');
234+
}
235+
assert.equal(evaluateGroup('main','release'),departure,
236+
'supported contexts share the same invalidation serialization');
237+
assert.notEqual(evaluateGroup('release','main',43),departure,
238+
'different pull requests retain separate invalidation groups');
214239
}
215240

216241
const repairStart = source.indexOf('const terminalState = await publicationState();');

‎docs/ORGANIZATION-ONBOARDING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The canonical source is [hemsoft-dev/set-it-free-loop](https://github.com/hemsof
44

55
## New repository
66

7-
Install the [checksum-verified canonical release](https://github.com/hemsoft-dev/set-it-free-loop/releases/tag/v2.1.0-rc.28). With repository write access, run `gh sfl init --repo hemsoft-dev/REPOSITORY --pr`. The default tier is reviewer. Add owner-bound `.github/CODEOWNERS` only when no CODEOWNERS already exists, keeping it separate from SFL managed files. Review and merge the deployment PR, then run `gh sfl gate --repo hemsoft-dev/REPOSITORY`. Run a registered `gh sfl review --repo hemsoft-dev/REPOSITORY --pr NUMBER` on an actual consumer PR. Inspect the current head/base and successful Actions-owned gate before merging.
7+
Install the [checksum-verified canonical release](https://github.com/hemsoft-dev/set-it-free-loop/releases/tag/v2.1.0-rc.29). With repository write access, run `gh sfl init --repo hemsoft-dev/REPOSITORY --pr`. The default tier is reviewer. Add owner-bound `.github/CODEOWNERS` only when no CODEOWNERS already exists, keeping it separate from SFL managed files. Review and merge the deployment PR, then run `gh sfl gate --repo hemsoft-dev/REPOSITORY`. Run a registered `gh sfl review --repo hemsoft-dev/REPOSITORY --pr NUMBER` on an actual consumer PR. Inspect the current head/base and successful Actions-owned gate before merging.
88

99
Repeat init/sync through `--pr` and confirm no additional changes. `gh sfl status --repo hemsoft-dev/REPOSITORY` reports the deployed version, source pin, managed file drift and effective gate. Status alone does not turn an advisory deployment into a required gate.
1010

‎sfl.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "2.1.0-rc.28",
2+
"version": "2.1.0-rc.29",
33
"deployedAt": "2026-02-22T22:00:00Z",
44
"tier": "full",
55
"source": "hemsoft-dev/set-it-free-loop",

0 commit comments

Comments
 (0)