Skip to content

Commit ab9fcab

Browse files
authored
fix(spec-enforcer): recover round-robin state from merged pkg-specifications PRs when cache is empty (#28075)
1 parent 1b22aed commit ab9fcab

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

.github/workflows/spec-enforcer.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,39 @@ You MUST NOT:
123123
}
124124
```
125125

126+
3. If `rotation.json` is missing or empty, recover round-robin state from the most recently merged PR with the `pkg-specifications` label:
127+
- Use the GitHub MCP server (not direct `gh api` calls) to find the latest merged PR in this repository with a query equivalent to:
128+
- `repo:${{ github.repository }} is:pr is:merged label:pkg-specifications sort:merged-desc`
129+
- Parse this line from the PR body:
130+
- `- **Next packages in rotation**: <list>`
131+
- Use this matching pattern:
132+
- `^- \*\*Next packages in rotation\*\*:\s*([A-Za-z0-9_.]+(?:-[A-Za-z0-9_.]+)*(?:\s*,\s*[A-Za-z0-9_.]+(?:-[A-Za-z0-9_.]+)*)*)\s*$`
133+
- This is the final regex pattern (it already escapes literal `**` as `\*\*`)
134+
- If you implement this in a string-literal context, escape backslashes as required by that language
135+
- YAML/Markdown plain text: `\s`
136+
- JSON string: `\\s`
137+
- JavaScript/TypeScript string literal: `\\s`
138+
- Expected list format: `pkg1, pkg2, pkg3` (comma-separated package directory names; the regex enforces package-name character constraints)
139+
- Valid examples: `actionpins, cli`, `123-pkg, console`
140+
- Invalid examples: `pkg1,,pkg2`, `pkg1, pkg two`, `pkg-, nextpkg`
141+
- The regex requires at least one valid package token between commas, so consecutive commas are rejected
142+
- Split the captured value by comma, trim each entry, and (defensively) discard empty entries
143+
- Reconstruct `rotation.json` as:
144+
- `last_packages`: recovered package list
145+
- `last_index`: build a map of `eligible_package -> eligible_list_index`, then scan recovered packages left-to-right and keep the index for the last package in the recovered list that exists in the eligible map; if no recovered package matches, use `-1`
146+
- Example: eligible=`[a,b,c,d]`, recovered=`[c,x,b]``last_index=1` (package `b`)
147+
- `last_run`: merge date of the source PR (UTC date)
148+
- `total_eligible`: current count of eligible packages with `README.md`
149+
- If no such PR (or no parsable line) exists, initialize fallback state:
150+
```json
151+
{
152+
"last_index": -1,
153+
"last_packages": [],
154+
"last_run": "unknown",
155+
"total_eligible": 0
156+
}
157+
```
158+
126159
## Phase 1: Select Packages (Round Robin)
127160

128161
Select **2-3 packages** that have README.md specifications:

0 commit comments

Comments
 (0)