-
Notifications
You must be signed in to change notification settings - Fork 0
313 lines (274 loc) Β· 13.3 KB
/
Copy pathtest-workflow.yml
File metadata and controls
313 lines (274 loc) Β· 13.3 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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
name: Reusable Code Linting Workflow
# This workflow is designed to be called from other repositories
on:
workflow_call:
inputs:
node-version:
description: "Node.js version to use"
required: false
type: string
default: "18"
working-directory:
description: "Working directory for the project"
required: false
type: string
default: "."
environment:
description: "Target environment (development, staging, production)"
required: false
type: string
default: "development"
lint-severity:
description: "Minimum severity level for linting (error, warning, info)"
required: false
type: string
default: "warning"
run-security-audit:
description: "Whether to run npm security audit"
required: false
type: boolean
default: true
package-manager:
description: "Package manager to use (npm, yarn, pnpm)"
required: false
type: string
default: "npm"
eslint-config:
description: "Path to custom ESLint config file"
required: false
type: string
default: ""
secrets:
# Optional custom token if needed, otherwise uses default GITHUB_TOKEN
ACCESS_TOKEN:
required: false
# Optional secrets for custom operations
CUSTOM_SECRET:
required: false
outputs:
lint-status:
description: "Status of the linting job"
value: ${{ jobs.code-linting.outputs.status }}
security-status:
description: "Status of the security audit"
value: ${{ jobs.security-scan.outputs.status }}
# Environment variables
env:
NODE_VERSION: ${{ inputs.node-version }}
WORKING_DIR: ${{ inputs.working-directory }}
ENVIRONMENT: ${{ inputs.environment }}
jobs:
setup-validation:
name: Validate Inputs
runs-on: ubuntu-latest
outputs:
should-proceed: ${{ steps.validate.outputs.should-proceed }}
package-manager: ${{ steps.validate.outputs.package-manager }}
steps:
- name: Validate workflow inputs
id: validate
run: |
echo "π Validating workflow inputs..."
echo "Node Version: ${{ inputs.node-version }}"
echo "Working Directory: ${{ inputs.working-directory }}"
echo "Environment: ${{ inputs.environment }}"
echo "Lint Severity: ${{ inputs.lint-severity }}"
echo "Package Manager: ${{ inputs.package-manager }}"
echo "Run Security Audit: ${{ inputs.run-security-audit }}"
# Validate package manager
if [[ "${{ inputs.package-manager }}" =~ ^(npm|yarn|pnpm)$ ]]; then
echo "β
Valid package manager"
echo "package-manager=${{ inputs.package-manager }}" >> $GITHUB_OUTPUT
else
echo "β Invalid package manager. Using npm as default."
echo "package-manager=npm" >> $GITHUB_OUTPUT
fi
echo "should-proceed=true" >> $GITHUB_OUTPUT
echo "β
Validation complete"
code-linting:
name: Run Code Linting
runs-on: ubuntu-latest
needs: setup-validation
if: needs.setup-validation.outputs.should-proceed == 'true'
outputs:
status: ${{ steps.lint.outcome }}
steps:
- name: Checkout calling repository
uses: actions/checkout@v4
with:
token: ${{ secrets.ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: ${{ needs.setup-validation.outputs.package-manager }}
cache-dependency-path: ${{ inputs.working-directory }}/package-lock.json
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
${{ inputs.working-directory }}/node_modules
~/.npm
~/.cache/yarn
~/.cache/pnpm
key: ${{ runner.os }}-${{ needs.setup-validation.outputs.package-manager }}-${{ hashFiles(format('{0}/package-lock.json', inputs.working-directory)) }}
restore-keys: |
${{ runner.os }}-${{ needs.setup-validation.outputs.package-manager }}-
- name: Install dependencies
working-directory: ${{ inputs.working-directory }}
run: |
echo "π¦ Installing dependencies using ${{ needs.setup-validation.outputs.package-manager }}..."
case "${{ needs.setup-validation.outputs.package-manager }}" in
npm)
npm ci
;;
yarn)
yarn install --frozen-lockfile
;;
pnpm)
pnpm install --frozen-lockfile
;;
esac
- name: Run ESLint
id: lint
working-directory: ${{ inputs.working-directory }}
continue-on-error: true
run: |
echo "π Running ESLint with severity level: ${{ inputs.lint-severity }}"
ESLINT_CONFIG=""
if [ -n "${{ inputs.eslint-config }}" ]; then
ESLINT_CONFIG="--config ${{ inputs.eslint-config }}"
fi
case "${{ needs.setup-validation.outputs.package-manager }}" in
npm)
npm run lint -- $ESLINT_CONFIG --format json --output-file eslint-report.json || \
npm run lint -- $ESLINT_CONFIG
;;
yarn)
yarn lint $ESLINT_CONFIG --format json --output-file eslint-report.json || \
yarn lint $ESLINT_CONFIG
;;
pnpm)
pnpm lint $ESLINT_CONFIG --format json --output-file eslint-report.json || \
pnpm lint $ESLINT_CONFIG
;;
esac
env:
LINT_SEVERITY: ${{ inputs.lint-severity }}
- name: Upload ESLint report
if: always()
uses: actions/upload-artifact@v4
with:
name: eslint-report-${{ github.run_id }}
path: ${{ inputs.working-directory }}/eslint-report.json
retention-days: 30
if-no-files-found: warn
- name: Comment lint results on PR
if: github.event_name == 'pull_request' && steps.lint.outcome == 'failure'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const reportPath = '${{ inputs.working-directory }}/eslint-report.json';
try {
if (fs.existsSync(reportPath)) {
const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
const errorCount = report.reduce((sum, file) => sum + file.errorCount, 0);
const warningCount = report.reduce((sum, file) => sum + file.warningCount, 0);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## π ESLint Results\n\nβ **Errors:** ${errorCount}\nβ οΈ **Warnings:** ${warningCount}\n\nPlease fix the linting issues before merging.`
});
}
} catch (error) {
console.log('Could not post comment:', error.message);
}
security-scan:
name: Security Audit
runs-on: ubuntu-latest
needs: setup-validation
if: needs.setup-validation.outputs.should-proceed == 'true' && inputs.run-security-audit
outputs:
status: ${{ steps.audit.outcome }}
steps:
- name: Checkout calling repository
uses: actions/checkout@v4
with:
token: ${{ secrets.ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Run security audit
id: audit
working-directory: ${{ inputs.working-directory }}
continue-on-error: true
run: |
echo "π Running security audit..."
case "${{ needs.setup-validation.outputs.package-manager }}" in
npm)
npm audit --audit-level=moderate --json > security-audit.json || true
npm audit --audit-level=moderate
;;
yarn)
yarn audit --level moderate --json > security-audit.json || true
yarn audit --level moderate
;;
pnpm)
pnpm audit --audit-level moderate --json > security-audit.json || true
pnpm audit --audit-level moderate
;;
esac
- name: Upload security audit report
if: always()
uses: actions/upload-artifact@v4
with:
name: security-audit-${{ github.run_id }}
path: ${{ inputs.working-directory }}/security-audit.json
retention-days: 30
if-no-files-found: warn
summary:
name: Generate Workflow Summary
runs-on: ubuntu-latest
needs: [setup-validation, code-linting, security-scan]
if: always()
steps:
- name: Create workflow summary
run: |
echo "## π Reusable Workflow Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Configuration" >> $GITHUB_STEP_SUMMARY
echo "| Parameter | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Node Version | ${{ inputs.node-version }} |" >> $GITHUB_STEP_SUMMARY
echo "| Environment | ${{ inputs.environment }} |" >> $GITHUB_STEP_SUMMARY
echo "| Package Manager | ${{ needs.setup-validation.outputs.package-manager }} |" >> $GITHUB_STEP_SUMMARY
echo "| Working Directory | ${{ inputs.working-directory }} |" >> $GITHUB_STEP_SUMMARY
echo "| Lint Severity | ${{ inputs.lint-severity }} |" >> $GITHUB_STEP_SUMMARY
echo "| Security Audit | ${{ inputs.run-security-audit }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Job Results" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Validation | ${{ needs.setup-validation.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Code Linting | ${{ needs.code-linting.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Security Scan | ${{ needs.security-scan.result }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Overall status
if [[ "${{ needs.code-linting.result }}" == "success" && "${{ needs.security-scan.result }}" == "success" ]]; then
echo "### β
All checks passed!" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.code-linting.result }}" == "failure" || "${{ needs.security-scan.result }}" == "failure" ]]; then
echo "### β Some checks failed" >> $GITHUB_STEP_SUMMARY
else
echo "### β οΈ Some checks were skipped or cancelled" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo "**Triggered by:** ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "**Repository:** ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "**Run ID:** ${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY