@plainconceptsplatform/workflows 0.4.34 → 0.5.1
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.
- package/README.md +88 -88
- package/loops/actions/agent-output.cjs +17 -17
- package/loops/actions/audit-close/action.yml +24 -0
- package/loops/actions/classify-route/action.yml +1 -3
- package/loops/actions/classify-route/classify-route.sh +40 -35
- package/loops/actions/update-changelog/action.yml +113 -0
- package/loops/actions/validate-merge-gate-output/action.yml +40 -40
- package/loops/actions/validate-refine-output/validate-refine-output.sh +16 -3
- package/loops/actions/validate-review-output/action.yml +35 -35
- package/loops/actions/validate-triage-output/action.yml +36 -36
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +91 -36
- package/loops/scripts/compile-agent-workflows.mjs +195 -6
- package/loops/templates/agentics/agentics-checks.yml +86 -86
- package/loops/templates/agentics/agentics-maintenance.yml +121 -121
- package/loops/templates/ci/app-ci-dotnet-next.yml +268 -171
- package/loops/templates/ci/app-ci-node-monorepo.yml +208 -178
- package/loops/templates/issues/bug_report.yml +109 -109
- package/loops/templates/issues/feature_request.yml +75 -75
- package/loops/templates/opencode/opencode.ci.json +49 -47
- package/loops/templates/opencode/opencode.ci.json.md +46 -41
- package/loops/templates/release/github-release.yml +30 -30
- package/loops/workflows/agent-apply-review.md +465 -443
- package/loops/workflows/agent-audit.md +213 -197
- package/loops/workflows/agent-implement.md +538 -414
- package/loops/workflows/agent-merge-gate.md +730 -584
- package/loops/workflows/agent-refine.md +609 -418
- package/loops/workflows/agent-release.md +258 -0
- package/loops/workflows/agent-triage.md +447 -439
- package/loops/workflows/authorize-bot-work.yml +85 -82
- package/loops/workflows/shared/opencode-ci.md +206 -197
- package/loops/workflows/shared/platform-defaults.md +19 -16
- package/loops/workflows/work-router.yml +862 -632
- package/package.json +7 -8
- package/dist/action-validation.test.d.ts +0 -1
- package/dist/action-validation.test.js +0 -84
- package/dist/catalog-installation.d.ts +0 -30
- package/dist/catalog-installation.js +0 -379
- package/dist/catalog-installation.test.d.ts +0 -1
- package/dist/catalog-installation.test.js +0 -448
- package/dist/catalog-listing.d.ts +0 -13
- package/dist/catalog-listing.js +0 -70
- package/dist/catalog-listing.test.d.ts +0 -1
- package/dist/catalog-listing.test.js +0 -150
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -218
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -273
- package/dist/repository-inspection.d.ts +0 -23
- package/dist/repository-inspection.js +0 -113
- package/dist/repository-inspection.test.d.ts +0 -1
- package/dist/repository-inspection.test.js +0 -77
- package/dist/repository-state.d.ts +0 -18
- package/dist/repository-state.js +0 -77
- package/dist/repository-state.test.d.ts +0 -1
- package/dist/repository-state.test.js +0 -96
- package/dist/route-processing.d.ts +0 -6
- package/dist/route-processing.js +0 -150
- package/dist/route-processing.test.d.ts +0 -1
- package/dist/route-processing.test.js +0 -350
- package/dist/stack-defaults.d.ts +0 -11
- package/dist/stack-defaults.js +0 -104
- package/dist/stack-defaults.test.d.ts +0 -1
- package/dist/stack-defaults.test.js +0 -266
- package/dist/tui.d.ts +0 -25
- package/dist/tui.js +0 -287
- package/dist/tui.test.d.ts +0 -1
- package/dist/tui.test.js +0 -246
- package/dist/workflow-catalog.d.ts +0 -25
- package/dist/workflow-catalog.js +0 -59
- package/dist/workflow-catalog.test.d.ts +0 -1
- package/dist/workflow-catalog.test.js +0 -29
- package/loops/workflows/agent-direct.md +0 -375
- package/loops/workflows/agent-propose.md +0 -342
|
@@ -1,171 +1,268 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/templates/ci/app-ci-dotnet-next.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
-
name: "App: CI"
|
|
3
|
-
|
|
4
|
-
on:
|
|
5
|
-
pull_request:
|
|
6
|
-
schedule:
|
|
7
|
-
- cron: "0 6 * * 1"
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
workflow_call:
|
|
10
|
-
secrets:
|
|
11
|
-
NPM_REGISTRY_TOKEN:
|
|
12
|
-
required: false
|
|
13
|
-
|
|
14
|
-
env:
|
|
15
|
-
DOTNET_VERSION: "10.0.x"
|
|
16
|
-
NODE_VERSION: "22"
|
|
17
|
-
PNPM_VERSION: "10"
|
|
18
|
-
API_WORKING_DIRECTORY: apps/api
|
|
19
|
-
DOTNET_SOLUTION:
|
|
20
|
-
UNIT_TEST_PROJECT: tests/
|
|
21
|
-
PARITY_TEST_PROJECT: tests/
|
|
22
|
-
INTEGRATION_TEST_PROJECT: tests/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- name:
|
|
94
|
-
env:
|
|
95
|
-
|
|
96
|
-
DataLayer__ConnectionString: Server=localhost,${{
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
dotnet
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/templates/ci/app-ci-dotnet-next.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
+
name: "App: CI"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
pull_request:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "0 6 * * 1"
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
workflow_call:
|
|
10
|
+
secrets:
|
|
11
|
+
NPM_REGISTRY_TOKEN:
|
|
12
|
+
required: false
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
DOTNET_VERSION: "10.0.x"
|
|
16
|
+
NODE_VERSION: "22"
|
|
17
|
+
PNPM_VERSION: "10"
|
|
18
|
+
API_WORKING_DIRECTORY: apps/api
|
|
19
|
+
DOTNET_SOLUTION: App.slnx
|
|
20
|
+
UNIT_TEST_PROJECT: tests/App.UnitTests/App.UnitTests.csproj
|
|
21
|
+
PARITY_TEST_PROJECT: tests/App.ParityTests/App.ParityTests.csproj
|
|
22
|
+
INTEGRATION_TEST_PROJECT: tests/App.IntegrationTests/App.IntegrationTests.csproj
|
|
23
|
+
# Per-PR mutation gate. Stryker mutates only files changed since the PR base (--since),
|
|
24
|
+
# so a green unit suite that never actually pins behaviour fails here instead of shipping.
|
|
25
|
+
# dotnet-stryker is pinned in the api tools manifest (.config/dotnet-tools.json / dotnet-tools.json).
|
|
26
|
+
MUTATION_TARGET_PROJECT: src/App.Domain/App.Domain.csproj
|
|
27
|
+
MUTATION_TEST_PROJECT: tests/App.UnitTests/App.UnitTests.csproj
|
|
28
|
+
MUTATION_THRESHOLD: "60"
|
|
29
|
+
COVERAGE_SETTINGS: coverage.runsettings
|
|
30
|
+
COVERAGE_CHECK_COMMAND: node ../../scripts/check-coverage.mjs TestResults/merged/Cobertura.xml
|
|
31
|
+
MIGRATION_PROJECT: src/App.Infrastructure/App.Infrastructure.csproj
|
|
32
|
+
MIGRATION_STARTUP_PROJECT: src/App.Api/App.Api.csproj
|
|
33
|
+
SEED_PROJECT: src/App.Seed
|
|
34
|
+
PRIMARY_DATABASE: app
|
|
35
|
+
DATA_LAYER_DATABASE: numa_dl
|
|
36
|
+
SQL_SA_PASSWORD: "YourStrong!Passw0rd"
|
|
37
|
+
WEB_PACKAGE: "@app/web"
|
|
38
|
+
NPM_REGISTRY_URL: "//npm.pkg.github.com/"
|
|
39
|
+
TRUFFLEHOG_IMAGE: "trufflesecurity/trufflehog:latest"
|
|
40
|
+
SEMGREP_IMAGE: "semgrep/semgrep:1.168.0"
|
|
41
|
+
SBOM_ARTIFACT_NAME: app-sbom.cyclonedx.json
|
|
42
|
+
MIGRATION_CONTEXT: AppDbContext
|
|
43
|
+
|
|
44
|
+
permissions:
|
|
45
|
+
contents: read
|
|
46
|
+
|
|
47
|
+
concurrency:
|
|
48
|
+
group: ci-${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
|
49
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
50
|
+
|
|
51
|
+
jobs:
|
|
52
|
+
api:
|
|
53
|
+
name: API (.NET)
|
|
54
|
+
if: github.event_name != 'schedule'
|
|
55
|
+
runs-on: agents-arc
|
|
56
|
+
timeout-minutes: 30
|
|
57
|
+
services:
|
|
58
|
+
sqlserver:
|
|
59
|
+
image: mcr.microsoft.com/mssql/server:2022-latest
|
|
60
|
+
env:
|
|
61
|
+
ACCEPT_EULA: "Y"
|
|
62
|
+
MSSQL_SA_PASSWORD: ${{ env.SQL_SA_PASSWORD }}
|
|
63
|
+
ports:
|
|
64
|
+
# Ephemeral host port. Four runners share this machine, so a fixed 1433 means the
|
|
65
|
+
# second concurrent job fails at Initialize containers with "Docker start fail with
|
|
66
|
+
# exit code 1". Steps read the assigned port from the job.services context.
|
|
67
|
+
- 1433
|
|
68
|
+
options: >-
|
|
69
|
+
--health-cmd "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P '${{ env.SQL_SA_PASSWORD }}' -Q 'SELECT 1' -C || exit 1"
|
|
70
|
+
--health-interval 10s --health-timeout 5s --health-retries 12 --health-start-period 30s
|
|
71
|
+
defaults:
|
|
72
|
+
run:
|
|
73
|
+
working-directory: ${{ env.API_WORKING_DIRECTORY }}
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
76
|
+
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
|
|
77
|
+
with:
|
|
78
|
+
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
79
|
+
- name: Restore tools, solution, and build
|
|
80
|
+
run: |
|
|
81
|
+
dotnet tool restore
|
|
82
|
+
dotnet restore "$DOTNET_SOLUTION"
|
|
83
|
+
dotnet build "$DOTNET_SOLUTION" --no-restore -c Release
|
|
84
|
+
- name: Unit tests with coverage
|
|
85
|
+
run: dotnet test "$UNIT_TEST_PROJECT" --no-build -c Release --collect:"XPlat Code Coverage" --settings "$COVERAGE_SETTINGS" --results-directory TestResults
|
|
86
|
+
- name: Parity tests
|
|
87
|
+
run: dotnet test "$PARITY_TEST_PROJECT" --no-build -c Release
|
|
88
|
+
- name: Create test databases
|
|
89
|
+
run: |
|
|
90
|
+
for database in "$PRIMARY_DATABASE" "$DATA_LAYER_DATABASE"; do
|
|
91
|
+
docker exec ${{ job.services.sqlserver.id }} /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$SQL_SA_PASSWORD" -C -Q "IF DB_ID('$database') IS NULL CREATE DATABASE [$database];"
|
|
92
|
+
done
|
|
93
|
+
- name: Apply migrations and seed test data
|
|
94
|
+
env:
|
|
95
|
+
ConnectionStrings__App: Server=localhost,${{ job.services.sqlserver.ports['1433'] }};Database=${{ env.PRIMARY_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
|
|
96
|
+
DataLayer__ConnectionString: Server=localhost,${{ job.services.sqlserver.ports['1433'] }};Database=${{ env.DATA_LAYER_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
|
|
97
|
+
DATALAYER_SEED: "true"
|
|
98
|
+
run: |
|
|
99
|
+
dotnet ef database update -p "$MIGRATION_PROJECT" -s "$MIGRATION_STARTUP_PROJECT" --context "$MIGRATION_CONTEXT"
|
|
100
|
+
dotnet run --project "$SEED_PROJECT" --no-build -c Release
|
|
101
|
+
- name: Integration tests with coverage
|
|
102
|
+
env:
|
|
103
|
+
ConnectionStrings__App: Server=localhost,${{ job.services.sqlserver.ports['1433'] }};Database=${{ env.PRIMARY_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
|
|
104
|
+
DataLayer__ConnectionString: Server=localhost,${{ job.services.sqlserver.ports['1433'] }};Database=${{ env.DATA_LAYER_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
|
|
105
|
+
run: dotnet test "$INTEGRATION_TEST_PROJECT" --no-build -c Release --collect:"XPlat Code Coverage" --settings "$COVERAGE_SETTINGS" --results-directory TestResults
|
|
106
|
+
- name: Enforce merged coverage floor
|
|
107
|
+
run: |
|
|
108
|
+
dotnet tool install --global dotnet-reportgenerator-globaltool
|
|
109
|
+
export PATH="$PATH:$HOME/.dotnet/tools" # ephemeral ARC runners do not have dotnet tools on PATH
|
|
110
|
+
reportgenerator -reports:"TestResults/**/coverage.cobertura.xml" -targetdir:TestResults/merged -reporttypes:Cobertura
|
|
111
|
+
bash -c "$COVERAGE_CHECK_COMMAND"
|
|
112
|
+
|
|
113
|
+
mutation-api:
|
|
114
|
+
name: Mutation (.NET, diff)
|
|
115
|
+
if: github.event_name == 'pull_request'
|
|
116
|
+
runs-on: agents-arc
|
|
117
|
+
timeout-minutes: 25
|
|
118
|
+
defaults:
|
|
119
|
+
run:
|
|
120
|
+
working-directory: ${{ env.API_WORKING_DIRECTORY }}
|
|
121
|
+
steps:
|
|
122
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
123
|
+
with:
|
|
124
|
+
# Stryker --since diffs against the PR base; it needs history, not a shallow tip.
|
|
125
|
+
fetch-depth: 0
|
|
126
|
+
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
|
|
127
|
+
with:
|
|
128
|
+
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
129
|
+
- name: Detect backend changes
|
|
130
|
+
id: scope
|
|
131
|
+
working-directory: ${{ github.workspace }}
|
|
132
|
+
run: |
|
|
133
|
+
git fetch origin "$GITHUB_BASE_REF" --depth=1
|
|
134
|
+
if git diff --name-only "origin/$GITHUB_BASE_REF" HEAD | grep -qE "^${API_WORKING_DIRECTORY}/"; then
|
|
135
|
+
echo "run=true" >> "$GITHUB_OUTPUT"
|
|
136
|
+
else
|
|
137
|
+
echo "run=false" >> "$GITHUB_OUTPUT"
|
|
138
|
+
echo "No ${API_WORKING_DIRECTORY} changes in this PR; skipping .NET mutation."
|
|
139
|
+
fi
|
|
140
|
+
- name: Restore tools and build
|
|
141
|
+
if: steps.scope.outputs.run == 'true'
|
|
142
|
+
run: |
|
|
143
|
+
dotnet tool restore
|
|
144
|
+
dotnet build "$DOTNET_SOLUTION" -c Release
|
|
145
|
+
- name: Stryker.NET (changed files only)
|
|
146
|
+
if: steps.scope.outputs.run == 'true'
|
|
147
|
+
run: |
|
|
148
|
+
export PATH="$PATH:$HOME/.dotnet/tools" # ephemeral ARC runners do not have dotnet tools on PATH
|
|
149
|
+
dotnet stryker \
|
|
150
|
+
--project "$MUTATION_TARGET_PROJECT" \
|
|
151
|
+
--test-projects "$MUTATION_TEST_PROJECT" \
|
|
152
|
+
--since:"origin/$GITHUB_BASE_REF" \
|
|
153
|
+
--concurrency 2 \
|
|
154
|
+
--threshold-high "$MUTATION_THRESHOLD" \
|
|
155
|
+
--threshold-low "$MUTATION_THRESHOLD" \
|
|
156
|
+
--break-at "$MUTATION_THRESHOLD" \
|
|
157
|
+
--reporter progress --reporter json
|
|
158
|
+
|
|
159
|
+
web:
|
|
160
|
+
name: Web (Next.js)
|
|
161
|
+
if: github.event_name != 'schedule'
|
|
162
|
+
runs-on: agents-arc
|
|
163
|
+
timeout-minutes: 15
|
|
164
|
+
steps:
|
|
165
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
166
|
+
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
167
|
+
with:
|
|
168
|
+
version: ${{ env.PNPM_VERSION }}
|
|
169
|
+
run_install: false
|
|
170
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
171
|
+
with:
|
|
172
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
173
|
+
cache: pnpm
|
|
174
|
+
cache-dependency-path: pnpm-lock.yaml
|
|
175
|
+
- name: Configure optional private registry authentication
|
|
176
|
+
env:
|
|
177
|
+
NPM_REGISTRY_TOKEN: ${{ secrets.NPM_REGISTRY_TOKEN }}
|
|
178
|
+
run: |
|
|
179
|
+
if [ -n "$NPM_REGISTRY_TOKEN" ]; then
|
|
180
|
+
echo "${NPM_REGISTRY_URL}:_authToken=$NPM_REGISTRY_TOKEN" >> .npmrc
|
|
181
|
+
fi
|
|
182
|
+
- run: pnpm install --frozen-lockfile
|
|
183
|
+
- name: Lint, test, verify boundaries, and build
|
|
184
|
+
run: |
|
|
185
|
+
pnpm --filter "$WEB_PACKAGE" run lint
|
|
186
|
+
pnpm --filter "$WEB_PACKAGE" run test
|
|
187
|
+
pnpm --filter "$WEB_PACKAGE" run lint:fsd
|
|
188
|
+
pnpm --filter "$WEB_PACKAGE" run build
|
|
189
|
+
|
|
190
|
+
mutation-web:
|
|
191
|
+
name: Mutation (web, diff)
|
|
192
|
+
if: github.event_name == 'pull_request'
|
|
193
|
+
runs-on: agents-arc
|
|
194
|
+
timeout-minutes: 25
|
|
195
|
+
steps:
|
|
196
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
197
|
+
with:
|
|
198
|
+
fetch-depth: 0
|
|
199
|
+
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
200
|
+
with:
|
|
201
|
+
version: ${{ env.PNPM_VERSION }}
|
|
202
|
+
run_install: false
|
|
203
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
204
|
+
with:
|
|
205
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
206
|
+
cache: pnpm
|
|
207
|
+
cache-dependency-path: pnpm-lock.yaml
|
|
208
|
+
- name: Detect web changes
|
|
209
|
+
id: scope
|
|
210
|
+
run: |
|
|
211
|
+
git fetch origin "$GITHUB_BASE_REF" --depth=1
|
|
212
|
+
if git diff --name-only "origin/$GITHUB_BASE_REF" HEAD | grep -qE "^apps/web/"; then
|
|
213
|
+
echo "run=true" >> "$GITHUB_OUTPUT"
|
|
214
|
+
else
|
|
215
|
+
echo "run=false" >> "$GITHUB_OUTPUT"
|
|
216
|
+
echo "No apps/web changes in this PR; skipping web mutation."
|
|
217
|
+
fi
|
|
218
|
+
- name: Configure optional private registry authentication
|
|
219
|
+
if: steps.scope.outputs.run == 'true'
|
|
220
|
+
env:
|
|
221
|
+
NPM_REGISTRY_TOKEN: ${{ secrets.NPM_REGISTRY_TOKEN }}
|
|
222
|
+
run: |
|
|
223
|
+
if [ -n "$NPM_REGISTRY_TOKEN" ]; then
|
|
224
|
+
echo "${NPM_REGISTRY_URL}:_authToken=$NPM_REGISTRY_TOKEN" >> .npmrc
|
|
225
|
+
fi
|
|
226
|
+
- name: Install and run StrykerJS (changed files only)
|
|
227
|
+
if: steps.scope.outputs.run == 'true'
|
|
228
|
+
run: |
|
|
229
|
+
pnpm install --frozen-lockfile
|
|
230
|
+
pnpm --filter "$WEB_PACKAGE" exec stryker run --since="origin/$GITHUB_BASE_REF"
|
|
231
|
+
|
|
232
|
+
secret-scan:
|
|
233
|
+
name: Secret scan (TruffleHog)
|
|
234
|
+
runs-on: agents-arc
|
|
235
|
+
steps:
|
|
236
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
237
|
+
- run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
|
|
238
|
+
|
|
239
|
+
deps-and-iac-scan:
|
|
240
|
+
name: Dependencies and IaC (Trivy)
|
|
241
|
+
runs-on: agents-arc
|
|
242
|
+
steps:
|
|
243
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
244
|
+
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
|
|
245
|
+
with:
|
|
246
|
+
scan-type: fs
|
|
247
|
+
scanners: vuln,misconfig,secret
|
|
248
|
+
severity: CRITICAL,HIGH
|
|
249
|
+
ignore-unfixed: true
|
|
250
|
+
exit-code: "1"
|
|
251
|
+
format: table
|
|
252
|
+
|
|
253
|
+
sast-scan:
|
|
254
|
+
name: SAST (Semgrep)
|
|
255
|
+
runs-on: agents-arc
|
|
256
|
+
steps:
|
|
257
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
258
|
+
- run: docker run --rm -v "${{ github.workspace }}:/src" -w /src "$SEMGREP_IMAGE" semgrep scan --error --metrics=off --oss-only --disable-version-check --config p/default --config p/security-audit --config p/secrets --config p/csharp --config p/typescript --config p/react --exclude-rule yaml.github-actions.security.github-actions-mutable-action-tag.github-actions-mutable-action-tag
|
|
259
|
+
|
|
260
|
+
sbom:
|
|
261
|
+
name: SBOM (CycloneDX)
|
|
262
|
+
runs-on: agents-arc
|
|
263
|
+
steps:
|
|
264
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
265
|
+
- uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
|
|
266
|
+
with:
|
|
267
|
+
format: cyclonedx-json
|
|
268
|
+
artifact-name: ${{ env.SBOM_ARTIFACT_NAME }}
|