Skip to content

Commit 09aaf71

Browse files
GvieveGenevieve Nuebel
andauthored
Fix on push master job gate/serialization and docs (#76)
Co-authored-by: Genevieve Nuebel <genevieve.nuebel@mx.com>
1 parent d50b460 commit 09aaf71

3 files changed

Lines changed: 106 additions & 44 deletions

File tree

.github/workflows/on-push-master.yml

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,48 +27,67 @@ jobs:
2727
echo "✅ No skip flag - proceeding with publish/release"
2828
fi
2929
30+
# Detect which API versions were modified in this push
31+
# Uses dorny/paths-filter to reliably check which directories changed
32+
# This allows us to run publish/release jobs only for versions that were actually modified
33+
detect-changes:
34+
runs-on: ubuntu-latest
35+
outputs:
36+
v20111101: ${{ steps.filter.outputs.v20111101 }}
37+
v20250224: ${{ steps.filter.outputs.v20250224 }}
38+
steps:
39+
- uses: actions/checkout@v3
40+
- uses: dorny/paths-filter@v2
41+
id: filter
42+
with:
43+
filters: |
44+
v20111101:
45+
- 'v20111101/**'
46+
v20250224:
47+
- 'v20250224/**'
48+
3049
# Publish and release for each version conditionally
3150
# Only runs if [skip-publish] flag is NOT present AND files for that version were modified
3251

3352
publish-v20111101:
34-
needs: check-skip-publish
35-
if: needs.check-skip-publish.outputs.skip_publish == 'false' && contains(github.event.head_commit.modified, 'v20111101')
53+
needs: [check-skip-publish, detect-changes]
54+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20111101 == 'true'
3655
uses: ./.github/workflows/publish.yml
3756
with:
3857
version_directory: v20111101
3958
secrets: inherit
4059

4160
release-v20111101:
42-
needs: [check-skip-publish, publish-v20111101]
43-
if: needs.check-skip-publish.outputs.skip_publish == 'false' && contains(github.event.head_commit.modified, 'v20111101')
61+
needs: [check-skip-publish, detect-changes, publish-v20111101]
62+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20111101 == 'true'
4463
uses: ./.github/workflows/release.yml
4564
with:
4665
version_directory: v20111101
4766
secrets: inherit
4867

4968
# Gate job to handle serial ordering when v20111101 is modified
50-
# Uses always() to run even if release-v20111101 is skipped, allowing downstream jobs to proceed
51-
# This ensures v20250224 can run when only v20250224 is modified, while still maintaining
52-
# serial ordering when both versions are modified
69+
# Depends on release-v20111101 to enforce serial ordering (waits for v20111101 to complete)
70+
# Uses always() to continue even when release-v20111101 is skipped (when v20111101 wasn't modified)
71+
# This ensures: v20111101 publishes first (serially) → then v20250224 publishes (serially)
5372
gate-v20111101-complete:
5473
runs-on: ubuntu-latest
55-
needs: [check-skip-publish, release-v20111101]
74+
needs: [check-skip-publish, detect-changes, release-v20111101]
5675
if: always() && needs.check-skip-publish.outputs.skip_publish == 'false'
5776
steps:
58-
- name: Gate complete - ready for v20250224
59-
run: echo "v20111101 release workflow complete (or skipped)"
77+
- name: Gate reached - v20111101 release complete (or skipped)
78+
run: echo "Ready to proceed with v20250224 publication"
6079

6180
publish-v20250224:
62-
needs: [check-skip-publish, gate-v20111101-complete]
63-
if: needs.check-skip-publish.outputs.skip_publish == 'false' && contains(github.event.head_commit.modified, 'v20250224')
81+
needs: [check-skip-publish, detect-changes, gate-v20111101-complete]
82+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20250224 == 'true'
6483
uses: ./.github/workflows/publish.yml
6584
with:
6685
version_directory: v20250224
6786
secrets: inherit
6887

6988
release-v20250224:
70-
needs: [check-skip-publish, publish-v20250224]
71-
if: needs.check-skip-publish.outputs.skip_publish == 'false' && contains(github.event.head_commit.modified, 'v20250224')
89+
needs: [check-skip-publish, detect-changes, publish-v20250224]
90+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20250224 == 'true'
7291
uses: ./.github/workflows/release.yml
7392
with:
7493
version_directory: v20250224

docs/Adding-a-New-API-Version.md

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,36 @@ This ensures when multiple versions are generated, changelog entries appear in o
187187

188188
### 2.4 Update on-push-master.yml
189189

190-
This workflow automatically triggers publish and release jobs when version directories are pushed to master. Since individual version jobs use conditional `if` statements based on path changes, you need to add new conditional jobs for your new version.
190+
This workflow automatically triggers publish and release jobs when version directories are pushed to master. The workflow uses path-based detection (via `dorny/paths-filter`) to determine which versions were modified, then conditionally runs the appropriate publish/release jobs in serial order.
191191

192-
**Location 1: Path trigger**
192+
**Location 1: Update detect-changes job with new version filter**
193+
194+
In the `detect-changes` job's filter section, add your new version:
195+
196+
```yaml
197+
detect-changes:
198+
runs-on: ubuntu-latest
199+
outputs:
200+
v20111101: ${{ steps.filter.outputs.v20111101 }}
201+
v20250224: ${{ steps.filter.outputs.v20250224 }}
202+
v20300101: ${{ steps.filter.outputs.v20300101 }} # NEW output
203+
steps:
204+
- uses: actions/checkout@v3
205+
- uses: dorny/paths-filter@v2
206+
id: filter
207+
with:
208+
filters: |
209+
v20111101:
210+
- 'v20111101/**'
211+
v20250224:
212+
- 'v20250224/**'
213+
v20300101: # NEW filter
214+
- 'v20300101/**'
215+
```
216+
217+
This is **critical**: Without this, the path detection won't work for your new version, and the publish/release jobs won't trigger when it's modified.
218+
219+
**Location 2: Add path trigger**
193220

194221
In the `on.push.paths` section, add a new path for your version:
195222

@@ -205,55 +232,68 @@ on:
205232

206233
This ensures the workflow triggers when changes to your version directory are pushed to master.
207234

208-
**Location 2: Add publish job for new version**
235+
**Location 3: Add publish job for new version**
209236

210237
Add a new publish job for your version (copy and modify the existing v20250224 jobs):
211238

212239
```yaml
213240
publish-v20300101:
214-
runs-on: ubuntu-latest
215-
needs: [check-skip-publish, gate-v20250224-complete] # Gate waits for previous version
216-
if: needs.check-skip-publish.outputs.skip_publish == 'false' && contains(github.event.head_commit.modified, 'v20300101')
217-
uses: ./.github/workflows/publish.yml@master
241+
needs: [check-skip-publish, detect-changes, gate-v20250224-complete]
242+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20300101 == 'true'
243+
uses: ./.github/workflows/publish.yml
218244
with:
219245
version_directory: v20300101
220246
secrets: inherit
221247
```
222248

223-
**Location 3: Add release job for new version**
249+
**Important**: The `needs` array must include the **previous version's gate job** to enforce serial ordering. This ensures v20250224 finishes before v20300101 starts publishing.
250+
251+
**Location 4: Add release job for new version**
224252

225253
Add a new release job for your version:
226254

227255
```yaml
228256
release-v20300101:
229-
runs-on: ubuntu-latest
230-
needs: [check-skip-publish, publish-v20300101]
231-
if: needs.check-skip-publish.outputs.skip_publish == 'false' && contains(github.event.head_commit.modified, 'v20300101')
232-
uses: ./.github/workflows/release.yml@master
257+
needs: [check-skip-publish, detect-changes, publish-v20300101]
258+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20300101 == 'true'
259+
uses: ./.github/workflows/release.yml
233260
with:
234261
version_directory: v20300101
235262
secrets: inherit
236263
```
237264

238-
**Location 4: Add gate job for previous version**
265+
**Location 5: Add gate job for previous version**
239266

240267
Add a new gate job after the previous version's release to handle serial ordering:
241268

242269
```yaml
243270
gate-v20250224-complete:
244271
runs-on: ubuntu-latest
245-
needs: [check-skip-publish, release-v20250224]
272+
needs: [check-skip-publish, detect-changes, release-v20250224]
246273
if: always() && needs.check-skip-publish.outputs.skip_publish == 'false'
247274
steps:
248-
- name: Gate complete - ready for v20300101
249-
run: echo "v20250224 release workflow complete (or skipped)"
275+
- name: Gate reached - v20250224 release complete (or skipped)
276+
run: echo "Ready to proceed with v20300101 publication"
250277
```
251278

252-
**Important Notes**:
253-
- Each publish job depends on the **previous version's gate job** to maintain serial ordering
254-
- Each release job depends on its corresponding publish job
255-
- Gate jobs use the `always()` condition so they run even when intermediate jobs are skipped
256-
- This prevents npm registry race conditions and ensures correct behavior whether one or multiple versions are modified
279+
**Critical implementation details**:
280+
281+
1. **Each publish job** depends on the **previous version's gate job** (not the previous release directly)
282+
- This prevents race conditions when multiple versions are modified
283+
- Ensures strict serial ordering at the npm registry level
284+
285+
2. **Each release job** depends on its corresponding publish job
286+
- Ensures publication completes before creating release
287+
288+
3. **Each gate job** uses `needs: [check-skip-publish, detect-changes, release-v<VERSION>]`
289+
- Waits for the previous version's release to complete
290+
- The `if: always()` condition ensures the gate continues running even when the release job is **skipped**
291+
- This is crucial: when the previous version isn't modified, its release is skipped, but the gate still runs and unblocks the next version
292+
293+
4. **Each publish/release if condition** uses `needs.detect-changes.outputs.v<VERSION> == 'true'`
294+
- This is more reliable than the older `contains()` pattern
295+
- Uses the path-filter outputs to determine which versions changed
296+
- Prevents false publishes when only docs change
257297

258298
### 2.5 Verify Workflow Syntax
259299

@@ -434,6 +474,7 @@ Use this checklist to verify you've completed all steps:
434474
- [ ] Updated `.github/workflows/openapi-generate-and-push.yml` with version-to-config mapping in Setup job
435475
- [ ] Updated `.github/changelog_manager.rb` with new version in `API_VERSION_ORDER` array
436476
- [ ] Updated `.github/workflows/on-push-master.yml` path triggers with `v20300101/**`
477+
- [ ] Updated `detect-changes` job in `.github/workflows/on-push-master.yml` with new version output and filter
437478
- [ ] Updated `.github/workflows/on-push-master.yml` with new publish job for v20300101
438479
- [ ] Updated `.github/workflows/on-push-master.yml` with new release job for v20300101
439480
- [ ] Updated `.github/workflows/on-push-master.yml` with new gate job for previous version (v20250224)

docs/Workflow-and-Configuration-Reference.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,12 @@ strategy:
137137
- Prevents duplicate publishes: Manual generate.yml + PR merge only triggers publish once (via on-push-master.yml)
138138
139139
**Process** (handled by `on-push-master.yml`):
140-
1. Check-skip-publish job detects if `[skip-publish]` flag is in commit message
141-
2. For each version with path changes (v20111101/**, v20250224/**):
142-
- Publish job: Call `publish.yml` with version-specific directory
143-
- Release job: Call `release.yml` after publish completes
144-
3. Path-based matrix execution ensures only modified versions are published
140+
1. Detect-changes job uses `dorny/paths-filter@v2` to identify which version directories changed (v20111101/**, v20250224/**)
141+
2. Check-skip-publish job detects if `[skip-publish]` flag is in commit message
142+
3. For each version with path changes (output by detect-changes):
143+
- Publish job: Call `publish.yml` with version-specific directory (only if paths modified)
144+
- Release job: Call `release.yml` after publish completes (only if paths modified)
145+
4. Path-based filtering ensures only modified versions are published, never in parallel
145146
146147
**Serialization Chain** (for race condition prevention):
147148
- v20111101 publish runs first (depends on check-skip-publish)
@@ -293,11 +294,12 @@ publish:
293294
**Serial Approach** (Explicit, safe, maintainable):
294295
```yaml
295296
publish-v20111101:
296-
if: skip_publish == false && contains(modified, 'v20111101')
297+
needs: [check-skip-publish, detect-changes]
298+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20111101 == 'true'
297299

298300
publish-v20250224:
299-
needs: [gate-v20111101-complete] # Must wait
300-
if: skip_publish == false && contains(modified, 'v20250224')
301+
needs: [check-skip-publish, detect-changes, gate-v20111101-complete] # Must wait for gate
302+
if: needs.check-skip-publish.outputs.skip_publish == 'false' && needs.detect-changes.outputs.v20250224 == 'true'
301303
```
302304
303305
**Advantages**:
@@ -382,7 +384,7 @@ Include `[skip-publish]` in commit message to prevent publish/release for this p
382384
```yaml
383385
gate-v20111101-complete:
384386
runs-on: ubuntu-latest
385-
needs: [check-skip-publish, release-v20111101]
387+
needs: [check-skip-publish, detect-changes, release-v20111101]
386388
if: always() && needs.check-skip-publish.outputs.skip_publish == 'false'
387389
steps:
388390
- name: Gate complete - ready for v20250224

0 commit comments

Comments
 (0)