declapract-typescript-ehmpathy 0.49.8 → 0.49.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/__snapshots__/actionPins.declapract.integration.test.ts.snap +70 -0
  2. package/dist/actionPins.declapract.integration.test.ts +785 -0
  3. package/dist/practices/cicd-app-react-native-expo/best-practice/.declapract.readme.md +27 -0
  4. package/dist/practices/cicd-app-react-native-expo/best-practice/.github/workflows/.deploy-expo.yml +10 -10
  5. package/dist/practices/cicd-app-react-native-expo/best-practice/.github/workflows/deploy.yml +4 -0
  6. package/dist/practices/cicd-app-react-native-expo/best-practice/.github/workflows/test.yml +4 -0
  7. package/dist/practices/cicd-app-react-native-expo/best-practice/.gitignore.declapract.ts +18 -11
  8. package/dist/practices/cicd-common/.declapract.integration.test.ts +572 -0
  9. package/dist/practices/cicd-common/.test/assets/repo-with-unpinned-workflow/.github/workflows/.test.yml +19 -0
  10. package/dist/practices/cicd-common/.test/assets/repo-with-unpinned-workflow/.github/workflows/consumer-owned.yml +21 -0
  11. package/dist/practices/cicd-common/.test/assets/repo-with-unpinned-workflow/.github/workflows/review.yml +26 -0
  12. package/dist/practices/cicd-common/.test/assets/repo-with-unpinned-workflow/declapract.use.yml +6 -0
  13. package/dist/practices/cicd-common/.test/assets/repo-with-unpinned-workflow/package.json +4 -0
  14. package/dist/practices/cicd-common/__snapshots__/.declapract.integration.test.ts.snap +550 -0
  15. package/dist/practices/cicd-common/best-practice/.declapract.readme.md +5 -0
  16. package/dist/practices/cicd-common/best-practice/.github/workflows/.declastruct.yml +12 -12
  17. package/dist/practices/cicd-common/best-practice/.github/workflows/.install.yml +5 -5
  18. package/dist/practices/cicd-common/best-practice/.github/workflows/.test.yml +25 -25
  19. package/dist/practices/cicd-common/best-practice/.github/workflows/release.yml +2 -2
  20. package/dist/practices/cicd-common/best-practice/.github/workflows/review.yml +1 -1
  21. package/dist/practices/cicd-package/best-practice/.github/workflows/.publish-npm.yml +3 -3
  22. package/dist/practices/cicd-package/best-practice/.github/workflows/provision.yml +4 -0
  23. package/dist/practices/cicd-service/best-practice/.github/workflows/.deploy-sls.yml +13 -13
  24. package/dist/practices/cicd-service/best-practice/.github/workflows/.sql-schema-control.yml +8 -8
  25. package/dist/practices/cicd-service/best-practice/.github/workflows/.terraform.yml +6 -6
  26. package/dist/practices/cicd-service/best-practice/.github/workflows/provision.yml +4 -0
  27. package/dist/practices/git/.declapract.integration.test.ts +950 -0
  28. package/dist/practices/git/.test/assets/repo-with-rhachet-only/declapract.use.yml +6 -0
  29. package/dist/practices/git/.test/assets/repo-with-rhachet-only/package.json +4 -0
  30. package/dist/practices/git/.test/assets/repo-without-cache-ignores/declapract.use.yml +9 -0
  31. package/dist/practices/git/.test/assets/repo-without-cache-ignores/package.json +4 -0
  32. package/dist/practices/git/__snapshots__/.declapract.integration.test.ts.snap +51 -0
  33. package/dist/practices/git/best-practice/.declapract.readme.md +23 -0
  34. package/dist/practices/git/best-practice/.gitignore.declapract.ts +59 -33
  35. package/dist/practices/rhachet/best-practice/.declapract.readme.md +32 -0
  36. package/dist/practices/rhachet/best-practice/.gitignore.declapract.ts +64 -0
  37. package/dist/utils/defineExpectedGitignoreContents.ts +84 -0
  38. package/package.json +7 -7
@@ -0,0 +1,550 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`cicd-common workflow templates given: [case1] a consumer repo whose workflow still carries a tag ref when: [t0] before any apply then: the input file matches snapshot: review.yml -- before 1`] = `
4
+ "name: review
5
+
6
+ on:
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - edited
11
+ - synchronize
12
+
13
+ permissions:
14
+ pull-requests: read
15
+
16
+ jobs:
17
+ pullreq-title:
18
+ runs-on: ubuntu-24.04
19
+ steps:
20
+ - name: test:pullreq:title
21
+ uses: amannn/action-semantic-pull-request@v5
22
+ env:
23
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
24
+ with:
25
+ # https://github.com/commitizen/conventional-commit-types
26
+ types: |
27
+ fix
28
+ feat
29
+ chore
30
+ "
31
+ `;
32
+
33
+ exports[`cicd-common workflow templates given: [case1] a consumer repo whose workflow still carries a tag ref when: [t1] the cicd-common practice is applied then: the settled file matches snapshot: review.yml -- after 1`] = `
34
+ "name: review
35
+
36
+ on:
37
+ pull_request:
38
+ types:
39
+ - opened
40
+ - edited
41
+ - synchronize
42
+
43
+ permissions:
44
+ pull-requests: read
45
+
46
+ jobs:
47
+ pullreq-title:
48
+ runs-on: ubuntu-24.04
49
+ steps:
50
+ - name: test:pullreq:title
51
+ uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5
52
+ env:
53
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
54
+ with:
55
+ # https://github.com/commitizen/conventional-commit-types
56
+ types: |
57
+ fix
58
+ feat
59
+ chore
60
+ "
61
+ `;
62
+
63
+ exports[`cicd-common workflow templates given: [case2] a consumer whose .test.yml is stale, on the custom-fix path when: [t0] before any apply then: the input file matches snapshot: .test.yml -- before 1`] = `
64
+ "name: .test
65
+
66
+ on:
67
+ workflow_call:
68
+
69
+ jobs:
70
+ test:
71
+ runs-on: ubuntu-24.04
72
+ steps:
73
+ - name: checkout
74
+ uses: actions/checkout@v4
75
+
76
+ - name: node
77
+ uses: actions/setup-node@v4
78
+ with:
79
+ node-version: 22
80
+
81
+ - name: test:unit
82
+ run: npm run test:unit
83
+ "
84
+ `;
85
+
86
+ exports[`cicd-common workflow templates given: [case2] a consumer whose .test.yml is stale, on the custom-fix path when: [t1] the cicd-common practice is applied then: the settled file matches snapshot: .test.yml -- after 1`] = `
87
+ "name: .test
88
+
89
+ on:
90
+ workflow_call:
91
+ inputs:
92
+ creds-aws-role-arn:
93
+ description: "creds for aws, specifies the role to assume via oidc. if not provided, aws auth is skipped"
94
+ required: false
95
+ type: string
96
+ creds-aws-region:
97
+ description: "creds for aws, specifies the region. defaults to us-east-1"
98
+ required: false
99
+ type: string
100
+ default: "us-east-1"
101
+
102
+ permissions:
103
+ id-token: write # required for oidc
104
+ contents: read
105
+
106
+ jobs:
107
+ # install the dependencies
108
+ install:
109
+ uses: ./.github/workflows/.install.yml
110
+
111
+ # run tests in parallel
112
+ test-commits:
113
+ runs-on: ubuntu-24.04
114
+ needs: [install, test-shards-omit]
115
+ steps:
116
+ - name: checkout
117
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
118
+ with:
119
+ fetch-depth: 0 # we need all commits to test:commits
120
+
121
+ - name: set node-version
122
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
123
+ with:
124
+ node-version-file: ".nvmrc"
125
+
126
+ - name: get node-modules from cache
127
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
128
+ with:
129
+ path: ./node_modules
130
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
131
+
132
+ - name: test:commits
133
+ run: npm run test:commits
134
+
135
+ test-types:
136
+ runs-on: ubuntu-24.04
137
+ needs: [install, test-shards-omit]
138
+ steps:
139
+ - name: checkout
140
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
141
+
142
+ - name: set node-version
143
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
144
+ with:
145
+ node-version-file: ".nvmrc"
146
+
147
+ - name: get node-modules from cache
148
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
149
+ with:
150
+ path: ./node_modules
151
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
152
+
153
+ - name: build
154
+ run: npm run build # build before test:types, to ensure .dist/ artifacts are importable for blackbox tests
155
+
156
+ - name: test:types
157
+ run: npm run test:types
158
+
159
+ test-format:
160
+ runs-on: ubuntu-24.04
161
+ needs: [install, test-shards-omit]
162
+ steps:
163
+ - name: checkout
164
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
165
+
166
+ - name: set node version
167
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
168
+ with:
169
+ node-version-file: ".nvmrc"
170
+
171
+ - name: set terraform version
172
+ uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3
173
+
174
+ - name: get node-modules from cache
175
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
176
+ with:
177
+ path: ./node_modules
178
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
179
+
180
+ - name: test:format
181
+ run: npm run test:format
182
+
183
+ test-lint:
184
+ runs-on: ubuntu-24.04
185
+ needs: [install, test-shards-omit]
186
+ steps:
187
+ - name: checkout
188
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
189
+
190
+ - name: set node-version
191
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
192
+ with:
193
+ node-version-file: ".nvmrc"
194
+
195
+ - name: get node-modules from cache
196
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
197
+ with:
198
+ path: ./node_modules
199
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
200
+
201
+ - name: test:lint
202
+ run: npm run test:lint
203
+
204
+ test-unit:
205
+ runs-on: ubuntu-24.04
206
+ needs: [install, test-shards-omit]
207
+ steps:
208
+ - name: checkout
209
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
210
+
211
+ - name: set node-version
212
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
213
+ with:
214
+ node-version-file: ".nvmrc"
215
+
216
+ - name: get node-modules from cache
217
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
218
+ with:
219
+ path: ./node_modules
220
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
221
+
222
+ - name: test:unit
223
+ run: THOROUGH=true npm run test:unit
224
+
225
+ # shard setup job
226
+ enshard:
227
+ name: enshard
228
+ runs-on: ubuntu-24.04
229
+ outputs:
230
+ integration-matrix: \${{ steps.integration.outputs.matrix }}
231
+ integration-patterns: \${{ steps.integration.outputs.patterns }}
232
+ acceptance-matrix: \${{ steps.acceptance.outputs.matrix }}
233
+ acceptance-patterns: \${{ steps.acceptance.outputs.patterns }}
234
+ steps:
235
+ - name: checkout
236
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
237
+ with:
238
+ sparse-checkout: |
239
+ jest.integration.shards.jsonc
240
+ jest.acceptance.shards.jsonc
241
+ .github/actions/test-shards-setup
242
+ sparse-checkout-cone-mode: false
243
+
244
+ - name: setup integration shards
245
+ id: integration
246
+ uses: ./.github/actions/test-shards-setup
247
+ with:
248
+ config-file: jest.integration.shards.jsonc
249
+ test-type: integration
250
+
251
+ - name: setup acceptance shards
252
+ id: acceptance
253
+ uses: ./.github/actions/test-shards-setup
254
+ with:
255
+ config-file: jest.acceptance.shards.jsonc
256
+ test-type: acceptance
257
+
258
+ # placeholder job for github actions visualization alignment
259
+ # note: github actions has no column position controls;
260
+ # this job pushes test-* jobs one column right to align with test-shards-* column
261
+ test-shards-omit:
262
+ runs-on: ubuntu-24.04
263
+ needs: [install]
264
+ steps:
265
+ - run: echo "👌 placeholder for column alignment"
266
+
267
+ # shard runner jobs
268
+ test-shards-integration:
269
+ runs-on: ubuntu-24.04
270
+ needs: [install, enshard]
271
+ strategy:
272
+ fail-fast: false
273
+ matrix:
274
+ shard: \${{ fromJson(needs.enshard.outputs.integration-matrix) }}
275
+ steps:
276
+ - name: checkout
277
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
278
+
279
+ - name: set node-version
280
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
281
+ with:
282
+ node-version-file: ".nvmrc"
283
+
284
+ - name: get node-modules from cache
285
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
286
+ with:
287
+ path: ./node_modules
288
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
289
+
290
+ # .why = keyrack.yml can extend other manifests via symlinks (e.g., .agent/repo=ehmpathy/role=mechanic/keyrack.yml)
291
+ # prepare:rhachet creates these symlinks so keyrack.source() can hydrate extended keys
292
+ - name: prepare:rhachet
293
+ run: npm run prepare:rhachet --if-present
294
+
295
+ # .why = keyrack firewall translates and validates secrets before tests run
296
+ # - filters to declared keys in keyrack.yml
297
+ # - translates mechanisms (e.g., GitHub App → ghs_* token)
298
+ # - blocks dangerous patterns (ghp_*, AKIA*, etc.)
299
+ # - exports to $GITHUB_ENV with mask applied
300
+ - name: keyrack firewall
301
+ run: npx rhachet keyrack firewall --env test --from 'json(env://SECRETS_JSON)' --into github.actions
302
+ env:
303
+ SECRETS_JSON: \${{ toJSON(secrets) }}
304
+
305
+ - name: get aws auth, if creds supplied
306
+ if: \${{ inputs.creds-aws-role-arn }}
307
+ uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
308
+ with:
309
+ role-to-assume: \${{ inputs.creds-aws-role-arn }}
310
+ aws-region: \${{ inputs.creds-aws-region }}
311
+
312
+ - name: start:testdb
313
+ run: npm run start:testdb --if-present
314
+
315
+ - name: start:livedb:prep
316
+ run: npm run start:livedb:prep --if-present
317
+
318
+ - name: build
319
+ run: npm run build
320
+
321
+ - name: test:integration (explicit \${{ matrix.shard.index }})
322
+ if: matrix.shard.type == 'explicit'
323
+ run: |
324
+ set -eu
325
+ patterns='\${{ join(matrix.shard.patterns, '|') }}'
326
+ THOROUGH=true npm run test:integration -- --testPathPatterns="$patterns" --json --outputFile=jest-results.json
327
+
328
+ - name: test:integration (dynamic \${{ matrix.shard.shard }}/\${{ matrix.shard.total }})
329
+ if: matrix.shard.type == 'dynamic'
330
+ run: |
331
+ set -eu
332
+ exclude='\${{ needs.enshard.outputs.integration-patterns }}'
333
+ if [[ -n "$exclude" ]]; then
334
+ THOROUGH=true npm run test:integration -- --testPathIgnorePatterns="$exclude" --shard=\${{ matrix.shard.shard }}/\${{ matrix.shard.total }} --json --outputFile=jest-results.json
335
+ else
336
+ THOROUGH=true npm run test:integration -- --shard=\${{ matrix.shard.shard }}/\${{ matrix.shard.total }} --json --outputFile=jest-results.json
337
+ fi
338
+
339
+ - name: report slow tests
340
+ if: always() && hashFiles('jest-results.json') != ''
341
+ run: |
342
+ set -eu
343
+ jq -r '.testResults[] | select(.perfStats.runtime != null) | "\\(.name):\\(.perfStats.runtime)"' jest-results.json | while IFS=: read -r name runtime; do
344
+ seconds=$((runtime / 1000))
345
+ if [[ $seconds -ge 30 ]]; then
346
+ echo "::warning file=\${name}::slow test: \${seconds}s"
347
+ elif [[ $seconds -ge 10 ]]; then
348
+ echo "::notice file=\${name}::test duration: \${seconds}s"
349
+ fi
350
+ done
351
+
352
+ test-shards-acceptance:
353
+ runs-on: ubuntu-24.04
354
+ needs: [install, enshard]
355
+ strategy:
356
+ fail-fast: false
357
+ matrix:
358
+ shard: \${{ fromJson(needs.enshard.outputs.acceptance-matrix) }}
359
+ steps:
360
+ - name: checkout
361
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
362
+
363
+ - name: set node-version
364
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
365
+ with:
366
+ node-version-file: ".nvmrc"
367
+
368
+ - name: get node-modules from cache
369
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
370
+ with:
371
+ path: ./node_modules
372
+ key: \${{ needs.install.outputs.node-modules-cache-key }}
373
+
374
+ # .why = keyrack.yml can extend other manifests via symlinks (e.g., .agent/repo=ehmpathy/role=mechanic/keyrack.yml)
375
+ # prepare:rhachet creates these symlinks so keyrack.source() can hydrate extended keys
376
+ - name: prepare:rhachet
377
+ run: npm run prepare:rhachet --if-present
378
+
379
+ # .why = keyrack firewall translates and validates secrets before tests run
380
+ # - filters to declared keys in keyrack.yml
381
+ # - translates mechanisms (e.g., GitHub App → ghs_* token)
382
+ # - blocks dangerous patterns (ghp_*, AKIA*, etc.)
383
+ # - exports to $GITHUB_ENV with mask applied
384
+ - name: keyrack firewall
385
+ run: npx rhachet keyrack firewall --env test --from 'json(env://SECRETS_JSON)' --into github.actions
386
+ env:
387
+ SECRETS_JSON: \${{ toJSON(secrets) }}
388
+
389
+ - name: get aws auth, if creds supplied
390
+ if: \${{ inputs.creds-aws-role-arn }}
391
+ uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
392
+ with:
393
+ role-to-assume: \${{ inputs.creds-aws-role-arn }}
394
+ aws-region: \${{ inputs.creds-aws-region }}
395
+
396
+ - name: start:testdb
397
+ run: npm run start:testdb --if-present
398
+
399
+ - name: start:livedb:prep
400
+ run: npm run start:livedb:prep --if-present
401
+
402
+ - name: build
403
+ run: npm run build
404
+
405
+ - name: test:acceptance (explicit \${{ matrix.shard.index }})
406
+ if: matrix.shard.type == 'explicit'
407
+ run: |
408
+ set -eu
409
+ patterns='\${{ join(matrix.shard.patterns, '|') }}'
410
+ THOROUGH=true npm run test:acceptance -- --testPathPatterns="$patterns" --json --outputFile=jest-results.json
411
+
412
+ - name: test:acceptance (dynamic \${{ matrix.shard.shard }}/\${{ matrix.shard.total }})
413
+ if: matrix.shard.type == 'dynamic'
414
+ run: |
415
+ set -eu
416
+ exclude='\${{ needs.enshard.outputs.acceptance-patterns }}'
417
+ if [[ -n "$exclude" ]]; then
418
+ THOROUGH=true npm run test:acceptance -- --testPathIgnorePatterns="$exclude" --shard=\${{ matrix.shard.shard }}/\${{ matrix.shard.total }} --json --outputFile=jest-results.json
419
+ else
420
+ THOROUGH=true npm run test:acceptance -- --shard=\${{ matrix.shard.shard }}/\${{ matrix.shard.total }} --json --outputFile=jest-results.json
421
+ fi
422
+
423
+ - name: report slow tests
424
+ if: always() && hashFiles('jest-results.json') != ''
425
+ run: |
426
+ set -eu
427
+ jq -r '.testResults[] | select(.perfStats.runtime != null) | "\\(.name):\\(.perfStats.runtime)"' jest-results.json | while IFS=: read -r name runtime; do
428
+ seconds=$((runtime / 1000))
429
+ if [[ $seconds -ge 30 ]]; then
430
+ echo "::warning file=\${name}::slow test: \${seconds}s"
431
+ elif [[ $seconds -ge 10 ]]; then
432
+ echo "::notice file=\${name}::test duration: \${seconds}s"
433
+ fi
434
+ done
435
+
436
+ # union job: aggregates shard results into single status for pr merge constraints
437
+ test-integration:
438
+ runs-on: ubuntu-24.04
439
+ needs: [install, enshard, test-shards-integration]
440
+ if: always() && needs.install.result == 'success' && needs.enshard.result == 'success'
441
+ steps:
442
+ - name: report shard results
443
+ run: |
444
+ set -eu
445
+ if [[ "\${{ needs.test-shards-integration.result }}" == "success" ]]; then
446
+ echo "👌 all integration test shards passed"
447
+ else
448
+ echo "::error::some integration test shards failed"
449
+ exit 1
450
+ fi
451
+
452
+ # union job: aggregates shard results into single status for pr merge constraints
453
+ test-acceptance-locally:
454
+ runs-on: ubuntu-24.04
455
+ needs: [install, enshard, test-shards-acceptance]
456
+ if: always() && needs.install.result == 'success' && needs.enshard.result == 'success'
457
+ steps:
458
+ - name: report shard results
459
+ run: |
460
+ set -eu
461
+ if [[ "\${{ needs.test-shards-acceptance.result }}" == "success" ]]; then
462
+ echo "👌 all acceptance test shards passed"
463
+ else
464
+ echo "::error::some acceptance test shards failed"
465
+ exit 1
466
+ fi
467
+ "
468
+ `;
469
+
470
+ exports[`cicd-common workflow templates given: [case3] a consumer repo that also has a workflow of its OWN when: [t0] the whole practice is applied, unscoped then: and both halves of the untouched file match snapshot: consumer-owned.yml -- after 1`] = `
471
+ "# .what = a workflow NO practice declares — it belongs to the consumer alone
472
+ # .why = wish constraint 2: "the template's reach ends at the refs it owns. do not silently
473
+ # rewrite what the practice does not own."
474
+ # .note = the tag refs below are DELIBERATE and must NOT be pinned. they are what the test
475
+ # asserts survives untouched. a "helpful" pin here makes the clamp vacuous
476
+ name: consumer-owned
477
+
478
+ on:
479
+ workflow_dispatch:
480
+
481
+ jobs:
482
+ whatever:
483
+ runs-on: ubuntu-24.04
484
+ steps:
485
+ - name: checkout
486
+ uses: actions/checkout@v4
487
+
488
+ - name: setup node
489
+ uses: actions/setup-node@v3
490
+ with:
491
+ node-version: 20
492
+ "
493
+ `;
494
+
495
+ exports[`cicd-common workflow templates given: [case3] a consumer repo that also has a workflow of its OWN when: [t0] the whole practice is applied, unscoped then: and both halves of the untouched file match snapshot: consumer-owned.yml -- before 1`] = `
496
+ "# .what = a workflow NO practice declares — it belongs to the consumer alone
497
+ # .why = wish constraint 2: "the template's reach ends at the refs it owns. do not silently
498
+ # rewrite what the practice does not own."
499
+ # .note = the tag refs below are DELIBERATE and must NOT be pinned. they are what the test
500
+ # asserts survives untouched. a "helpful" pin here makes the clamp vacuous
501
+ name: consumer-owned
502
+
503
+ on:
504
+ workflow_dispatch:
505
+
506
+ jobs:
507
+ whatever:
508
+ runs-on: ubuntu-24.04
509
+ steps:
510
+ - name: checkout
511
+ uses: actions/checkout@v4
512
+
513
+ - name: setup node
514
+ uses: actions/setup-node@v3
515
+ with:
516
+ node-version: 20
517
+ "
518
+ `;
519
+
520
+ exports[`cicd-common workflow templates given: [case4] a consumer repo where the declared workflow is ABSENT when: [t0] before any apply, with the workflow removed then: the before-state reads as absent: review.yml -- before (absent) 1`] = `"absent"`;
521
+
522
+ exports[`cicd-common workflow templates given: [case4] a consumer repo where the declared workflow is ABSENT when: [t1] the cicd-common practice is applied then: the created file matches snapshot: review.yml -- after (created) 1`] = `
523
+ "name: review
524
+
525
+ on:
526
+ pull_request:
527
+ types:
528
+ - opened
529
+ - edited
530
+ - synchronize
531
+
532
+ permissions:
533
+ pull-requests: read
534
+
535
+ jobs:
536
+ pullreq-title:
537
+ runs-on: ubuntu-24.04
538
+ steps:
539
+ - name: test:pullreq:title
540
+ uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5
541
+ env:
542
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
543
+ with:
544
+ # https://github.com/commitizen/conventional-commit-types
545
+ types: |
546
+ fix
547
+ feat
548
+ chore
549
+ "
550
+ `;
@@ -1,3 +1,8 @@
1
1
  flows:
2
2
  - test on every commit
3
3
  - create please-release pull requests on every commit to main
4
+
5
+ every third-party `uses:` here is pinned to a full-length commit sha with the tag it came from
6
+ (`actions/checkout@11d5960… # v4`), because the ehmpathy org sets `sha_pinning_required`. the shape
7
+ is held by `src/actionPins.declapract.integration.test.ts`, which also carries the note on how to derive a sha
8
+ for a bump.
@@ -77,15 +77,15 @@ jobs:
77
77
  has-changes-planned: ${{ steps.evaluate-plan.outputs.has-changes-planned }}
78
78
  steps:
79
79
  - name: checkout
80
- uses: actions/checkout@v4
80
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
81
81
 
82
82
  - name: set node-version
83
- uses: actions/setup-node@v4
83
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
84
84
  with:
85
85
  node-version-file: ".nvmrc"
86
86
 
87
87
  - name: get node-modules from cache
88
- uses: actions/cache/restore@v4
88
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
89
89
  with:
90
90
  path: ./node_modules
91
91
  key: ${{ needs.install.outputs.node-modules-cache-key }}
@@ -94,7 +94,7 @@ jobs:
94
94
  - name: get github auth, if creds supplied
95
95
  if: ${{ inputs.creds-github-app-id }}
96
96
  id: github-app-token
97
- uses: actions/create-github-app-token@v2
97
+ uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2
98
98
  with:
99
99
  owner: ${{ inputs.creds-github-app-owner }}
100
100
  repositories: ${{ github.event.repository.name }}
@@ -103,7 +103,7 @@ jobs:
103
103
 
104
104
  - name: get aws auth, if creds supplied
105
105
  if: ${{ inputs.creds-aws-role-arn-plan }}
106
- uses: aws-actions/configure-aws-credentials@v4
106
+ uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
107
107
  with:
108
108
  role-to-assume: ${{ inputs.creds-aws-role-arn-plan }}
109
109
  aws-region: ${{ inputs.creds-aws-region }}
@@ -132,7 +132,7 @@ jobs:
132
132
 
133
133
  - name: upload plan artifact
134
134
  if: ${{ inputs.allow-apply == true && steps.evaluate-plan.outputs.has-changes-planned == 'true' }}
135
- uses: actions/upload-artifact@v4
135
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
136
136
  with:
137
137
  name: declastruct-${{ inputs.scope }}-${{ inputs.access }}-plan
138
138
  path: |
@@ -149,15 +149,15 @@ jobs:
149
149
  ACCESS: ${{ inputs.access }} # aws wishes: sdk-environment getEnvironment reads ACCESS
150
150
  steps:
151
151
  - name: checkout
152
- uses: actions/checkout@v4
152
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
153
153
 
154
154
  - name: set node-version
155
- uses: actions/setup-node@v4
155
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
156
156
  with:
157
157
  node-version-file: ".nvmrc"
158
158
 
159
159
  - name: get node-modules from cache
160
- uses: actions/cache/restore@v4
160
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
161
161
  with:
162
162
  path: ./node_modules
163
163
  key: ${{ needs.install.outputs.node-modules-cache-key }}
@@ -168,7 +168,7 @@ jobs:
168
168
  run: echo "wish-dir=$(dirname "${{ inputs.wish-path }}")" >> "$GITHUB_OUTPUT"
169
169
 
170
170
  - name: download plan artifact
171
- uses: actions/download-artifact@v4
171
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
172
172
  with:
173
173
  name: declastruct-${{ inputs.scope }}-${{ inputs.access }}-plan
174
174
  path: ${{ steps.extract-dir.outputs.wish-dir }}
@@ -176,7 +176,7 @@ jobs:
176
176
  - name: get github auth, if creds supplied
177
177
  if: ${{ inputs.creds-github-app-id }}
178
178
  id: github-app-token
179
- uses: actions/create-github-app-token@v2
179
+ uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2
180
180
  with:
181
181
  owner: ${{ inputs.creds-github-app-owner }}
182
182
  repositories: ${{ github.event.repository.name }}
@@ -185,7 +185,7 @@ jobs:
185
185
 
186
186
  - name: get aws auth, if creds supplied
187
187
  if: ${{ inputs.creds-aws-role-arn-apply }}
188
- uses: aws-actions/configure-aws-credentials@v4
188
+ uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
189
189
  with:
190
190
  role-to-assume: ${{ inputs.creds-aws-role-arn-apply }}
191
191
  aws-region: ${{ inputs.creds-aws-region }}
@@ -14,7 +14,7 @@ jobs:
14
14
  node-modules-cache-key: ${{ steps.cache.outputs.cache-primary-key }}
15
15
  steps:
16
16
  - name: checkout
17
- uses: actions/checkout@v4
17
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
18
18
 
19
19
  - name: node-modules deps hash
20
20
  id: deps-hash
@@ -27,7 +27,7 @@ jobs:
27
27
  echo "package-deps-hash=$PACKAGE_DEPS_HASH" >> "$GITHUB_OUTPUT"
28
28
 
29
29
  - name: node-modules cache check
30
- uses: actions/cache/restore@v4
30
+ uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
31
31
  id: cache
32
32
  with:
33
33
  path: ./node_modules
@@ -36,13 +36,13 @@ jobs:
36
36
 
37
37
  - name: node-modules cache miss setup node
38
38
  if: steps.cache.outputs.cache-hit != 'true'
39
- uses: actions/setup-node@v4
39
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
40
40
  with:
41
41
  node-version-file: ".nvmrc"
42
42
 
43
43
  - name: node-modules cache miss setup pnpm
44
44
  if: steps.cache.outputs.cache-hit != 'true'
45
- uses: pnpm/action-setup@v4
45
+ uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
46
46
 
47
47
  - name: node-modules cache miss install
48
48
  if: steps.cache.outputs.cache-hit != 'true'
@@ -50,7 +50,7 @@ jobs:
50
50
 
51
51
  - name: node-modules cache set
52
52
  if: steps.cache.outputs.cache-hit != 'true'
53
- uses: actions/cache/save@v4
53
+ uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
54
54
  with:
55
55
  path: ./node_modules
56
56
  key: ${{ steps.cache.outputs.cache-primary-key }}