Skip to content

fix(repo-maintenance): Quality Gate 必須チェックの fallback ワークフローを配布対象に追加 - #721

Merged
keito4 merged 3 commits into
mainfrom
fix/quality-gate-fallback-template
May 9, 2026
Merged

keito4 merged 3 commits into
mainfrom
fix/quality-gate-fallback-template

Conversation

@keito4

@keito4 keito4 commented May 9, 2026

Copy link
Copy Markdown
Owner

Why

setup-team-protection.sh はブランチ保護に Quality Gate を必須として登録するが、対応する fallback ワークフローが templates/workflows/ に存在せず、config 管理下の各リポジトリに自動配布されていなかった。

その結果、以下のケースで PR が永続的に Expected — Waiting for status to be reported のまま blocked になる:

  • ci.yml が paths フィルタでスキップされる
  • ci.yml 自体が無い / 名前が違う
  • claude[bot] / dependabot[bot] の GITHUB_TOKEN による push でワークフローが発火しない (GitHub の仕様)

このブロック状態を 3 時間ごとの n8n resolveGitConflict 監視が「CI 失敗」として誤検出し、@claude PRがbaseにマージする際にCIが落ちています を誤投稿する原因になっていた (例: https://github.com/Elu-co-jp/prog-insight/pull/129 で複数回ループ)。

What

  • templates/workflows/quality-gate-fallback.yml を新規作成 (.github/workflows/quality-gate-fallback.yml 相当 + 既知の制限を明記したヘッダーコメント)
  • .claude/commands/repo-maintenance.md section 3.22 のマネージドファイル一覧に quality-gate-fallback.yml を追加
  • .claude/commands/repo-maintenance.md に section 3.5.0.2 Quality Gate Fallback Consistency Check を追加し、ブランチ保護に Quality Gate がある repo で fallback 未配置時に警告 + full mode で section 3.22 経由で自動配置

How

  • 次回 /repo-maintenance 実行時、config 管理下の全リポジトリの .github/workflows/quality-gate-fallback.yml が config の最新版で上書きされる
  • ci.yml が走った場合は本体の Quality Gate が優先され、fallback は no-op
  • ci.yml が走らなかった場合のみ fallback が Pass を emit し、required check を満たす

Risk

  • 低: 新規テンプレートの追加とマネージドファイル登録のみ。既存の fallback ファイル (.github/workflows/quality-gate-fallback.yml) はそのまま機能継続
  • GITHUB_TOKEN の制限上、claude[bot] push 後のコミットでは fallback も発火しない。この場合は Claude Code Action の push に PAT を使うか workflow_dispatch での再トリガーが別途必要 (本 PR スコープ外)
  • 関連: n8n 側の誤検出修正は keito4-org/n8n_custom_node#1857 で対応

Test plan

  • prettier --check パス
  • pre-commit hooks (lint / test 95 件) パス
  • 別リポジトリで /repo-maintenance --mode full を実行し、quality-gate-fallback.yml が配置されることを確認
  • 配置後の Dependabot PR で Quality Gate が Pass で報告されることを確認

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Enhanced quality gate enforcement for pull requests with added fallback mechanisms to ensure critical checks are always evaluated before merging to production branches.
    • Updated repository maintenance documentation to reflect new quality assurance procedures.

setup-team-protection.sh はブランチ保護に "Quality Gate" を必須として登録するが、
ci.yml が paths フィルタでスキップされたり、claude[bot] / dependabot[bot] の
GITHUB_TOKEN による push でワークフローが発火しなかった場合、Quality Gate が
報告されず PR が "Expected — Waiting for status to be reported" のまま blocked になる。

この状態を 3 時間ごとの n8n resolveGitConflict 監視が「CI 失敗」として誤検出し、
@claude PRがbaseにマージする際にCIが落ちています を誤投稿する原因になっていた
(例: https://github.com/Elu-co-jp/prog-insight/pull/129)。

- templates/workflows/quality-gate-fallback.yml をテンプレート化
- repo-maintenance.md section 3.22 のマネージドファイルに追加し、
  config 管理下の全リポジトリへ自動配布されるようにする
- repo-maintenance.md に section 3.5.0.2 (Quality Gate Fallback Consistency Check)
  を追加し、ブランチ保護に Quality Gate がある repo で fallback 未配置時に警告

n8n 側の修正は keito4-org/n8n_custom_node#1857 で対応。
@coderabbitai

coderabbitai Bot commented May 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@keito4 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 27 minutes and 55 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 023013f4-4ecc-47b7-bfa1-28faf1239ba1

📥 Commits

Reviewing files that changed from the base of the PR and between 7418f28 and 2e97c48.

📒 Files selected for processing (2)
  • .github/workflows/quality-gate-fallback.yml
  • templates/workflows/quality-gate-fallback.yml
📝 Walkthrough

Walkthrough

This PR introduces a new GitHub Actions workflow, CI Fallback, that enforces a required Quality Gate status for pull requests targeting protected branches. The workflow is registered in repository maintenance checks and file synchronization to ensure consistent deployment and validation across the configuration repository.

Changes

Quality Gate Fallback Implementation

Layer / File(s) Summary
Workflow Template
templates/workflows/quality-gate-fallback.yml
New CI Fallback workflow queries workflow runs for the current commit and determines whether the main CI workflow is running or has succeeded. If CI has not run, the workflow emits a fallback pass status; otherwise, the fallback is skipped.
Maintenance Validation
.claude/commands/repo-maintenance.md (Step 3.5.0.2)
Adds validation step to confirm that when Quality Gate is required by branch protection, the quality-gate-fallback.yml file exists and is deployed in full mode if missing.
File Synchronization
.claude/commands/repo-maintenance.md (Step 3.22)
Registers quality-gate-fallback.yml as a managed file in the sync policy table and implementation array so it is automatically kept synchronized with the latest version from the config repository.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • keito4/config#597: Introduces the Config Template Sync step and managed-files logic that this PR builds upon for workflow synchronization.
  • keito4/config#581: Updates repo-maintenance.md documentation and Quality Gate branch protection requirements that interact with this PR's fallback workflow.
  • keito4/config#631: Adds similar existence checks and auto-deploy behavior to Step 3.5 for other workflow files alongside the quality-gate-fallback pattern.

Suggested labels

bug

Poem

🐰 A fallback workflow hops into place,
When CI takes time or skips the race.
Quality Gate stands proud and tall,
With sync and checks—we've covered all!
Configuration blooms, neat and bright! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a fallback workflow template for the Quality Gate required check to the distribution targets in repo-maintenance.
Description check ✅ Passed The description comprehensively addresses all template sections with clear context for the Why, What, How, and includes a detailed test plan and risk assessment.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/quality-gate-fallback-template

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Claude finished @keito4's task in 3m 3s —— View job


コードレビュー

タスク一覧

  • コンテキストの収集
  • 変更ファイルの読み込み
  • レビューフィードバックの作成・投稿

総評

PRの目的(bot push 後の PR stuck 問題の解消)は明確で、アプローチも合理的です。quality-gate-fallback.yml の配布基盤整備と repo-maintenance.md の整合性チェック追加はどちらも価値があります。

verdict: minor/recommendation のみ → APPROVE 相当(修正は任意)


指摘事項

[major] actions: read 権限が欠落している可能性

ファイル: templates/workflows/quality-gate-fallback.yml (line 32-34)

permissions:
  contents: read
  # actions: read が欠落

github.rest.actions.listWorkflowRunsForRepo を呼ぶには、プライベートリポジトリでは actions: read が必要です。permissions: を明示した時点でデフォルト権限が上書きされるため、contents: read のみでは private repo でこの API 呼び出しが 403 で失敗する可能性があります。

修正案:

permissions:
  contents: read
  actions: read

既存の .github/workflows/quality-gate-fallback.yml も同じ問題を持っているため、今回のテンプレート追加と合わせて両方修正することを推奨します。

Fix this →


[minor] CI 失敗ケースが「CI 未実行」と同一分岐で処理される

ファイル: templates/workflows/quality-gate-fallback.yml (line 57-70)

// else ブランチは以下の2ケースを同時に処理している
// 1. ciRun が存在しない(CI が本当に走っていない)← 意図通り
// 2. ciRun は存在するが conclusion !== 'success'(CI が失敗/キャンセル)← 意図外?
} else {
  core.info('CI workflow did not run for this commit. Providing fallback Quality Gate.');
  core.setOutput('ci_running', 'false');
}

CI が失敗した場合もこの else に落ちるため、ログに "CI workflow did not run" と出力し "Pass (CI skipped)" ステップが実行されます。CI の Quality Gate チェックが failure でも、このジョブ(quality-gate / "Quality Gate")は常に success で完了します。

GitHub の required status checks は同名チェックが複数存在する場合、全て成功しなければマージ不可なので、実際には CI failure がブロックされるはずです。ただしログメッセージが誤解を招くため、分岐を明示的にすることを推奨します:

if (!ciRun) {
  core.info('CI workflow did not run for this commit. Providing fallback Quality Gate.');
  core.setOutput('ci_running', 'false');
} else if (ciRun.status !== 'completed') {
  core.info(`CI workflow is running (${ciRun.html_url}), fallback will still pass.`);
  core.setOutput('ci_running', 'true');
} else if (ciRun.conclusion === 'success') {
  core.info(`CI workflow already succeeded (${ciRun.html_url}).`);
  core.setOutput('ci_running', 'true');
} else {
  core.info(`CI workflow completed with conclusion: ${ciRun.conclusion} (${ciRun.html_url}). CI Quality Gate will report independently.`);
  core.setOutput('ci_running', 'true'); // fallback の pass step を抑制
}

[recommendation] ハードコードされた CI ワークフロー名

ファイル: templates/workflows/quality-gate-fallback.yml (line 57-58)

const ciRun = runs.workflow_runs.find(
  r => r.name === 'CI' && r.id !== context.runId
);

ワークフロー名が 'CI' 以外のリポジトリ(例: "Build and Test", "Node.js CI")ではこの検索が常に失敗し、fallback が常に Pass を emit します(= CI が走っていても fallback が Pass を出す)。

この制限は header comment の「既知の制限」セクションに追記することを推奨します:

# 既知の制限:
#   ...
#   - CI ワークフロー名が 'CI' 以外の場合は検出されず、fallback が常に Pass を emit する。
#     この場合でも ci.yml の Quality Gate が failure になれば PR はブロックされる。

[minor] テンプレートと既存ファイルのメッセージ差異

テンプレート (templates/workflows/quality-gate-fallback.yml line 74):

echo "Quality Gate passed (CI skipped — no code changes detected or workflow disabled)."

既存ファイル (.github/workflows/quality-gate-fallback.yml line最終行):

echo "Quality Gate passed (CI skipped — no code changes detected)."

/repo-maintenance --mode full 実行後に既存ファイルがテンプレートで上書きされるので意図的な変更だと思いますが、差異があることを認識の上で進めているか確認です。


ポジティブな点

  • commit hash ピン留め (actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3) — セキュリティベストプラクティス ✅
  • timeout-minutes: 2 — 軽量なジョブに適切な上限 ✅
  • header comment の充実 — 背景・動作・使い方・制限が明記されており、他リポジトリでの採用者に親切 ✅
  • repo-maintenance.md の section 3.5.0.2 — 背景・確認ロジック・結果パターンが表で整理されており、スキル実行者が判断しやすい構成 ✅
  • MANAGED_FILES 配列への追加 (line 2333) — 自動配布ロジックとドキュメントが一致している ✅

@keito4 keito4 self-assigned this May 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/commands/repo-maintenance.md:
- Around line 982-985: The check hardcodes "branches/main" so REQUIRED_CHECKS
misses protections on other branches; update the logic that calls gh api
"repos/{owner}/{repo}/branches/main/protection/required_status_checks" to
iterate the branch names in the existing PROTECT_BRANCHES (or otherwise-detected
branch list used for Next.js: main, pre-production, production) and aggregate
required contexts into REQUIRED_CHECKS; for each branch name call gh api
".../branches/{branch}/protection/required_status_checks" (or skip if API 404),
join/merge the .contexts results and fallback to empty if none so the subsequent
Quality Gate logic correctly detects required checks across all protected
branches.

In `@templates/workflows/quality-gate-fallback.yml`:
- Around line 32-33: The workflow currently grants only contents: read, but the
script calls github.rest.actions.listWorkflowRunsForRepo which requires the
actions: read permission; update the permissions section by adding actions: read
(in addition to contents: read) so the GITHUB_TOKEN has the required access for
the workflow-runs API.
- Around line 61-70: The current logic around ciRun treats any completed run
without conclusion 'success' as "did not run" and sets ci_running to true in
some branches; update the conditional in the ciRun handling so only
ciRun.conclusion === 'success' results in core.setOutput('ci_running','true')
and all other completed conclusions (failed, cancelled, timed_out) set
core.setOutput('ci_running','false') and log an appropriate message; also ensure
the workflow permissions include actions: read (in addition to contents: read)
so the listWorkflowRunsForRepo call works with GITHUB_TOKEN.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: accd105c-552b-453d-bfc7-b4d9e0da16cb

📥 Commits

Reviewing files that changed from the base of the PR and between 26aefb7 and 7418f28.

📒 Files selected for processing (2)
  • .claude/commands/repo-maintenance.md
  • templates/workflows/quality-gate-fallback.yml

Comment on lines +982 to +985
if gh api "repos/{owner}/{repo}/branches/main/protection/required_status_checks" >/dev/null 2>&1; then
REQUIRED_CHECKS=$(gh api "repos/{owner}/{repo}/branches/main/protection/required_status_checks" \
--jq '.contexts // [] | join(",")' 2>/dev/null || echo "")
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# First, let's locate and examine the file
find . -name "repo-maintenance.md" -type f

Repository: keito4/config

Length of output: 96


🏁 Script executed:

# Once found, read the relevant section around lines 982-985
head -985 .claude/commands/repo-maintenance.md | tail -20

Repository: keito4/config

Length of output: 1008


🏁 Script executed:

# Search for references to protected branches throughout the file
rg "main|master|pre-production|production" .claude/commands/repo-maintenance.md -n | head -30

Repository: keito4/config

Length of output: 2593


🏁 Script executed:

# Check the PR objective section
rg -A 5 -B 2 "Objective|objective|PR objective" .claude/commands/repo-maintenance.md | head -50

Repository: keito4/config

Length of output: 39


🏁 Script executed:

# Look for the fallback workflow section
rg -A 10 "quality-gate-fallback|fallback.*workflow" .claude/commands/repo-maintenance.md | head -50

Repository: keito4/config

Length of output: 2308


🏁 Script executed:

# Check if there's any other logic handling multiple branches for Quality Gate
rg "Quality Gate|required_status_checks" .claude/commands/repo-maintenance.md -B 3 -A 3

Repository: keito4/config

Length of output: 5022


🏁 Script executed:

# Verify the logic flow - check what happens after REQUIRED_CHECKS is set
sed -n '982,1010p' .claude/commands/repo-maintenance.md

Repository: keito4/config

Length of output: 1259


🏁 Script executed:

# Check if default branch is used anywhere else in the script
rg "defaultBranchRef|default.*branch|DEFAULT_BRANCH" .claude/commands/repo-maintenance.md

Repository: keito4/config

Length of output: 39


Hardcoding main creates inconsistency with multi-branch protection logic.

The Quality Gate check only inspects branches/main, but the script's PROTECT_BRANCHES logic supports main, pre-production, and production for Next.js projects. When Quality Gate is registered as required on pre-production or production, the hardcoded check misses them, incorrectly determining no fallback is needed and allowing the PR to block on "Expected — Waiting for status to be reported."

Dynamic branch detection is needed to align with the protection scope.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/commands/repo-maintenance.md around lines 982 - 985, The check
hardcodes "branches/main" so REQUIRED_CHECKS misses protections on other
branches; update the logic that calls gh api
"repos/{owner}/{repo}/branches/main/protection/required_status_checks" to
iterate the branch names in the existing PROTECT_BRANCHES (or otherwise-detected
branch list used for Next.js: main, pre-production, production) and aggregate
required contexts into REQUIRED_CHECKS; for each branch name call gh api
".../branches/{branch}/protection/required_status_checks" (or skip if API 404),
join/merge the .contexts results and fallback to empty if none so the subsequent
Quality Gate logic correctly detects required checks across all protected
branches.

Comment thread templates/workflows/quality-gate-fallback.yml
Comment thread templates/workflows/quality-gate-fallback.yml Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7418f28dbf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +64 to +67
} else if (ciRun && ciRun.conclusion === 'success') {
core.info(`CI workflow already succeeded (${ciRun.html_url}).`);
core.setOutput('ci_running', 'true');
} else {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Treat failed CI runs as fallback-not-needed

This logic marks ci_running=false whenever a CI run exists but finished with a non-success conclusion (for example failure or cancelled), so the fallback job then emits a successful Quality Gate check even though CI actually ran and failed. Because setup-team-protection.sh configures branch protection to require only the Quality Gate context (script/setup-team-protection.sh lines 271-273), repos that adopt this template can get a green required check from the fallback in the exact case where CI should block merging.

Useful? React with 👍 / 👎.

github-actions Bot and others added 2 commits May 9, 2026 10:28
prog-insight#132 で fallback ワークフローが 403 Resource not accessible by
integration で失敗し、Quality Gate が fail として報告されることを確認。

原因: github.rest.actions.listWorkflowRunsForRepo は actions: read 権限を
要求するが、permissions ブロックには contents: read のみ宣言していた。

- permissions に actions: read を追加 (templates/ と .github/workflows/ 両方)
- 権限不足や API 障害で listWorkflowRuns が失敗した場合は ci_running='true'
  扱いにして fallback の Pass emit をスキップ。誤った Pass / Fail よりは
  Required check が未報告のまま残る方が安全
@keito4
keito4 merged commit 5c9ebaf into main May 9, 2026
12 checks passed
@keito4
keito4 deleted the fix/quality-gate-fallback-template branch May 9, 2026 01:37
@github-actions

github-actions Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.111.4 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released リリース済み

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant