feat: remove default job-level concurrency (none is now the default)#18142
feat: remove default job-level concurrency (none is now the default)#18142
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…oncurrency Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
engine.concurrency: none to opt out of default job-level concurrency
|
@copilot set engine.concurrency: none as the default value |
…ency by default) Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in a87cf64. |
engine.concurrency: none to opt out of default job-level concurrency|
Hey This PR looks well-structured and ready for maintainer review. ✅ Here's the full evaluation summary:
Verdict: 🟢 Aligned — Quality: One small note for reviewers: the
|
workflow_dispatchworkflows that process individual issues were incorrectly serialized at the agent/detection job level because the compiler injected a sharedgh-aw-{engine-id}-${{ github.workflow }}concurrency group — overriding the user's intent expressed via workflow-levelconcurrency.Changes
pkg/workflow/engine.go: Recognize"none"as a special string value forengine.concurrency; store the sentinel directly instead of wrapping it in YAML concurrency block syntaxpkg/workflow/concurrency.go:GenerateJobConcurrencyConfig()now returns""by default — no job-level concurrency is injected unlessengine.concurrencyis explicitly set. Removed thehasSpecialTriggers()helper (no longer needed).pkg/workflow/concurrency_test.go: Updated tests to reflect the new default (no job-level concurrency forworkflow_dispatch,schedule, etc.); retained test for explicitengine.concurrency: nonepkg/parser/schemas/main_workflow_schema.json: Documentnoneas a valid value forengine.concurrencydocs/src/content/docs/reference/concurrency.md: Updated to reflect thatnoneis the default;engine.concurrencymust be explicitly set to opt in to job-level serializationBehavior
By default, no job-level concurrency group is applied to agent or detection jobs. Multiple workflow runs — even across different workflows — execute in parallel without engine-level serialization.
To opt in to job-level concurrency (e.g., to limit concurrent AI agent resource usage), set
engine.concurrencyexplicitly:The
nonevalue can also be set explicitly for clarity:Original prompt
This section details on the original issue you should resolve
<issue_title>Bug: Per-engine job concurrency blocks workflow_dispatch issue workflows from running in parallel</issue_title>
<issue_description>## Summary
The default per-engine job-level concurrency group (
gh-aw-{engine-id}-${{ github.workflow }}) preventsworkflow_dispatch-triggered issue workflows from processing different issues simultaneously. Two runs of the same workflow for different issues are serialized at the agent and detection job level, even though they operate on completely independent data.Reproduction
workflow_dispatch(noton: issues:):gh aw compileRoot Cause
In
pkg/workflow/concurrency.goGenerateJobConcurrencyConfig():hasSpecialTriggers()checksworkflowData.Onfor substrings like"issues","pull_request", etc. But workflows that useworkflow_dispatchto process issues (common for triage workflows triggered by other workflows) don't contain these substrings, so they fall through to the default engine-scoped concurrency.The compiled lock file gets:
Meanwhile, the workflow-level concurrency is correctly per-issue:
Evidence
Two runs on
bv/triage-aw2branch for different issues, dispatched simultaneously:Both eventually succeeded, but github/gh-aw#295537 was unnecessarily delayed by ~6 minutes waiting in the concurrency queue.
Interaction with workflow-level concurrency
The workflow-level concurrency (from the
.mdfrontmatter) correctly includes the issue number. When both levels are set:cancel-in-progress: truecancels runs for the same issue → correctThe user's intent (expressed via
concurrencyin the.md) is per-issue isolation. The compiler-injected job-level group overrides this for the agent/detection jobs.Suggested Fixes
Option A: Inherit workflow-level concurrency context
When the user has set a custom workflow-level
concurrencygroup, the job-level default should incorporate the same context variables. If the workflow concurrency group includesissue_number, the job group should too.Option B: Skip job concurrency when workflow concurrency is set
If the user explicitly defined
concurrencyin their.mdfrontmatter, don't inject the default per-engine job concurrency — the user has already expressed their concurrency intent.Option C: Allow
engine.concurrencyto suppress the defaultDocument that users can set
engine.concurrency: none(or similar) to opt out of the default job-level serialization.Workaround (current)
Users can manually edit the
.lock.ymlto remove theconcurrency:blocks from agent and detection jobs, but this is lost on recompile.Alternatively, set
engine.concurrencyin the.mdfrontmatter to include the issue number:Environment
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.