-
Notifications
You must be signed in to change notification settings - Fork 0
197 lines (162 loc) · 5.61 KB
/
release-check.yml
File metadata and controls
197 lines (162 loc) · 5.61 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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
name: CI - Release Check
on:
pull_request:
branches: [master]
concurrency:
group: ci-release-${{ github.ref }}
cancel-in-progress: true
env:
SONAR_HOST_URL: "https://sonarcloud.io"
SONAR_ORGANIZATION: "ciscode"
SONAR_PROJECT_KEY: "CISCODE-MA_CacheKit"
NODE_VERSION: "22"
# ─── Job 1: Static checks (fast feedback, runs in parallel with test) ──────────
jobs:
quality:
name: Quality Checks
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install
run: npm ci
- name: Security Audit
# Only fail on high/critical — moderate noise in dev deps is expected
run: npm audit --production --audit-level=high
- name: Format
run: npm run format
- name: Typecheck
run: npm run typecheck
- name: Lint
run: npm run lint
# ─── Job 2: Tests + Coverage (artifact passed to Sonar) ────────────────────────
test:
name: Test & Coverage
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install
run: npm ci
- name: Test (with coverage)
run: npm run test:cov
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 1
# ─── Job 3: Build ──────────────────────────────────────────────────────────────
build:
name: Build
runs-on: ubuntu-latest
needs: [quality, test]
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install
run: npm ci
- name: Build
run: npm run build
# ─── Job 4: SonarCloud (depends on test for coverage data) ─────────────────────
sonar:
name: SonarCloud Analysis
runs-on: ubuntu-latest
needs: [test]
timeout-minutes: 15
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Full history required for accurate blame & new code detection
fetch-depth: 0
- name: Download coverage report
uses: actions/download-artifact@v4
with:
name: coverage-report
path: coverage/
- name: Cache SonarCloud packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: sonar-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: sonar-${{ runner.os }}-
- name: SonarCloud Scan
uses: SonarSource/sonarqube-scan-action@v6
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ env.SONAR_HOST_URL }}
with:
args: >
-Dsonar.organization=${{ env.SONAR_ORGANIZATION }}
-Dsonar.projectKey=${{ env.SONAR_PROJECT_KEY }}
-Dsonar.sources=src
-Dsonar.test.inclusions=**/*.spec.ts,**/*.test.ts
-Dsonar.exclusions=**/node_modules/**,**/dist/**,**/coverage/**,**/*.d.ts
-Dsonar.coverage.exclusions=**/*.spec.ts,**/*.test.ts,**/index.ts
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
-Dsonar.typescript.tsconfigPath=tsconfig.json
-Dsonar.qualitygate.wait=true
-Dsonar.qualitygate.timeout=300
# ─── Job 5: Final status report (always runs) ──────────────────────────────────
report:
name: Report CI Status
runs-on: ubuntu-latest
needs: [quality, test, build, sonar]
# Run even if upstream jobs failed
if: always()
timeout-minutes: 5
permissions:
contents: read
statuses: write
steps:
- name: Resolve overall result
id: result
run: |
results="${{ needs.quality.result }} ${{ needs.test.result }} ${{ needs.build.result }} ${{ needs.sonar.result }}"
if echo "$results" | grep -qE "failure|cancelled"; then
echo "state=failure" >> $GITHUB_OUTPUT
echo "desc=One or more CI checks failed" >> $GITHUB_OUTPUT
else
echo "state=success" >> $GITHUB_OUTPUT
echo "desc=All CI checks passed" >> $GITHUB_OUTPUT
fi
- name: Post commit status
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: context.sha,
state: '${{ steps.result.outputs.state }}',
context: 'CI / Release Check',
description: '${{ steps.result.outputs.desc }}',
target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`
})