-
Notifications
You must be signed in to change notification settings - Fork 0
governance: merge queue 改 repo 级声明与对账(P2-7 修正,ADR-0042) #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
74141c4
9728a09
32ad8bb
02757c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -140,6 +140,20 @@ for r in $REPOS; do | |
| expect_ok "repo '$r' 基线" "$code" | ||
| done | ||
|
|
||
| echo "==> 6/6 merge queue(repo 级 ruleset;ADR-0042——REST 不支持 merge_queue 规则,写入走 GraphQL)" | ||
| for r in $(jq -r '.merge_queue.repos // [] | .[]' "$EXPECTED"); do | ||
| SRC_ID=$(curl -sS -H "Authorization: Bearer ${GH_TOKEN}" -H "Content-Type: application/json" -d '{"query":"{repository(owner:\"Cloudbird-Software\", name:\"'"$r"'\" ){id}}"}' https://api.github.com/graphql | jq -r '.data.repository.id') | ||
| RID=$(curl -sS -H "Authorization: Bearer ${GH_TOKEN}" -H "Content-Type: application/json" -d '{"query":"query($r:String!){repository(owner:\"Cloudbird-Software\", name:$r){rulesets(first:50){nodes{name databaseId}}}}","variables":{"r":"'"$r"'"}}' https://api.github.com/graphql | jq -r '.data.repository.rulesets.nodes[]? | select(.name == "merge-queue") | .databaseId') | ||
| if [[ -n "$RID" && "$RID" != "null" ]]; then | ||
| echo " repo '$r' merge-queue ruleset 已存在(id=$RID;参数对账由 drift-check §14 执法)" | ||
| continue | ||
| fi | ||
| MUT='mutation($src: ID!) { createRepositoryRuleset(input: { sourceId: $src, name: "merge-queue", target: BRANCH, enforcement: ACTIVE, conditions: { refName: { include: ["~DEFAULT_BRANCH"], exclude: [] } }, rules: [ { type: PULL_REQUEST, parameters: { pullRequest: { requiredApprovingReviewCount: 0, dismissStaleReviewsOnPush: true, requireCodeOwnerReview: false, requireLastPushApproval: false, requiredReviewThreadResolution: false, allowedMergeMethods: [SQUASH] } } }, { type: REQUIRED_STATUS_CHECKS, parameters: { requiredStatusChecks: { requiredStatusChecks: [{ context: "gate", integrationId: null }], strictRequiredStatusChecksPolicy: false } } }, { type: MERGE_QUEUE, parameters: { mergeQueue: { mergeMethod: SQUASH, checkResponseTimeoutMinutes: 60, maxEntriesToBuild: 5, minEntriesToMerge: 1, maxEntriesToMerge: 1, minEntriesToMergeWaitMinutes: 0, groupingStrategy: ALLGREEN } } } ] }) { ruleset { databaseId } } }' | ||
| RESP=$(jq -n --arg q "$MUT" --arg src "$SRC_ID" '{query:$q, variables:{src:$src}}') | ||
|
Comment on lines
+151
to
+152
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 7. Apply ignores declared parameters The creation mutation hardcodes every merge-queue parameter rather than reading .merge_queue.params from expected-state.json. A future parameter change in the declared single source creates the old configuration, after which drift-check immediately rejects the result. Agent Prompt
|
||
| OUT=$(curl -sS -H "Authorization: Bearer ${GH_TOKEN}" -H "Content-Type: application/json" -d "$RESP" https://api.github.com/graphql) | ||
| echo "$OUT" | jq -e '.data.createRepositoryRuleset.ruleset.databaseId' >/dev/null 2>&1 && echo " repo '$r' merge-queue: created" || { echo " repo '$r' merge-queue: FAIL $(echo "$OUT" | jq -r '.errors[0].message // "未知"')" >&2; FAILS=$((FAILS+1)); } | ||
| done | ||
|
|
||
| echo "----------------------------------------" | ||
| if [[ $FAILS -gt 0 ]]; then | ||
| echo "结果: $FAILS 项 FAIL(见上方 stderr)。部分应用——修复后重跑本脚本(幂等)。验证: bash $DIR/drift-check.sh" >&2 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -555,6 +555,39 @@ for r in $REPOS; do | |
| done | ||
| [[ $STUCK_TOTAL -eq 0 ]] && ok "pr-liveness(全部受管仓 open PR 无卡死,阈值 ${LIVENESS_H}h)" | ||
|
|
||
| # ---------- 14. merge queue 对账(P2-7,ADR-0042;repo 级 ruleset)---------- | ||
| # org rulesets API 不支持 merge_queue 规则类型(实测 422)——merge queue 只能以 | ||
| # repo 级 ruleset 存在(须与 pull_request/required_status_checks 同集)。期望状态 | ||
| # expected-state.json#merge_queue 声明仓清单与参数;REST 读 repo ruleset 可见 | ||
| # merge_queue 规则(读支持,写须 GraphQL——apply.sh step6)。 | ||
| MQ_REPOS=$(jq -r '.merge_queue.repos // [] | .[]' "$EXPECTED") | ||
| for r in $MQ_REPOS; do | ||
| RS=$(api "https://api.github.com/repos/$ORG/$r/rulesets?per_page=100") | ||
| if ! jq -e 'type == "array"' <<<"$RS" >/dev/null 2>&1; then | ||
| drift "repo '$r' rulesets 清单拉取失败,merge queue 对账无法执行(fail-closed)"; continue | ||
| fi | ||
| row=$(jq -c --arg n "merge-queue" '.[] | select(.name == $n)' <<<"$RS") | ||
| if [[ -z "$row" || "$row" == "null" ]]; then | ||
| drift "repo '$r' 期望启用 merge queue(ADR-0042)但无 'merge-queue' ruleset"; continue | ||
| fi | ||
| rid=$(jq -r .id <<<"$row") | ||
| detail=$(api "https://api.github.com/repos/$ORG/$r/rulesets/$rid") | ||
| want_p=$(jq -c '.merge_queue.params' "$EXPECTED") | ||
| got_p=$(jq -c '.rules[] | select(.type == "merge_queue") | .parameters | ||
| | {merge_method, check_response_timeout_minutes, max_entries_to_build, | ||
| min_entries_to_merge, max_entries_to_merge, min_entries_to_merge_wait_minutes, | ||
| grouping_strategy}' <<<"$detail") | ||
|
Comment on lines
+576
to
+579
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3. Disabled queue passes reconciliation Section 14 compares only the merge_queue rule parameters and never verifies ruleset enforcement, target, or default-branch conditions. A ruleset changed to disabled evaluation or made inapplicable to the default branch therefore still produces an OK result despite the expected merge queue no longer being enforced. Agent Prompt
|
||
| [[ "$got_p" == "$want_p" ]] || drift "repo '$r' merge-queue 参数漂移: got=$got_p 期望=$want_p" | ||
| ok "merge-queue '$r'(参数与期望一致)" | ||
| done | ||
| # 未声明仓不得私自开队列(期望清单外的仓出现 merge-queue ruleset = 漂移) | ||
| for r in $REPOS; do | ||
| jq -e --arg r "$r" '.merge_queue.repos // [] | index($r) != null' "$EXPECTED" >/dev/null && continue | ||
| RS=$(api "https://api.github.com/repos/$ORG/$r/rulesets?per_page=100") | ||
| jq -e 'type == "array"' <<<"$RS" >/dev/null 2>&1 || continue | ||
|
Comment on lines
+586
to
+587
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 5. Undeclared scan fails open When an undeclared repository’s rulesets request fails or returns an error object, line 587 silently skips that repository without recording drift. The overall check can therefore exit successfully while being unable to determine whether that repository has an unauthorized merge queue. Agent Prompt
|
||
| jq -e '.[] | select(.name == "merge-queue")' <<<"$RS" >/dev/null 2>&1 && drift "repo '$r' 存在未声明的 merge-queue ruleset(expected-state.merge_queue.repos 未列——扩围须修订 ADR-0042)" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4. Renamed queues evade detection The undeclared-repository check identifies merge queues solely by the arbitrary ruleset name merge-queue, rather than by a contained rule whose type is merge_queue. An undeclared repository can therefore enable a queue under any other ruleset name without producing drift. Agent Prompt
|
||
| done | ||
|
|
||
| echo "----------------------------------------" | ||
| if [[ $DRIFTS -gt 0 ]]; then | ||
| echo "结果: $DRIFTS 项漂移。修复: bash governance/apply.sh 或手动改回" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -79,5 +79,21 @@ | |
| "60bd1557481fa89d0358302e150a8f7d9381309c", | ||
| "e9424d220ded331c221b37135faa9d6e9cd1ecac" | ||
| ] | ||
| }, | ||
| "merge_queue": { | ||
| "comment": "P2-7 ADR-0042:merge queue 为 repo 级 ruleset(org rulesets API 不支持 merge_queue 规则类型)。串行保守起步;扩围须修订 ADR-0042。", | ||
| "repos": [ | ||
| "agent-registry", | ||
| "template-service" | ||
| ], | ||
| "params": { | ||
| "merge_method": "squash", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. Merge method always mismatches The expected state stores merge_method as lowercase squash, while GitHub’s merge-queue REST representation uses the uppercase enum SQUASH. Consequently §14 reports parameter drift for the GraphQL-created ruleset even when it has exactly the intended merge method. Agent Prompt
|
||
| "check_response_timeout_minutes": 60, | ||
| "max_entries_to_build": 5, | ||
| "min_entries_to_merge": 1, | ||
| "max_entries_to_merge": 1, | ||
| "min_entries_to_merge_wait_minutes": 0, | ||
| "grouping_strategy": "ALLGREEN" | ||
| } | ||
| } | ||
| } | ||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6. Configured organization is ignored
🐞 Bug≡ CorrectnessAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools