Skip to content

PR mode: FindExistingPR matches PRs from other branches due to HasPrefix #304

@alovak

Description

@alovak

Bug Description

In PR mode, FindExistingPR() in internal/git/git.go uses strings.HasPrefix to match PR titles. When the workflow runs on the main branch, the search pattern has no branch qualifier suffix, causing it to greedily match PRs created from other branches.

Steps to Reproduce

  1. Configure sdk_generation.yaml with mode: pr
  2. Run the workflow on a feature branch (e.g., release-sdks-on-api-release) — this creates a PR with title:
    "chore: 🐝 Update SDKs - Generate and Publish OpenAPI specs [release-sdks-on-api-release]"
  3. Run the workflow on main — it searches for a PR with title prefix:
    "chore: 🐝 Update SDKs - Generate and Publish OpenAPI specs"
  4. strings.HasPrefix matches the branch-specific PR from step 2, because the branch PR title starts with the main search pattern
  5. The action tries to reuse the branch from step 2, finds commits on it, and fails with:
    Error: external changes detected on branch speakeasy-sdk-regen-release-sdks-on-api-release-XXXXXXXXXX.
    The action cannot proceed because non-automated commits were pushed to this branch.
    

Root Cause

internal/git/git.go line 218:

if strings.HasPrefix(p.GetTitle(), prTitle) || strings.HasPrefix(p.GetTitle(), legacyPrTitle) {

When running from main:

  • prTitle = "chore: 🐝 Update SDKs - <workflow_name>" (no [branch] suffix)
  • A PR with title "chore: 🐝 Update SDKs - <workflow_name> [my-branch]" matches via HasPrefix

The existing base-branch guard at line 226 only activates when !isMainBranch, so it doesn't help here.

Suggested Fix

After the HasPrefix match, check whether the remainder of the title starts with [. When running from main (no branch qualifier expected), skip PRs that have a branch qualifier suffix:

matchedPrefix := prTitle
if !strings.HasPrefix(title, prTitle) {
    matchedPrefix = legacyPrTitle
}
remainder := strings.TrimPrefix(title, matchedPrefix)

if isMainBranch && environment.GetFeatureBranch() == "" && strings.HasPrefix(strings.TrimSpace(remainder), "[") {
    logging.Info("Skipping PR with branch qualifier that doesn't match current context: %s", title)
    continue
}

Additional Note

There's a secondary issue that contributes to the failure: the findNonCICommits() function doesn't recognize commits made by the action when enable_sdk_changelog is enabled. The changelog feature replaces the commit message (which normally starts with "ci: ") with a markdown report from GetCommitMarkdownSection(), causing those action-created commits to be classified as "non-CI" / "external" on subsequent runs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions