Skip to content

ci: fix false-positive issue dedup in go-version-check - #4834

Open
Behzad Mirkhanzadeh (behzad-mir) wants to merge 1 commit into
masterfrom
fix/go-version-dedup-exact-match
Open

ci: fix false-positive issue dedup in go-version-check#4834
Behzad Mirkhanzadeh (behzad-mir) wants to merge 1 commit into
masterfrom
fix/go-version-dedup-exact-match

Conversation

@behzad-mir

Copy link
Copy Markdown
Contributor

Problem

All four issue-dedup checks in go-version-check.yaml used:

gh issue list --repo "$REPO" --state open --search "$MARKER" ...

--search goes through GitHub's full-text index, which tokenizes markers like go-minor-update:1.27.1 on -, : and . and returns results by relevance, not exact content. So it matches unrelated issues.

Observed failure

In run 33692611337 the Tier 3 job searched for go-minor-update:1.27.1 and matched two Release Tracking issues that do not contain the marker anywhere:

#4667  🔄 Release Tracking: v1.8.12   -> contains marker: 0
#4541  🔄 Release Tracking: v1.8.11   -> contains marker: 0

existing_count became 2, so the gate if: steps.existing.outputs.existing_count == '0' failed and the "Create issue and assign Copilot agent" step never ran.

The job still reported success — skipping a step is not a failure — so the Go 1.27 upgrade issue was silently never created. It had to be created by hand (#4832).

Fix

Match the marker as an exact substring of the issue body:

EXISTING=$(gh issue list --repo "$REPO" --state open --limit 200 --json number,body \
  | jq --arg m "$MARKER" 'map(select((.body // "") | contains($m))) | length')

Applied to all four dedup sites:

Job Marker
auto-bump go-patch-update:* / go-digest-update:*
backport-release (prereq) fips-prereq:*
backport-release go-backport:*
minor-upgrade-agent go-minor-update:*

Also added a ::notice:: with the match count so a suppressed creation is visible in the logs rather than silent.

Verification

Run against the live repo, old vs new:

Marker old (--search) new (exact) Correct
go-minor-update:1.27.1 3 1 ✅ only #4832 contains it
go-minor-update:1.27.0 1 0 #4748 is closed
go-patch-update:1.26.8 0 0

YAML parses cleanly (yaml.safe_load).

Impact

Without this, any tier (digest refresh, patch bump, backport, minor upgrade) can silently fail to create its issue whenever the marker happens to score against an unrelated open issue — with a green check mark.

Related

The dedup checks used `gh issue list --search "$MARKER"`, which relies on
GitHub's full-text index. That index tokenizes markers like
`go-minor-update:1.27.1` on `-`, `:` and `.`, so it matches unrelated
issues by relevance rather than by exact content.

Observed in run 33692611337: the Tier 3 job searched for
`go-minor-update:1.27.1` and matched two "Release Tracking" issues
(#4667, #4541) that do not contain the marker at all. `existing_count`
became 2, the `== '0'` gate failed, and the "Create issue and assign
Copilot agent" step was skipped. The job still reported success, so the
upgrade issue was never created and the failure was silent.

Replace all four dedup sites (auto-bump, fips-prereq, backport, minor
upgrade) with an exact substring match over open issue bodies via jq.

Verified against the live repo:

  marker                    old(search)   new(exact)
  go-minor-update:1.27.1        3             1   <- only #4832 has it
  go-minor-update:1.27.0        1             0   <- #4748 is closed
  go-patch-update:1.26.8        0             0

Also emit a notice with the match count so a suppressed creation is
visible in the logs instead of silent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b043d9fe-4797-42bf-9482-c337444c5a6f
Copilot AI lite review requested due to automatic review settings September 2, 2026 23:03
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new contains($MARKER) logic can still false-match via prefix collisions (e.g. ...:1.27.1 matching ...:1.27.10), so dedup may still suppress issue creation incorrectly.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Updates the go-version-check GitHub Actions workflow to avoid false-positive issue deduplication when detecting existing Go upgrade/patch/backport issues, so automation doesn’t silently skip creating the required tracking issues.

Changes:

  • Replaces gh issue list --search ... (full-text indexed, tokenized) with a --json ... | jq contains(...) substring scan over issue bodies for dedup.
  • Adds additional log notices (notably for the minor-upgrade gate) to make dedup outcomes visible in job logs.
File summaries
File Description
.github/workflows/go-version-check.yaml Switches issue-dedup logic from --search to body substring matching to prevent unrelated issues from suppressing automation.
Review details

Suppressed comments (3)

.github/workflows/go-version-check.yaml:455

  • This dedup check can still be tripped by prefix matches (e.g. fips-prereq:release/v1.7 would match fips-prereq:release/v1.70) because it searches for the raw marker substring. Since the issue body includes the marker as an HTML comment (<!-- ${MARKER} -->), matching that exact token avoids version/branch prefix collisions.
          EXISTING_ISSUE=$(gh issue list --repo "$REPO" --state open --limit 200 --json number,body \
            | jq -r --arg m "$MARKER" 'map(select((.body // "") | contains($m))) | .[0].number // empty')

.github/workflows/go-version-check.yaml:593

  • The exact-match count still uses the raw marker substring. This can incorrectly count an issue whose marker merely shares a prefix (e.g. go-minor-update:1.27.10 would be counted when searching for go-minor-update:1.27.1). Matching the full HTML comment token (<!-- ${MARKER} -->) avoids these collisions.
            --limit 200 \
            --json number,body \
            | jq --arg m "$MARKER" 'map(select((.body // "") | contains($m))) | length')

.github/workflows/go-version-check.yaml:508

  • Dedup currently matches the raw marker substring, which can still yield false positives via prefix matches (e.g. go-backport:...:patch matching a longer marker). Since the issue body embeds the marker as <!-- ${MARKER} -->, matching that full token makes the dedup exact and avoids suppressing issue creation incorrectly.
          EXISTING_ISSUE=$(gh issue list --repo "$REPO" --state open --limit 200 --json number,body \
            | jq -r --arg m "$MARKER" 'map(select((.body // "") | contains($m))) | .[0].number // empty')
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +328 to +329
EXISTING_ISSUE=$(gh issue list --repo "$REPO" --state open --limit 200 --json number,body \
| jq -r --arg m "$MARKER" 'map(select((.body // "") | contains($m))) | .[0].number // empty')
Behzad Mirkhanzadeh (behzad-mir) added a commit that referenced this pull request Sep 2, 2026
…t-instructions

Follow-up to the worktree diagnosis. Two changes, one probabilistic and
one not:

1. .github/copilot-instructions.md — move the cloud-agent exception here,
   above the line that pulls in agents.md. This is the file the coding
   agent loads automatically and first, and its opening line is what
   routes agents.md (and therefore the worktree mandate) to the agent in
   the first place. Putting the carve-out ahead of that line gives it the
   best chance of being applied. This is still an instruction to a model,
   so it reduces the failure rate rather than eliminating it.

2. .github/workflows/empty-pr-guard.yml — a check that does not depend on
   the agent behaving correctly. It reads changed_files from the PR API
   and fails when an agent-authored branch (copilot/*, auto/*) changes
   zero files. Human branches are exempt, since intentionally empty PRs
   are legitimate.

Simulated against the known cases:

  PR #4833  copilot/chore-upgrade-go-1-26-to-1-27-1  0 files  -> FAIL
  PR #4756  copilot/acn-go-version-bump-again        0 files  -> FAIL
  PR #4834  fix/go-version-dedup-exact-match         1 file   -> PASS

Both empty PRs previously reported success with green checks, which is
why the problem went unnoticed for two rounds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b043d9fe-4797-42bf-9482-c337444c5a6f
@github-actions github-actions Bot mentioned this pull request Sep 4, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants