default: before_script: - set -ex # env -0 | sort -z | tr '\0' '\n': Sort env output alphabetically, keeping multiline variables intact # egrep: Remove sensitive information from the output of env - env -0 | sort -z | tr '\0' '\n' | egrep -ve '^(DOCKER_AUTH_CONFIG|GOOGLE_APPLICATION_CREDENTIALS)=.*' interruptible: true tags: - 1cpu-4gb # build on smaller machine stages: - build - deploy - smoketest - destroy variables: # This variable needs to be named differently than in triggering projects # because if not, it gets set to '/api_domain', which breaks the e2e stage # due to the file not being in the artifacts. API_DOMAIN_FILE: "$CI_PROJECT_DIR/api_domain" # job templates .deploy: image: name: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/hashicorp/terraform:1.6.6' # default entrypoint is terraform command, but we want to run shell scripts entrypoint: ["/bin/sh", "-c"] variables: ENVIRONMENT_ID: $CI_ENVIRONMENT_SLUG artifacts: paths: - "terraform/environments/crash.log" # optional, only available in case of a crash/panic - "terraform/environments/terraform-*.log" # separate log for every step/command - $API_DOMAIN_FILE name: "${CI_JOB_NAME}_${CI_JOB_ID}" #when: on_failure expire_in: 1 week script: - terraform/environments/scripts/create-or-update-env.sh $ENVIRONMENT_ID ${CI_COMMIT_SHA}_${CI_PIPELINE_IID} - echo "$(terraform/environments/scripts/get-output.sh api_domain)" > $API_DOMAIN_FILE resource_group: $ENVIRONMENT_ID # never execute terraform in parallel on the same environment interruptible: false .smoketest: stage: "smoketest" image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/holi-k6-builder' script: - API_DOMAIN=$(cat $API_DOMAIN_FILE) - terraform/environments/scripts/wait-for-ssl.sh "https://${API_DOMAIN}" - BASE_URL="https://${API_DOMAIN}/graphql" /tmp/k6 run smoketest/main.js # TODO should/could we roll back the service to the last working revision on test failure? # end job templates # pipeline in chronological order ## common steps install_lint_test: stage: build image: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/node:22-alpine' script: - yarn install - yarn lint - yarn test tags: - 4cpu-4gb # You can override the included template(s) by including variable overrides # SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings # Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings # Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings # Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings # Note that environment variables can be set in several places # See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence sast: needs: ['install_lint_test'] stage: build include: - template: Security/SAST.gitlab-ci.yml .build_mesh: needs: ['install_lint_test'] image: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/node:22-alpine' script: - yarn install - yarn run mesh build - yarn run mesh validate tags: - 4cpu-4gb artifacts: paths: - ".mesh/" .build_docker: needs: ['install_lint_test'] image: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/docker:27' services: - 'docker:27-dind' variables: # this could be fetched via terraform output ("gcr_location" in infra project), but then we would need an extra job for terraform GCR_IMAGE: europe-north1-docker.pkg.dev/holi-shared/docker/holi-unified-api script: - docker pull $GCR_IMAGE || true # Allows us to use --cache-from, we need to tag with latest in the next command for this to work - docker build --cache-from $GCR_IMAGE -t $GCR_IMAGE:latest -t $GCR_IMAGE:${CI_COMMIT_SHA}_${CI_PIPELINE_IID} -t $GCR_IMAGE:$CI_COMMIT_REF_SLUG . - docker push $GCR_IMAGE:${CI_COMMIT_SHA}_${CI_PIPELINE_IID} # this is the tag that is used for deployment - docker push $GCR_IMAGE:$CI_COMMIT_REF_SLUG # just for easyly knowing which is the last image for a branch build_mesh_staging: stage: build extends: .build_mesh variables: # these could be fetched via terraform output ("gcr_location" in infra project), but then we would need an extra job for terraform DONATIONS_API_URL: https://staging.donations.apis.holi.social/graphql GEO_API_URL: https://staging.geo.apis.holi.social/graphql GOODNEWS_API_URL: https://staging.goodnews.apis.holi.social/graphql OKUNA_URL: https://staging.social.apis.holi.social/graphql VOLUNTEERING_API_URL: https://staging.volunteering.apis.holi.social/graphql NOTIFICATIONS_API_URL: https://staging.notifications.apis.holi.social/graphql TRANSLATION_API_URL: https://staging.translation.apis.holi.social/graphql REDIS_HOST: 10.104.0.3 REDIS_PORT: 6379 REDIS_DB: 5 build_docker_staging: stage: build extends: .build_docker needs: ['build_mesh_staging'] variables: ENVIRONMENT_ID: staging ## review environments deploy_review: stage: deploy extends: .deploy needs: ['build_docker_staging'] environment: name: review/$CI_COMMIT_REF_SLUG url: https://$CI_ENVIRONMENT_SLUG.unified.apis.holi.social on_stop: destroy_review auto_stop_in: 1 week except: - main - production - /^noenv\/.*/ smoketest_review: extends: .smoketest needs: ['deploy_review'] except: - main - production - /^noenv\/.*/ destroy_review: stage: destroy needs: ['deploy_review'] image: name: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/hashicorp/terraform:1.6.6' # default entrypoint is terraform command, but we want to run shell scripts entrypoint: ["/bin/sh", "-c"] variables: # has to be set to none for auto stop GIT_STRATEGY: none ENVIRONMENT_ID: $CI_ENVIRONMENT_SLUG environment: name: review/$CI_COMMIT_REF_SLUG action: stop dependencies: [] # explicitly disable artifact usage script: # branch may have been deleted, so we clone and checkout main - git clone $CI_REPOSITORY_URL main-clone - cd main-clone - terraform/environments/scripts/destroy-env.sh $CI_ENVIRONMENT_SLUG # can't use rules here: https://gitlab.com/gitlab-org/gitlab/-/issues/34077 when: manual allow_failure: false except: - main - production - /^noenv\/.*/ resource_group: $ENVIRONMENT_ID # never execute terraform in parallel on the same environment interruptible: false ## staging environment deploy_staging: stage: deploy extends: .deploy needs: ['build_docker_staging'] environment: name: staging deployment_tier: staging url: https://staging.unified.apis.holi.social variables: ENVIRONMENT_ID: staging only: - main smoketest_staging: extends: .smoketest needs: ['deploy_staging'] only: - main ## production environment build_mesh_production: stage: build extends: .build_mesh variables: # these could be fetched via terraform output ("gcr_location" in infra project), but then we would need an extra job for terraform DONATIONS_API_URL: https://production.donations.apis.holi.social/graphql GEO_API_URL: https://production.geo.apis.holi.social/graphql GOODNEWS_API_URL: https://production.goodnews.apis.holi.social/graphql OKUNA_URL: https://production.social.apis.holi.social/graphql VOLUNTEERING_API_URL: https://production.volunteering.apis.holi.social/graphql NOTIFICATIONS_API_URL: https://production.notifications.apis.holi.social/graphql TRANSLATION_API_URL: https://production.translation.apis.holi.social/graphql REDIS_HOST: 10.104.0.3 REDIS_PORT: 6379 REDIS_DB: 13 only: - production build_docker_production: stage: build extends: .build_docker needs: ['build_mesh_production'] variables: ENVIRONMENT_ID: production only: - production deploy_production: stage: deploy extends: .deploy needs: ['build_docker_production'] allow_failure: false environment: name: production deployment_tier: production url: https://production.unified.apis.holi.social variables: ENVIRONMENT_ID: production only: - production smoketest_staging: extends: .smoketest needs: ['deploy_production'] only: - production/home/ole/projects/holi/holi-meta/holi-okuna/smoketest trigger_docs_generation: stage: deploy needs: ['deploy_production'] trigger: project: app/app.gitlab-pages.holi.team branch: main strategy: depend only: - production