Skip to content

Commit d6c909b

Browse files
Restore single caller concurrency policy
Return caller guidance and direct workflow tests to the experimentally adopted workflow-level concurrency group and one reusable-workflow calling job. Keep public caller permissions scoped to that job. Co-authored-by: Copilot <223556698+Copilot@users.noreply.github.com>
1 parent a157acf commit d6c909b

10 files changed

Lines changed: 101 additions & 223 deletions

File tree

.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -154,28 +154,13 @@ on:
154154
- labeled
155155
- unlabeled
156156

157-
jobs:
158-
Process-PSModule-Production:
159-
if: ${{ github.event_name != 'pull_request' }}
160-
concurrency:
161-
group: ${{ github.workflow }}-${{ github.ref }}
162-
queue: max
163-
permissions:
164-
contents: read
165-
pages: write
166-
id-token: write
167-
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8
168-
secrets:
169-
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
170-
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
171-
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
157+
concurrency:
158+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
159+
queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }}
160+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
172161

173-
Process-PSModule-PullRequest:
174-
if: ${{ github.event_name == 'pull_request' }}
175-
concurrency:
176-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
177-
queue: single
178-
cancel-in-progress: true
162+
jobs:
163+
Process-PSModule:
179164
permissions:
180165
contents: read
181166
pages: write
@@ -187,10 +172,11 @@ jobs:
187172
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
188173
```
189174
190-
The only permitted variation is an optional identical `TestData` entry under both caller jobs' `secrets` mappings.
191-
Do not add `with:` inputs, extra jobs, conditions, schedule changes, `run-name`, permission changes, trigger changes,
192-
concurrency changes, debug options, or version overrides. Repository-owned automation belongs in separate workflow
193-
files.
175+
The only permitted variation is an optional `TestData` entry under
176+
`jobs.Process-PSModule.secrets`. Do not add `with:` inputs, extra jobs,
177+
conditions, schedule changes, `run-name`, permission changes, trigger changes,
178+
concurrency changes, debug options, or version overrides. Repository-owned
179+
automation belongs in separate workflow files.
194180

195181
### TestData preservation
196182

.github/workflows/Workflow-Test-Default.yml

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,16 @@ on:
3030
schedule:
3131
- cron: '0 0 * * *'
3232

33+
concurrency:
34+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
35+
queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }}
36+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
37+
3338
permissions: {}
3439

3540
jobs:
3641
WorkflowTestDefault:
37-
if: ${{ github.event_name != 'pull_request' }}
38-
concurrency:
39-
group: ${{ github.workflow }}-${{ github.ref }}
40-
queue: max
41-
permissions:
42-
contents: read
43-
pages: write
44-
id-token: write
45-
uses: ./.github/workflows/workflow.yml
46-
secrets:
47-
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
48-
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
49-
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
50-
TestData: >-
51-
{
52-
"secrets": {
53-
"PSMODULE_TEST_SINGLELINE_SECRET": "${{ secrets.PSMODULE_TEST_SINGLELINE_SECRET }}"
54-
},
55-
"variables": {
56-
"PSMODULE_TEST_VARIABLE": ${{ toJSON(vars.PSMODULE_TEST_VARIABLE) }}
57-
}
58-
}
59-
with:
60-
WorkingDirectory: tests/srcTestRepo
61-
ImportantFilePatterns: |
62-
^tests/srcTestRepo/
63-
^\.github/actions/
64-
^\.github/workflows/(?!Release\.yml$|Linter\.yml$)
65-
66-
WorkflowTestDefaultPullRequest:
67-
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
68-
concurrency:
69-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
70-
queue: single
71-
cancel-in-progress: true
42+
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
7243
permissions:
7344
contents: read
7445
pages: write
@@ -95,15 +66,11 @@ jobs:
9566
^\.github/workflows/(?!Release\.yml$|Linter\.yml$)
9667
9768
VerifyRootFunctionsIndexDefault:
98-
if: >-
99-
${{ always() && github.event.action != 'closed' &&
100-
(needs.WorkflowTestDefault.result == 'success' ||
101-
needs.WorkflowTestDefaultPullRequest.result == 'success') }}
69+
if: github.event.action != 'closed'
10270
name: Verify root Functions index [Default]
10371
runs-on: ubuntu-latest
10472
needs:
10573
- WorkflowTestDefault
106-
- WorkflowTestDefaultPullRequest
10774
permissions:
10875
contents: read
10976
steps:

.github/workflows/Workflow-Test-WithManifest.yml

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,16 @@ on:
3030
schedule:
3131
- cron: '0 0 * * *'
3232

33+
concurrency:
34+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
35+
queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }}
36+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
37+
3338
permissions: {}
3439

3540
jobs:
3641
WorkflowTestWithManifest:
37-
if: ${{ github.event_name != 'pull_request' }}
38-
concurrency:
39-
group: ${{ github.workflow }}-${{ github.ref }}
40-
queue: max
41-
permissions:
42-
contents: read
43-
pages: write
44-
id-token: write
45-
uses: ./.github/workflows/workflow.yml
46-
secrets:
47-
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
48-
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
49-
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
50-
TestData: >-
51-
{
52-
"secrets": {
53-
"PSMODULE_TEST_SINGLELINE_SECRET": "${{ secrets.PSMODULE_TEST_SINGLELINE_SECRET }}"
54-
},
55-
"variables": {
56-
"PSMODULE_TEST_VARIABLE": ${{ toJSON(vars.PSMODULE_TEST_VARIABLE) }}
57-
}
58-
}
59-
with:
60-
WorkingDirectory: tests/srcWithManifestTestRepo
61-
ImportantFilePatterns: |
62-
^tests/srcWithManifestTestRepo/
63-
^\.github/actions/
64-
^\.github/workflows/(?!Release\.yml$|Linter\.yml$)
65-
66-
WorkflowTestWithManifestPullRequest:
67-
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
68-
concurrency:
69-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
70-
queue: single
71-
cancel-in-progress: true
42+
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
7243
permissions:
7344
contents: read
7445
pages: write
@@ -95,15 +66,11 @@ jobs:
9566
^\.github/workflows/(?!Release\.yml$|Linter\.yml$)
9667
9768
VerifyRootFunctionsIndexWithManifest:
98-
if: >-
99-
${{ always() && github.event.action != 'closed' &&
100-
(needs.WorkflowTestWithManifest.result == 'success' ||
101-
needs.WorkflowTestWithManifestPullRequest.result == 'success') }}
69+
if: github.event.action != 'closed'
10270
name: Verify root Functions index [WithManifest]
10371
runs-on: ubuntu-latest
10472
needs:
10573
- WorkflowTestWithManifest
106-
- WorkflowTestWithManifestPullRequest
10774
permissions:
10875
contents: read
10976
steps:

docs/content/get-started/repository-setup.md

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -71,28 +71,13 @@ on:
7171
- labeled
7272
- unlabeled
7373

74-
jobs:
75-
Process-PSModule-Production:
76-
if: ${{ github.event_name != 'pull_request' }}
77-
concurrency:
78-
group: ${{ github.workflow }}-${{ github.ref }}
79-
queue: max
80-
permissions:
81-
contents: read
82-
pages: write
83-
id-token: write
84-
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8
85-
secrets:
86-
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
87-
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
88-
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
74+
concurrency:
75+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
76+
queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }}
77+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
8978

90-
Process-PSModule-PullRequest:
91-
if: ${{ github.event_name == 'pull_request' }}
92-
concurrency:
93-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
94-
queue: single
95-
cancel-in-progress: true
79+
jobs:
80+
Process-PSModule:
9681
permissions:
9782
contents: read
9883
pages: write
@@ -104,16 +89,16 @@ jobs:
10489
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
10590
```
10691
107-
Every permission on the calling jobs is required. GitHub App installation tokens perform repository writes. A push to
92+
Every permission on the calling job is required. GitHub App installation tokens perform repository writes. A push to
10893
`main` publishes a stable release after the full pipeline passes; the pull-request trigger handles CI, prereleases,
10994
and prerelease cleanup. See
11095
[Workflow inputs](../reference/workflow-inputs.md) for what each permission is used for, and
11196
[Calling the workflow](../guides/calling-the-workflow.md) for passing test secrets and variables.
11297

113-
The production job retains pushes, dispatches, and scheduled work in the maximum native queue. The pull-request job
114-
cancels obsolete activity and uses the pull-request number for every action, including `closed`. GitHub requires a
115-
literal queue value and does not permit cancellation with `queue: max`, so the two jobs use separate compatible
116-
policies. Keep both groups distinct from the reusable workflow's prefixed group.
98+
The caller-level concurrency block retains production, dispatch, and scheduled work in the maximum native queue while
99+
replacing obsolete activity for the same pull request. Its fallback expression uses the pull-request number for every
100+
pull-request action, including `closed`; other events use their Git ref. Keep its group distinct from the reusable
101+
workflow's prefixed group.
117102

118103
## 5. Configure the settings file
119104

docs/content/guides/calling-the-workflow.md

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,13 @@ on:
3636
- labeled
3737
- unlabeled
3838

39-
jobs:
40-
Process-PSModule-Production:
41-
if: ${{ github.event_name != 'pull_request' }}
42-
concurrency:
43-
group: ${{ github.workflow }}-${{ github.ref }}
44-
queue: max
45-
permissions:
46-
contents: read
47-
pages: write
48-
id-token: write
49-
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8
50-
secrets:
51-
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
52-
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
53-
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
39+
concurrency:
40+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
41+
queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }}
42+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
5443

55-
Process-PSModule-PullRequest:
56-
if: ${{ github.event_name == 'pull_request' }}
57-
concurrency:
58-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
59-
queue: single
60-
cancel-in-progress: true
44+
jobs:
45+
Process-PSModule:
6146
permissions:
6247
contents: read
6348
pages: write
@@ -75,11 +60,10 @@ Stable releases are evaluated from a push to the default branch. A merged pull r
7560
release notes; a direct default-branch push or a manual dispatch uses the default `Patch` bump and commit-based notes.
7661
Keep the `pull_request` trigger for CI, prereleases, and prerelease cleanup.
7762

78-
The production job serializes default-branch pushes, manual releases, and scheduled work in the maximum native queue.
79-
The pull-request job uses a separate group for each pull request, so a close event interrupts only its own activity and
80-
does not block the resulting stable release. Its `single` queue and cancellation replace obsolete activity. GitHub
81-
requires a literal queue value and rejects cancellation with `queue: max`, so these policies must remain separate.
82-
The reusable workflow uses a distinct prefixed concurrency group. Do not give either caller job that group name.
63+
The concurrency group uses the pull-request number when available and the Git ref otherwise, so a close event
64+
interrupts only its own pull-request activity and does not block the resulting stable release. Pull-request events use
65+
the `single` queue and cancel obsolete activity; other events use the maximum native queue without cancellation. The
66+
reusable workflow uses a distinct prefixed concurrency group. Do not give the caller that group name.
8367

8468
## Passing test data
8569

@@ -101,9 +85,9 @@ The reusable workflow accepts test data through `TestData` and no longer declare
10185
- `TEST_USER_USER_FG_PAT`
10286
- `TEST_USER_PAT`
10387

104-
If a caller passed any of these secrets directly, place them in the `secrets` map inside `TestData`. Add the same
105-
`TestData` mapping to the `secrets` block of both caller jobs. The environment variable names used by the tests can
106-
stay the same; only the workflow-call interface changes:
88+
If a caller passed any of these secrets directly, place them in the `secrets` map inside `TestData`. Add the
89+
`TestData` mapping to the calling job's `secrets` block. The environment variable names used by the tests can stay the
90+
same; only the workflow-call interface changes:
10791

10892
```yaml
10993
TestData: >-
@@ -122,8 +106,8 @@ workflow. It is one JSON object with two maps, so everything the tests need is v
122106
```
123107

124108
Values under `secrets` are masked in the logs; values under `variables` are not. Build it in the calling workflow and
125-
pass it through the `secrets:` blocks of both caller jobs so the whole blob is masked. Reference each secret directly
126-
as `"${{ secrets.<name> }}"` and each variable as `${{ toJSON(vars.<name>) }}`. A folded `>-` scalar keeps the source
109+
pass it through the calling job's `secrets:` block so the whole blob is masked. Reference each secret directly as
110+
`"${{ secrets.<name> }}"` and each variable as `${{ toJSON(vars.<name>) }}`. A folded `>-` scalar keeps the source
127111
readable while producing a single-line value, as long as the JSON content lines stay at the same indentation level:
128112

129113
```yaml

docs/content/guides/github-app-authentication.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,11 @@ The reusable workflow declares three required secrets at its `workflow_call` bou
1919
| `GitHubAppPrivateKey` | The GitHub App private key passed to the token action. |
2020

2121
The names are the reusable workflow contract, not a requirement for the caller's repository or organization secret
22-
names. Map the caller's secrets explicitly in both caller jobs:
22+
names. Map the caller's secrets explicitly in the calling job:
2323

2424
```yaml
2525
jobs:
26-
Process-PSModule-Production:
27-
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8
28-
secrets:
29-
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
30-
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
31-
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
32-
33-
Process-PSModule-PullRequest:
26+
Process-PSModule:
3427
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8
3528
secrets:
3629
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}

docs/content/reference/repository-standard.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,15 @@ repository. Name it `Process-PSModule.yml`, matching
124124
`workflow.yml` is the reusable workflow's own filename inside `PSModule/Process-PSModule` and belongs only in the
125125
`uses:` reference.
126126

127-
The caller uses these mutually exclusive jobs:
127+
The caller uses one `Process-PSModule` job. Its workflow-level concurrency group uses the pull-request number when
128+
available and the Git ref otherwise. Pull-request events use `queue: single` and cancel obsolete activity; other
129+
events use `queue: max` without cancellation.
128130

129-
| Job | Events | Concurrency policy |
130-
| --- | --- | --- |
131-
| `Process-PSModule-Production` | Non-pull-request events | Group by Git ref with `queue: max`; do not cancel runs. |
132-
| `Process-PSModule-PullRequest` | Pull-request events | Group by pull-request number with `queue: single`; cancel obsolete runs. |
133-
134-
Both jobs use the same reusable-workflow reference, required job-level permissions, and explicit `PSGALLERY_API_KEY`,
131+
The job uses the reusable-workflow reference, required job-level permissions, and explicit `PSGALLERY_API_KEY`,
135132
`GitHubAppClientId`, and `GitHubAppPrivateKey` mapping. The exact
136133
[caller template](../guides/calling-the-workflow.md) is part of this standard. Use the controlled
137134
`PSModule/Process-PSModule` `@v8` major reference; pin external Actions dependencies to a commit SHA with the version
138-
tag in a trailing comment so Dependabot can update them. Permissions are declared only on the caller jobs, not at the
135+
tag in a trailing comment so Dependabot can update them. Permissions are declared only on the calling job, not at the
139136
workflow root.
140137

141138
## Required common files

docs/content/specification/design.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ documented in [Workflow inputs](../reference/workflow-inputs.md).
2020
### Trigger admission
2121

2222
The [workflow trigger design](workflow-triggers/design.md) owns caller admission before processing: a retained
23-
production queue and replaceable pull-request activity. The caller jobs cover each complete reusable-workflow call
24-
through its final enabled stage; the reusable workflow identifies closure and performs optional prerelease cleanup.
23+
production queue and replaceable pull-request activity. The caller-level concurrency group covers each complete
24+
reusable-workflow call through its final enabled stage; the reusable workflow identifies closure and performs optional
25+
prerelease cleanup.
2526

2627
### Composed reusable workflows
2728

0 commit comments

Comments
 (0)