-
Notifications
You must be signed in to change notification settings - Fork 7
332 lines (308 loc) · 14.2 KB
/
build.yml
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
name: Build and test
on:
push:
branches-ignore:
- 'dependabot/**' #evita duplicados, ejecuta solo el PR no el commit que genera dependabot
- 'gh-pages' #si hay github pages se excluiran todos los test y resto de jobs
tags-ignore:
- 'v*' #evita reejecutar ultimo commit cuando se crea una etiqueta y release desde github
pull_request:
branches:
- 'develop' #default branch for this project
jobs:
test:
runs-on: ubuntu-latest
#avoids duplicate execution of pr from local repo, but allows pr from forked repos and dependabot
if: (github.event_name != 'pull_request' && ! github.event.pull_request.head.repo.fork) || (github.event_name == 'pull_request' && (github.event.pull_request.head.repo.fork || startsWith(github.head_ref, 'dependabot/')))
#if: ${{ false }} # disable for now
steps:
- name: Checkout GitHub repo
uses: actions/checkout@v4
#Especifica java 17, requerido por Spring Boot 3
- name: Select Java Version
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
#Para selenoid:
# la url del driver es localhost porque el container mapeara el puerto a este ejecutor
# la url de la aplicacion debe ser la ip de este ejecutor
#Configura tambien browsers.json que necesita Selenoid (la version debe coincidir con la del container)
#Para usar vnc hay que especificar una version, p.e. selenoid/vnc:chrome_95.0
- name: Selenoid configuration
run: |
echo "remote.web.driver.url=http://127.0.0.1:4444/wd/hub" > samples-test-spring.properties
echo "application.url=http://`(hostname -i)`" >> samples-test-spring.properties
mkdir -p target/browsers
echo '{"chrome": {"default": "latest", "versions": {"latest": {"image":"selenoid/chrome:latest","port":"4444","tmpfs": {"/tmp":"size=512m"} } } } }' > target/browsers/browsers.json
- name: Selenoid startup
run: |
mkdir -p target/site/video
docker pull selenoid/chrome:latest
docker pull selenoid/video-recorder:latest-release
docker run -d --name selenoid -p 4444:4444 \
-v /var/run/docker.sock:/var/run/docker.sock -v $GITHUB_WORKSPACE/target/browsers:/etc/selenoid/:ro \
-v $GITHUB_WORKSPACE/target/site/video/:/opt/selenoid/video/ -e OVERRIDE_VIDEO_OUTPUT_DIR=$GITHUB_WORKSPACE/target/site/video/ \
aerokube/selenoid:latest-release
docker logs selenoid
#Para que falle el build pero se ejecuten todas las fases de maven produciendo los reports
#se configura maven para ignorar fallos
- name: Build and test
run: mvn verify -Dmaven.test.failure.ignore=true -U --no-transfer-progress
#Para ver los resultados de los tests en los checks de las actions se anyade la action scacap/action-surefire-report@v1
#que sera el que cause el fallo del build si ha fallado algun test
#(similar comportamienta a cuando se usa junit reporter en jenkins)
#Otras actions similares que son scacap/action-surefire-report@v1 o dorny/test-reporter@v1
#pero suelen tener el problema que con los PR fallan aunque pasen los tests porque no pueden escribir los tests (por motivos de seguridad de Actions)
- name: Generate test report checks
if: always()
uses: mikepenz/[email protected]
with:
check_name: test-report (ut, it)
report_paths: '**/target/*-reports/TEST-*.xml'
fail_on_failure: 'true'
#Detiene selenoid (se ha observado en alguna ocasion un problema de acceso concurrente a los videos que podrian tardar algo en cargarse)
- if: always()
name: Selenoid stop
run: docker stop selenoid
#Publica archivos de reports
- if: always()
run: mv ./target/site/video/video-*.mp4 ./target/selema/
- if: always()
name: Publish test report artifacts
uses: actions/upload-artifact@v4
with:
name: test-reports
path: |
target/surefire-reports/
target/failsafe-reports/
target/site/
target/selema/
!target/site/video/slenoid*.mp4
- if: always()
name: Publish test reports for sonarqube job
uses: actions/upload-artifact@v4
with:
name: test-reports-for-sonar
path: |
target/surefire-reports/
target/failsafe-reports/
target/site/jacoco*/jacoco.xml
dependency-check:
needs: [test]
runs-on: ubuntu-latest
#if: ${{ false }} # disable for now
if: ${{ github.actor != 'dependabot[bot]' }}
steps:
- uses: actions/checkout@v4
- name: Select Java Version
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
- name: Build jar with dependencies
run: mvn package -DskipTests=true
- name: OWASP Dependency Check
uses: dependency-check/Dependency-Check_Action@main
env:
JAVA_HOME: /opt/jdk
with:
project: 'samples-test-spring'
path: 'target/*.jar'
format: 'HTML'
#formato json adicional para sonarqube, --failOnCVSS n para fallar build por dependencias vultnerables
args: --format JSON
#--failOnCVSS 1
- if: always()
name: Publish reports
uses: actions/upload-artifact@v4
with:
name: dependency-check-reports
path: reports/
sonarqube:
needs: [test]
#if: ${{ false }} # disable for now
#Cuando viene de una PR de dependabot este job falla porque no puede leer el token de sonarqube
#(restriccion de seguridad de GitHub Actions). Discusion y workarounds:
#https://community.sonarsource.com/t/youre-not-authorized-to-run-analysis-and-github-bots/41994/4
#https://github.com/dependabot/dependabot-core/issues/3253#issuecomment-797125425
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
steps:
- uses: javiertuya/[email protected]
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
sonar-token: ${{ secrets.SONAR_TOKEN }}
restore-artifact-name1: "test-reports-for-sonar"
restore-artifact-path1: "target"
deploy-azure:
needs: [sonarqube, dependency-check]
#if: ${{ false }} # disable for now
runs-on: ubuntu-latest
timeout-minutes: 8
concurrency:
group: samples-test-spring-${{ github.ref == 'refs/heads/main'}}
steps:
#Establece el mombre de la aplicacion dependiendo de la rama donde se ejecuta este worflow (en una variable de entorno APP_NAME)
#La rama main se publica en una app, el resto en otra
#(nota, github.ref no es el valor de la rama en una PR, no probado despliegue a main si se hace con una pr)
- if: ${{ github.ref == 'refs/heads/main' }}
run: echo "APP_NAME=samples-test-spring-main" >> $GITHUB_ENV
- if: ${{ github.ref != 'refs/heads/main' }}
run: echo "APP_NAME=samples-test-spring-develop" >> $GITHUB_ENV
- run: echo "Deploying to '${{ env.APP_NAME }}'"
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
- name: Delete old container versions
uses: actions/delete-package-versions@v5
with:
package-name: ${{ env.APP_NAME }}
package-type: 'container'
min-versions-to-keep: 1
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: https://ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
#Como en azure el despliege tarda un tiempo y mientras tanto se ve la version anterior,
#escribe el sha en un archivo accesible via curl. Antes de ejecutar los smoke test se
#esperara a que se pueda leer el sha que se ha escrito aqui
- name: Build and push container
run: |
echo "github.sha: '${{ github.sha }}'"
echo "${{ github.sha }}" > src/main/resources/static/github-sha.txt
mvn package -DskipTests=true -U --no-transfer-progress
cp target/*.jar target/samples-test-spring-latest-deploy.jar
docker build -t ${{ env.APP_NAME }} .
docker tag ${{ env.APP_NAME }} ghcr.io/${{ github.actor }}/${{ env.APP_NAME }}:${{ github.sha }}
docker push ghcr.io/${{ github.actor }}/${{ env.APP_NAME }}:${{ github.sha }}
# https://github.com/Azure/webapps-deploy
# no se puede eliminar la duplicacion porque el profile no puede guardarse en una variable
- name: Deploy to Azure WebApp (main)
if: ${{ github.ref == 'refs/heads/main' }}
uses: azure/webapps-deploy@v3
with:
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE_MAIN }}
app-name: ${{ env.APP_NAME }}
images: ghcr.io/${{ github.actor }}/${{ env.APP_NAME }}:${{ github.sha }}
#this is to deploy the webapp without container
#package: target/samples-test-spring-latest-deploy.jar
- name: Deploy to Azure WebApp (develop)
if: ${{ github.ref != 'refs/heads/main' }}
uses: azure/webapps-deploy@v3
with:
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE_DEVELOP }}
app-name: ${{ env.APP_NAME }}
images: ghcr.io/${{ github.actor }}/${{ env.APP_NAME }}:${{ github.sha }}
# espera a que este accesible el container que se acaba de desplegar
- name: Wait until container up
run: |
while [ "$(curl --silent 'https://${{ env.APP_NAME }}.azurewebsites.net/github-sha.txt')" != "${{ github.sha }}" ] ; do
echo "Waiting for container fully deployed ..."
sleep 5
done
#La configuracion para este test se hace con chrome headless contra la aplicacion desplegada
- name: Test configuration
run: |
echo "remote.web.driver.url=headless" > samples-test-spring.properties
echo "application.url=https://${{ env.APP_NAME }}.azurewebsites.net" >> samples-test-spring.properties
cat samples-test-spring.properties
#Ejecuta maven solo para este test, controlando los fallos
#ojo, al especificar un unico test, maven lo ejecuta en la fase test aunque este en it!!!
- name: Build and test
run: mvn test -Dtest=TestPostDeploy -Dmaven.test.failure.ignore=false -U --no-transfer-progress
- name: Generate post deploy test checks
if: always()
uses: mikepenz/[email protected]
with:
check_name: test-report (deploy)
report_paths: '**/target/*-reports/TEST-*.xml'
fail_on_failure: 'true'
#Publica archivos de reports
- if: always()
name: Publish test report artifacts
uses: actions/upload-artifact@v4
with:
name: deploy-test-reports
path: |
!target/site/jacoco/
target/site/
target/surefire-reports/
#Cada build crea una imagen en github packages, limpieza
- if: ${{ github.ref == 'refs/heads/main' }}
name: Cleanup main packages
uses: actions/delete-package-versions@v5
with:
package-name: 'samples-test-spring-main'
package-type: 'container'
min-versions-to-keep: 4
- if: ${{ github.ref != 'refs/heads/main' }}
name: Cleanup develop packages
uses: actions/delete-package-versions@v5
with:
package-name: 'samples-test-spring-develop'
package-type: 'container'
min-versions-to-keep: 4
# Disable Heroku deploy as it requires payment subscription
deploy-heroku:
needs: [test, sonarqube, dependency-check]
if: ${{ false }} # disabled permanently
runs-on: ubuntu-latest
steps:
#Establece el mombre de la aplicacion dependiendo de la rama donde se ejecuta este worflow (en una variable de entorno APP_NAME)
#La rama main se publica en una app, el resto en otra
#(nota, github.ref no es el valor de la rama en una PR, no probado despliegue a main si se hace con una pr)
- if: ${{ github.ref == 'refs/heads/main' }}
run: echo "APP_NAME=samples-test-spring-main" >> $GITHUB_ENV
- if: ${{ github.ref != 'refs/heads/main' }}
run: echo "APP_NAME=samples-test-spring-develop" >> $GITHUB_ENV
- run: echo "Deploying to '${{ env.APP_NAME }}'"
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
- name: Build executable jar
run: mvn package -DskipTests=true && cp target/*.jar target/samples-test-spring-latest-deploy.jar
- name: Deploy to ${{ env.APP_NAME }}
uses: akhileshns/heroku-deploy@v4
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}}
heroku_app_name: ${{ env.APP_NAME }}
heroku_email: ${{secrets.HEROKU_MY_USERNAME}}
usedocker: true
#La configuracion para este test se hace con chrome headless contra la aplicacion desplegada
- name: Test configuration
run: |
echo "remote.web.driver.url=headless" > samples-test-spring.properties
echo "application.url=https://${{ env.APP_NAME }}.herokuapp.com" >> samples-test-spring.properties
cat samples-test-spring.properties
#Ejecuta maven solo para este test, controlando los fallos
#ojo, al especificar un unico test, maven lo ejecuta en la fase test aunque este en it!!!
- name: Build and test
run: mvn test -Dtest=TestPostDeploy -Dmaven.test.failure.ignore=false
- name: Generate post deploy test checks
if: always()
uses: mikepenz/[email protected]
with:
check_name: test-report (deploy)
report_paths: '**/target/*-reports/TEST-*.xml'
fail_on_failure: 'true'
#Publica archivos de reports
- if: always()
name: Publish test report artifacts
uses: actions/upload-artifact@v4
with:
name: deploy-test-reports
path: |
!target/site/jacoco/
target/site/
target/surefire-reports/