@codyswann/lisa 1.52.2 → 1.52.3
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/dist/core/config.d.ts +2 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +5 -0
- package/dist/core/lisa.js.map +1 -1
- package/expo/create-only/.github/workflows/ci.yml +2 -2
- package/expo/create-only/.github/workflows/deploy.yml +1 -1
- package/expo/deletions.json +8 -0
- package/nestjs/create-only/.github/workflows/ci.yml +1 -1
- package/nestjs/create-only/.github/workflows/deploy.yml +1 -1
- package/nestjs/deletions.json +7 -1
- package/package.json +1 -1
- package/typescript/copy-overwrite/.github/workflows/auto-update-pr-branches.yml +9 -30
- package/typescript/copy-overwrite/.github/workflows/claude-ci-auto-fix.yml +6 -131
- package/typescript/copy-overwrite/.github/workflows/claude-code-review-response.yml +9 -101
- package/typescript/copy-overwrite/.github/workflows/claude-deploy-auto-fix.yml +6 -129
- package/typescript/copy-overwrite/.github/workflows/claude-nightly-code-complexity.yml +2 -118
- package/typescript/copy-overwrite/.github/workflows/claude-nightly-test-coverage.yml +2 -115
- package/typescript/copy-overwrite/.github/workflows/claude-nightly-test-improvement.yml +4 -108
- package/typescript/copy-overwrite/.github/workflows/claude.yml +8 -38
- package/typescript/copy-overwrite/.github/workflows/reusable-auto-update-pr-branches.yml +63 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude-ci-auto-fix.yml +167 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude-code-review-response.yml +139 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude-deploy-auto-fix.yml +165 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude-nightly-code-complexity.yml +131 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude-nightly-test-coverage.yml +128 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude-nightly-test-improvement.yml +127 -0
- package/typescript/copy-overwrite/.github/workflows/reusable-claude.yml +67 -0
- package/typescript/deletions.json +12 -0
- package/expo/copy-overwrite/.github/workflows/build.yml +0 -75
- package/expo/copy-overwrite/.github/workflows/lighthouse.yml +0 -88
- package/expo/copy-overwrite/.github/workflows/zap-baseline.yml +0 -107
- package/nestjs/copy-overwrite/.github/workflows/load-test.yml +0 -285
- package/nestjs/copy-overwrite/.github/workflows/zap-baseline.yml +0 -123
- package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +0 -115
- package/typescript/copy-overwrite/.github/workflows/create-issue-on-failure.yml +0 -176
- package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +0 -197
- package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +0 -269
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
# This file is managed by Lisa.
|
|
2
|
-
# Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
3
|
-
|
|
4
|
-
name: K6 Load Testing
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
workflow_call:
|
|
8
|
-
inputs:
|
|
9
|
-
environment:
|
|
10
|
-
description: 'Target environment to test'
|
|
11
|
-
required: true
|
|
12
|
-
type: string
|
|
13
|
-
test_scenario:
|
|
14
|
-
description: 'Test scenario to run (smoke, load, stress, spike, soak)'
|
|
15
|
-
required: false
|
|
16
|
-
type: string
|
|
17
|
-
default: 'smoke'
|
|
18
|
-
base_url:
|
|
19
|
-
description: 'Base URL of the application to test'
|
|
20
|
-
required: true
|
|
21
|
-
type: string
|
|
22
|
-
k6_version:
|
|
23
|
-
description: 'k6 version to use'
|
|
24
|
-
required: false
|
|
25
|
-
type: string
|
|
26
|
-
default: 'latest'
|
|
27
|
-
test_duration:
|
|
28
|
-
description: 'Override test duration (e.g., 5m, 1h)'
|
|
29
|
-
required: false
|
|
30
|
-
type: string
|
|
31
|
-
virtual_users:
|
|
32
|
-
description: 'Override number of virtual users'
|
|
33
|
-
required: false
|
|
34
|
-
type: number
|
|
35
|
-
thresholds_config:
|
|
36
|
-
description: 'Path to custom thresholds configuration'
|
|
37
|
-
required: false
|
|
38
|
-
type: string
|
|
39
|
-
test_script:
|
|
40
|
-
description: 'Path to custom k6 test script'
|
|
41
|
-
required: false
|
|
42
|
-
type: string
|
|
43
|
-
default: '.github/k6/scripts/default-test.js'
|
|
44
|
-
fail_on_threshold:
|
|
45
|
-
description: 'Fail workflow if thresholds are not met'
|
|
46
|
-
required: false
|
|
47
|
-
type: boolean
|
|
48
|
-
default: true
|
|
49
|
-
upload_results:
|
|
50
|
-
description: 'Upload test results as artifacts'
|
|
51
|
-
required: false
|
|
52
|
-
type: boolean
|
|
53
|
-
default: true
|
|
54
|
-
cloud_run:
|
|
55
|
-
description: 'Run tests on k6 Cloud (requires K6_CLOUD_TOKEN secret)'
|
|
56
|
-
required: false
|
|
57
|
-
type: boolean
|
|
58
|
-
default: false
|
|
59
|
-
outputs:
|
|
60
|
-
test_passed:
|
|
61
|
-
description: 'Whether the test passed all thresholds'
|
|
62
|
-
value: ${{ jobs.k6_test.outputs.passed }}
|
|
63
|
-
results_url:
|
|
64
|
-
description: 'URL to test results (if uploaded)'
|
|
65
|
-
value: ${{ jobs.k6_test.outputs.results_url }}
|
|
66
|
-
summary:
|
|
67
|
-
description: 'Test execution summary'
|
|
68
|
-
value: ${{ jobs.k6_test.outputs.summary }}
|
|
69
|
-
secrets:
|
|
70
|
-
K6_CLOUD_TOKEN:
|
|
71
|
-
required: false
|
|
72
|
-
description: 'k6 Cloud API token for cloud runs'
|
|
73
|
-
CUSTOM_HEADERS:
|
|
74
|
-
required: false
|
|
75
|
-
description: 'Custom headers for authenticated endpoints (JSON format)'
|
|
76
|
-
|
|
77
|
-
jobs:
|
|
78
|
-
k6_test:
|
|
79
|
-
name: K6 Load Test - ${{ inputs.test_scenario }}
|
|
80
|
-
runs-on: ubuntu-latest
|
|
81
|
-
outputs:
|
|
82
|
-
passed: ${{ steps.run_test.outputs.passed }}
|
|
83
|
-
results_url: ${{ steps.upload_results.outputs.artifact-url }}
|
|
84
|
-
summary: ${{ steps.generate_summary.outputs.summary }}
|
|
85
|
-
|
|
86
|
-
steps:
|
|
87
|
-
- name: Checkout repository
|
|
88
|
-
uses: actions/checkout@v4
|
|
89
|
-
|
|
90
|
-
- name: Set up k6
|
|
91
|
-
run: |
|
|
92
|
-
if [ "${{ inputs.k6_version }}" = "latest" ]; then
|
|
93
|
-
sudo gpg -k
|
|
94
|
-
sudo gpg --no-default-keyring \
|
|
95
|
-
--keyring /usr/share/keyrings/k6-archive-keyring.gpg \
|
|
96
|
-
--keyserver hkp://keyserver.ubuntu.com:80 \
|
|
97
|
-
--recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
|
|
98
|
-
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
|
|
99
|
-
| sudo tee /etc/apt/sources.list.d/k6.list
|
|
100
|
-
sudo apt-get update
|
|
101
|
-
sudo apt-get install k6
|
|
102
|
-
else
|
|
103
|
-
K6_VERSION="${{ inputs.k6_version }}"
|
|
104
|
-
wget "https://github.com/grafana/k6/releases/download/v${K6_VERSION}/k6-v${K6_VERSION}-linux-amd64.tar.gz"
|
|
105
|
-
tar -xzf "k6-v${K6_VERSION}-linux-amd64.tar.gz"
|
|
106
|
-
sudo mv "k6-v${K6_VERSION}-linux-amd64/k6" /usr/local/bin/
|
|
107
|
-
fi
|
|
108
|
-
k6 version
|
|
109
|
-
|
|
110
|
-
- name: Prepare test environment
|
|
111
|
-
id: prepare_test
|
|
112
|
-
run: |
|
|
113
|
-
# Create results directory
|
|
114
|
-
mkdir -p k6-results
|
|
115
|
-
|
|
116
|
-
# Export environment variables for k6
|
|
117
|
-
{
|
|
118
|
-
echo "K6_BASE_URL=${{ inputs.base_url }}"
|
|
119
|
-
echo "K6_SCENARIO=${{ inputs.test_scenario }}"
|
|
120
|
-
echo "K6_ENVIRONMENT=${{ inputs.environment }}"
|
|
121
|
-
} >> "$GITHUB_ENV"
|
|
122
|
-
|
|
123
|
-
# Set custom duration if provided
|
|
124
|
-
if [ -n "${{ inputs.test_duration }}" ]; then
|
|
125
|
-
echo "K6_DURATION=${{ inputs.test_duration }}" >> "$GITHUB_ENV"
|
|
126
|
-
fi
|
|
127
|
-
|
|
128
|
-
# Set custom VUs if provided
|
|
129
|
-
if [ -n "${{ inputs.virtual_users }}" ]; then
|
|
130
|
-
echo "K6_VUS=${{ inputs.virtual_users }}" >> "$GITHUB_ENV"
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
# Set custom headers if provided
|
|
134
|
-
if [ -n "${{ secrets.CUSTOM_HEADERS }}" ]; then
|
|
135
|
-
echo "K6_CUSTOM_HEADERS=${{ secrets.CUSTOM_HEADERS }}" >> "$GITHUB_ENV"
|
|
136
|
-
fi
|
|
137
|
-
|
|
138
|
-
# Set cloud token if cloud run is enabled
|
|
139
|
-
if [ "${{ inputs.cloud_run }}" = "true" ] && [ -n "${{ secrets.K6_CLOUD_TOKEN }}" ]; then
|
|
140
|
-
echo "K6_CLOUD_TOKEN=${{ secrets.K6_CLOUD_TOKEN }}" >> "$GITHUB_ENV"
|
|
141
|
-
fi
|
|
142
|
-
|
|
143
|
-
- name: Run k6 test
|
|
144
|
-
id: run_test
|
|
145
|
-
run: |
|
|
146
|
-
set +e # Don't exit immediately on error
|
|
147
|
-
|
|
148
|
-
# Use the shared runner script if a scenario is specified, otherwise use custom script
|
|
149
|
-
if [ "${{ inputs.test_script }}" = ".github/k6/scripts/default-test.js" ]; then
|
|
150
|
-
# Use shared runner for standard scenarios
|
|
151
|
-
RUNNER_ARGS="--scenario ${{ inputs.test_scenario }} --url ${{ inputs.base_url }} --json --csv"
|
|
152
|
-
|
|
153
|
-
# Add cloud option if enabled
|
|
154
|
-
if [ "${{ inputs.cloud_run }}" = "true" ]; then
|
|
155
|
-
RUNNER_ARGS="$RUNNER_ARGS --cloud"
|
|
156
|
-
fi
|
|
157
|
-
|
|
158
|
-
# Add duration override if provided
|
|
159
|
-
if [ -n "${{ inputs.test_duration }}" ]; then
|
|
160
|
-
RUNNER_ARGS="$RUNNER_ARGS --duration ${{ inputs.test_duration }}"
|
|
161
|
-
fi
|
|
162
|
-
|
|
163
|
-
# Add VUs override if provided
|
|
164
|
-
if [ -n "${{ inputs.virtual_users }}" ]; then
|
|
165
|
-
RUNNER_ARGS="$RUNNER_ARGS --vus ${{ inputs.virtual_users }}"
|
|
166
|
-
fi
|
|
167
|
-
|
|
168
|
-
# Add no-thresholds flag if needed
|
|
169
|
-
if [ "${{ inputs.fail_on_threshold }}" != "true" ]; then
|
|
170
|
-
RUNNER_ARGS="$RUNNER_ARGS --no-thresholds"
|
|
171
|
-
fi
|
|
172
|
-
|
|
173
|
-
echo "Running shared k6 runner: ./scripts/k6-run.sh $RUNNER_ARGS"
|
|
174
|
-
./scripts/k6-run.sh $RUNNER_ARGS
|
|
175
|
-
TEST_EXIT_CODE=$?
|
|
176
|
-
else
|
|
177
|
-
# Use custom script directly with k6
|
|
178
|
-
TEST_SCRIPT="${{ inputs.test_script }}"
|
|
179
|
-
|
|
180
|
-
# Build k6 command
|
|
181
|
-
K6_CMD="k6 run"
|
|
182
|
-
|
|
183
|
-
# Add cloud option if enabled
|
|
184
|
-
if [ "${{ inputs.cloud_run }}" = "true" ]; then
|
|
185
|
-
K6_CMD="$K6_CMD --cloud"
|
|
186
|
-
fi
|
|
187
|
-
|
|
188
|
-
# Add output options for local runs
|
|
189
|
-
if [ "${{ inputs.cloud_run }}" != "true" ]; then
|
|
190
|
-
K6_CMD="$K6_CMD --out json=k6-results/results.json --out csv=k6-results/results.csv"
|
|
191
|
-
fi
|
|
192
|
-
|
|
193
|
-
# Add thresholds config if provided
|
|
194
|
-
if [ -n "${{ inputs.thresholds_config }}" ]; then
|
|
195
|
-
K6_CMD="$K6_CMD --config ${{ inputs.thresholds_config }}"
|
|
196
|
-
fi
|
|
197
|
-
|
|
198
|
-
# Add test script
|
|
199
|
-
K6_CMD="$K6_CMD $TEST_SCRIPT"
|
|
200
|
-
|
|
201
|
-
echo "Running k6 command: $K6_CMD"
|
|
202
|
-
$K6_CMD
|
|
203
|
-
TEST_EXIT_CODE=$?
|
|
204
|
-
fi
|
|
205
|
-
|
|
206
|
-
echo "exit_code=$TEST_EXIT_CODE" >> "$GITHUB_OUTPUT"
|
|
207
|
-
|
|
208
|
-
# Determine if test passed
|
|
209
|
-
if [ $TEST_EXIT_CODE -eq 0 ]; then
|
|
210
|
-
echo "passed=true" >> "$GITHUB_OUTPUT"
|
|
211
|
-
echo "✅ Test passed all thresholds" >> "$GITHUB_STEP_SUMMARY"
|
|
212
|
-
else
|
|
213
|
-
echo "passed=false" >> "$GITHUB_OUTPUT"
|
|
214
|
-
echo "❌ Test failed thresholds" >> "$GITHUB_STEP_SUMMARY"
|
|
215
|
-
fi
|
|
216
|
-
|
|
217
|
-
# Exit with appropriate code based on fail_on_threshold setting
|
|
218
|
-
if [ "${{ inputs.fail_on_threshold }}" = "true" ] && [ $TEST_EXIT_CODE -ne 0 ]; then
|
|
219
|
-
exit $TEST_EXIT_CODE
|
|
220
|
-
fi
|
|
221
|
-
|
|
222
|
-
- name: Generate test summary
|
|
223
|
-
id: generate_summary
|
|
224
|
-
if: always()
|
|
225
|
-
run: |
|
|
226
|
-
# Create summary content
|
|
227
|
-
SUMMARY="# K6 Load Test Results\n\n"
|
|
228
|
-
SUMMARY+="**Environment:** ${{ inputs.environment }}\n"
|
|
229
|
-
SUMMARY+="**Test Scenario:** ${{ inputs.test_scenario }}\n"
|
|
230
|
-
SUMMARY+="**Base URL:** ${{ inputs.base_url }}\n"
|
|
231
|
-
SUMMARY+="**Test Status:** "
|
|
232
|
-
|
|
233
|
-
if [ "${{ steps.run_test.outputs.passed }}" = "true" ]; then
|
|
234
|
-
SUMMARY+="✅ PASSED\n"
|
|
235
|
-
else
|
|
236
|
-
SUMMARY+="❌ FAILED\n"
|
|
237
|
-
fi
|
|
238
|
-
|
|
239
|
-
# Add summary to GitHub Step Summary
|
|
240
|
-
echo -e "$SUMMARY" >> "$GITHUB_STEP_SUMMARY"
|
|
241
|
-
|
|
242
|
-
# Extract key metrics from results if available
|
|
243
|
-
if [ -f "k6-results/results.json" ]; then
|
|
244
|
-
echo -e "\n## Key Metrics\n" >> "$GITHUB_STEP_SUMMARY"
|
|
245
|
-
|
|
246
|
-
# Parse JSON results for key metrics (simplified example)
|
|
247
|
-
# In a real implementation, you'd use jq or similar to extract detailed metrics
|
|
248
|
-
echo "📊 Detailed metrics available in artifacts" >> "$GITHUB_STEP_SUMMARY"
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
# Output summary for workflow output
|
|
252
|
-
{
|
|
253
|
-
echo "summary<<EOF"
|
|
254
|
-
echo -e "$SUMMARY"
|
|
255
|
-
echo "EOF"
|
|
256
|
-
} >> "$GITHUB_OUTPUT"
|
|
257
|
-
|
|
258
|
-
- name: Upload test results
|
|
259
|
-
id: upload_results
|
|
260
|
-
if: always() && inputs.upload_results
|
|
261
|
-
uses: actions/upload-artifact@v4
|
|
262
|
-
with:
|
|
263
|
-
name: k6-results-${{ inputs.environment }}-${{ inputs.test_scenario }}-${{ github.run_id }}
|
|
264
|
-
path: k6-results/
|
|
265
|
-
retention-days: 30
|
|
266
|
-
|
|
267
|
-
- name: Comment on PR
|
|
268
|
-
if: github.event_name == 'pull_request' && always()
|
|
269
|
-
uses: actions/github-script@v7
|
|
270
|
-
with:
|
|
271
|
-
script: |
|
|
272
|
-
const summary = `${{ steps.generate_summary.outputs.summary }}`;
|
|
273
|
-
const resultsUrl = '${{ steps.upload_results.outputs.artifact-url }}';
|
|
274
|
-
|
|
275
|
-
let comment = summary;
|
|
276
|
-
if (resultsUrl) {
|
|
277
|
-
comment += `\n\n[📊 View detailed results](${resultsUrl})`;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
github.rest.issues.createComment({
|
|
281
|
-
issue_number: context.issue.number,
|
|
282
|
-
owner: context.repo.owner,
|
|
283
|
-
repo: context.repo.repo,
|
|
284
|
-
body: comment
|
|
285
|
-
});
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# This file is managed by Lisa.
|
|
2
|
-
# Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
3
|
-
|
|
4
|
-
name: ZAP Baseline Scan (NestJS)
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
workflow_call:
|
|
8
|
-
inputs:
|
|
9
|
-
node_version:
|
|
10
|
-
description: 'Node.js version to use'
|
|
11
|
-
required: false
|
|
12
|
-
default: '22.21.1'
|
|
13
|
-
type: string
|
|
14
|
-
package_manager:
|
|
15
|
-
description: 'Package manager to use (npm, yarn, or bun)'
|
|
16
|
-
required: false
|
|
17
|
-
default: 'bun'
|
|
18
|
-
type: string
|
|
19
|
-
zap_target_url:
|
|
20
|
-
description: 'Override URL for ZAP to scan (default: http://localhost:3000/graphql)'
|
|
21
|
-
required: false
|
|
22
|
-
default: 'http://localhost:3000/graphql'
|
|
23
|
-
type: string
|
|
24
|
-
zap_rules_file:
|
|
25
|
-
description: 'Path to ZAP rules configuration file'
|
|
26
|
-
required: false
|
|
27
|
-
default: '.zap/baseline.conf'
|
|
28
|
-
type: string
|
|
29
|
-
|
|
30
|
-
jobs:
|
|
31
|
-
zap_baseline:
|
|
32
|
-
name: ZAP Baseline Scan
|
|
33
|
-
runs-on: ubuntu-latest
|
|
34
|
-
timeout-minutes: 20
|
|
35
|
-
|
|
36
|
-
steps:
|
|
37
|
-
- name: Checkout repository
|
|
38
|
-
uses: actions/checkout@v4
|
|
39
|
-
|
|
40
|
-
- name: Setup Node.js
|
|
41
|
-
uses: actions/setup-node@v4
|
|
42
|
-
with:
|
|
43
|
-
node-version: ${{ inputs.node_version }}
|
|
44
|
-
cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
|
|
45
|
-
|
|
46
|
-
- name: Setup Bun
|
|
47
|
-
if: inputs.package_manager == 'bun'
|
|
48
|
-
uses: oven-sh/setup-bun@v2
|
|
49
|
-
with:
|
|
50
|
-
bun-version: '1.3.8'
|
|
51
|
-
|
|
52
|
-
- name: Install dependencies
|
|
53
|
-
run: |
|
|
54
|
-
if [ "${{ inputs.package_manager }}" = "npm" ]; then
|
|
55
|
-
npm ci
|
|
56
|
-
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
|
|
57
|
-
yarn install --frozen-lockfile
|
|
58
|
-
elif [ "${{ inputs.package_manager }}" = "bun" ]; then
|
|
59
|
-
bun install --frozen-lockfile
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
- name: Build project
|
|
63
|
-
run: ${{ inputs.package_manager }} run build
|
|
64
|
-
|
|
65
|
-
- name: Start NestJS server
|
|
66
|
-
run: |
|
|
67
|
-
${{ inputs.package_manager }} run start &
|
|
68
|
-
SERVER_PID=$!
|
|
69
|
-
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
|
|
70
|
-
env:
|
|
71
|
-
NODE_ENV: test
|
|
72
|
-
PORT: 3000
|
|
73
|
-
|
|
74
|
-
- name: Wait for server ready
|
|
75
|
-
run: |
|
|
76
|
-
echo "Waiting for NestJS server to be ready..."
|
|
77
|
-
RETRIES=30
|
|
78
|
-
until curl -sf http://localhost:3000/health > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
|
|
79
|
-
echo "Waiting for server... ($RETRIES retries left)"
|
|
80
|
-
RETRIES=$((RETRIES - 1))
|
|
81
|
-
sleep 2
|
|
82
|
-
done
|
|
83
|
-
if [ $RETRIES -eq 0 ]; then
|
|
84
|
-
echo "Server failed to start within timeout"
|
|
85
|
-
exit 1
|
|
86
|
-
fi
|
|
87
|
-
echo "Server is ready"
|
|
88
|
-
|
|
89
|
-
- name: Check for ZAP rules file
|
|
90
|
-
id: check_rules
|
|
91
|
-
run: |
|
|
92
|
-
if [ -f "${{ inputs.zap_rules_file }}" ]; then
|
|
93
|
-
echo "has_rules=true" >> $GITHUB_OUTPUT
|
|
94
|
-
else
|
|
95
|
-
echo "has_rules=false" >> $GITHUB_OUTPUT
|
|
96
|
-
fi
|
|
97
|
-
|
|
98
|
-
- name: Run ZAP baseline scan
|
|
99
|
-
uses: zaproxy/action-baseline@v0.14.0
|
|
100
|
-
with:
|
|
101
|
-
target: ${{ inputs.zap_target_url }}
|
|
102
|
-
rules_file_name: ${{ steps.check_rules.outputs.has_rules == 'true' && inputs.zap_rules_file || '' }}
|
|
103
|
-
fail_action: true
|
|
104
|
-
allow_issue_writing: false
|
|
105
|
-
artifact_name: 'zap-report-nestjs'
|
|
106
|
-
|
|
107
|
-
- name: Stop NestJS server
|
|
108
|
-
if: always()
|
|
109
|
-
run: |
|
|
110
|
-
if [ -n "$SERVER_PID" ]; then
|
|
111
|
-
kill "$SERVER_PID" 2>/dev/null || true
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
- name: Upload ZAP report
|
|
115
|
-
if: always()
|
|
116
|
-
uses: actions/upload-artifact@v4
|
|
117
|
-
with:
|
|
118
|
-
name: zap-baseline-report-nestjs-${{ github.run_id }}
|
|
119
|
-
path: |
|
|
120
|
-
zap-report.html
|
|
121
|
-
zap-report.json
|
|
122
|
-
zap-report.md
|
|
123
|
-
retention-days: 14
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# This file is managed by Lisa.
|
|
2
|
-
# Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
3
|
-
# -----------------------------------------------------------------------------
|
|
4
|
-
# GitHub Issue Creation Workflow
|
|
5
|
-
# -----------------------------------------------------------------------------
|
|
6
|
-
# ⚠️ WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT MANUALLY! ⚠️
|
|
7
|
-
# Any changes may be overwritten by the generation process.
|
|
8
|
-
# This workflow creates a GitHub issue when another workflow fails.
|
|
9
|
-
# It captures details about the failure and creates a standardized issue
|
|
10
|
-
# to help track and resolve CI/CD problems.
|
|
11
|
-
#
|
|
12
|
-
# Example usage in another workflow:
|
|
13
|
-
# ```yaml
|
|
14
|
-
# create_github_issue_on_failure:
|
|
15
|
-
# if: failure()
|
|
16
|
-
# uses: ./.github/workflows/github-issue-on-failure.yml
|
|
17
|
-
# with:
|
|
18
|
-
# workflow_name: 'My Workflow'
|
|
19
|
-
# failed_job: 'build_and_test'
|
|
20
|
-
# secrets:
|
|
21
|
-
# PAT: ${{ secrets.PAT }}
|
|
22
|
-
# ```
|
|
23
|
-
|
|
24
|
-
name: 🚨 GitHub Issue on Workflow Failure
|
|
25
|
-
|
|
26
|
-
on:
|
|
27
|
-
workflow_call:
|
|
28
|
-
inputs:
|
|
29
|
-
workflow_name:
|
|
30
|
-
required: true
|
|
31
|
-
type: string
|
|
32
|
-
description: 'Name of the workflow that failed'
|
|
33
|
-
failed_job:
|
|
34
|
-
required: false
|
|
35
|
-
type: string
|
|
36
|
-
description: 'Name of the job that failed (optional)'
|
|
37
|
-
node_version:
|
|
38
|
-
description: 'Node.js version to use'
|
|
39
|
-
required: false
|
|
40
|
-
default: '22.21.1'
|
|
41
|
-
type: string
|
|
42
|
-
package_manager:
|
|
43
|
-
description: 'Package manager to use (npm, yarn, or bun)'
|
|
44
|
-
required: false
|
|
45
|
-
default: 'npm'
|
|
46
|
-
type: string
|
|
47
|
-
working_directory:
|
|
48
|
-
description: 'Directory to run commands in (if not root)'
|
|
49
|
-
required: false
|
|
50
|
-
default: ''
|
|
51
|
-
type: string
|
|
52
|
-
secrets:
|
|
53
|
-
PAT:
|
|
54
|
-
required: false
|
|
55
|
-
description: 'Personal Access Token with repo scope (falls back to GITHUB_TOKEN)'
|
|
56
|
-
|
|
57
|
-
# Concurrency is managed by the parent workflow that calls this one
|
|
58
|
-
# This avoids deadlocks between parent and child workflows
|
|
59
|
-
|
|
60
|
-
jobs:
|
|
61
|
-
create_issue:
|
|
62
|
-
name: 📝 Create GitHub Issue
|
|
63
|
-
runs-on: ubuntu-latest
|
|
64
|
-
timeout-minutes: 5
|
|
65
|
-
steps:
|
|
66
|
-
- name: 📥 Checkout repository
|
|
67
|
-
uses: actions/checkout@v4
|
|
68
|
-
|
|
69
|
-
- name: 🔧 Setup Node.js
|
|
70
|
-
uses: actions/setup-node@v4
|
|
71
|
-
with:
|
|
72
|
-
node-version: ${{ inputs.node_version }}
|
|
73
|
-
cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
|
|
74
|
-
|
|
75
|
-
- name: 🔖 Create Issue
|
|
76
|
-
uses: actions/github-script@v7
|
|
77
|
-
with:
|
|
78
|
-
github-token: ${{ secrets.PAT || github.token }}
|
|
79
|
-
script: |
|
|
80
|
-
// Get repository and run information
|
|
81
|
-
const { owner, repo } = context.repo;
|
|
82
|
-
const runId = context.runId;
|
|
83
|
-
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`;
|
|
84
|
-
|
|
85
|
-
// Get workflow information from inputs
|
|
86
|
-
const workflowName = '${{ inputs.workflow_name }}';
|
|
87
|
-
const failedJob = '${{ inputs.failed_job }}' || 'Unknown';
|
|
88
|
-
|
|
89
|
-
// Create standardized issue title and body
|
|
90
|
-
const title = `🚨 Workflow Failure: ${workflowName}${failedJob !== 'Unknown' ? ` - ${failedJob}` : ''}`;
|
|
91
|
-
const body = `
|
|
92
|
-
## Workflow Failure
|
|
93
|
-
|
|
94
|
-
The "${workflowName}" workflow has failed${failedJob !== 'Unknown' ? ` in job: **${failedJob}**` : ''}.
|
|
95
|
-
|
|
96
|
-
### Details
|
|
97
|
-
- **Workflow Run**: [View Run Details](${runUrl})
|
|
98
|
-
- **Commit**: ${context.sha}
|
|
99
|
-
- **Commit Message**: ${context.payload.head_commit ? context.payload.head_commit.message : 'N/A'}
|
|
100
|
-
- **Triggered by**: ${context.actor}
|
|
101
|
-
- **Failed at**: ${new Date().toISOString()}
|
|
102
|
-
|
|
103
|
-
Please investigate the workflow logs for more details on the failure.
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
// Create the issue
|
|
107
|
-
await github.rest.issues.create({
|
|
108
|
-
owner,
|
|
109
|
-
repo,
|
|
110
|
-
title,
|
|
111
|
-
body,
|
|
112
|
-
labels: ['bug', 'automation', 'ci-failure']
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
console.log(`Issue created for workflow failure: ${runUrl}`);
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# This file is managed by Lisa.
|
|
2
|
-
# Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
3
|
-
# -----------------------------------------------------------------------------
|
|
4
|
-
# Cascading Issue Creation Workflow
|
|
5
|
-
# -----------------------------------------------------------------------------
|
|
6
|
-
# ⚠️ WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT MANUALLY! ⚠️
|
|
7
|
-
# Any changes may be overwritten by the generation process.
|
|
8
|
-
#
|
|
9
|
-
# This is a dispatcher workflow that intelligently routes failures to the
|
|
10
|
-
# appropriate issue tracking system based on available credentials:
|
|
11
|
-
#
|
|
12
|
-
# 1. If Sentry credentials exist → Create Sentry issue
|
|
13
|
-
# 2. Else if Jira credentials exist → Create Jira issue
|
|
14
|
-
# 3. Else → Create GitHub issue (fallback)
|
|
15
|
-
#
|
|
16
|
-
# Example usage in another workflow:
|
|
17
|
-
# ```yaml
|
|
18
|
-
# create_issue_on_failure:
|
|
19
|
-
# if: failure()
|
|
20
|
-
# uses: ./.github/workflows/create-issue-on-failure.yml
|
|
21
|
-
# with:
|
|
22
|
-
# workflow_name: 'My Workflow'
|
|
23
|
-
# failed_job: 'build_and_test'
|
|
24
|
-
# secrets: inherit
|
|
25
|
-
# ```
|
|
26
|
-
#
|
|
27
|
-
# The workflow automatically detects which system to use based on repository
|
|
28
|
-
# variables and secrets. No configuration needed in the calling workflow.
|
|
29
|
-
|
|
30
|
-
name: 📌 Create Issue on Failure (Auto-Dispatch)
|
|
31
|
-
|
|
32
|
-
on:
|
|
33
|
-
workflow_call:
|
|
34
|
-
inputs:
|
|
35
|
-
workflow_name:
|
|
36
|
-
required: true
|
|
37
|
-
type: string
|
|
38
|
-
description: 'Name of the workflow that failed'
|
|
39
|
-
failed_job:
|
|
40
|
-
required: false
|
|
41
|
-
type: string
|
|
42
|
-
description: 'Name of the job that failed (optional)'
|
|
43
|
-
issue_type:
|
|
44
|
-
required: false
|
|
45
|
-
type: string
|
|
46
|
-
default: 'Bug'
|
|
47
|
-
description: 'Type of issue to create (Bug, Task, etc.)'
|
|
48
|
-
environment:
|
|
49
|
-
required: false
|
|
50
|
-
type: string
|
|
51
|
-
default: 'production'
|
|
52
|
-
description: 'Environment where the failure occurred'
|
|
53
|
-
level:
|
|
54
|
-
required: false
|
|
55
|
-
type: string
|
|
56
|
-
default: 'error'
|
|
57
|
-
description: 'Severity level (debug, info, warning, error, fatal)'
|
|
58
|
-
node_version:
|
|
59
|
-
description: 'Node.js version to use'
|
|
60
|
-
required: false
|
|
61
|
-
default: '22.21.1'
|
|
62
|
-
type: string
|
|
63
|
-
package_manager:
|
|
64
|
-
description: 'Package manager to use (npm, yarn, or bun)'
|
|
65
|
-
required: false
|
|
66
|
-
default: 'npm'
|
|
67
|
-
type: string
|
|
68
|
-
working_directory:
|
|
69
|
-
description: 'Directory to run commands in (if not root)'
|
|
70
|
-
required: false
|
|
71
|
-
default: ''
|
|
72
|
-
type: string
|
|
73
|
-
secrets:
|
|
74
|
-
SENTRY_AUTH_TOKEN:
|
|
75
|
-
required: false
|
|
76
|
-
description: 'Sentry Auth Token (if using Sentry)'
|
|
77
|
-
JIRA_API_TOKEN:
|
|
78
|
-
required: false
|
|
79
|
-
description: 'Jira API token (if using Jira)'
|
|
80
|
-
PAT:
|
|
81
|
-
required: false
|
|
82
|
-
description: 'Personal Access Token (if using GitHub Issues)'
|
|
83
|
-
|
|
84
|
-
# Concurrency is managed by the parent workflow that calls this one
|
|
85
|
-
# This avoids deadlocks between parent and child workflows
|
|
86
|
-
|
|
87
|
-
jobs:
|
|
88
|
-
# Dispatch job determines which system to use based on available credentials
|
|
89
|
-
dispatch:
|
|
90
|
-
name: 🧭 Determine Issue Tracking System
|
|
91
|
-
runs-on: ubuntu-latest
|
|
92
|
-
timeout-minutes: 5
|
|
93
|
-
outputs:
|
|
94
|
-
use_sentry: ${{ steps.check.outputs.sentry }}
|
|
95
|
-
use_jira: ${{ steps.check.outputs.jira }}
|
|
96
|
-
use_github: ${{ steps.check.outputs.github }}
|
|
97
|
-
steps:
|
|
98
|
-
- name: 🔍 Check Available Credentials
|
|
99
|
-
id: check
|
|
100
|
-
run: |
|
|
101
|
-
# Check for Sentry (highest priority)
|
|
102
|
-
if [ -n "${{ vars.SENTRY_ORG }}" ] && [ -n "${{ vars.SENTRY_PROJECT }}" ] && [ -n "${{ secrets.SENTRY_AUTH_TOKEN }}" ]; then
|
|
103
|
-
echo "sentry=true" >> $GITHUB_OUTPUT
|
|
104
|
-
echo "jira=false" >> $GITHUB_OUTPUT
|
|
105
|
-
echo "github=false" >> $GITHUB_OUTPUT
|
|
106
|
-
echo "✓ Using Sentry for issue tracking"
|
|
107
|
-
exit 0
|
|
108
|
-
fi
|
|
109
|
-
|
|
110
|
-
# Check for Jira (second priority)
|
|
111
|
-
if [ -n "${{ vars.JIRA_BASE_URL }}" ] && [ -n "${{ vars.JIRA_USER_EMAIL }}" ] && [ -n "${{ vars.JIRA_PROJECT_KEY }}" ] && [ -n "${{ secrets.JIRA_API_TOKEN }}" ]; then
|
|
112
|
-
echo "sentry=false" >> $GITHUB_OUTPUT
|
|
113
|
-
echo "jira=true" >> $GITHUB_OUTPUT
|
|
114
|
-
echo "github=false" >> $GITHUB_OUTPUT
|
|
115
|
-
echo "✓ Using Jira for issue tracking"
|
|
116
|
-
exit 0
|
|
117
|
-
fi
|
|
118
|
-
|
|
119
|
-
# Fall back to GitHub (always available)
|
|
120
|
-
echo "sentry=false" >> $GITHUB_OUTPUT
|
|
121
|
-
echo "jira=false" >> $GITHUB_OUTPUT
|
|
122
|
-
echo "github=true" >> $GITHUB_OUTPUT
|
|
123
|
-
echo "✓ Using GitHub Issues for issue tracking (fallback)"
|
|
124
|
-
|
|
125
|
-
# Create Sentry issue (if available)
|
|
126
|
-
create_sentry_issue:
|
|
127
|
-
name: 📌 Create Sentry Issue
|
|
128
|
-
needs: [dispatch]
|
|
129
|
-
if: ${{ needs.dispatch.outputs.use_sentry == 'true' }}
|
|
130
|
-
uses: ./.github/workflows/create-sentry-issue-on-failure.yml
|
|
131
|
-
with:
|
|
132
|
-
workflow_name: ${{ inputs.workflow_name }}
|
|
133
|
-
failed_job: ${{ inputs.failed_job }}
|
|
134
|
-
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
|
|
135
|
-
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }}
|
|
136
|
-
environment: ${{ inputs.environment }}
|
|
137
|
-
level: ${{ inputs.level }}
|
|
138
|
-
node_version: ${{ inputs.node_version }}
|
|
139
|
-
package_manager: ${{ inputs.package_manager }}
|
|
140
|
-
working_directory: ${{ inputs.working_directory }}
|
|
141
|
-
secrets:
|
|
142
|
-
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
|
143
|
-
|
|
144
|
-
# Create Jira issue (if available)
|
|
145
|
-
create_jira_issue:
|
|
146
|
-
name: 📌 Create Jira Issue
|
|
147
|
-
needs: [dispatch]
|
|
148
|
-
if: ${{ needs.dispatch.outputs.use_jira == 'true' }}
|
|
149
|
-
uses: ./.github/workflows/create-jira-issue-on-failure.yml
|
|
150
|
-
with:
|
|
151
|
-
workflow_name: ${{ inputs.workflow_name }}
|
|
152
|
-
failed_job: ${{ inputs.failed_job }}
|
|
153
|
-
issue_type: ${{ inputs.issue_type }}
|
|
154
|
-
JIRA_BASE_URL: ${{ vars.JIRA_BASE_URL }}
|
|
155
|
-
JIRA_USER_EMAIL: ${{ vars.JIRA_USER_EMAIL }}
|
|
156
|
-
JIRA_PROJECT_KEY: ${{ vars.JIRA_PROJECT_KEY }}
|
|
157
|
-
node_version: ${{ inputs.node_version }}
|
|
158
|
-
package_manager: ${{ inputs.package_manager }}
|
|
159
|
-
working_directory: ${{ inputs.working_directory }}
|
|
160
|
-
secrets:
|
|
161
|
-
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
|
162
|
-
|
|
163
|
-
# Create GitHub issue (fallback)
|
|
164
|
-
create_github_issue:
|
|
165
|
-
name: 📌 Create GitHub Issue
|
|
166
|
-
needs: [dispatch]
|
|
167
|
-
if: ${{ needs.dispatch.outputs.use_github == 'true' }}
|
|
168
|
-
uses: ./.github/workflows/create-github-issue-on-failure.yml
|
|
169
|
-
with:
|
|
170
|
-
workflow_name: ${{ inputs.workflow_name }}
|
|
171
|
-
failed_job: ${{ inputs.failed_job }}
|
|
172
|
-
node_version: ${{ inputs.node_version }}
|
|
173
|
-
package_manager: ${{ inputs.package_manager }}
|
|
174
|
-
working_directory: ${{ inputs.working_directory }}
|
|
175
|
-
secrets:
|
|
176
|
-
PAT: ${{ secrets.PAT }}
|