33on :
44 push :
55 branches : [main]
6+ tags : ['v*']
67 pull_request :
78 branches : [main]
89
@@ -14,15 +15,13 @@ jobs:
1415
1516 - uses : actions/setup-go@v5
1617 with :
17- go-version : ' 1.24 '
18+ go-version : ' 1.26 '
1819
1920 - name : Download dependencies
2021 run : go mod download
2122
2223 - name : Run tests
23- # Note: -race disabled due to pre-existing race conditions in tests that spawn
24- # background goroutines. These should be fixed by adding proper synchronization.
25- run : go test -v ./...
24+ run : go test -race -v ./...
2625
2726 lint :
2827 runs-on : ubuntu-latest
@@ -31,12 +30,12 @@ jobs:
3130
3231 - uses : actions/setup-go@v5
3332 with :
34- go-version : ' 1.24 '
33+ go-version : ' 1.26 '
3534
3635 - name : golangci-lint
37- uses : golangci/golangci-lint-action@v6
36+ uses : golangci/golangci-lint-action@v7
3837 with :
39- version : latest
38+ version : v2.9.0
4039
4140 security :
4241 runs-on : ubuntu-latest
@@ -45,16 +44,15 @@ jobs:
4544
4645 - uses : actions/setup-go@v5
4746 with :
48- go-version : ' 1.24'
47+ go-version : ' 1.26'
48+
49+ - name : Install gosec
50+ run : go install github.com/securego/gosec/v2/cmd/gosec@latest
4951
5052 - name : Run gosec
51- uses : securego/gosec@master
52- with :
53- # Exclude G101 (hardcoded credentials - false positive on env var names)
54- # Exclude G115 (integer overflow - false positive for PR numbers)
55- # Exclude G304 (file inclusion - intentional for CLI tools)
56- # Exclude G306 (file permissions - config files don't need 0600)
57- args : -exclude=G101,G115,G304,G306 ./...
53+ # All false positives are suppressed with inline #nosec comments.
54+ # No global exclusions — every suppression is documented at the call site.
55+ run : gosec ./...
5856
5957 build :
6058 runs-on : ubuntu-latest
@@ -64,16 +62,34 @@ jobs:
6462
6563 - uses : actions/setup-go@v5
6664 with :
67- go-version : ' 1.24 '
65+ go-version : ' 1.26 '
6866
6967 - name : Build
7068 run : go build -v ./...
7169
70+ scan :
71+ runs-on : ubuntu-latest
72+ needs : [build]
73+ steps :
74+ - uses : actions/checkout@v4
75+
76+ - name : Run Trivy vulnerability scanner
77+ uses : aquasecurity/trivy-action@master
78+ with :
79+ scan-type : ' fs'
80+ scan-ref : ' .'
81+ severity : ' CRITICAL,HIGH'
82+ exit-code : ' 1'
83+
7284 deploy :
7385 runs-on : ubuntu-latest
74- needs : [build, security]
75- # Only deploy on push to main (not on PRs)
76- if : github.event_name == 'push' && github.ref == 'refs/heads/main'
86+ needs : [build, security, scan]
87+ # Only deploy on version tag pushes (e.g. v1.0.0)
88+ if : github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
89+
90+ environment :
91+ name : production
92+ url : ${{ steps.show-url.outputs.url }}
7793
7894 permissions :
7995 contents : read
@@ -87,6 +103,10 @@ jobs:
87103 steps :
88104 - uses : actions/checkout@v4
89105
106+ - name : Extract version from tag
107+ id : version
108+ run : echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
109+
90110 - name : Authenticate to Google Cloud
91111 uses : google-github-actions/auth@v2
92112 with :
@@ -104,6 +124,9 @@ jobs:
104124 --project $PROJECT_ID \
105125 --allow-unauthenticated \
106126 --env-vars-file=env-cloudrun.yaml \
127+ --set-env-vars="GITHUB_APP_ID=${{ secrets.GITHUB_APP_ID }},INSTALLATION_ID=${{ secrets.INSTALLATION_ID }}" \
128+ --build-arg="VERSION=${{ steps.version.outputs.tag }}" \
129+ --tag="${{ steps.version.outputs.tag }}" \
107130 --max-instances=10 \
108131 --cpu=1 \
109132 --memory=512Mi \
@@ -113,10 +136,11 @@ jobs:
113136 --platform=managed
114137
115138 - name : Show deployment URL
139+ id : show-url
116140 run : |
117141 URL=$(gcloud run services describe $SERVICE_NAME \
118142 --region $REGION \
119143 --project $PROJECT_ID \
120144 --format='value(status.url)')
121- echo "🚀 Deployed to: $URL"
122-
145+ echo "url= $URL" >> $GITHUB_OUTPUT
146+ echo "Deployed ${{ steps.version.outputs.tag }} to: $URL"
0 commit comments