-
Notifications
You must be signed in to change notification settings - Fork 0
182 lines (159 loc) · 5.71 KB
/
Copy pathci.yml
File metadata and controls
182 lines (159 loc) · 5.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
94
95
96
97
98
99
100
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
172
173
174
175
176
177
178
179
180
181
182
name: CI
# Unified CI for all develop-bound code paths:
# - pull_request: gate before merging into develop
# - push to develop: post-merge verification
# - push to ci/**: escape hatch for iterating on workflows or
# build setup without PR ceremony — see
# docs/contribute/local-ci.md
#
# The changes-detector job gates each downstream job (backend /
# frontend / docs) on path-filters, so a docs-only typo PR doesn't
# pay for backend tests, and a backend-only change doesn't rebuild
# the frontend. Changes to the workflow itself (`ci.yml`) trigger
# everything — that's how we catch a broken workflow before it
# lands.
on:
pull_request:
branches: [develop]
push:
branches: [develop, 'ci/**']
jobs:
changes:
name: Detect changes
runs-on: ubuntu-latest
permissions:
contents: read
# Needed by paths-filter when running on pull_request events
# to read the list of changed files. Harmless on push events.
pull-requests: read
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
docs: ${{ steps.filter.outputs.docs }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Detect changed paths
id: filter
uses: dorny/paths-filter@v4
with:
filters: |
backend:
- 'src/dotnet/**'
- '.github/workflows/ci.yml'
- '.github/actions/setup-dotnet/**'
- 'GitVersion.yml'
frontend:
- 'src/frontend-vue/**'
- '.github/workflows/ci.yml'
- '.github/actions/setup-node-pnpm/**'
docs:
- 'docs/**'
- '.github/workflows/ci.yml'
- '.github/actions/setup-node-pnpm/**'
backend:
name: Backend Build & Test
needs: changes
if: needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup .NET + GitVersion
id: dotnet
uses: ./.github/actions/setup-dotnet
with:
with-gitversion: 'true'
- name: Log version
run: echo "Building version ${{ steps.dotnet.outputs.version }}"
- name: Restore backend dependencies
run: dotnet restore Modgud.slnx
working-directory: ./src/dotnet
- name: Audit NuGet dependencies for known CVEs
run: |
set -o pipefail
out=$(dotnet list package --vulnerable --include-transitive 2>&1)
echo "$out"
if echo "$out" | grep -qE "has the following vulnerable packages"; then
echo "::error ::Vulnerable NuGet packages detected. See log above."
exit 1
fi
working-directory: ./src/dotnet
- name: Build backend
run: dotnet build Modgud.slnx -c Release --no-restore -p:Version=${{ steps.dotnet.outputs.version }}
working-directory: ./src/dotnet
- name: Test backend
run: dotnet test Modgud.slnx -c Release --no-build --verbosity normal
working-directory: ./src/dotnet
frontend:
name: Frontend Build
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node + pnpm + install
uses: ./.github/actions/setup-node-pnpm
with:
working-directory: ./src/frontend-vue
- name: Audit npm dependencies for known CVEs
run: pnpm audit --prod --audit-level=moderate
working-directory: ./src/frontend-vue
- name: Type-check frontend
run: pnpm type-check
working-directory: ./src/frontend-vue
- name: Build frontend
run: pnpm build
working-directory: ./src/frontend-vue
docs:
name: Docs Build
needs: changes
if: needs.changes.outputs.docs == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node + pnpm + install
uses: ./.github/actions/setup-node-pnpm
with:
working-directory: ./docs
- name: Build docs (public + in-app)
run: pnpm build:all
working-directory: ./docs
# Aggregator gate so branch protection can require a single check
# that resolves correctly even when path-gated jobs were `skipped`.
# `success` and `skipped` are both treated as OK; only `failure` /
# `cancelled` fail the gate.
ci-success:
name: CI Pass
needs: [changes, backend, frontend, docs]
if: always()
runs-on: ubuntu-latest
steps:
- name: Verify upstream jobs
run: |
fail=0
if [[ "${{ needs.changes.result }}" != "success" ]]; then
echo "::error ::changes detector did not succeed (${{ needs.changes.result }})"
fail=1
fi
if [[ "${{ needs.backend.result }}" == "failure" || "${{ needs.backend.result }}" == "cancelled" ]]; then
echo "::error ::backend job ${{ needs.backend.result }}"; fail=1
fi
if [[ "${{ needs.frontend.result }}" == "failure" || "${{ needs.frontend.result }}" == "cancelled" ]]; then
echo "::error ::frontend job ${{ needs.frontend.result }}"; fail=1
fi
if [[ "${{ needs.docs.result }}" == "failure" || "${{ needs.docs.result }}" == "cancelled" ]]; then
echo "::error ::docs job ${{ needs.docs.result }}"; fail=1
fi
if [[ $fail -eq 1 ]]; then exit 1; fi
echo "All upstream jobs OK (success or correctly skipped)"