fids/.gitlab-ci.yml

480 lines
15 KiB
YAML

image: docker:latest
variables:
IMAGE_BASE: "$CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME"
DOCKER_BUILDKIT: 1
GIT_DEPTH: 1
default:
retry:
max: 1
when:
- runner_system_failure
- script_failure
- api_failure
before_script:
- docker login -u $CI_REGISTRY_USER --password $CI_JOB_TOKEN $CI_REGISTRY
stages:
- prep
- build
- test
- deliver
- deploy
.changes-backend: &changes-backend
changes:
- auth-domain/**/*
- flights-domain/**/*
- subscription-domain/**/*
- gateway/**/*
.changes-frontend: &changes-frontend
changes:
- screen-domain/**/*
- browser-domain/**/*
preparation:
stage: prep
tags:
- dev
before_script: []
rules:
- *changes-frontend
- *changes-backend
script:
- export BUILD_ID=$(date +%Y%m%d%H%M)
- echo "BUILD_ID=${BUILD_ID}" > context.env
- echo "FLIGHTS_INFO_PROD_IMAGE_NAME=${IMAGE_BASE}/flights-information:prod-${BUILD_ID}" >> context.env
- echo "FLIGHTS_INFO_TEST_IMAGE_NAME=${IMAGE_BASE}/flights-information:test-${BUILD_ID}" >> context.env
- echo "GATEWAY_PROD_IMAGE_NAME=${IMAGE_BASE}/gateway:prod-${BUILD_ID}" >> context.env
- echo "GATEWAY_TEST_IMAGE_NAME=${IMAGE_BASE}/gateway:test-${BUILD_ID}" >> context.env
- echo "USER_MANAGER_PROD_IMAGE_NAME=${IMAGE_BASE}/user-manager:prod-${BUILD_ID}" >> context.env
- echo "USER_MANAGER_TEST_IMAGE_NAME=${IMAGE_BASE}/user-manager:test-${BUILD_ID}" >> context.env
- echo "SUBSCRIPTION_PROD_IMAGE_NAME=${IMAGE_BASE}/subs-manager:prod-${BUILD_ID}" >> context.env
- echo "SUBSCRIPTION_TEST_IMAGE_NAME=${IMAGE_BASE}/subs-manager:test-${BUILD_ID}" >> context.env
- echo "SCREEN_CLIENT_PROD_IMAGE_NAME=${IMAGE_BASE}/screens-client:prod-${BUILD_ID}" >> context.env
- echo "SCREEN_CLIENT_TEST_IMAGE_NAME=${IMAGE_BASE}/screens-client:test-${BUILD_ID}" >> context.env
- echo "BROWSER_CLIENT_PROD_IMAGE_NAME=${IMAGE_BASE}/browser-client:prod-${BUILD_ID}" >> context.env
- echo "BROWSER_CLIENT_TEST_IMAGE_NAME=${IMAGE_BASE}/browser-client:test-${BUILD_ID}" >> context.env
- echo "DOCKER_HUB_SCREEN_CLIENT_IMAGE=$DOCKER_HUB_USER/screens-client:${BUILD_ID}" >> context.env
- echo "DOCKER_HUB_BROWSER_CLIENT_IMAGE=$DOCKER_HUB_USER/browser-client:${BUILD_ID}" >> context.env
- echo "DOCKER_HUB_GATEWAY_IMAGE=$DOCKER_HUB_USER/gateway:${BUILD_ID}" >> context.env
- echo "DOCKER_HUB_SUBSCRIPTION_IMAGE=$DOCKER_HUB_USER/subs-manager:${BUILD_ID}" >> context.env
- echo "DOCKER_HUB_USER_MANAGER_IMAGE=$DOCKER_HUB_USER/user-manager:${BUILD_ID}" >> context.env
- echo "DOCKER_HUB_FLIGHT_INFO_IMAGE=$DOCKER_HUB_USER/flights-information:${BUILD_ID}" >> context.env
- echo "ENV_DEV_FILE=$(echo $ENV_DEV)" >> context.env
- echo "ENV_PROD_FILE=$(echo $ENV_PROD)" >> context.env
artifacts:
reports:
dotenv: context.env
.build-and-push-script: &build-and-push-script
- docker build ${FOLDER} -f ${FOLDER}/Dockerfile.prod --build-arg "${BUILD_ARG_PROD}" --build-arg "${BUILD_ARG_PROD_OTHER}" -t ${PROD_IMAGE}
- docker build ${FOLDER} -f ${FOLDER}/Dockerfile.test --build-arg "${BUILD_ARG_TEST}" -t ${TEST_IMAGE}
- docker push ${PROD_IMAGE}
- docker push ${TEST_IMAGE}
.build:
stage: build
tags:
- dev
rules:
- *changes-frontend
- *changes-backend
needs:
- job: preparation
optional: true
artifacts: true
build-auth-api:
extends:
- .build
script:
- export FOLDER=auth-domain/user-manager
- export PROD_IMAGE=${USER_MANAGER_PROD_IMAGE_NAME}
- export TEST_IMAGE=${USER_MANAGER_TEST_IMAGE_NAME}
- *build-and-push-script
build-flights-api:
extends:
- .build
script:
- export FOLDER=flights-domain/flights-information
- export PROD_IMAGE=${FLIGHTS_INFO_PROD_IMAGE_NAME}
- export TEST_IMAGE=${FLIGHTS_INFO_TEST_IMAGE_NAME}
- *build-and-push-script
build-browser-client:
extends:
- .build
script:
- export FOLDER=browser-domain
- export PROD_IMAGE=${BROWSER_CLIENT_PROD_IMAGE_NAME}
- export TEST_IMAGE=${BROWSER_CLIENT_TEST_IMAGE_NAME}
- export BUILD_ARG_PROD="REACT_APP_ENDPOINT=https://api.fids.slc.ar/"
- *build-and-push-script
build-screen-client:
extends:
- .build
script:
- export FOLDER=screen-domain
- export PROD_IMAGE=${SCREEN_CLIENT_PROD_IMAGE_NAME}
- export TEST_IMAGE=${SCREEN_CLIENT_TEST_IMAGE_NAME}
- export BUILD_ARG_PROD="REACT_APP_ENDPOINT=https://api.fids.slc.ar/"
- export BUILD_ARG_PROD_OTHER="REACT_APP_ORIGIN=Frankfurt"
- *build-and-push-script
build-subscription-api:
extends:
- .build
script:
- export FOLDER=subscription-domain/subscription-manager
- export PROD_IMAGE=${SUBSCRIPTION_PROD_IMAGE_NAME}
- export TEST_IMAGE=${SUBSCRIPTION_TEST_IMAGE_NAME}
- *build-and-push-script
build-gateway:
extends:
- .build
script:
- export FOLDER=gateway
- export PROD_IMAGE=${GATEWAY_PROD_IMAGE_NAME}
- export TEST_IMAGE=${GATEWAY_TEST_IMAGE_NAME}
- *build-and-push-script
.test-script: &test-script
- docker compose -f ${FOLDER}/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- docker compose -f ${FOLDER}/docker-compose.dev.yml --env-file $ENV_DEV_FILE pull
- docker compose -f ${FOLDER}/docker-compose.dev.yml --env-file $ENV_DEV_FILE up --abort-on-container-exit --renew-anon-volumes
.test-api-script: &test-api-script
- *test-script
- docker cp ${DOCKER_CONTAINER}:/usr/src/app/coverage.xml .
- docker cp ${DOCKER_CONTAINER}:/usr/src/app/report.xml .
.test-api:
stage: test
tags:
- dev
artifacts:
when: always
paths:
- coverage.xml
- report.xml
reports:
junit: report.xml
test-auth-api:
extends:
- .test-api
rules:
- changes:
- auth-domain/**/*
script:
- export API_IMAGE=${USER_MANAGER_TEST_IMAGE_NAME}
- export CLIENT_IMAGE=dummy-image
- export FOLDER=auth-domain
- export DOCKER_CONTAINER=fids-auth-dev_auth-api
- *test-api-script
needs:
- job: build-auth-api
optional: true
- job: preparation
optional: true
artifacts: true
test-subscription-api:
extends:
- .test-api
rules:
- changes:
- subscription-domain/**/*
script:
- export API_IMAGE=${SUBSCRIPTION_TEST_IMAGE_NAME}
- export CLIENT_IMAGE=dummy-image
- export FOLDER=subscription-domain
- export DOCKER_CONTAINER=fids-subs-dev_subscriptions-api
- *test-api-script
needs:
- job: build-subscription-api
optional: true
- job: preparation
optional: true
artifacts: true
test-flights-api:
extends:
- .test-api
rules:
- changes:
- flights-domain/**/*
script:
- export API_IMAGE=${FLIGHTS_INFO_TEST_IMAGE_NAME}
- export CLIENT_IMAGE=dummy-image
- export FOLDER=flights-domain
- export DOCKER_CONTAINER=fids-flights-dev_flights-api
- *test-api-script
needs:
- job: build-flights-api
optional: true
- job: preparation
optional: true
artifacts: true
test-gateway:
extends:
- .test-api
rules:
- changes:
- gateway/**/*
script:
- export API_IMAGE=${GATEWAY_TEST_IMAGE_NAME}
- export CLIENT_IMAGE=dummy-image
- export FOLDER=gateway
- export DOCKER_CONTAINER=fids-gateway-dev_api-gw
- *test-api-script
needs:
- job: build-gateway
optional: true
- job: preparation
optional: true
artifacts: true
.test-client-script: &test-client-script
- *test-script
- docker cp ${DOCKER_CONTAINER}:/app/coverage/cobertura-coverage.xml .
- docker cp ${DOCKER_CONTAINER}:/app/junit.xml .
.test-client:
extends:
- .test-api
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
artifacts:
when: always
paths:
- cobertura-coverage.xml
reports:
junit: junit.xml
coverage_report:
coverage_format: cobertura
path: cobertura-coverage.xml
test-browser-client:
extends:
- .test-client
rules:
- changes:
- browser-domain/**/*
script:
- export CLIENT_IMAGE=${BROWSER_CLIENT_TEST_IMAGE_NAME}
- export FOLDER=browser-domain
- export DOCKER_CONTAINER=fids-browser-dev_browser-client
- *test-client-script
needs:
- job: build-browser-client
optional: true
- job: preparation
optional: true
artifacts: true
test-screen-client:
extends:
- .test-client
rules:
- changes:
- screen-domain/**/*
script:
- export CLIENT_IMAGE=${SCREEN_CLIENT_TEST_IMAGE_NAME}
- export FOLDER=screen-domain
- export DOCKER_CONTAINER=fids-screen-dev_screen-client
- *test-client-script
needs:
- job: build-screen-client
optional: true
- job: preparation
optional: true
artifacts: true
.test-integration: &test-integration
- export TEST_TARGET=INTEGRATION
- export API_IMAGE=$FLIGHTS_INFO_TEST_IMAGE_NAME
- docker compose -f flights-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- docker compose -f flights-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE pull
- docker compose -f flights-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE up -d
- export API_IMAGE=$GATEWAY_TEST_IMAGE_NAME
- docker compose -f gateway/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- docker compose -f gateway/docker-compose.dev.yml --env-file $ENV_DEV_FILE pull
- docker compose -f gateway/docker-compose.dev.yml --env-file $ENV_DEV_FILE up -d
- export API_IMAGE=$USER_MANAGER_TEST_IMAGE_NAME
- docker compose -f auth-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- docker compose -f auth-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE pull
- docker compose -f auth-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE up -d
- docker compose -f auth-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE exec auth-api python manage.py recreate_db
- docker compose -f auth-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE exec auth-api python manage.py seed_db
- export API_IMAGE=$SUBSCRIPTION_TEST_IMAGE_NAME
- docker compose -f subscription-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- docker compose -f subscription-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE pull
- docker compose -f subscription-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE up -d
- docker compose -f ${FOLDER}/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- docker compose -f ${FOLDER}/docker-compose.dev.yml --env-file $ENV_DEV_FILE pull
- docker compose -f ${FOLDER}/docker-compose.dev.yml --env-file $ENV_DEV_FILE up --abort-on-container-exit
.test-integration-clean: &test-integration-clean
- export API_IMAGE=${FLIGHTS_INFO_TEST_IMAGE_NAME}
- docker compose -f flights-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- export API_IMAGE=${USER_MANAGER_TEST_IMAGE_NAME}
- docker compose -f auth-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- export API_IMAGE=${SUBSCRIPTION_TEST_IMAGE_NAME}
- docker compose -f subscription-domain/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
- export API_IMAGE=${GATEWAY_TEST_IMAGE_NAME}
- docker compose -f gateway/docker-compose.dev.yml --env-file $ENV_DEV_FILE down
.needs-backend-tests: &needs-backend-tests
- job: test-flights-api
optional: true
artifacts: false
- job: test-auth-api
optional: true
artifacts: false
- job: test-subscription-api
optional: true
artifacts: false
- job: test-gateway
optional: true
artifacts: false
- job: preparation
optional: true
artifacts: true
test-browser-integration:
stage: test
tags:
- dev
rules:
- *changes-backend
- changes:
- browser-domain/**/*
script:
- export CLIENT_IMAGE=${BROWSER_CLIENT_TEST_IMAGE_NAME}
- export FOLDER=browser-domain
- *test-integration
after_script:
- *test-integration-clean
needs:
- job: test-browser-client
optional: true
artifacts: false
- *needs-backend-tests
test-screen-integration:
stage: test
tags:
- dev
rules:
- *changes-backend
- changes:
- screen-domain/**/*
script:
- export CLIENT_IMAGE=${SCREEN_CLIENT_TEST_IMAGE_NAME}
- export FOLDER=screen-domain
- *test-integration
after_script:
- *test-integration-clean
needs:
- job: test-screen-client
optional: true
artifacts: false
- job: test-browser-integration
optional: true
- *needs-backend-tests
deliver-dockerhub:
stage: deliver
tags:
- dev
rules:
- *changes-backend
- *changes-frontend
- if: $FORCE_DEPLOY == "true"
script:
- docker login -u $DOCKER_HUB_USER --password $DOCKER_HUB_PASS
- docker tag $FLIGHTS_INFO_PROD_IMAGE_NAME $DOCKER_HUB_FLIGHT_INFO_IMAGE
- docker tag $USER_MANAGER_PROD_IMAGE_NAME $DOCKER_HUB_USER_MANAGER_IMAGE
- docker tag $GATEWAY_PROD_IMAGE_NAME $DOCKER_HUB_GATEWAY_IMAGE
- docker tag $SUBSCRIPTION_PROD_IMAGE_NAME $DOCKER_HUB_SUBSCRIPTION_IMAGE
- docker tag $BROWSER_CLIENT_PROD_IMAGE_NAME $DOCKER_HUB_BROWSER_CLIENT_IMAGE
- docker tag $SCREEN_CLIENT_PROD_IMAGE_NAME $DOCKER_HUB_SCREEN_CLIENT_IMAGE
- docker push $DOCKER_HUB_FLIGHT_INFO_IMAGE
- docker push $DOCKER_HUB_USER_MANAGER_IMAGE
- docker push $DOCKER_HUB_SUBSCRIPTION_IMAGE
- docker push $DOCKER_HUB_GATEWAY_IMAGE
- docker push $DOCKER_HUB_BROWSER_CLIENT_IMAGE
- docker push $DOCKER_HUB_SCREEN_CLIENT_IMAGE
needs:
- job: test-browser-integration
optional: true
artifacts: false
- job: test-screen-integration
optional: true
artifacts: false
- job: preparation
optional: true
artifacts: true
.stop-and-run: &stop-and-run
- docker compose -f ${FOLDER}/docker-compose.yml --env-file $ENV_PROD_FILE down
- docker compose -f ${FOLDER}/docker-compose.yml --env-file $ENV_PROD_FILE pull
- docker compose -f ${FOLDER}/docker-compose.yml --env-file $ENV_PROD_FILE up -d
deploy-prod:
stage: deploy
tags:
- prod
rules:
- if: $CI_COMMIT_REF_NAME == "master"
changes:
- auth-domain/**/*
- screen-domain/**/*
- browser-domain/**/*
- flights-domain/**/*
- subscription-domain/**/*
- gateway/**/*
- if: $FORCE_DEPLOY == "true"
script:
- docker login -u $DOCKER_HUB_USER --password $DOCKER_HUB_PASS
- export API_IMAGE=$DOCKER_HUB_USER_MANAGER_IMAGE
- export FOLDER=auth-domain
- *stop-and-run
- export API_IMAGE=$DOCKER_HUB_SUBSCRIPTION_IMAGE
- export FOLDER=subscription-domain
- *stop-and-run
- export API_IMAGE=$DOCKER_HUB_FLIGHT_INFO_IMAGE
- export FOLDER=flights-domain
- *stop-and-run
- export API_IMAGE=$DOCKER_HUB_GATEWAY_IMAGE
- export FOLDER=gateway
- *stop-and-run
- export CLIENT_IMAGE=$DOCKER_HUB_SCREEN_CLIENT_IMAGE
- export FOLDER=screen-domain
- *stop-and-run
- export CLIENT_IMAGE=$DOCKER_HUB_BROWSER_CLIENT_IMAGE
- export FOLDER=browser-domain
- *stop-and-run
needs:
- job: deliver-dockerhub
optional: true
artifacts: false
- job: preparation
optional: true
artifacts: true