You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add a note for copilot-setup-steps.yml and using with a merge queue #43246
In the github docs, it says that you can add the following to you copilot-setup-steps.yml file:
name: "Copilot Setup Steps"## Background# Automatically run the setup steps when they are changed to allow for easy validation, and# allow manual testing through the repository's "Actions" tabon:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.ymlpull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
While this works, I've found that if you use a merge queue then using the above configuration results in your workflow running every time a PR is added to the merge queue. We are use the larger, custom image GitHub hosted runners and this results in unnecessary runs & costs.
github/copilot-sdk was the first public GitHub repo I found that had the same issue(although this one is just using default ubuntu-latest runners). It helped me figure out that behavior wasn't unique to our setup
Proposed Content Update
I'd like to update the docs to either add an inline comment with commented out code or add a little inline note about if using a merge queue. This is what ended up working for us:
name: "Copilot Setup Steps"# Automatically run when changed so setup issues surface immediately.# Also allows manual testing via the "Actions" tab.on:
workflow_dispatch:
push:
branches-ignore:
- 'gh-readonly-queue/**'paths:
- .github/workflows/copilot-setup-steps.ymlpull_request:
branches:
- mainpaths:
- .github/workflows/copilot-setup-steps.yml
A stale label has been added to this issue, because it has been open for 30 days with no activity. If you think this issue should remain open, please add a new comment.
A stale label has been added to this issue, because it has been open for 30 days with no activity. If you think this issue should remain open, please add a new comment.
@jonstacks Hi, thanks for raising an issue and a PR, and I'm sorry for the late reply here.
Based on your PR, I understand the recommended change you've made would've been useful for your specific use case. If I understand correctly, though, this recommendation wouldn't necessarily exclusively apply to that context, it's just that it would've been useful as you were reviewing that article(?)
Hi @subatoi, thank you for following up and sorry for the delay on my end! Since it's been several months since I originally opened this, I used AI to help re-investigate the exact mechanics, pull workflow logs, and help write up this response.
I found concrete evidence from GitHub's own public repositories showing that this isn't just an isolated user setup quirk—it is a direct consequence of the starter template YAML provided in the docs.
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.ymlpull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
The accompanying doc comment says:
# Automatically run the setup steps when they are changed to allow for easy validation
However, because push: does not specify a branches: filter, it defaults to listening on all branches and all Git tags. This causes two unexpected bypass behaviors:
Every Merge Queue entry triggers the workflow:
When a PR enters a merge queue, GitHub pushes a temporary merge commit to refs/heads/gh-readonly-queue/{base_branch}/{pr_id}. Because the push trigger has no branch restriction, GitHub Actions evaluates the push event on the newly created queue branch. On new branch pushes with synthetic merge commits, path filtering does not prevent execution, causing copilot-setup-steps.yml to trigger on every queued PR regardless of which files were modified.
"Path filters are not evaluated for pushes of tags."
Because path filters are skipped for tags, pushing any Git tag triggers copilot-setup-steps.yml unconditionally.
Concrete Examples in GitHub's own copilot-sdk repository
When added to the merge queue, github-merge-queue[bot] pushed branch gh-readonly-queue/main/pr-784-d71ef4c6e3c76218b098005b72f69dabd7fbdf1b, which immediately triggered Run 23060638347 of Copilot Setup Steps.
Interestingly, once merged into main, GitHub Actions evaluated docs/getting-started.md against main and correctly skippedCopilot Setup Steps. But it ran while in the queue.
Because the release bot pushed the tag refs/tags/go/v1.0.22, it bypassed the paths filter as per the Actions specification.
Why signposting to managing-a-merge-queue doesn't resolve this
User Journey & Expectations: Developers setting up Copilot Agent follow the Copilot documentation and copy the starter YAML. The comment in the snippet tells them it will only run when the setup steps change. They have no reason to suspect this validation workflow will fire on merge queues or release tags, and wouldn't think to look at merge queue documentation.
Content Gap: The managing-a-merge-queue documentation explains how to configure CI checks to run for merge groups (merge_group:). It does not provide guidance on how to prevent validation/utility workflows from unintentionally running on gh-readonly-queue/**.
Cost Impact: Because copilot-setup-steps.yml frequently uses larger GitHub-hosted runners or self-hosted runners to install heavy dependencies, running on every queue entry and tag push wastes significant compute and runner minutes.
Proposed Solutions
Option A (Recommended): Update the starter snippet in the article directly
Add branches: targeting the default branch to both triggers:
Why this works: Restricting to branches: [main] cleanly eliminates both problems in one shot—it ignores Git tag pushes (closing the tag bypass) and ignores temporary gh-readonly-queue/** branches, while still validating changes on PRs targeting main and pushes to main.
Option B: Include an inline callout/note
If the snippet remains open-ended, include a note directly in this section explaining that without branch restrictions, push.paths triggers on merge queue branches (gh-readonly-queue/**) and tag pushes, and recommend adding branches: [YOUR-DEFAULT-BRANCH] or branches-ignore: ['gh-readonly-queue/**'].
Would the team be open to updating the snippet directly (Option A) or incorporating the callout note (Option B as drafted in #43247)?
Activity
jameswillard515-gif commentedon Mar 6, 2026
Destop-Trang1801 commentedon Mar 7, 2026
Sharra-writes commentedon Mar 10, 2026
@jonstacks I'll take this to the Actions team and see what they think.
jonstacks commentedon Mar 20, 2026
Thank you, @Sharra-writes! I appreciate it.
github-actions commentedon Apr 20, 2026
A stale label has been added to this issue, because it has been open for 30 days with no activity. If you think this issue should remain open, please add a new comment.
github-actions commentedon Aug 24, 2026
A stale label has been added to this issue, because it has been open for 30 days with no activity. If you think this issue should remain open, please add a new comment.
subatoi commentedon Sep 9, 2026
@jonstacks Hi, thanks for raising an issue and a PR, and I'm sorry for the late reply here.
Based on your PR, I understand the recommended change you've made would've been useful for your specific use case. If I understand correctly, though, this recommendation wouldn't necessarily exclusively apply to that context, it's just that it would've been useful as you were reviewing that article(?)
I'm wondering if a simpler solution here would've helped, such as some more obvious signposting to https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue?
subatoi commentedon Oct 12, 2026
@jonstacks 👋 Hi, just to follow up if you've seen the above? Thank you
jonstacks commentedon Oct 15, 2026
Hi @subatoi, thank you for following up and sorry for the delay on my end! Since it's been several months since I originally opened this, I used AI to help re-investigate the exact mechanics, pull workflow logs, and help write up this response.
I found concrete evidence from GitHub's own public repositories showing that this isn't just an isolated user setup quirk—it is a direct consequence of the starter template YAML provided in the docs.
The Root Cause
In the Customize Copilot's environment article, the recommended starter YAML is:
The accompanying doc comment says:
However, because
push:does not specify abranches:filter, it defaults to listening on all branches and all Git tags. This causes two unexpected bypass behaviors:When a PR enters a merge queue, GitHub pushes a temporary merge commit to
refs/heads/gh-readonly-queue/{base_branch}/{pr_id}. Because thepushtrigger has no branch restriction, GitHub Actions evaluates the push event on the newly created queue branch. On new branch pushes with synthetic merge commits, path filtering does not prevent execution, causingcopilot-setup-steps.ymlto trigger on every queued PR regardless of which files were modified.According to the GitHub Actions workflow syntax documentation:
Concrete Examples in GitHub's own
copilot-sdkrepositoryThe
github/copilot-sdkrepository uses this exact template in.github/workflows/copilot-setup-steps.yml, and we can observe both failure modes in production:1. The Merge Queue Bypass
Look at commit
38603f28cb6e892857c9f64209360447fcc1ee8b(which merged PR #784):docs/getting-started.md. It did not touchcopilot-setup-steps.yml.github-merge-queue[bot]pushed branchgh-readonly-queue/main/pr-784-d71ef4c6e3c76218b098005b72f69dabd7fbdf1b, which immediately triggered Run 23060638347 ofCopilot Setup Steps.main, GitHub Actions evaluateddocs/getting-started.mdagainstmainand correctly skippedCopilot Setup Steps. But it ran while in the queue..devcontaineronly, Run 23060791638) and PR #783 (dotnet/only, Run 23060689124).2. The Tag Bypass
Look at commit
ffd25c775742f73e13a492093be0287d7885123f:nodejs/package.jsonandnodejs/src/cliVersion.ts.Copilot Setup Stepsran on Run 38629654860.116077712747), the checkout ref was:refs/tags/go/v1.0.22, it bypassed thepathsfilter as per the Actions specification.Why signposting to
managing-a-merge-queuedoesn't resolve thismanaging-a-merge-queuedocumentation explains how to configure CI checks to run for merge groups (merge_group:). It does not provide guidance on how to prevent validation/utility workflows from unintentionally running ongh-readonly-queue/**.copilot-setup-steps.ymlfrequently uses larger GitHub-hosted runners or self-hosted runners to install heavy dependencies, running on every queue entry and tag push wastes significant compute and runner minutes.Proposed Solutions
Option A (Recommended): Update the starter snippet in the article directly
Add
branches:targeting the default branch to both triggers:Why this works: Restricting to
branches: [main]cleanly eliminates both problems in one shot—it ignores Git tag pushes (closing the tag bypass) and ignores temporarygh-readonly-queue/**branches, while still validating changes on PRs targetingmainand pushes tomain.Option B: Include an inline callout/note
If the snippet remains open-ended, include a note directly in this section explaining that without branch restrictions,
push.pathstriggers on merge queue branches (gh-readonly-queue/**) and tag pushes, and recommend addingbranches: [YOUR-DEFAULT-BRANCH]orbranches-ignore: ['gh-readonly-queue/**'].Would the team be open to updating the snippet directly (Option A) or incorporating the callout note (Option B as drafted in #43247)?
subatoi commentedon Oct 15, 2026
OK, thank you—I'll add this for review by the relevant team, when possible