-
Notifications
You must be signed in to change notification settings - Fork 0
governance: flaky_governance 参数落地 + 隔离到期回炉 sweep(P2-9,ADR-0043) #122
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
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 |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| name: flaky-sweep | ||
| # P2-9(ADR-0043):隔离清单到期回炉检测——过期隔离不豁免 + 升级 issue。 | ||
| # 回炉执法在 check 侧(过期条目不参与豁免)+ 本 sweep 提示人工按 ADR 移除条目。 | ||
| on: | ||
| schedule: | ||
| - cron: "30 2 * * *" # 每日(错开整点 drift 洪峰) | ||
| workflow_dispatch: | ||
|
|
||
| permissions: {} | ||
|
|
||
| concurrency: | ||
| group: flaky-sweep | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| sweep: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - name: 隔离清单到期扫描 | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GOVERNANCE_TOKEN }} | ||
| run: | | ||
| if [[ -z "$GH_TOKEN" ]]; then | ||
| echo "::error::缺 org secret GOVERNANCE_TOKEN" >&2; exit 2 | ||
| fi | ||
| set -o pipefail | ||
| bash governance/flaky-sweep.sh | tee sweep-report.txt |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| #!/usr/bin/env bash | ||
| # flaky-sweep.sh —— 隔离清单到期回炉检测(P2-9,ADR-0043) | ||
| # 每日扫描全部受管仓的 tests/quarantine.yaml: | ||
| # - 条目结构校验(test/owner/expires/adr 齐备;expires ≤ quarantine_max_days) | ||
| # - expires 已过 → 该条目自动回炉(过期隔离不豁免)+ 开升级 issue(人工按 ADR 移除条目) | ||
| # - 清单拉取失败 = fail-closed | ||
| # 用法: GH_TOKEN=<org admin> bash flaky-sweep.sh(CI 由 flaky-sweep.yml 调度) | ||
| set -uo pipefail | ||
| ORG="${ORG:-Cloudbird-Software}" | ||
| DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| MAX_DAYS=$(python3 -c "import yaml;print(yaml.safe_load(open('$DIR/policy/testing.yaml',encoding='utf-8'))['flaky_governance']['quarantine_max_days'])") | ||
| api() { curl -sS -H "Authorization: Bearer ${GH_TOKEN:?}" -H "Accept: application/vnd.github+json" "$@"; } | ||
| REPOS=$(python3 -c "import yaml;print(' '.join(r['name'] for r in yaml.safe_load(open('$DIR/REPOS.yaml',encoding='utf-8'))['repos'] if r.get('status')=='active'))") | ||
| ISSUES=0; EXPIRED=0; MALFORMED=0 | ||
| for r in $REPOS; do | ||
| RESP=$(api "https://api.github.com/repos/$ORG/$r/contents/tests/quarantine.yaml") | ||
| CONTENT=$(jq -r '.content // empty' <<<"$RESP" | base64 -d 2>/dev/null) | ||
| if [[ -z "$CONTENT" ]]; then | ||
| jq -e '.message == "Not Found"' <<<"$RESP" >/dev/null 2>&1 && continue | ||
| echo "DRIFT repo '$r' tests/quarantine.yaml 读取失败(fail-closed,ADR-0043)"; MALFORMED=$((MALFORMED+1)); continue | ||
| fi | ||
| OUT=$(python3 - "$r" "$MAX_DAYS" <<'PYEOF' | ||
| import sys, yaml, datetime | ||
| repo, max_days = sys.argv[1], int(sys.argv[2]) | ||
| d = yaml.safe_load(sys.stdin) or {} | ||
| today = datetime.date.today() | ||
| expired, malformed = [], [] | ||
| for e in d.get("quarantined", []): | ||
| for k in ("test", "owner", "expires", "adr"): | ||
| if not e.get(k): | ||
| malformed.append(f"{e} 缺 {k}") | ||
| try: | ||
| exp = datetime.date.fromisoformat(str(e["expires"])) | ||
|
Comment on lines
+30
to
+33
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. Malformed manifests falsely pass The parser assumes both the document and every quarantined entry are mappings, then accesses missing required fields after merely recording them. Scalar/list documents, non-mapping entries, or entries missing expires raise uncaught exceptions; without set -e or an explicit status check, the shell continues with empty output and can exit successfully. Agent Prompt
|
||
| if (exp - today).days > max_days: | ||
| malformed.append(f"{e['test']} expires 距今超 quarantine_max_days={max_days}") | ||
| elif exp < today: | ||
| expired.append(f"{e['test']}(owner={e['owner']},过期于 {e['expires']},adr={e['adr']})") | ||
| except ValueError: | ||
| malformed.append(f"{e} expires 非法") | ||
| print("EXPIRED\n" + "\n".join(expired) if expired else "EXPIRED\n-") | ||
| print("MALFORMED\n" + "\n".join(malformed) if malformed else "MALFORMED\n-") | ||
| PYEOF | ||
| ) <<<"$CONTENT" | ||
| EXP_LIST=$(sed -n '/^EXPIRED$/,/^MALFORMED$/p' <<<"$OUT" | sed '1d;$d' | grep -v '^-$' || true) | ||
| MAL_LIST=$(sed -n '/^MALFORMED$/,$p' <<<"$OUT" | sed '1d' | grep -v '^-$' || true) | ||
| if [[ -n "$EXP_LIST" || -n "$MAL_LIST" ]]; then | ||
| TITLE="[flaky] $r 隔离清单待处置(过期回炉/结构违规,ADR-0043)" | ||
| BODY="flaky-sweep 每日检测(ADR-0043):\n\n## 过期条目(已自动回炉——过期隔离不豁免,须修复测试或走 ADR 重新隔离)\n${EXP_LIST:--}\n\n## 结构违规\n${MAL_LIST:--}\n\n处置:修复测试后经 PR 移除条目(引用 ADR);或新 ADR 重新隔离。" | ||
| api -X POST "https://api.github.com/repos/$ORG/$r/issues" -d "$(jq -n --arg t "$TITLE" --arg b "$BODY" '{title:$t,body:$b,labels:["flaky-quarantine"]}')" >/dev/null 2>&1 || \ | ||
|
Comment on lines
+46
to
+49
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. Daily sweep duplicates issues Every run with a persistent expired or malformed entry unconditionally creates another issue without looking for an existing sweep-owned issue. Because the workflow runs daily, unresolved violations will produce one duplicate issue per repository per day. Agent Prompt
|
||
| api -X POST "https://api.github.com/repos/$ORG/$r/issues" -d "$(jq -n --arg t "$TITLE" --arg b "$BODY" '{title:$t,body:$b}')" >/dev/null | ||
|
Comment on lines
+49
to
+50
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. flaky-sweep opens forbidden issues The new automation reports quarantine violations by creating repository issues, but the automation standard permits machine feedback only through failed check runs or ordinary PR comments. This introduces a feedback channel outside the documented bot standards. Agent Prompt
Comment on lines
+49
to
+50
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. 6. Failed issue posts look successful The API wrapper uses curl without --fail-with-body, so HTTP 4xx/5xx responses return success and the unlabeled fallback is not attempted; transport failures from both attempts are also ignored because set -e is disabled. The script then unconditionally prints ISSUE and increments ISSUES, even when no escalation issue exists. Agent Prompt
|
||
| echo "ISSUE repo '$r': 过期 $(grep -c . <<<"$EXP_LIST" || true) / 违规 $(grep -c . <<<"$MAL_LIST" || true)" | ||
| ISSUES=$((ISSUES+1)); EXPIRED=$((EXPIRED+$(grep -c . <<<"$EXP_LIST" || true))) | ||
|
Comment on lines
+51
to
+52
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. Structural violations exit green Parsed structural violations populate MAL_LIST, but line 52 only increments EXPIRED; MALFORMED is reserved for content-fetch failures. A repository containing only invalid quarantine entries is therefore reported as 违规仓=0 and the workflow exits successfully. Agent Prompt
|
||
| fi | ||
| done | ||
| echo "结果: 开 issue=$ISSUES 过期条目=$EXPIRED 违规仓=$MALFORMED(无输出=全部健康)" | ||
| [[ $EXPIRED -eq 0 && $MALFORMED -eq 0 ]] | ||
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.
3. Manifest content never parsed
🐞 Bug≡ CorrectnessAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools