-
Notifications
You must be signed in to change notification settings - Fork 0
159 lines (137 loc) · 6.01 KB
/
Copy pathtest.yaml
File metadata and controls
159 lines (137 loc) · 6.01 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
name: tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
permissions:
contents: read
env:
GO_VERSION: '1.21'
GOLANGCI_LINT_VERSION: 'v2.0.2'
jobs:
test:
permissions:
contents: read
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
# Build validation (cross-platform).
# Pure-stdlib libraries have no go.sum, so we only diff go.mod.
- name: Build validation
run: |
go build ./...
go mod tidy
git diff --exit-code go.mod
- name: Run tests (Unix)
if: runner.os != 'Windows'
run: go test -v -race -coverprofile=coverage.out ./...
- name: Run tests (Windows)
if: runner.os == 'Windows'
run: go test -v -coverprofile="coverage.out" ./...
- name: Run benchmarks
run: go test -bench=. -benchmem ./...
- name: Upload coverage artifact
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: coverage-out
path: coverage.out
retention-days: 1
# Badge generation runs only on main, and is the only job that needs
# contents: write. Separating it from the test matrix keeps every test
# job running with read-only credentials (least privilege).
badges:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
security-events: read
steps:
- uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Download coverage artifact
uses: actions/download-artifact@v4
with:
name: coverage-out
- name: Generate badge data
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
mkdir -p .github/badges
# Install pinned golangci-lint (never @latest in CI).
go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}"
# Coverage badge
if [[ -f "coverage.out" ]]; then
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
if (( $(echo "$COVERAGE >= 80" | bc -l) )); then
COLOR="brightgreen"
elif (( $(echo "$COVERAGE >= 60" | bc -l) )); then
COLOR="yellow"
else
COLOR="red"
fi
echo '{"schemaVersion":1,"label":"coverage","message":"'$COVERAGE'%","color":"'$COLOR'"}' > .github/badges/coverage.json
fi
# Go version badge
GO_VERSION=$(go version | grep -oE 'go[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1)
echo '{"schemaVersion":1,"label":"Go","message":"'$GO_VERSION'","color":"00ADD8"}' > .github/badges/go-version.json
# Last updated badge
LAST_COMMIT_DATE=$(git log -1 --format=%cd --date=short)
echo '{"schemaVersion":1,"label":"last updated","message":"'$LAST_COMMIT_DATE'","color":"teal"}' > .github/badges/last-updated.json
# golangci-lint badge
if golangci-lint run; then
echo '{"schemaVersion":1,"label":"golangci-lint","message":"0 issues","color":"brightgreen"}' > .github/badges/golangci-lint.json
else
ISSUES=$(golangci-lint run 2>&1 | grep -c "^.*\.go:" || echo "0")
if [[ $ISSUES -eq 0 ]]; then
echo '{"schemaVersion":1,"label":"golangci-lint","message":"passing","color":"brightgreen"}' > .github/badges/golangci-lint.json
else
echo '{"schemaVersion":1,"label":"golangci-lint","message":"'$ISSUES' issues","color":"red"}' > .github/badges/golangci-lint.json
fi
fi
# Security/dependabot badge — queries THIS repo via $REPO env var
DEPENDABOT_ALERTS=$(gh api "repos/$REPO/dependabot/alerts" --jq 'length' 2>/dev/null || echo "0")
CODE_SCANNING_ALERTS=$(gh api "repos/$REPO/code-scanning/alerts" --jq '[.[] | select(.state == "open")] | length' 2>/dev/null || echo "0")
TOTAL_ALERTS=$((DEPENDABOT_ALERTS + CODE_SCANNING_ALERTS))
OPEN_PRS=$(gh pr list --author "app/dependabot" --state open --json number --jq 'length' 2>/dev/null || echo "0")
if [[ $TOTAL_ALERTS -gt 0 ]]; then
if [[ $DEPENDABOT_ALERTS -gt 0 && $CODE_SCANNING_ALERTS -gt 0 ]]; then
echo '{"schemaVersion":1,"label":"security","message":"'$TOTAL_ALERTS' alerts","color":"red"}' > .github/badges/dependabot.json
elif [[ $DEPENDABOT_ALERTS -gt 0 ]]; then
echo '{"schemaVersion":1,"label":"security","message":"'$DEPENDABOT_ALERTS' dependency alerts","color":"red"}' > .github/badges/dependabot.json
else
echo '{"schemaVersion":1,"label":"security","message":"'$CODE_SCANNING_ALERTS' code alerts","color":"red"}' > .github/badges/dependabot.json
fi
elif [[ $OPEN_PRS -gt 0 ]]; then
echo '{"schemaVersion":1,"label":"dependabot","message":"'$OPEN_PRS' updates","color":"blue"}' > .github/badges/dependabot.json
else
echo '{"schemaVersion":1,"label":"security","message":"all clear","color":"brightgreen"}' > .github/badges/dependabot.json
fi
- name: Commit badges to main
env:
RUN_NUMBER: ${{ github.run_number }}
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add .github/badges/
if git diff --staged --quiet; then
echo "No badge changes to commit"
else
git commit -m "Update badges from CI run $RUN_NUMBER [skip ci]"
git push origin main
fi