t318.5: End-to-end PR task ID validation testing#1260
Conversation
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a robust system for validating PR task IDs, ensuring that all pull requests are linked to existing and active tasks defined in Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Feb 12 14:11:35 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
WalkthroughThis PR adds a new GitHub Actions workflow job "PR Task ID Check" and corresponding Bash test harness to validate that PR titles and branches contain task IDs (tNNN or tNNN.N format) that exist in TODO.md on the base branch. Includes exemption logic for dependabot, auto-fix, release, and emergency hotfix branches. Changes
Sequence DiagramsequenceDiagram
participant GH as GitHub
participant WF as PR Task Check Job
participant Git as Git
participant TODO as TODO.md
participant Comment as PR Comment
participant Exit as Exit Code
GH->>WF: Pull request event triggered
WF->>WF: Extract task ID from PR title/branch
WF->>WF: Check branch exemption patterns<br/>(dependabot, auto-fix, release, hotfix)
alt Exempt Branch
WF->>Exit: Exit 0 (success)
else Non-Exempt
WF->>Git: Sparse checkout base branch TODO.md
Git->>TODO: Retrieve TODO.md file
alt Task ID Found
WF->>TODO: Search for task ID
alt Task Exists & Not Declined
WF->>Exit: Exit 0 (success)
else Task Missing or Declined
WF->>Comment: Post detailed fix instructions
WF->>Exit: Exit 1 (failure)
end
else No Task ID Found
WF->>Comment: Post task ID requirement comment
WF->>Exit: Exit 1 (failure)
end
alt TODO.md Missing
WF->>WF: Log warning and skip check
WF->>Exit: Exit 0 (success)
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts (beta)
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. Comment |
2120919 to
b1c2e53
Compare
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Feb 12 14:15:14 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable CI check for validating task IDs in PRs, along with a comprehensive test harness. The implementation is solid, and the test script covers an impressive range of scenarios and edge cases. My feedback focuses on aligning the new shell scripts with the repository's style guide to enhance robustness and maintainability. I've suggested adding set -euo pipefail to the CI script, and in the test script, ensuring functions have explicit return statements and temporary files are cleaned up using trap.
| + PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| + run: | | ||
| + echo "PR Task ID Validation" |
There was a problem hiding this comment.
The script within the run block should start with set -euo pipefail to ensure robustness. The repository style guide (line 10) requires all scripts to use it. While GitHub Actions enables -e by default, -u (for unbound variables) and -o pipefail are crucial for preventing subtle bugs.
set -euo pipefail
echo "PR Task ID Validation"
References
- All scripts should use
set -euo pipefailfor strict error checking. (link)
| fi | ||
| } |
There was a problem hiding this comment.
The repository style guide (line 12) requires all functions to have an explicit return statement. The check_pr_task_id function is missing one.
| fi | |
| } | |
| fi | |
| return 0 | |
| } |
References
- All functions must have an explicit
returnstatement. (link)
| TEMP_TODO=$(mktemp) | ||
| echo "- [ ] t318.5 Test task" >"$TEMP_TODO" | ||
| check_pr_task_id \ | ||
| "t318: Parent task" \ | ||
| "feature/t318" \ | ||
| "$TEMP_TODO" \ | ||
| "fail-not-found" | ||
| rm -f "$TEMP_TODO" |
There was a problem hiding this comment.
This block creates a temporary file without using a trap for cleanup, which violates the repository style guide (line 33). If the script were to exit unexpectedly between lines 215 and 222, the temporary file would be left behind.
This pattern is repeated multiple times in the script. A better approach would be to create a helper function that encapsulates the creation of the temp file, setting a trap, running the test, and cleaning up. This would make the code safer and more readable.
References
- Temporary files created with
mktempmust have atrapfor cleanup to ensure they are removed on script exit or return. (link)
Implements end-to-end testing for the PR task ID enforcement system (t318). 1. test-pr-task-check.sh: 25 test cases validating all CI check logic: - PRs without task ID -> rejected (3 cases) - PRs with valid task ID -> accepted (4 cases) - Non-existent task IDs -> rejected (3 cases) - Exempted branches: dependabot, auto-fix, release, hotfix-emergency (5 cases) - Edge cases: boundary matching, declined tasks, subtasks (6 cases) - Supervisor PR patterns -> accepted (2 cases) - Real-world PR patterns -> accepted (2 cases) All 25 tests pass. 2. pr-task-check-ci.patch: GitHub Actions workflow change for code-quality.yml Adds pr-task-check job that validates every PR has a task ID (tNNN) in its title or branch name, and that the task exists in TODO.md on the base branch. Exemptions: dependabot/*, auto-fix/*, release/*, hotfix/*-emergency-*. Posts PR comment with fix instructions on failure. Apply with: git apply .agents/scripts/pr-task-check-ci.patch Requires token with workflow scope to push .github/workflows/ changes. BLOCKER: GH_TOKEN (OAuth) lacks workflow scope — cannot push .github/workflows/ changes. User must apply patch and push with a PAT that has workflow scope.
b1c2e53 to
4ea82db
Compare
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Feb 12 20:13:45 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @.agents/scripts/pr-task-check-ci.patch:
- Around line 78-92: The multi-line string passed to gh pr comment "$PR_NUMBER"
--body is indented so GitHub will render it as a code block; fix both gh pr
comment invocations by dedenting the message text or switching to a heredoc so
the body has no leading spaces—for example, replace the inline quoted, indented
literal with a construct that injects an unindented multi-line string (e.g., gh
pr comment "$PR_NUMBER" --body "$(cat <<'EOF'\n...your unindented
message...\nEOF\n)") ensuring the same change is applied to the second gh pr
comment block as well.
In @.agents/scripts/test-pr-task-check.sh:
- Around line 27-83: The function check_pr_task_id currently exits by falling
through; add an explicit return code at the end of the function (e.g., return 0)
to satisfy the shell scripting guideline requiring explicit returns. Locate the
closing brace of check_pr_task_id and append a single return 0 just before it so
the function always returns an explicit success status when it finishes.
- Around line 22-23: The verbose helper uses the unsafe `[[ "$VERBOSE" ==
"--verbose" ]] && echo -e ... || true` pattern flagged as SC2015; refactor the
`verbose()` function into an explicit if/then/else that calls `echo -e "
${YELLOW}$1${NC}"` when VERBOSE equals "--verbose" and otherwise returns
success, and add explicit return statements to both `log()` and `verbose()` so
failures from `echo -e` are not silently swallowed; update the `log()` function
to also include an explicit return after the `echo -e "$1"` call.
🧹 Nitpick comments (4)
.agents/scripts/test-pr-task-check.sh (3)
22-22:log()function also lacks explicit return.Same guideline applies here. Minor, but for zero-debt consistency:
🔧 Proposed fix
-log() { echo -e "$1"; } +log() { echo -e "$1"; return 0; }As per coding guidelines, "Include explicit returns in shell scripts."
214-271: Temp files leak ifset -etriggers an early exit betweenmktempandrm.If
check_pr_task_id(or any command in-between) fails unexpectedly underset -e, the temp file won't be cleaned up. Consider using atrapfor cleanup or grouping each temp-file test in a subshell.🔧 Proposed fix — trap-based cleanup
Add near the top of the script (after
set -euo pipefail):+TEMP_FILES=() +cleanup_temp() { + for f in "${TEMP_FILES[@]}"; do + rm -f "$f" + done +} +trap cleanup_temp EXITThen replace each
mktemp/rmpair like:TEMP_TODO=$(mktemp) +TEMP_FILES+=("$TEMP_TODO") echo "- [ ] t318.5 Test task" >"$TEMP_TODO" check_pr_task_id \ "t318: Parent task" \ "feature/t318" \ "$TEMP_TODO" \ "fail-not-found" -rm -f "$TEMP_TODO"The
EXITtrap handles cleanup regardless of how the script terminates.
67-73: Dots intask_idare unescaped in grep regex — minor false-match risk.
task_idvalues liket318.5are interpolated directly into the grep ERE pattern. The.matches any character, sot318.5would also match a hypotheticalt31825. Given the controlled TODO.md format and trailing-space anchor, false positives are extremely unlikely, but for correctness purity you could escape dots.🔧 Proposed fix
+ # Escape dots in task_id for grep regex + local escaped_id="${task_id//./\\.}" + - elif grep -qE "^[[:space:]]*- \[-\] ${task_id} " "$todo_file"; then + elif grep -qE "^[[:space:]]*- \[-\] ${escaped_id} " "$todo_file"; then result="fail-declined" - elif grep -qE "^[[:space:]]*- \[[ x]\] ${task_id} " "$todo_file"; then + elif grep -qE "^[[:space:]]*- \[[ x]\] ${escaped_id} " "$todo_file"; then result="pass".agents/scripts/pr-task-check-ci.patch (1)
103-113: Same unescaped-dot-in-grep note applies here too.
${task_id}containing dots (e.g.,t318.5) is used unescaped in the ERE pattern, identical to the test harness. Low risk given the controlled format, but worth noting for consistency if you fix it in the test script.
| + gh pr comment "$PR_NUMBER" --body "## PR Task ID Check Failed | ||
| + | ||
| + This PR does not reference a task ID (\`tNNN\`) in its title or branch name. | ||
| + | ||
| + Every PR must be traceable to a planned task in TODO.md. This ensures: | ||
| + - All work is planned before implementation | ||
| + - Every PR can be traced back to its task | ||
| + - Every task can be traced forward to its PR | ||
| + | ||
| + **How to fix:** | ||
| + 1. If a task exists, add its ID to the PR title (e.g., \`t001: Fix the thing\`) | ||
| + 2. If no task exists, create one in TODO.md first | ||
| + 3. Then update the PR title to include the task ID | ||
| + | ||
| + **Exempted branches:** \`dependabot/*\`, \`auto-fix/*\`, \`release/*\`, \`hotfix/*-emergency-*\`" || echo "Warning: Could not post PR comment" |
There was a problem hiding this comment.
PR comment body will render with unwanted leading whitespace in GitHub Markdown.
The body text on lines 80–92 is indented to match the YAML nesting, but gh pr comment --body will preserve that whitespace verbatim. GitHub Markdown will render the leading spaces as a code block or preformatted text, making the comment look broken.
Dedent the comment body so lines start at column 1 (or use a heredoc approach). The same issue applies to the second gh pr comment block on lines 129–137.
🔧 Proposed fix (first comment block)
# Post comment on PR with fix instructions
- gh pr comment "$PR_NUMBER" --body "## PR Task ID Check Failed
-
- This PR does not reference a task ID (\`tNNN\`) in its title or branch name.
-
- Every PR must be traceable to a planned task in TODO.md. This ensures:
- - All work is planned before implementation
- - Every PR can be traced back to its task
- - Every task can be traced forward to its PR
-
- **How to fix:**
- 1. If a task exists, add its ID to the PR title (e.g., \`t001: Fix the thing\`)
- 2. If no task exists, create one in TODO.md first
- 3. Then update the PR title to include the task ID
-
- **Exempted branches:** \`dependabot/*\`, \`auto-fix/*\`, \`release/*\`, \`hotfix/*-emergency-*\`" || echo "Warning: Could not post PR comment"
+ gh pr comment "$PR_NUMBER" --body "## PR Task ID Check Failed
+
+This PR does not reference a task ID (\`tNNN\`) in its title or branch name.
+
+Every PR must be traceable to a planned task in TODO.md. This ensures:
+- All work is planned before implementation
+- Every PR can be traced back to its task
+- Every task can be traced forward to its PR
+
+**How to fix:**
+1. If a task exists, add its ID to the PR title (e.g., \`t001: Fix the thing\`)
+2. If no task exists, create one in TODO.md first
+3. Then update the PR title to include the task ID
+
+**Exempted branches:** \`dependabot/*\`, \`auto-fix/*\`, \`release/*\`, \`hotfix/*-emergency-*\`" || echo "Warning: Could not post PR comment"🤖 Prompt for AI Agents
In @.agents/scripts/pr-task-check-ci.patch around lines 78 - 92, The multi-line
string passed to gh pr comment "$PR_NUMBER" --body is indented so GitHub will
render it as a code block; fix both gh pr comment invocations by dedenting the
message text or switching to a heredoc so the body has no leading spaces—for
example, replace the inline quoted, indented literal with a construct that
injects an unindented multi-line string (e.g., gh pr comment "$PR_NUMBER" --body
"$(cat <<'EOF'\n...your unindented message...\nEOF\n)") ensuring the same change
is applied to the second gh pr comment block as well.
| log() { echo -e "$1"; } | ||
| verbose() { [[ "$VERBOSE" == "--verbose" ]] && echo -e " ${YELLOW}$1${NC}" || true; } |
There was a problem hiding this comment.
SC2015: A && B || C is not a safe if-then-else substitute.
The || true guard helps, but if echo -e fails (e.g., write error to a closed fd), the || true silently swallows it. ShellCheck flags this as SC2015. Since the coding guidelines mandate zero ShellCheck violations, refactor to a proper conditional.
🔧 Proposed fix
-verbose() { [[ "$VERBOSE" == "--verbose" ]] && echo -e " ${YELLOW}$1${NC}" || true; }
+verbose() {
+ if [[ "$VERBOSE" == "--verbose" ]]; then
+ echo -e " ${YELLOW}$1${NC}"
+ fi
+ return 0
+}As per coding guidelines, "Run ShellCheck with zero violations on all scripts in .agents/scripts/" and "Include explicit returns in shell scripts."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| log() { echo -e "$1"; } | |
| verbose() { [[ "$VERBOSE" == "--verbose" ]] && echo -e " ${YELLOW}$1${NC}" || true; } | |
| log() { echo -e "$1"; } | |
| verbose() { | |
| if [[ "$VERBOSE" == "--verbose" ]]; then | |
| echo -e " ${YELLOW}$1${NC}" | |
| fi | |
| return 0 | |
| } |
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis
[warning] 23-23: .agents/scripts/test-pr-task-check.sh#L23
Note that A && B || C is not if-then-else. C may run when A is true.
🤖 Prompt for AI Agents
In @.agents/scripts/test-pr-task-check.sh around lines 22 - 23, The verbose
helper uses the unsafe `[[ "$VERBOSE" == "--verbose" ]] && echo -e ... || true`
pattern flagged as SC2015; refactor the `verbose()` function into an explicit
if/then/else that calls `echo -e " ${YELLOW}$1${NC}"` when VERBOSE equals
"--verbose" and otherwise returns success, and add explicit return statements to
both `log()` and `verbose()` so failures from `echo -e` are not silently
swallowed; update the `log()` function to also include an explicit return after
the `echo -e "$1"` call.
| check_pr_task_id() { | ||
| local pr_title="$1" | ||
| local pr_branch="$2" | ||
| local todo_file="$3" | ||
| local expected="$4" # "pass", "fail-no-id", "fail-not-found", "fail-declined", "exempt" | ||
|
|
||
| TOTAL=$((TOTAL + 1)) | ||
| local result="" | ||
| local task_id="" | ||
|
|
||
| # Exempted branch patterns (must match code-quality.yml exactly) | ||
| local exempt_patterns=( | ||
| "^dependabot/" | ||
| "^auto-fix/" | ||
| "^release/" | ||
| "^hotfix/.*-emergency-" | ||
| ) | ||
|
|
||
| for pattern in "${exempt_patterns[@]}"; do | ||
| if [[ "$pr_branch" =~ $pattern ]]; then | ||
| result="exempt" | ||
| verbose "Branch '${pr_branch}' matches exemption '${pattern}'" | ||
| break | ||
| fi | ||
| done | ||
|
|
||
| if [[ -z "$result" ]]; then | ||
| # Extract task ID from PR title first, then branch name | ||
| if [[ "$pr_title" =~ (t[0-9]+(\.[0-9]+)*) ]]; then | ||
| task_id="${BASH_REMATCH[1]}" | ||
| verbose "Found task ID '${task_id}' in PR title" | ||
| elif [[ "$pr_branch" =~ (t[0-9]+(\.[0-9]+)*) ]]; then | ||
| task_id="${BASH_REMATCH[1]}" | ||
| verbose "Found task ID '${task_id}' in branch name" | ||
| fi | ||
|
|
||
| if [[ -z "$task_id" ]]; then | ||
| result="fail-no-id" | ||
| elif [[ ! -f "$todo_file" ]]; then | ||
| result="pass" # No TODO.md = skip check (graceful) | ||
| elif grep -qE "^[[:space:]]*- \[-\] ${task_id} " "$todo_file"; then | ||
| result="fail-declined" | ||
| elif grep -qE "^[[:space:]]*- \[[ x]\] ${task_id} " "$todo_file"; then | ||
| result="pass" | ||
| else | ||
| result="fail-not-found" | ||
| fi | ||
| fi | ||
|
|
||
| if [[ "$result" == "$expected" ]]; then | ||
| PASS=$((PASS + 1)) | ||
| log "${GREEN}PASS${NC} [$result] title='$pr_title' branch='$pr_branch'" | ||
| else | ||
| FAIL=$((FAIL + 1)) | ||
| log "${RED}FAIL${NC} expected=$expected got=$result title='$pr_title' branch='$pr_branch'" | ||
| fi | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Missing explicit return statements in check_pr_task_id.
The function falls through without an explicit return. The coding guidelines require explicit returns in shell scripts. Add return 0 at the end of the function.
🔧 Proposed fix
else
FAIL=$((FAIL + 1))
log "${RED}FAIL${NC} expected=$expected got=$result title='$pr_title' branch='$pr_branch'"
fi
+ return 0
}As per coding guidelines, "Include explicit returns in shell scripts."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| check_pr_task_id() { | |
| local pr_title="$1" | |
| local pr_branch="$2" | |
| local todo_file="$3" | |
| local expected="$4" # "pass", "fail-no-id", "fail-not-found", "fail-declined", "exempt" | |
| TOTAL=$((TOTAL + 1)) | |
| local result="" | |
| local task_id="" | |
| # Exempted branch patterns (must match code-quality.yml exactly) | |
| local exempt_patterns=( | |
| "^dependabot/" | |
| "^auto-fix/" | |
| "^release/" | |
| "^hotfix/.*-emergency-" | |
| ) | |
| for pattern in "${exempt_patterns[@]}"; do | |
| if [[ "$pr_branch" =~ $pattern ]]; then | |
| result="exempt" | |
| verbose "Branch '${pr_branch}' matches exemption '${pattern}'" | |
| break | |
| fi | |
| done | |
| if [[ -z "$result" ]]; then | |
| # Extract task ID from PR title first, then branch name | |
| if [[ "$pr_title" =~ (t[0-9]+(\.[0-9]+)*) ]]; then | |
| task_id="${BASH_REMATCH[1]}" | |
| verbose "Found task ID '${task_id}' in PR title" | |
| elif [[ "$pr_branch" =~ (t[0-9]+(\.[0-9]+)*) ]]; then | |
| task_id="${BASH_REMATCH[1]}" | |
| verbose "Found task ID '${task_id}' in branch name" | |
| fi | |
| if [[ -z "$task_id" ]]; then | |
| result="fail-no-id" | |
| elif [[ ! -f "$todo_file" ]]; then | |
| result="pass" # No TODO.md = skip check (graceful) | |
| elif grep -qE "^[[:space:]]*- \[-\] ${task_id} " "$todo_file"; then | |
| result="fail-declined" | |
| elif grep -qE "^[[:space:]]*- \[[ x]\] ${task_id} " "$todo_file"; then | |
| result="pass" | |
| else | |
| result="fail-not-found" | |
| fi | |
| fi | |
| if [[ "$result" == "$expected" ]]; then | |
| PASS=$((PASS + 1)) | |
| log "${GREEN}PASS${NC} [$result] title='$pr_title' branch='$pr_branch'" | |
| else | |
| FAIL=$((FAIL + 1)) | |
| log "${RED}FAIL${NC} expected=$expected got=$result title='$pr_title' branch='$pr_branch'" | |
| fi | |
| } | |
| check_pr_task_id() { | |
| local pr_title="$1" | |
| local pr_branch="$2" | |
| local todo_file="$3" | |
| local expected="$4" # "pass", "fail-no-id", "fail-not-found", "fail-declined", "exempt" | |
| TOTAL=$((TOTAL + 1)) | |
| local result="" | |
| local task_id="" | |
| # Exempted branch patterns (must match code-quality.yml exactly) | |
| local exempt_patterns=( | |
| "^dependabot/" | |
| "^auto-fix/" | |
| "^release/" | |
| "^hotfix/.*-emergency-" | |
| ) | |
| for pattern in "${exempt_patterns[@]}"; do | |
| if [[ "$pr_branch" =~ $pattern ]]; then | |
| result="exempt" | |
| verbose "Branch '${pr_branch}' matches exemption '${pattern}'" | |
| break | |
| fi | |
| done | |
| if [[ -z "$result" ]]; then | |
| # Extract task ID from PR title first, then branch name | |
| if [[ "$pr_title" =~ (t[0-9]+(\.[0-9]+)*) ]]; then | |
| task_id="${BASH_REMATCH[1]}" | |
| verbose "Found task ID '${task_id}' in PR title" | |
| elif [[ "$pr_branch" =~ (t[0-9]+(\.[0-9]+)*) ]]; then | |
| task_id="${BASH_REMATCH[1]}" | |
| verbose "Found task ID '${task_id}' in branch name" | |
| fi | |
| if [[ -z "$task_id" ]]; then | |
| result="fail-no-id" | |
| elif [[ ! -f "$todo_file" ]]; then | |
| result="pass" # No TODO.md = skip check (graceful) | |
| elif grep -qE "^[[:space:]]*- \[-\] ${task_id} " "$todo_file"; then | |
| result="fail-declined" | |
| elif grep -qE "^[[:space:]]*- \[[ x]\] ${task_id} " "$todo_file"; then | |
| result="pass" | |
| else | |
| result="fail-not-found" | |
| fi | |
| fi | |
| if [[ "$result" == "$expected" ]]; then | |
| PASS=$((PASS + 1)) | |
| log "${GREEN}PASS${NC} [$result] title='$pr_title' branch='$pr_branch'" | |
| else | |
| FAIL=$((FAIL + 1)) | |
| log "${RED}FAIL${NC} expected=$expected got=$result title='$pr_title' branch='$pr_branch'" | |
| fi | |
| return 0 | |
| } |
🤖 Prompt for AI Agents
In @.agents/scripts/test-pr-task-check.sh around lines 27 - 83, The function
check_pr_task_id currently exits by falling through; add an explicit return code
at the end of the function (e.g., return 0) to satisfy the shell scripting
guideline requiring explicit returns. Locate the closing brace of
check_pr_task_id and append a single return 0 just before it so the function
always returns an explicit success status when it finishes.



Summary
End-to-end testing of the PR task ID validation system (t318). Also implements the CI check (t318.1) since it had no existing PR or branch.
Ref #1239
What is included
1. Local test harness (test-pr-task-check.sh)
23 test cases validating all CI check logic:
2. CI workflow patch (pr-task-check-ci.patch)
Adds pr-task-check job to code-quality.yml that:
Apply with:
git apply .agents/scripts/pr-task-check-ci.patch3. Real PR audit
Audited 30 most recent PRs:
Blocker: workflow scope
The GH_TOKEN (OAuth) lacks workflow scope, which GitHub requires to push changes to .github/workflows/. The CI workflow change is provided as a patch file.
Test evidence
All 23 local tests pass. See test-pr-task-check.sh for full test suite.
Summary by CodeRabbit