Add zerocode postdeploy test #896
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" > src/test/resources/selenium.properties | |
echo "application.url=http://`(hostname -i)`" >> src/test/resources/selenium.properties | |
echo "application.port=" >> src/test/resources/selenium.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 | |
echo "*** Selenium properties:" && cat src/test/resources/selenium.properties | |
- 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 test -Dtest=!**/st/** -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 | |
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/site/ | |
target/selema/ | |
!target/site/video/ | |
- 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/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: Selenium web test configuration | |
run: | | |
echo "remote.web.driver.url=headless" > src/test/resources/selenium.properties | |
echo "application.url=https://${{ env.APP_NAME }}.azurewebsites.net" >> src/test/resources/selenium.properties | |
echo "application.port=" >> src/test/resources/selenium.properties | |
echo "*** Selenium properties:" && cat src/test/resources/selenium.properties | |
- name: Zerocode api test configuration | |
run: | | |
echo "web.application.endpoint.host=https://${{ env.APP_NAME }}.azurewebsites.net" > src/test/resources/zerocode.properties | |
echo "web.application.endpoint.port=443" >> src/test/resources/zerocode.properties | |
echo "web.application.endpoint.context=" >> src/test/resources/zerocode.properties | |
echo "*** Zerocode properties:" && cat src/test/resources/zerocode.properties | |
#Ejecuta maven para los test de sistema | |
- name: Build and test | |
run: mvn test -Dtest=**/st/** -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/junit*/ | |
target/site/screenshot/ | |
target/logs/ | |
target/zerocode*.html | |
#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" > src/test/resources/selenium.properties | |
echo "application.url=https://${{ env.APP_NAME }}.herokuapp.com" >> src/test/resources/selenium.properties | |
echo "*** Selenium properties:" && cat src/test/resources/selenium.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/ |