Skip to content

Combined dependency updates (2024-06-29) #865

Combined dependency updates (2024-06-29)

Combined dependency updates (2024-06-29) #865

Workflow file for this run

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/action-junit-report@v4.3.1
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/sonarqube-action@v1.3.2
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/action-junit-report@v4.3.1
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/action-junit-report@v4.3.1
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/