Skip to content

(PC-32388)[BO] fix: batch validation crash when something went wrong #13083

(PC-32388)[BO] fix: batch validation crash when something went wrong

(PC-32388)[BO] fix: batch validation crash when something went wrong #13083

name: "1 [on_push] Initiate workflow"
on:
push:
branches:
- master
- "maint/**"
permissions: write-all
jobs:
pcapi-init-job:
name: "pcapi init job"
runs-on: ubuntu-latest
outputs:
api-changed: ${{ steps.check-api-changes.outputs.any_modified }}
api-documentation-changed: ${{ steps.check-api-documentation-changes.outputs.any_modified }}
pro-changed: ${{ steps.check-pro-changes.outputs.any_modified }}
dependencies-changed: ${{ steps.check-dependencies-changes.outputs.any_modified }}
push-tags: ${{ steps.pcapi-tags.outputs.push-tags }}
checksum-tag: ${{ steps.pcapi-tags.outputs.checksum-tag }}
checksum-tag-exists: ${{ steps.check-checksum-tag.outputs.tag-exists }}
checksum-console-tag-exists: ${{ steps.check-console-checksum-tag.outputs.tag-exists }}
steps:
- uses: actions/checkout@v4.2.1
with:
fetch-depth: 0
fetch-tags: false
- name: "Check api folder changes"
id: check-api-changes
uses: tj-actions/changed-files@v45
with:
files: |
api/**
!api/documentation/**
!api/src/pcapi/scripts/**/main.py
!api/src/pcapi/scripts/**/main.sql
- name: "Check api documentation folder changes"
id: check-api-documentation-changes
uses: tj-actions/changed-files@v45
with:
files: api/documentation/**
- name: "Check pro folder changes"
id: check-pro-changes
uses: tj-actions/changed-files@v45
with:
files: pro/**
- name: "Check changes in dependencies (frontend + backend)"
id: check-dependencies-changes
uses: tj-actions/changed-files@v45
with:
files: |
api/poetry.lock
pro/yarn.lock
- name: "Define pcapi image tags."
id: pcapi-tags
run: |
DOCKER_IMAGE="${{ env.docker_registry }}/pcapi"
API_CHECKSUM=`tar --sort=name --owner=0 --group=0 --mtime='UTC 2019-01-01' -cf - api | sha1sum | awk '{ print $1 }'`
PUSH_TAGS="push-tags=$DOCKER_IMAGE:${{ github.sha }},$DOCKER_IMAGE:$API_CHECKSUM,$DOCKER_IMAGE:latest"
API_TAG="checksum-tag=$API_CHECKSUM"
echo "PUSH_TAGS=$PUSH_TAGS"
echo "API_TAG=$API_TAG"
echo $PUSH_TAGS >> "$GITHUB_OUTPUT"
echo $API_TAG >> "$GITHUB_OUTPUT"
- name: "Authentification to Google"
uses: 'google-github-actions/auth@v2'
with:
workload_identity_provider: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
- name: "Get Secret"
id: 'secrets'
uses: 'google-github-actions/get-secretmanager-secrets@v2'
with:
secrets: |-
ARTIFACT_REGISTRY_WORKLOAD_IDENTITY_PROVIDER:passculture-metier-ehp/passculture-main-gcp-workload-identity-provider
ARTIFACT_REGISTRY_SERVICE_ACCOUNT:passculture-metier-ehp/passculture-main-artifact-registry-service-account
- name: "OpenID Connect Authentication"
id: "openid-auth"
uses: "google-github-actions/auth@v2"
with:
create_credentials_file: false
token_format: "access_token"
workload_identity_provider: ${{ steps.secrets.outputs.ARTIFACT_REGISTRY_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ steps.secrets.outputs.ARTIFACT_REGISTRY_SERVICE_ACCOUNT }}
- name: "Docker login"
id: "docker-login"
uses: "docker/login-action@v3"
with:
registry: "europe-west1-docker.pkg.dev"
username: "oauth2accesstoken"
password: "${{ steps.openid-auth.outputs.access_token }}"
- name: "pcapi"
id: check-checksum-tag
run: ./.github/workflows/scripts/check-image-tag-exists.sh
env:
image: pcapi
tag: ${{ steps.pcapi-tags.outputs.checksum-tag }}
- name: "pcapi-console"
id: check-console-checksum-tag
run: ./.github/workflows/scripts/check-image-tag-exists.sh
env:
image: pcapi-console
tag: ${{ steps.pcapi-tags.outputs.checksum-tag }}
- name: "Summary"
run: |
echo "[api] folder changed : ${{ steps.check-api-changes.outputs.any_modified }}"
echo "[pcapi] push-tags : ${{ steps.pcapi-tags.outputs.push-tags }}"
echo "[pcapi] checksum-tag : ${{ steps.pcapi-tags.outputs.checksum-tag }}"
echo "[pcapi] image tag ${{ steps.pcapi-tags.outputs.checksum-tag }} exists : ${{ steps.check-checksum-tag.outputs.tag-exists }}"
echo "[pcapi-console] image tag ${{ steps.pcapi-tags.outputs.checksum-tag }} exists : ${{ steps.check-console-checksum-tag.outputs.tag-exists }}"
check-folders-changes:
# Perform all changes checks at once to remove the need for multiple checkouts accross jobs
name: "Check changes in folders"
runs-on: ubuntu-latest
outputs:
maintenance-site-changed: ${{ steps.check-maintenance-site-changes.outputs.any_modified }}
db-migrations-changed: ${{ steps.check-db-migrations-changes.outputs.any_modified }}
steps:
- uses: actions/checkout@v4.2.1
with:
fetch-depth: 0
fetch-tags: false
- name: "Check maintenance-site folder changes"
id: check-maintenance-site-changes
uses: tj-actions/changed-files@v45
with:
files: maintenance-site/**
- name: "Check db migration folder changes"
id: check-db-migrations-changes
uses: tj-actions/changed-files@v45
with:
files: |-
api/src/pcapi/alembic/versions/**
api/src/pcapi/alembic/run_migrations.py
build-pcapi:
name: "[pcapi] build docker image."
needs: [pcapi-init-job]
if: needs.pcapi-init-job.outputs.api-changed == 'true' && needs.pcapi-init-job.outputs.checksum-tag-exists == 'false'
uses: ./.github/workflows/dev_on_workflow_build_docker_image.yml
with:
ref: ${{ github.sha }}
image: pcapi
tag: ${{ needs.pcapi-init-job.outputs.checksum-tag }}
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
build-pcapi-tests:
name: "[pcapi-tests] build docker image."
needs: [pcapi-init-job]
if: needs.pcapi-init-job.outputs.api-changed == 'true'
uses: ./.github/workflows/dev_on_workflow_build_docker_image.yml
with:
ref: ${{ github.sha }}
image: pcapi-tests
tag: ${{ needs.pcapi-init-job.outputs.checksum-tag }}
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
build-pcapi-console:
name: "[pcapi-console] build docker image."
needs: [pcapi-init-job]
if: |
( needs.pcapi-init-job.outputs.api-changed == 'true' ||
needs.pcapi-init-job.outputs.pro-changed == 'true' ) &&
needs.pcapi-init-job.outputs.checksum-console-tag-exists == 'false' &&
github.ref == 'refs/heads/master'
uses: ./.github/workflows/dev_on_workflow_build_docker_image.yml
with:
ref: ${{ github.sha }}
image: pcapi-console
tag: ${{ needs.pcapi-init-job.outputs.checksum-tag }}
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
prepare-cache-master: # on "master" branch only
name: "Reset cache on master on dependency update"
needs: [build-pcapi]
uses: ./.github/workflows/dev_on_workflow_update_api_client_template.yml
if: github.ref == 'refs/heads/master'
with:
PCAPI_DOCKER_TAG: ${{ needs.pcapi-init-job.outputs.checksum-tag }}
TRIGGER_ONLY_ON_API_CHANGE: false
TRIGGER_ONLY_ON_DEPENDENCY_CHANGE: true
CACHE_BUCKET_NAME: "passculture-infra-prod-github-runner-cache"
api-changed: ${{ needs.pcapi-init-job.outputs.api-changed }}
dependencies-changed: ${{ needs.pcapi-init-job.outputs.dependencies-changed }}
secrets:
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
test-api:
name: "Test api"
needs: [pcapi-init-job, build-pcapi-tests]
uses: ./.github/workflows/dev_on_workflow_tests_api.yml
with:
tag: ${{ needs.build-pcapi-tests.result == 'skipped' && 'latest' || needs.pcapi-init-job.outputs.checksum-tag }}
secrets:
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
test-api-documentation:
name: "Tests API documentation"
needs: [pcapi-init-job]
if: needs.pcapi-init-job.outputs.api-documentation-changed == 'true'
uses: ./.github/workflows/dev_on_workflow_tests_api_documentation.yml
secrets:
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
test-pro:
name: "Tests pro"
needs: [pcapi-init-job]
if: needs.pcapi-init-job.outputs.pro-changed == 'true'
uses: ./.github/workflows/dev_on_workflow_tests_pro.yml
with:
CACHE_BUCKET_NAME: "passculture-infra-prod-github-runner-cache"
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
# FIXME : (mageoffray, 19-09-2024)
# this workflow is temporary and will be used to transitioned between
# e2e tests based on e2e sandbox and e2e tests based on micro sandboxes
test-pro-e2e-migration:
name: "Tests pro E2E migrations"
needs: [pcapi-init-job, build-pcapi]
uses: ./.github/workflows/dev_on_workflow_tests_pro_e2e_migration.yml
if: |
always() &&
!cancelled() &&
needs.pcapi-init-job.outputs.api-changed == 'true' ||
needs.pcapi-init-job.outputs.pro-changed == 'true'
with:
tag: ${{ needs.build-pcapi.result == 'skipped' && 'latest' || needs.pcapi-init-job.outputs.checksum-tag }}
CACHE_BUCKET_NAME: "passculture-infra-prod-github-runner-cache"
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
test-pro-e2e:
name: "Tests pro E2E"
needs: [pcapi-init-job, build-pcapi]
uses: ./.github/workflows/dev_on_workflow_tests_pro_e2e.yml
if: |
always() &&
!cancelled() &&
needs.pcapi-init-job.outputs.api-changed == 'true' ||
needs.pcapi-init-job.outputs.pro-changed == 'true'
with:
tag: ${{ needs.build-pcapi.result == 'skipped' && 'latest' || needs.pcapi-init-job.outputs.checksum-tag }}
CACHE_BUCKET_NAME: "passculture-infra-prod-github-runner-cache"
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
deploy-storybook:
name: "Deploy Storybook"
needs: [pcapi-init-job]
if: ${{ github.ref == 'refs/heads/master' && needs.pcapi-init-job.outputs.pro-changed == 'true' }}
uses: ./.github/workflows/dev_on_workflow_deploy_storybook.yml
push-pcapi:
name: "Push pcapi docker image to registry"
needs: [build-pcapi, pcapi-init-job, test-api]
uses: ./.github/workflows/dev_on_workflow_push_docker_image.yml
with:
image: pcapi
commit-hash: ${{ github.sha }}
checksum-tag: ${{ needs.pcapi-init-job.outputs.checksum-tag }}
tag-latest: true
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
push-pcapi-console:
name: "Push pcapi-console docker image to registry"
needs: [build-pcapi-console, pcapi-init-job, test-api]
uses: ./.github/workflows/dev_on_workflow_push_docker_image.yml
with:
image: pcapi-console
commit-hash: ${{ github.sha }}
checksum-tag: ${{ needs.pcapi-init-job.outputs.checksum-tag }}
tag-latest: true
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
deploy-to-testing:
name: "Deploy to testing"
needs: [test-api, test-pro, push-pcapi-console, push-pcapi]
if: |
always() &&
github.ref == 'refs/heads/master' &&
contains(fromJSON('["success", "skipped"]'), needs.test-api.result) &&
contains(fromJSON('["success", "skipped"]'), needs.test-pro.result)
uses: ./.github/workflows/dev_on_workflow_deploy.yml
with:
environment: testing
app_version: ${{ github.sha }}
teleport_proxy: teleport.ehp.passculture.team:443
teleport_kubernetes_cluster: passculture-metier-ehp
deploy_api: ${{ needs.test-api.result == 'success' }}
deploy_pro: ${{ needs.test-pro.result == 'success' }}
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
deploy-to-ops:
name: "Deploy to ops"
needs: [test-api, test-pro, push-pcapi-console, push-pcapi]
if: |
always() &&
github.ref == 'refs/heads/master' &&
contains(fromJSON('["success", "skipped"]'), needs.test-api.result) &&
contains(fromJSON('["success", "skipped"]'), needs.test-pro.result) &&
vars.DISABLE_PCAPI_OPS_DEPLOY == 'false'
uses: ./.github/workflows/dev_on_workflow_deploy.yml
with:
environment: ops
app_version: ${{ github.sha }}
teleport_proxy: teleport.ops.passculture.team:443
teleport_kubernetes_cluster: passculture-metier-ops
deploy_api: ${{ needs.test-api.result == 'success' }}
deploy_pro: false
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
deploy-maintenance-site:
name: "Deploy maintenance site"
needs: check-folders-changes
if: |
always() &&
github.ref == 'refs/heads/master' &&
needs.check-folders-changes.outputs.maintenance-site-changed == 'true'
uses: ./.github/workflows/dev_on_workflow_deploy_maintenance_site.yml
secrets:
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
ping-data-team-on-slack:
name: "Ping data team on slack"
needs: check-folders-changes
if: |
always() &&
github.ref == 'refs/heads/master' &&
needs.check-folders-changes.outputs.db-migrations-changed == 'true'
uses: ./.github/workflows/dev_on_workflow_ping_data_team.yml
secrets:
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
update-jira-issue:
name: "Update Jira issue"
if: ${{ always() && github.ref == 'refs/heads/master' }}
concurrency: update-jira-issue-${{ github.workflow }}-${{ github.ref }}
uses: ./.github/workflows/dev_on_workflow_update_jira_issues.yml
secrets:
GCP_EHP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_EHP_SERVICE_ACCOUNT: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
slack-notify:
name: "Slack notification"
runs-on: ubuntu-latest
if: ${{ failure() && github.ref == 'refs/heads/master' }}
needs: deploy-to-testing
steps:
- uses: technote-space/workflow-conclusion-action@v3
- name: "Authentification to Google"
uses: 'google-github-actions/auth@v2'
with:
workload_identity_provider: ${{ secrets.GCP_EHP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCP_EHP_SERVICE_ACCOUNT }}
- name: "Get Secret"
id: 'secrets'
uses: 'google-github-actions/get-secretmanager-secrets@v2'
with:
secrets: |-
SLACK_BOT_TOKEN:passculture-metier-ehp/passculture-ci-slack-bot-token
- name: "Post to a Slack channel"
uses: slackapi/slack-github-action@v1.27.0
with:
# channel #alertes-deploiement
channel-id: "CQAMNFVPS"
payload: |
{
"attachments": [
{
"mrkdwn_in": ["text"],
"color": "#A30002",
"author_name": "${{github.actor}}",
"author_link": "https://github.com/${{github.actor}}",
"author_icon": "https://github.com/${{github.actor}}.png",
"title": "PCAPI Deployment",
"title_link": "https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}",
"text": "Le déploiement de la version `master` a échoué sur `testing` :boom:"
}
],
"unfurl_links": false,
"unfurl_media": false
}
env:
SLACK_BOT_TOKEN: ${{ steps.secrets.outputs.SLACK_BOT_TOKEN }}