-
-
Notifications
You must be signed in to change notification settings - Fork 45
Description
Description
When using git-spice to manage stacked PRs, GitHub Actions workflows with pull_request triggers are being kicked off twice for each PR in the stack after running gs upstack restack and gs stack submit. This occurs when the base branch (e.g., main) has changed while working on the stack.
Test Repository
I've created a public test repository to demonstrate this issue:
https://github.com/cerrorism/test-git-spice
You can examine the PRs, workflow runs, and event payloads directly.
Environment
- Tool: git-spice
- Repository: GitHub
- Workflow trigger:
pull_request(types:opened,synchronize,reopened)
Reproduction Steps
I can consistently reproduce this issue with the following steps:
- Create a stack with two branches (
stack-base-1andstack-base-2) - Submit both branches as PRs to GitHub:
- PR #1: "This is for git-spice test" (stack-base-1)
- PR #2: "stack base 2" (stack-base-2)
- Update the
mainbranch directly on GitHub (simulating another team member merging a PR) - Make changes to files in the mid-stack branch
- Run
gs upstack restack - Run
gs stack submit
Result: Both PRs trigger two separate GitHub Actions workflow runs each.
Concrete Evidence
Workflow Configuration
The test repository uses a simple workflow (.github/workflows/test.yaml.yml) that logs event details:
name: Automatic Test Execution
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Mock a test
run: |
echo "GitHub Event Name: ${{ github.event_name }}"
echo "Before SHA: ${{ github.event.before.sha }}"
echo "After SHA: ${{ github.event.after.sha }}"
echo "Base SHA: ${{ github.event.pull_request.base.sha }}}"Duplicate Runs
After running gs upstack restack and gs stack submit (following main branch changes), both PRs triggered duplicate workflow runs at the exact same timestamp:
PR #1 Duplicate Runs (created at 2025-12-05T18:34:37-38Z):
- Run 1: https://github.com/cerrorism/test-git-spice/actions/runs/19972454029
- Run 2: https://github.com/cerrorism/test-git-spice/actions/runs/19972453860
PR #2 Duplicate Runs (created at 2025-12-05T18:35:29Z):
- Run 1: https://github.com/cerrorism/test-git-spice/actions/runs/19972473937
- Run 2: https://github.com/cerrorism/test-git-spice/actions/runs/19972473821
Note that each pair of runs was created at the exact same second, confirming they were triggered by separate, nearly-simultaneous events.
Analysis
Findings
By examining the workflow logs in the test repository, I confirmed that the two events are not identical. Both events have:
- Same
beforeSHA - Same
afterSHA - Same event name:
pull_request - Same action type:
synchronize
However, the pull_request.base.sha values are different between the two events.
This suggests that git-spice is performing two separate operations that each trigger a pull_request synchronize event:
- Updating the PR's feature branch (head)
- Updating the PR's base reference
Impact
This duplicate triggering causes several issues:
1. Resource Waste
- Unnecessary compute resources consumed by duplicate pipeline runs
- Can be partially mitigated by adding a
concurrencygroup to cancel redundant runs
2. Branch Protection Rule Issues (Critical)
The more serious problem occurs with concurrency groups and branch protection rules:
- When two events are sent simultaneously, GitHub cannot guarantee which run gets cancelled
- Sometimes the first (top) run gets cancelled instead of the second
- If branch protection rules require specific checks to pass (e.g., "XXX check must be passed before merge"), a cancelled top run means the PR becomes stuck
- The PR will wait indefinitely for a successful check that will never complete
Expected Behavior
When updating stacked PRs after base branch changes, each PR should trigger only one pull_request synchronize event, not two.
This should be achievable because when performing the equivalent steps manually, no duplicate pipelines are triggered:
- Fetch
origin/main - Rebase the PR feature branch locally
- Push the feature branch once
With this manual approach:
- GitHub automatically detects and updates the base relationship
- Only one
pull_requestsynchronize event is triggered
Additional Context
The test repository at https://github.com/cerrorism/test-git-spice is public and was created specifically to reproduce this issue. You can:
- View the workflow file
- Examine the Actions tab to see all duplicate runs
- Check the specific workflow run logs linked above to see the event data differences
- Review the commit history showing the main branch changes
I've tested this multiple times and the behavior is consistently reproducible. Happy to provide additional logs, run more tests, or provide any other debugging information if needed.
Thank you for looking into this!