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
Copy file name to clipboardExpand all lines: docs/content/reference/process-workflow-lifecycle-design.md
+28-29Lines changed: 28 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,19 +19,19 @@ These facts establish the starting point. They do not implement the scheduled va
19
19
20
20
## Candidate event routing
21
21
22
-
The planner classifies the caller event before build and publication work begins. Each route produces one of three mutation classes: validation only, prerelease mutation, or stable-release mutation. The candidate also assigns an explicit mutability mode, because callers cannot safely infer it from labels alone.
22
+
The planner classifies the caller event before build and publication work begins. Each route produces one of three mutation classes: validation only, prerelease mutation, or stable-release mutation. Pull-request events may cancel their predecessors, so every pull-request route must converge to the latest pull-request state.
|`workflow_dispatch` on the default branch | Recovery release | Stable release or explicit no-op | Never cancel | Rebuild and validate the selected commit; reconstruct the unreleased release notes. |
27
-
|`schedule`| Published-artifact validation | Validation only |May cancel only another explicitly read-only validation; never cancel a default-branch release| Validate the latest published stable artifact and its documentation. |
28
-
| Pull request `opened`, `reopened`, `synchronize`| Pull-request CI |Explicitly read-only |May cancel a superseded run in the same read-only CI domain| Report configured validation on the pull request. |
29
-
| Pull request `labeled`, `unlabeled`| Prerelease evaluation |Potential prerelease mutation | Never cancel| Re-evaluate the full label set and publish only an eligible prerelease. |
30
-
| Merged pull request `closed`| Post-merge close | Validation only |May cancel only when explicitly routed as read-only| Do not clean up; the successful main-push release owns promotion cleanup. |
31
-
| Abandoned pull request `closed`| Pull-request cleanup | Prerelease cleanup only |Never cancel| Remove only prereleases owned by the abandoned pull request. |
27
+
|`schedule`| Published-artifact validation | Validation only |Never cancel | Validate the latest published stable artifact and its documentation. |
28
+
| Pull request `opened`, `reopened`, `synchronize`| Pull-request CI |Validation only |Cancels a superseded pull-request run; the later run converges state| Report configured validation on the pull request. |
29
+
| Pull request `labeled`, `unlabeled`| Prerelease evaluation |Prerelease or validation only | Cancels a superseded pull-request run; the later run converges state| Re-evaluate the full label set and publish only an eligible prerelease. |
30
+
| Merged pull request `closed`| Post-merge close | Validation only |Cancels a superseded pull-request run; the later run converges state| Do not clean up; the successful main-push release owns promotion cleanup. |
31
+
| Abandoned pull request `closed`| Pull-request cleanup | Prerelease cleanup only |Cancels a superseded pull-request run; the later run converges state| Remove only prereleases owned by the abandoned pull request. |
32
32
| Push to the default branch | Stable release | Stable release | Never cancel | Resolve merged-pull-request intent when applicable, then publish and perform promotion cleanup after required gates. |
33
33
34
-
The classifier records the route, mutability mode, mutable resource scope, commit identity, and release decision in the plan result. Downstream jobs consume that record rather than infer the event again.
34
+
The classifier records the route, mutable resource scope, commit identity, and release decision in the plan result. Downstream jobs consume that record rather than infer the event again.
35
35
36
36
## Candidate artifact and version boundary
37
37
@@ -64,31 +64,29 @@ A merged pull-request close performs no prerelease cleanup because the default-b
64
64
65
65
The alternative of never cleaning up on a close requires scheduled garbage collection and leaves abandoned prereleases available until that collection runs. This candidate selects abandoned-close cleanup instead; it does not change the existing unapproved caller contract.
66
66
67
-
## Candidate concurrency isolation
67
+
## Candidate concurrency and recovery
68
68
69
-
Cancellation is conditional, not globally disabled. Only an explicit read-only mode may cancel a superseded run. A route that can mutate an external release resource never cancels and is never canceled.
| Explicitly read-only pull-request CI | Pull request number and read-only mode | Superseded runs may cancel | None. |
74
-
| Prerelease evaluation and abandoned-close cleanup | Pull request number and mutation mode | Never cancel | Prerelease artifacts associated with that pull request. |
75
-
| Default-branch push and manual recovery | Default-branch ref and mutation mode | Never cancel | Stable package, GitHub Release, tag, uploads, Pages, and promotion cleanup. |
76
-
| Scheduled validation | Published-version read domain | May cancel only another explicit scheduled validation | None. |
Concurrency selection occurs before the reusable workflow can produce a planner output. The candidate therefore requires either an explicit event mode at the caller boundary or separate read-only and mutation workflow domains. Caller-level label inspection is insufficient: repository settings can make a label event release-capable. Manual and scheduled runs must not share a cancellation domain that can cancel a default-branch release.
77
+
This is a candidate, not an approved caller contract. All pull-request events for one pull request share a group and may cancel an earlier run. Push, manual-dispatch, and scheduled events serialize by ref and never cancel; a manual dispatch or schedule therefore cannot interrupt a main release.
79
78
80
-
Cleanup receives a pull-request-scoped artifact set and MUST NOT perform a broad prerelease deletion while a stable release can be active. Any future broad cleanup needs a separately approved exclusive scope; it cannot share the abandoned-close route.
81
-
82
-
## Why mutation-capable runs never cancel
83
-
84
-
Cancellation after an external mutation begins can leave the release lifecycle partially complete:
79
+
Cancellation can leave only transient partial state. Every pull-request route, including prerelease publication and abandoned-close cleanup, resumes and reconciles on the next `synchronize`, `labeled`, `unlabeled`, or `closed` event:
| PowerShell Gallery publication | The package can publish before the GitHub Release, release-asset upload, or pull-request comment completes. |
89
-
| Prerelease cleanup | Cleanup can delete only part of a prerelease tag and release set. |
90
-
| Default-branch release | A main release can stop between package publication, tag or GitHub Release creation, uploads, comments, Pages deployment, and promotion cleanup. |
91
-
| Manual or scheduled run sharing a ref | A cancellation domain keyed only by ref can interrupt a main release with a manual dispatch or scheduled validation. |
83
+
| PowerShell Gallery publication | Detect the existing resolved version and continue without duplicate publication. |
84
+
| GitHub Release creation | Resume or upsert the release and replace its asset set. |
85
+
| Prerelease cleanup | Repeat safely after partial deletion and converge to the latest pull-request state. |
86
+
| Prerelease lifecycle | A subsequent synchronize, label, unlabel, or close reconciles obsolete prereleases. |
87
+
| Production boundary | No pull-request event creates a stable or signable production artifact. |
88
+
89
+
Cleanup receives a pull-request-scoped artifact set and MUST NOT perform a broad prerelease deletion while a stable release can be active. Any future broad cleanup needs a separately approved exclusive scope; it cannot share the abandoned-close route.
92
90
93
91
## Candidate verification strategy
94
92
@@ -100,7 +98,8 @@ The lifecycle contract is exercised with event payload fixtures and publication
100
98
| Version boundary | A mismatched artifact fixture that proves publication stops. |
101
99
| Recovery release notes | Merged-pull-request query fixtures covering an empty range, one pull request, and multiple pull requests. |
102
100
| Scheduled validation | A published-version fixture that proves no release mutation is requested. |
103
-
| Conditional cancellation | A superseded read-only CI fixture plus release-capable label, cleanup, main-push, manual, and scheduled fixtures that prove mutation-capable runs do not cancel. |
101
+
| Pull-request convergence | Canceled prerelease-publication and cleanup fixtures followed by synchronize, label, unlabel, and close events that prove the latest pull-request state is reconciled. |
102
+
| Non-pull-request serialization | Overlapping main-push, manual-dispatch, and scheduled fixtures that prove runs queue by ref and do not cancel. |
104
103
105
104
## Decisions requiring approval
106
105
@@ -110,7 +109,7 @@ The candidate does not decide the following:
110
109
- Which source is authoritative when a PowerShell Gallery publication and GitHub release disagree about the last published stable version.
111
110
- Which consumer-facing checks comprise scheduled published-artifact validation.
112
111
- Whether removing prerelease eligibility cleans up existing prereleases immediately or leaves them until the abandoned-close cleanup route.
113
-
-The exact caller triggers and concurrency expression, which remain subject to[PSModule/Process-PSModule#514](https://github.com/PSModule/Process-PSModule/issues/514).
112
+
- Approval of the selected caller concurrency expression in [PSModule/Process-PSModule#514](https://github.com/PSModule/Process-PSModule/issues/514).
Copy file name to clipboardExpand all lines: docs/content/reference/process-workflow-lifecycle-specification.md
+48-19Lines changed: 48 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -165,29 +165,23 @@ Scenario: Retry a publication after an interrupted run
165
165
And it does not duplicate the package, tag, or release
166
166
```
167
167
168
-
### NFR2 — Cancellation MUST be conditional on an explicit mutability mode {#nfr2}
168
+
### NFR2 — Pull-request cancellation MUST preserve non-pull-request serialization {#nfr2}
169
169
170
-
A run explicitly classified as read-only pull-request CI SHOULD cancel a superseded `opened`, `reopened`, or `synchronize` run for the same pull request. A run that may publish to the PowerShell Gallery, create or upload a GitHub Release or tag, deploy Pages, or clean up prereleases MUST NOT be canceled. Caller-level label inspection MUST NOT determine mutability because repository settings can change the release decision. Manual and scheduled runs sharing a ref MUST NOT cancel a default-branch release.
170
+
All pull-request events for one pull request MUST share a cancellation scope, so a newer pull-request event cancels a superseded run. Push, manual dispatch, and scheduled runs MUST share ref-based serialization and MUST NOT cancel an in-progress run.
171
171
172
172
#### Behavioral scenarios {#nfr2-scenarios}
173
173
174
174
```gherkin
175
-
Scenario: Supersede read-only pull-request CI
176
-
Given an explicitly read-only pull-request CI run is in progress
177
-
When a newer synchronize event starts the same read-only route
178
-
Then the older run may be canceled
179
-
And no release-related resource is mutated by either run
180
-
181
-
Scenario: Preserve a release-capable run
182
-
Given a run may publish, deploy, or clean up prereleases
183
-
When a newer event starts
184
-
Then the release-capable run is not canceled
185
-
And the newer event does not infer safety from pull-request labels alone
186
-
187
-
Scenario: Keep main release independent from manual and scheduled runs
175
+
Scenario: Supersede a pull-request run
176
+
Given a pull-request run is in progress
177
+
When a newer synchronize, label, unlabel, or close event starts
178
+
Then the older pull-request run is canceled
179
+
180
+
Scenario: Serialize non-pull-request runs
188
181
Given a default-branch release is in progress
189
182
When a manual dispatch or scheduled validation starts for the same ref
190
-
Then neither event cancels the default-branch release
183
+
Then the later run waits for the default-branch release
184
+
And neither run cancels the other
191
185
```
192
186
193
187
### NFR3 — Each lifecycle outcome MUST be auditable {#nfr3}
@@ -205,6 +199,40 @@ Scenario: Inspect a scheduled validation result
205
199
And it identifies that no release mutation occurred
206
200
```
207
201
202
+
### NFR4 — Pull-request mutation paths MUST resume and converge {#nfr4}
203
+
204
+
Every pull-request path, including prerelease publication and cleanup, MUST be idempotent and resumable after cancellation. The next `synchronize`, `labeled`, `unlabeled`, or `closed` event MUST converge release-related state to the latest pull-request state. Cancellation MAY leave transient partial state, but it MUST NOT leave a permanent duplicate or obsolete artifact.
205
+
206
+
#### Behavioral scenarios {#nfr4-scenarios}
207
+
208
+
```gherkin
209
+
Scenario: Resume a canceled prerelease publication
210
+
Given a canceled pull-request run published a prerelease package but did not finish its release metadata
211
+
When a later pull-request event is processed
212
+
Then the workflow detects the existing version
213
+
And it completes or reconciles the prerelease release state without duplication
214
+
215
+
Scenario: Reconcile obsolete prereleases
216
+
Given a canceled pull-request run left prerelease artifacts for an earlier pull-request state
217
+
When a synchronize, label, unlabel, or close event is processed
218
+
Then the workflow reconciles prerelease artifacts to the latest pull-request state
219
+
And no obsolete prerelease artifact remains after reconciliation
220
+
```
221
+
222
+
### NFR5 — Pull-request events MUST NOT produce production artifacts {#nfr5}
223
+
224
+
A pull-request event MUST NOT create a stable or signable production artifact. Pull-request events MAY create only eligible prerelease artifacts and their associated metadata.
225
+
226
+
#### Behavioral scenarios {#nfr5-scenarios}
227
+
228
+
```gherkin
229
+
Scenario: Evaluate an eligible prerelease pull request
230
+
Given a pull request is eligible for prerelease publication
231
+
When its release-capable path completes
232
+
Then it creates only prerelease artifacts and metadata
233
+
And it does not create a stable or signable production artifact
0 commit comments