Skip to content

ci: limit push trigger to master to avoid duplicate runs on PRs#200

Merged
staryxchen merged 1 commit into
TencentCloud:masterfrom
staryxchen:worktree-fix-ci-double-trigger
May 12, 2026
Merged

ci: limit push trigger to master to avoid duplicate runs on PRs#200
staryxchen merged 1 commit into
TencentCloud:masterfrom
staryxchen:worktree-fix-ci-double-trigger

Conversation

@staryxchen
Copy link
Copy Markdown
Collaborator

@staryxchen staryxchen commented May 12, 2026

Summary

Stops every CI check on PRs from being executed twice. After this fix, each affected workflow runs exactly once per PR (via pull_request), instead of once via push and once via pull_request.

Why

Four workflows listen to both push and pull_request with the same paths. When a PR head branch is pushed (typical for Dependabot or any branch update), both events fire and produce two independent workflow runs. None of the existing concurrency blocks deduplicate them:

Workflow Concurrency status Why it does not dedup
build-check.yml group: build-check-${{ github.ref }} push ref is refs/heads/<branch>; pull_request ref is refs/pull/N/merge — different groups
build-builder-image.yml no concurrency block nothing to dedup with
build-envd-base-image.yml group: ...${{ github.ref }}... same as build-check
hypervisor-integration.yaml group includes ${{ github.event_name }} event_name itself is in the key, so push/pull_request never share a group

Real-world examples on the Build Check workflow:

The bug has existed since build-check.yml was first introduced in PR #61 (commit 85ab046, 2026-04-23); it just became visible recently as Dependabot PRs piled up.

What changed

For each of the four workflows, restrict push to the master branch only:

on:
  push:
    branches: [master]   # added
    paths: [...]
  pull_request:
    paths: [...]

PR validation continues to run on pull_request. Direct pushes to master (post-merge) keep triggering builds as before.

Affected files (4 lines added in total):

  • .github/workflows/build-check.yml
  • .github/workflows/build-builder-image.yml
  • .github/workflows/build-envd-base-image.yml
  • .github/workflows/hypervisor-integration.yaml

How to verify

This PR itself is the test case — it modifies all four workflow files, which are inside their own paths lists, so all four workflows will be triggered.

Note GitHub uses the base branch version of workflow files for pull_request events and the head branch version for push events. On this PR:

  • pull_request runs use master's old config → still fire once (this is the run we want to keep).
  • push event would use this branch's new config → skipped because the head branch is not master.

Net result: each workflow appears once in the PR checks list.

# Expect: count == 1 per workflow, events == ["pull_request"]
gh run list --branch worktree-fix-ci-double-trigger --repo TencentCloud/CubeSandbox \  --limit 50 --json event,name | \  jq 'group_by(.name) | map({name: .[0].name, count: length, events: [.[].event]})'

# Baseline (still 2 each, push + pull_request)
gh run list --branch dependabot/go_modules/network-agent/google.golang.org/grpc-1.79.3 \  --repo TencentCloud/CubeSandbox --limit 20 --json event,name

Test plan

Several workflows listen to both push and pull_request with overlapping
paths. When a PR head branch is pushed, GitHub fires both events, and
the existing concurrency keys cannot deduplicate them:
  - build-check / build-envd-base-image group by github.ref, which
    differs between push (refs/heads/<branch>) and pull_request
    (refs/pull/N/merge);
  - build-builder-image declares no concurrency block at all;
  - hypervisor-integration explicitly includes ${{ github.event_name }}
    in the concurrency key, which makes both runs coexist by design.

As a result, every check (Build CubeAPI, Build CubeMaster, ...) shows
up twice in the PR checks list, doubling CI cost for no benefit.
PR TencentCloud#195 and TencentCloud#196 are recent examples that triggered the duplicate
runs on Build Check.

Restrict the push trigger of the four affected workflows to the master
branch. PR validation now runs only via the pull_request event; direct
pushes to master remain covered.

Signed-off-by: staryxchen <staryxchen@tencent.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

Claude finished @staryxchen's task in 2m 57s —— View job


PR Review: ci: limit push trigger to master to avoid duplicate runs on PRs

  • Gather context: read changed files and git history
  • DCO check: verify all commits have Signed-off-by: trailer
  • Review code quality, correctness, and edge cases
  • Post inline comments for specific findings
  • Final summary

DCO Check

The single commit 9cb27be includes Signed-off-by: staryxchen <staryxchen@tencent.com> — DCO requirement is satisfied.

Overall Assessment

This is a clean, well-motivated, and minimal fix. The root cause analysis in the PR description is thorough and correct — each of the four workflows has a different reason why its concurrency block fails to deduplicate push/pull_request runs:

Workflow Why concurrency didn't help
build-check.yml github.ref differs between push and PR events
build-builder-image.yml No concurrency block at all
build-envd-base-image.yml Same github.ref mismatch
hypervisor-integration.yaml github.event_name explicitly in the key

Adding branches: [master] to the push trigger is the right fix — it eliminates the duplicate at the source rather than trying to deduplicate after the fact.

Specific Observations

  1. paths lists are consistent — All four files have matching paths for both push and pull_request, so path-based filtering works correctly after the change.

  2. No other workflows are affected — I checked the remaining pull_request workflows (dco-check.yml only has pull_request, code-review.yml uses pull_request_target, claude-response.yml is action-triggered). No other workflows have the double-trigger pattern.

  3. Release branch consideration — Direct pushes to non-master branches (e.g., a release/v1.x branch) will no longer trigger these workflows. This is a deliberate tradeoff and the workflow_dispatch trigger on all four workflows provides a manual fallback. Worth keeping in mind if the repo adds long-lived release branches.

  4. hypervisor-integration.yaml concurrency key — The key still includes ${{ github.event_name }} (line 16). With this fix, push only fires on master, so the event_name component is now redundant for the push case (no competing pull_request for the same commit on master). Not a bug — just a candidate for future cleanup. No action needed here.

  5. Consistency with existing push guardsbuild-builder-image.yml and build-envd-base-image.yml already guard their push-to-GHCR steps with github.ref == 'refs/heads/master' (lines 33/54 and 53/117 respectively). The branches: [master] filter is consistent with these existing guards — image publishing only ever happened on master pushes anyway.

Verdict

No issues found. The change is correct, minimal, and well-documented. The fix directly addresses the root cause and the PR description includes clear verification steps.


@staryxchen staryxchen merged commit b2eade2 into TencentCloud:master May 12, 2026
12 of 13 checks passed
@staryxchen staryxchen deleted the worktree-fix-ci-double-trigger branch May 12, 2026 04:33
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