-
Notifications
You must be signed in to change notification settings - Fork 3
165 lines (148 loc) · 5.28 KB
/
Copy pathci.yaml
File metadata and controls
165 lines (148 loc) · 5.28 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
name: CI/CD
on:
push:
branches:
- prod
- main
- dev
pull_request:
branches:
- '**'
jobs:
test:
name: Run tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 24
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests, first attempt
id: first_run
continue-on-error: true
run: npm test -- --coverage --json --outputFile=test-results.json
- name: Identify failed test suites
if: steps.first_run.outcome == 'failure'
id: failed_tests
run: |
if [ ! -f test-results.json ]; then
echo "No test results file found, treating as full failure"
exit 1
fi
FAILED_SUITES=$(node -e "
const results = require('./test-results.json');
const failed = results.testResults
.filter(suite => suite.status === 'failed')
.map(suite => suite.name)
.join('\n');
console.log(failed);
")
if [ -z "$FAILED_SUITES" ]; then
echo "No failed suites identified despite failure exit code"
exit 1
fi
echo "Failed test suites:"
echo "$FAILED_SUITES"
echo "$FAILED_SUITES" > failed-suites.txt
- name: Re-run failed test suites individually
if: steps.first_run.outcome == 'failure'
run: |
OVERALL_EXIT=0
while IFS= read -r suite; do
if [ -n "$suite" ]; then
echo ""
echo "=== Re-running: $suite ==="
if ! npx jest "$suite"; then
echo "Still failing: $suite"
OVERALL_EXIT=1
else
echo "Passed on retry: $suite"
fi
fi
done < failed-suites.txt
exit $OVERALL_EXIT
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
url: ${{ secrets.CODECOV_URL }}
slug: Alt-Org/Altzone-Server
files: ./coverage/coverage-final.json
build-and-push:
name: Build and Push Docker Image
needs: test
if: github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'prod'
runs-on: [self-hosted, gh-runner-common]
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push image
uses: docker/build-push-action@v7
env:
DOCKER_BUILD_RECORD_UPLOAD: false
with:
context: .
push: true
load: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPO }}:${{ github.ref_name }}-${{ github.run_number }}
${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPO }}:${{ github.ref_name }}-latest
- name: Scan image for vulnerabilities
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPO }}:${{ github.ref_name }}-${{ github.run_number }}
format: json
ignore-unfixed: true
exit-code: '0'
output: trivy-results.json
- name: Upload vulnerabilities to summary tab
if: always()
run: |
{
echo "## Vulnerability scan results"
echo ""
echo "| Target | Package | CVE | Severity | Installed | Fixed |"
echo "|---|---|---|---|---|---|"
jq -r '
.Results[]?
| select(.Vulnerabilities != null)
| .Target as $t
| .Vulnerabilities[]
| "| \($t) | \(.PkgName) | \(.VulnerabilityID) | \(.Severity) | \(.InstalledVersion) | \(.FixedVersion // "-") |"
' trivy-results.json
} >> "$GITHUB_STEP_SUMMARY"
- name: Convert scan results to SARIF format
if: always()
run: trivy convert --format sarif --output trivy-results.sarif trivy-results.json
- name: Upload vulnerabilities to Security tab
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: trivy-results.sarif
notify:
name: Notify server about new image build
needs: build-and-push
if: github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'prod'
runs-on: [self-hosted, gh-runner-common]
steps:
- name: Notify server
env:
WEBHOOK_SECRET: ${{ secrets.SERVER_WEBHOOK_NOTIFY_SECRET }}
WEBHOOK_URL: ${{ secrets.SERVER_WEBHOOK_NOTIFY_URL }}
PAYLOAD: '{"name": "api", "tag": "${{ github.ref_name }}"}'
run: |
SIGNATURE=$(echo "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | sed 's/^.* //')
curl -s -o /dev/null -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Hub-Signature: sha256=$SIGNATURE" \
-d "$PAYLOAD" \
--insecure