Skip to content

Commit 1e3ebb0

Browse files
authored
feat: add SonarCloud analysis to frontend workflows and reusable workflow (#167)
1 parent 5247db2 commit 1e3ebb0

3 files changed

Lines changed: 165 additions & 2 deletions

File tree

.github/workflows/frontend-deploy-workflow.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ on:
8585
type: string
8686
default: 'production'
8787

88+
# SonarCloud configuration
89+
run-sonarcloud:
90+
description: 'Run SonarCloud analysis'
91+
type: boolean
92+
default: true
93+
sonarcloud-timeout:
94+
description: 'SonarCloud job timeout (minutes)'
95+
type: number
96+
default: 10
97+
8898
# Timeout configuration
8999
build-timeout:
90100
description: 'Build job timeout (minutes)'
@@ -104,6 +114,8 @@ on:
104114
secrets:
105115
GH_TOKEN:
106116
required: true
117+
SONAR_CLOUD_TOKEN:
118+
required: false
107119
DATADOG_API_KEY:
108120
required: false
109121
LINEARB_API_KEY:
@@ -177,7 +189,26 @@ jobs:
177189
path: ${{ inputs.build-output-dir }}
178190
retention-days: 1
179191

180-
# Job 2: Deploy to Production
192+
# Job 2: SonarCloud Analysis (parallel with deploy)
193+
sonarcloud:
194+
name: 🔍 SonarCloud
195+
if: inputs.run-sonarcloud
196+
needs: build
197+
permissions:
198+
contents: read
199+
uses: Typeform/.github/reusable-workflows/sonarcloud-scan/workflow.yml@v1
200+
with:
201+
app-name: ${{ inputs.app-name }}
202+
node-version: ${{ inputs.node-version }}
203+
use-asdf: ${{ inputs.use-asdf }}
204+
runner: ${{ inputs.runner }}
205+
coverage-artifact-name: '' # No coverage for main branch deployments
206+
timeout: ${{ inputs.sonarcloud-timeout }}
207+
secrets:
208+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
209+
SONAR_CLOUD_TOKEN: ${{ secrets.SONAR_CLOUD_TOKEN }}
210+
211+
# Job 3: Deploy to Production
181212
deploy:
182213
name: 🚀 Deploy to Production
183214
needs: build

.github/workflows/frontend-pr-workflow.yml

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ on:
7979
type: string
8080
default: 'none'
8181

82+
# SonarCloud configuration
83+
run-sonarcloud:
84+
description: 'Run SonarCloud analysis'
85+
type: boolean
86+
default: true
87+
sonarcloud-timeout:
88+
description: 'SonarCloud job timeout (minutes)'
89+
type: number
90+
default: 10
91+
92+
# GraphQL configuration
93+
run-graphql-persisted-operations:
94+
description: 'Generate GraphQL persisted operations for BFF allow list'
95+
type: boolean
96+
default: false
97+
8298
# E2E configuration
8399
run-deep-purple:
84100
description: 'Run Deep Purple E2E tests'
@@ -150,6 +166,8 @@ on:
150166
secrets:
151167
GH_TOKEN:
152168
required: true
169+
SONAR_CLOUD_TOKEN:
170+
required: false
153171
DATADOG_API_KEY:
154172
required: false
155173
JENKINS_OKTA_USERNAME:
@@ -378,7 +396,37 @@ jobs:
378396
- name: Print GitHub SHA
379397
run: echo "The commit SHA is ${{ github.sha }}"
380398

381-
# Job 5: Deep Purple E2E Tests
399+
# Job 5: SonarCloud Analysis (parallel with tests)
400+
sonarcloud:
401+
name: 🔍 SonarCloud
402+
if: inputs.run-sonarcloud
403+
needs: build
404+
permissions:
405+
contents: read
406+
uses: Typeform/.github/reusable-workflows/sonarcloud-scan/workflow.yml@v1
407+
with:
408+
app-name: ${{ inputs.app-name }}
409+
node-version: ${{ inputs.node-version }}
410+
use-asdf: ${{ inputs.use-asdf }}
411+
runner: ${{ inputs.runner }}
412+
coverage-artifact-name: ${{ inputs.run-unit-tests && format('coverage-{0}', github.run_id) || '' }}
413+
timeout: ${{ inputs.sonarcloud-timeout }}
414+
secrets:
415+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
416+
SONAR_CLOUD_TOKEN: ${{ secrets.SONAR_CLOUD_TOKEN }}
417+
418+
# Job 6: GraphQL Persisted Operations (parallel with tests)
419+
graphql-persisted-operations:
420+
name: 🔐 GraphQL Persisted Operations
421+
if: inputs.run-graphql-persisted-operations
422+
needs: build
423+
permissions:
424+
contents: read
425+
uses: Typeform/.github/.github/workflows/graphql-generate-persisted-operations.yml@v1
426+
secrets:
427+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
428+
429+
# Job 7: Deep Purple E2E Tests
382430
deep-purple:
383431
name: 🔮 Deep Purple E2E
384432
if: inputs.run-deep-purple
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: SonarCloud Scan
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
# Project identification
7+
app-name:
8+
description: 'Application name (must match sonar.projectKey in sonar-project.properties)'
9+
type: string
10+
required: true
11+
12+
# Node configuration
13+
node-version:
14+
description: 'Node.js version (ignored if use-asdf is true)'
15+
type: string
16+
default: '20'
17+
use-asdf:
18+
description: 'Use asdf-vm for version management (reads from .tool-versions)'
19+
type: boolean
20+
default: false
21+
22+
# Runner configuration
23+
runner:
24+
description: 'Runner for SonarCloud scan'
25+
type: string
26+
default: '[self-hosted, ci-universal]'
27+
28+
# Coverage configuration
29+
coverage-artifact-name:
30+
description: 'Name of coverage artifact to download (optional, e.g., coverage-12345)'
31+
type: string
32+
default: ''
33+
34+
# Timeout configuration
35+
timeout:
36+
description: 'Job timeout (minutes)'
37+
type: number
38+
default: 10
39+
40+
secrets:
41+
GH_TOKEN:
42+
required: true
43+
SONAR_CLOUD_TOKEN:
44+
required: true
45+
46+
permissions:
47+
contents: read
48+
49+
jobs:
50+
sonarcloud:
51+
name: 🔍 SonarCloud Analysis
52+
runs-on: ${{ fromJSON(inputs.runner) }}
53+
timeout-minutes: ${{ inputs.timeout }}
54+
55+
steps:
56+
- name: Check out Git repository
57+
uses: actions/checkout@v4
58+
with:
59+
fetch-depth: 0 # Required for SonarCloud to analyze git history
60+
61+
- name: Setup Node with Cache
62+
uses: Typeform/.github/shared-actions/setup-node-with-cache@v1
63+
with:
64+
node-version: ${{ inputs.node-version }}
65+
use-asdf: ${{ inputs.use-asdf }}
66+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
67+
68+
- name: Download coverage artifacts
69+
if: inputs.coverage-artifact-name != ''
70+
uses: actions/download-artifact@v4
71+
with:
72+
name: ${{ inputs.coverage-artifact-name }}
73+
path: coverage/
74+
continue-on-error: true
75+
76+
- name: SonarCloud Scan
77+
uses: SonarSource/sonarqube-scan-action@v6
78+
with:
79+
args: >
80+
-Dsonar.projectVersion=${{ github.run_id }}
81+
env:
82+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
83+
SONAR_TOKEN: ${{ secrets.SONAR_CLOUD_TOKEN }}
84+
LC_ALL: "C.UTF-8"

0 commit comments

Comments
 (0)