1+ name : Frontend Deploy Workflow
2+
3+ on :
4+ workflow_call :
5+ inputs :
6+ # Project identification
7+ app-name :
8+ description : ' Application name (e.g., demo-app, app-shell)'
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 build/deploy jobs'
25+ type : string
26+ default : ' ["self-hosted", "ci-universal"]'
27+
28+ # Build configuration
29+ build-command :
30+ description : ' Production build command'
31+ type : string
32+ default : ' yarn dist'
33+ clean-command :
34+ description : ' Clean command before build'
35+ type : string
36+ default : ' yarn clean'
37+ build-output-dir :
38+ description : ' Build output directory name (dist, build, lib, etc.)'
39+ type : string
40+ default : ' dist'
41+
42+ # Deploy configuration
43+ deploy-command :
44+ description : ' Production deploy command'
45+ type : string
46+ default : ' yarn deploy'
47+ cdn-bucket :
48+ description : ' S3 bucket for production assets'
49+ type : string
50+ required : true
51+ cloudfront-dist :
52+ description : ' CloudFront distribution ID'
53+ type : string
54+ required : true
55+ cdn-url :
56+ description : ' Public CDN URL'
57+ type : string
58+ required : true
59+
60+ # AWS configuration
61+ aws-region :
62+ description : ' AWS region'
63+ type : string
64+ default : ' us-east-1'
65+ aws-account :
66+ description : ' AWS account (prod/staging)'
67+ type : string
68+ default : ' prod'
69+
70+ # Jarvis configuration
71+ jarvis-branch :
72+ description : ' Jarvis branch to use (empty = npm version)'
73+ type : string
74+ default : ' '
75+ jarvis-datadog-enabled :
76+ description : ' Enable Jarvis Datadog logging'
77+ type : boolean
78+ default : true
79+ jarvis-datadog-service :
80+ description : ' Datadog service name'
81+ type : string
82+ required : true
83+ jarvis-datadog-env :
84+ description : ' Datadog environment'
85+ type : string
86+ default : ' production'
87+
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+
98+ # Timeout configuration
99+ build-timeout :
100+ description : ' Build job timeout (minutes)'
101+ type : number
102+ default : 15
103+ deploy-timeout :
104+ description : ' Deploy job timeout (minutes)'
105+ type : number
106+ default : 10
107+
108+ # Revert mode
109+ revert-mode :
110+ description : ' Skip tests and linting (for emergency reverts)'
111+ type : boolean
112+ default : false
113+
114+ secrets :
115+ GH_TOKEN :
116+ required : true
117+ SONAR_CLOUD_TOKEN :
118+ required : false
119+ DATADOG_API_KEY :
120+ required : false
121+ LINEARB_API_KEY :
122+ required : false
123+ DATADOG_API_KEY_FRONTEND_METRICS :
124+ required : false
125+ DATADOG_JS_SOURCEMAPS_US :
126+ required : false
127+ DATADOG_JS_SOURCEMAPS_EU :
128+ required : false
129+ SLACK_OAUTH_TOKEN :
130+ required : false
131+
132+ permissions :
133+ id-token : write
134+ contents : read
135+
136+ # Concurrency control: Only one deploy at a time per workflow
137+ concurrency :
138+ group : ' deploy-${{ github.workflow }}'
139+ cancel-in-progress : false
140+
141+ jobs :
142+ # Job 1: Build for Production
143+ build :
144+ name : 🏗️ Build
145+ runs-on : ${{ fromJSON(inputs.runner) }}
146+ timeout-minutes : ${{ inputs.build-timeout }}
147+ outputs :
148+ artifact-name : ${{ steps.artifact-info.outputs.name }}
149+
150+ steps :
151+ - name : Check out Git repository
152+ uses : actions/checkout@v4
153+
154+ - name : Setup Node with Cache
155+ uses : Typeform/.github/shared-actions/setup-node-with-cache@v1
156+ with :
157+ node-version : ${{ inputs.node-version }}
158+ use-asdf : ${{ inputs.use-asdf }}
159+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
160+
161+ - name : Setup Jarvis
162+ uses : Typeform/.github/shared-actions/setup-jarvis@v1
163+ with :
164+ jarvis-branch : ${{ inputs.jarvis-branch }}
165+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
166+
167+ - name : Clean dist directory
168+ run : ${{ inputs.clean-command }}
169+
170+ - name : Build production assets
171+ run : ${{ inputs.build-command }}
172+ env :
173+ PUBLIC_CDN_URL : ${{ inputs.cdn-url }}
174+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
175+ JARVIS_DATADOG_LOGS_ENABLED : ${{ inputs.jarvis-datadog-enabled }}
176+ JARVIS_DATADOG_API_KEY : ${{ secrets.DATADOG_API_KEY }}
177+ JARVIS_DATADOG_SITE : datadoghq.com
178+ JARVIS_DATADOG_SERVICE : ${{ inputs.jarvis-datadog-service }}
179+ JARVIS_DATADOG_ENV : ${{ inputs.jarvis-datadog-env }}
180+
181+ - name : Set artifact info
182+ id : artifact-info
183+ run : echo "name=build-${{ github.run_id }}" >> $GITHUB_OUTPUT
184+
185+ - name : Upload build artifacts
186+ uses : actions/upload-artifact@v4
187+ with :
188+ name : build-${{ github.run_id }}
189+ path : ${{ inputs.build-output-dir }}
190+ retention-days : 1
191+
192+ # Job 2: SonarCloud Analysis (runs immediately, parallel with build)
193+ sonarcloud :
194+ name : SonarCloud
195+ if : inputs.run-sonarcloud
196+ permissions :
197+ contents : read
198+ uses : Typeform/.github/.github/workflows/sonarcloud-scan.yml@v1
199+ with :
200+ app-name : ${{ inputs.app-name }}
201+ node-version : ${{ inputs.node-version }}
202+ use-asdf : ${{ inputs.use-asdf }}
203+ runner : ${{ inputs.runner }}
204+ coverage-artifact-name : ' ' # No coverage for main branch deployments
205+ timeout : ${{ inputs.sonarcloud-timeout }}
206+ secrets :
207+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
208+ SONAR_CLOUD_TOKEN : ${{ secrets.SONAR_CLOUD_TOKEN }}
209+
210+ # Job 3: Deploy to Production
211+ deploy :
212+ name : 🚀 Deploy to Production
213+ needs : build
214+ runs-on : ${{ fromJSON(inputs.runner) }}
215+ timeout-minutes : ${{ inputs.deploy-timeout }}
216+ permissions :
217+ id-token : write
218+ contents : write
219+
220+ steps :
221+ - name : Check out Git repository
222+ uses : actions/checkout@v4
223+ with :
224+ token : ${{ secrets.GH_TOKEN }}
225+ fetch-depth : 0
226+
227+ - name : Configure Git
228+ run : |
229+ git config --global user.name "${{ github.actor }}"
230+ git config --global user.email "${{ github.actor }}@users.noreply.github.com"
231+
232+ - name : Setup Node with Cache
233+ uses : Typeform/.github/shared-actions/setup-node-with-cache@v1
234+ with :
235+ node-version : ${{ inputs.node-version }}
236+ use-asdf : ${{ inputs.use-asdf }}
237+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
238+
239+ - name : Download Build Artifacts
240+ uses : Typeform/.github/shared-actions/download-build-artifacts@v1
241+ with :
242+ artifact-name : ${{ needs.build.outputs.artifact-name }}
243+ output-dir : ${{ inputs.build-output-dir }}
244+
245+ - name : Setup Jarvis
246+ uses : Typeform/.github/shared-actions/setup-jarvis@v1
247+ with :
248+ jarvis-branch : ${{ inputs.jarvis-branch }}
249+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
250+
251+ - name : AWS auth
252+ uses : Typeform/.github-private/actions/aws-auth@aws-auth-0.0.2
253+ with :
254+ region : ${{ inputs.aws-region }}
255+ account : ${{ inputs.aws-account }}
256+ output_credentials : true
257+
258+ - name : Deploy to production
259+ run : ${{ inputs.deploy-command }}
260+ env :
261+ # Jarvis debug logging
262+ DEBUG : jarvis
263+ # GitHub
264+ GH_TOKEN : ${{ secrets.GH_TOKEN }}
265+ # AWS configuration
266+ AWS_REGION : ${{ inputs.aws-region }}
267+ AWS_ASSETS_BUCKET : ${{ inputs.cdn-bucket }}
268+ AWS_CLOUDFRONT_DIST : ${{ inputs.cloudfront-dist }}
269+ PUBLIC_CDN_URL : ${{ inputs.cdn-url }}
270+ # Jarvis Datadog logging
271+ JARVIS_DATADOG_LOGS_ENABLED : ${{ inputs.jarvis-datadog-enabled }}
272+ JARVIS_DATADOG_API_KEY : ${{ secrets.DATADOG_API_KEY }}
273+ JARVIS_DATADOG_SITE : datadoghq.com
274+ JARVIS_DATADOG_SERVICE : ${{ inputs.jarvis-datadog-service }}
275+ JARVIS_DATADOG_ENV : ${{ inputs.jarvis-datadog-env }}
276+ # Production-specific secrets
277+ LINEARB_API_KEY : ${{ secrets.LINEARB_API_KEY }}
278+ DATADOG_API_KEY_FRONTEND_METRICS : ${{ secrets.DATADOG_API_KEY_FRONTEND_METRICS }}
279+ DATADOG_API_KEY_US : ${{ secrets.DATADOG_JS_SOURCEMAPS_US }}
280+ DATADOG_API_KEY_EU : ${{ secrets.DATADOG_JS_SOURCEMAPS_EU }}
281+ SLACK_OAUTH_TOKEN : ${{ secrets.SLACK_OAUTH_TOKEN }}
282+
283+ - name : Print deployment info
284+ run : |
285+ echo "✅ Deployed to production"
286+ echo "📦 App: ${{ inputs.app-name }}"
287+ echo "🌐 CDN: ${{ inputs.cdn-url }}"
288+ echo "📝 Commit: ${{ github.sha }}"
0 commit comments