From 7085670a8d4dd4aaf1ee3f6fffb703c912cb024d Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Mon, 8 Dec 2025 13:14:35 +0100 Subject: [PATCH 1/8] Add redeploy ECS service action and update deployment workflow --- .../actions/redeploy-ecs-service/action.yml | 46 +++++ .github/workflows/hash-backend-cd.yml | 174 ++++++++++++------ 2 files changed, 166 insertions(+), 54 deletions(-) create mode 100644 .github/actions/redeploy-ecs-service/action.yml diff --git a/.github/actions/redeploy-ecs-service/action.yml b/.github/actions/redeploy-ecs-service/action.yml new file mode 100644 index 00000000000..847c03e41a9 --- /dev/null +++ b/.github/actions/redeploy-ecs-service/action.yml @@ -0,0 +1,46 @@ +name: Redeploy ECS service +description: Force a new ECS service deployment with optional role assumption + +inputs: + AWS_ACCESS_KEY_ID: + description: AWS access key id + required: true + AWS_SECRET_ACCESS_KEY: + description: AWS secret access key + required: true + AWS_SESSION_TOKEN: + description: AWS session token + required: true + AWS_REGION: + description: AWS region + required: true + ECS_CLUSTER_NAME: + description: ECS cluster name + required: true + ECS_SERVICE_NAME: + description: ECS service name + required: true + ROLE_ARN: + description: IAM role ARN to assume for deployment (cross-account) + required: false + +runs: + using: composite + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1 + with: + aws-access-key-id: ${{ inputs.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ inputs.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ inputs.AWS_SESSION_TOKEN }} + aws-region: ${{ inputs.AWS_REGION }} + role-to-assume: ${{ inputs.ROLE_ARN }} + role-duration-seconds: ${{ inputs.ROLE_DURATION_SECONDS }} + + - name: Redeploy ECS service + shell: bash + run: | + aws ecs update-service \ + --cluster "${{ inputs.ECS_CLUSTER_NAME }}" \ + --service "${{ inputs.ECS_SERVICE_NAME }}" \ + --force-new-deployment 1> /dev/null diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index db368ab4d2b..8827662aeb4 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -49,6 +49,24 @@ env: HASH_TEMPORAL_ECS_CLUSTER_NAME: h-temporal-prod-usea1-ecs HASH_TEMPORAL_SERVICE_NAME: h-temporal-prod-usea1-svc + STAGING_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-terraform-apply + STAGING_AWS_REGION: eu-central-1 + STAGING_APP_CLUSTER_NAME: h-stage-euc1-app + STAGING_APP_GRAPH_SERVICE_NAME: h-stage-euc1-app-graph + STAGING_APP_TYPE_FETCHER_SERVICE_NAME: h-stage-euc1-app-type-fetcher + STAGING_AUTH_CLUSTER_NAME: h-stage-euc1-auth + STAGING_AUTH_KRATOS_SERVICE_NAME: h-stage-euc1-auth-kratos + STAGING_AUTH_HYDRA_SERVICE_NAME: h-stage-euc1-auth-hydra + + PRODUCTION_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-terraform-apply + PRODUCTION_AWS_REGION: eu-central-1 + PRODUCTION_APP_CLUSTER_NAME: h-prod-euc1-app + PRODUCTION_APP_GRAPH_SERVICE_NAME: h-prod-euc1-app-graph + PRODUCTION_APP_TYPE_FETCHER_SERVICE_NAME: h-prod-euc1-app-type-fetcher + PRODUCTION_AUTH_CLUSTER_NAME: h-prod-euc1-auth + PRODUCTION_AUTH_KRATOS_SERVICE_NAME: h-prod-euc1-auth-kratos + PRODUCTION_AUTH_HYDRA_SERVICE_NAME: h-prod-euc1-auth-hydra + name: HASH backend deployment jobs: build-graph: @@ -431,24 +449,6 @@ jobs: BUILD_ARGS: | TEMPORAL_VERSION=${{ env.HASH_TEMPORAL_VERSION }} - - name: Push to artifacts ECR - uses: ./.github/actions/docker-build-push - with: - SHORTNAME: "temporal-migrate" - CONTEXT_PATH: ${{ github.workspace }}/apps/hash-external-services/temporal - DOCKERFILE_LOCATION: ${{ github.workspace }}/apps/hash-external-services/temporal/migrate.Dockerfile - AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} - AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} - AWS_REGION: ${{ env.ARTIFACTS_AWS_REGION }} - AWS_ECR_URL: ${{ env.ARTIFACTS_ECR_URL }} - ROLE_ARN: ${{ env.ARTIFACTS_ECR_ROLE_ARN }} - IMAGE_NAME: ${{ github.repository }}/temporal-migrate - GITHUB_TOKEN: ${{ github.token }} - IMAGE_TAG: ${{ env.HASH_TEMPORAL_VERSION }} - BUILD_ARGS: | - TEMPORAL_VERSION=${{ env.HASH_TEMPORAL_VERSION }} - build-temporal-setup: name: Build and push Temporal Setup image runs-on: ubuntu-24.04-arm @@ -491,24 +491,6 @@ jobs: BUILD_ARGS: | TEMPORAL_VERSION=${{ env.HASH_TEMPORAL_VERSION }} - - name: Push to artifacts ECR - uses: ./.github/actions/docker-build-push - with: - SHORTNAME: "temporal-setup" - CONTEXT_PATH: ${{ github.workspace }}/apps/hash-external-services/temporal - DOCKERFILE_LOCATION: ${{ github.workspace }}/apps/hash-external-services/temporal/setup.Dockerfile - AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} - AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} - AWS_REGION: ${{ env.ARTIFACTS_AWS_REGION }} - AWS_ECR_URL: ${{ env.ARTIFACTS_ECR_URL }} - ROLE_ARN: ${{ env.ARTIFACTS_ECR_ROLE_ARN }} - IMAGE_NAME: ${{ github.repository }}/temporal-setup - GITHUB_TOKEN: ${{ github.token }} - IMAGE_TAG: ${{ env.HASH_TEMPORAL_VERSION }} - BUILD_ARGS: | - TEMPORAL_VERSION=${{ env.HASH_TEMPORAL_VERSION }} - deploy-graph: name: Deploy HASH graph images runs-on: ubuntu-latest @@ -535,16 +517,59 @@ jobs: aws/creds/prod-deploy secret_key | AWS_SECRET_ACCESS_KEY ; aws/creds/prod-deploy security_token | AWS_SESSION_TOKEN - - uses: ./.github/actions/docker-ecr-login + - name: Redeploy service + uses: ./.github/actions/redeploy-ecs-service with: AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} AWS_REGION: ${{ env.AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.HASH_ECS_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.HASH_GRAPH_SERVICE_NAME }} - - name: Redeploy HASH graph service - run: | - aws ecs update-service --cluster ${{ env.HASH_ECS_CLUSTER_NAME }} --service ${{ env.HASH_GRAPH_SERVICE_NAME }} --force-new-deployment 1> /dev/null + - name: Redeploy graph staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_APP_GRAPH_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + + - name: Redeploy type-fetcher staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_APP_TYPE_FETCHER_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + + - name: Redeploy graph production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_APP_GRAPH_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} + + - name: Redeploy type-fetcher production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_APP_TYPE_FETCHER_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} deploy-app: name: Deploy HASH app images @@ -576,16 +601,59 @@ jobs: aws/creds/prod-deploy secret_key | AWS_SECRET_ACCESS_KEY ; aws/creds/prod-deploy security_token | AWS_SESSION_TOKEN - - uses: ./.github/actions/docker-ecr-login + - name: Redeploy service + uses: ./.github/actions/redeploy-ecs-service with: AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} AWS_REGION: ${{ env.AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.HASH_ECS_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.HASH_APP_SERVICE_NAME }} - - name: Redeploy HASH backend service - run: | - aws ecs update-service --cluster ${{ env.HASH_ECS_CLUSTER_NAME }} --service ${{ env.HASH_APP_SERVICE_NAME }} --force-new-deployment 1> /dev/null + - name: Redeploy kratos staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_AUTH_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_AUTH_KRATOS_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + + - name: Redeploy hydra staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_AUTH_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_AUTH_HYDRA_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + + - name: Redeploy kratos production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_AUTH_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_AUTH_KRATOS_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} + + - name: Redeploy hydra production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_AUTH_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_AUTH_HYDRA_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} deploy-workers: name: Deploy HASH worker images @@ -616,16 +684,15 @@ jobs: aws/creds/prod-deploy secret_key | AWS_SECRET_ACCESS_KEY ; aws/creds/prod-deploy security_token | AWS_SESSION_TOKEN - - uses: ./.github/actions/docker-ecr-login + - name: Redeploy service + uses: ./.github/actions/redeploy-ecs-service with: AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} AWS_REGION: ${{ env.AWS_REGION }} - - - name: Redeploy HASH worker service - run: | - aws ecs update-service --cluster ${{ env.HASH_ECS_CLUSTER_NAME }} --service ${{ env.HASH_WORKER_SERVICE_NAME }} --force-new-deployment 1> /dev/null + ECS_CLUSTER_NAME: ${{ env.HASH_ECS_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.HASH_WORKER_SERVICE_NAME }} deploy-temporal: name: Deploy Temporal images @@ -654,16 +721,15 @@ jobs: aws/creds/prod-deploy secret_key | AWS_SECRET_ACCESS_KEY ; aws/creds/prod-deploy security_token | AWS_SESSION_TOKEN - - uses: ./.github/actions/docker-ecr-login + - name: Redeploy service + uses: ./.github/actions/redeploy-ecs-service with: AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} AWS_REGION: ${{ env.AWS_REGION }} - - - name: Redeploy Temporal service - run: | - aws ecs update-service --cluster ${{ env.HASH_TEMPORAL_ECS_CLUSTER_NAME }} --service ${{ env.HASH_TEMPORAL_SERVICE_NAME }} --force-new-deployment 1> /dev/null + ECS_CLUSTER_NAME: ${{ env.HASH_TEMPORAL_ECS_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.HASH_TEMPORAL_SERVICE_NAME }} notify-slack: name: Notify Slack on failure From 5d742d96b9c28b8964e243948075a642c1ea457d Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Mon, 8 Dec 2025 13:19:20 +0100 Subject: [PATCH 2/8] Fix environment variable usage in ECS service redeployment action --- .github/actions/redeploy-ecs-service/action.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/actions/redeploy-ecs-service/action.yml b/.github/actions/redeploy-ecs-service/action.yml index 847c03e41a9..b459d94b6c4 100644 --- a/.github/actions/redeploy-ecs-service/action.yml +++ b/.github/actions/redeploy-ecs-service/action.yml @@ -35,12 +35,14 @@ runs: aws-session-token: ${{ inputs.AWS_SESSION_TOKEN }} aws-region: ${{ inputs.AWS_REGION }} role-to-assume: ${{ inputs.ROLE_ARN }} - role-duration-seconds: ${{ inputs.ROLE_DURATION_SECONDS }} - name: Redeploy ECS service + env: + ECS_CLUSTER_NAME: ${{ inputs.ECS_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ inputs.ECS_SERVICE_NAME }} shell: bash run: | aws ecs update-service \ - --cluster "${{ inputs.ECS_CLUSTER_NAME }}" \ - --service "${{ inputs.ECS_SERVICE_NAME }}" \ + --cluster "${ECS_CLUSTER_NAME}" \ + --service "${ECS_SERVICE_NAME}" \ --force-new-deployment 1> /dev/null From 92b6077904a7e8eb40f16c580d204fbb83f22cbb Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Mon, 8 Dec 2025 13:22:39 +0100 Subject: [PATCH 3/8] Comment out dependencies for testing --- .github/workflows/hash-backend-cd.yml | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index 8827662aeb4..bacf7429336 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -494,8 +494,8 @@ jobs: deploy-graph: name: Deploy HASH graph images runs-on: ubuntu-latest - needs: - - build-graph + # needs: + # - build-graph permissions: id-token: write contents: read @@ -575,9 +575,9 @@ jobs: name: Deploy HASH app images runs-on: ubuntu-latest needs: - - build-api - - build-kratos - - build-hydra + # - build-api + # - build-kratos + # - build-hydra # Technically not needed but it's good if the graph has been finished already - deploy-graph permissions: @@ -659,8 +659,8 @@ jobs: name: Deploy HASH worker images runs-on: ubuntu-latest needs: - - build-ts-worker - - build-integration-worker + # - build-ts-worker + # - build-integration-worker # Technically not needed but it's good if the graph has been finished already - deploy-graph permissions: @@ -697,9 +697,9 @@ jobs: deploy-temporal: name: Deploy Temporal images runs-on: ubuntu-latest - needs: - - build-temporal-migrate - - build-temporal-setup + # needs: + # - build-temporal-migrate + # - build-temporal-setup permissions: id-token: write contents: read @@ -731,23 +731,23 @@ jobs: ECS_CLUSTER_NAME: ${{ env.HASH_TEMPORAL_ECS_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.HASH_TEMPORAL_SERVICE_NAME }} - notify-slack: - name: Notify Slack on failure - needs: - - deploy-app - - deploy-graph - - deploy-workers - - deploy-temporal - runs-on: ubuntu-latest - if: ${{ failure() }} - steps: - - name: Slack Notification - uses: rtCamp/action-slack-notify@07cbdbfd6c6190970778d8f98f11d073b2932aae - env: - SLACK_LINK_NAMES: true - SLACK_MESSAGE: "Error deploying the HASH backend " # Notifies @devops - SLACK_TITLE: Backend deployment failed - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} - SLACK_USERNAME: GitHub - VAULT_ADDR: "" - VAULT_TOKEN: "" + # notify-slack: + # name: Notify Slack on failure + # needs: + # - deploy-app + # - deploy-graph + # - deploy-workers + # - deploy-temporal + # runs-on: ubuntu-latest + # if: ${{ failure() }} + # steps: + # - name: Slack Notification + # uses: rtCamp/action-slack-notify@07cbdbfd6c6190970778d8f98f11d073b2932aae + # env: + # SLACK_LINK_NAMES: true + # SLACK_MESSAGE: "Error deploying the HASH backend " # Notifies @devops + # SLACK_TITLE: Backend deployment failed + # SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + # SLACK_USERNAME: GitHub + # VAULT_ADDR: "" + # VAULT_TOKEN: "" From 92e847c3c52b8e8ec08facc36dc2c80f28351a65 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Mon, 8 Dec 2025 14:01:43 +0100 Subject: [PATCH 4/8] Refactor deployment role ARNs in workflow for staging and production services --- .github/workflows/hash-backend-cd.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index bacf7429336..871693e9ebd 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -49,21 +49,23 @@ env: HASH_TEMPORAL_ECS_CLUSTER_NAME: h-temporal-prod-usea1-ecs HASH_TEMPORAL_SERVICE_NAME: h-temporal-prod-usea1-svc - STAGING_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-terraform-apply STAGING_AWS_REGION: eu-central-1 STAGING_APP_CLUSTER_NAME: h-stage-euc1-app + STAGING_APP_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-app-deploy STAGING_APP_GRAPH_SERVICE_NAME: h-stage-euc1-app-graph STAGING_APP_TYPE_FETCHER_SERVICE_NAME: h-stage-euc1-app-type-fetcher STAGING_AUTH_CLUSTER_NAME: h-stage-euc1-auth + STAGING_AUTH_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-auth-deploy STAGING_AUTH_KRATOS_SERVICE_NAME: h-stage-euc1-auth-kratos STAGING_AUTH_HYDRA_SERVICE_NAME: h-stage-euc1-auth-hydra - PRODUCTION_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-terraform-apply PRODUCTION_AWS_REGION: eu-central-1 PRODUCTION_APP_CLUSTER_NAME: h-prod-euc1-app + PRODUCTION_APP_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-app-deploy PRODUCTION_APP_GRAPH_SERVICE_NAME: h-prod-euc1-app-graph PRODUCTION_APP_TYPE_FETCHER_SERVICE_NAME: h-prod-euc1-app-type-fetcher PRODUCTION_AUTH_CLUSTER_NAME: h-prod-euc1-auth + PRODUCTION_AUTH_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-auth-deploy PRODUCTION_AUTH_KRATOS_SERVICE_NAME: h-prod-euc1-auth-kratos PRODUCTION_AUTH_HYDRA_SERVICE_NAME: h-prod-euc1-auth-hydra @@ -536,7 +538,7 @@ jobs: AWS_REGION: ${{ env.STAGING_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.STAGING_APP_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.STAGING_APP_GRAPH_SERVICE_NAME }} - ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.STAGING_APP_DEPLOY_ROLE_ARN }} - name: Redeploy type-fetcher staging service uses: ./.github/actions/redeploy-ecs-service @@ -547,7 +549,7 @@ jobs: AWS_REGION: ${{ env.STAGING_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.STAGING_APP_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.STAGING_APP_TYPE_FETCHER_SERVICE_NAME }} - ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.STAGING_APP_DEPLOY_ROLE_ARN }} - name: Redeploy graph production service uses: ./.github/actions/redeploy-ecs-service @@ -558,7 +560,7 @@ jobs: AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.PRODUCTION_APP_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.PRODUCTION_APP_GRAPH_SERVICE_NAME }} - ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.PRODUCTION_APP_DEPLOY_ROLE_ARN }} - name: Redeploy type-fetcher production service uses: ./.github/actions/redeploy-ecs-service @@ -569,7 +571,7 @@ jobs: AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.PRODUCTION_APP_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.PRODUCTION_APP_TYPE_FETCHER_SERVICE_NAME }} - ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.PRODUCTION_APP_DEPLOY_ROLE_ARN }} deploy-app: name: Deploy HASH app images @@ -620,7 +622,7 @@ jobs: AWS_REGION: ${{ env.STAGING_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.STAGING_AUTH_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.STAGING_AUTH_KRATOS_SERVICE_NAME }} - ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.STAGING_AUTH_DEPLOY_ROLE_ARN }} - name: Redeploy hydra staging service uses: ./.github/actions/redeploy-ecs-service @@ -631,7 +633,7 @@ jobs: AWS_REGION: ${{ env.STAGING_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.STAGING_AUTH_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.STAGING_AUTH_HYDRA_SERVICE_NAME }} - ROLE_ARN: ${{ env.STAGING_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.STAGING_AUTH_DEPLOY_ROLE_ARN }} - name: Redeploy kratos production service uses: ./.github/actions/redeploy-ecs-service @@ -642,7 +644,7 @@ jobs: AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.PRODUCTION_AUTH_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.PRODUCTION_AUTH_KRATOS_SERVICE_NAME }} - ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.PRODUCTION_AUTH_DEPLOY_ROLE_ARN }} - name: Redeploy hydra production service uses: ./.github/actions/redeploy-ecs-service @@ -653,7 +655,7 @@ jobs: AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} ECS_CLUSTER_NAME: ${{ env.PRODUCTION_AUTH_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.PRODUCTION_AUTH_HYDRA_SERVICE_NAME }} - ROLE_ARN: ${{ env.PRODUCTION_DEPLOY_ROLE_ARN }} + ROLE_ARN: ${{ env.PRODUCTION_AUTH_DEPLOY_ROLE_ARN }} deploy-workers: name: Deploy HASH worker images From 8ac49b5ddd484763f90bcf824b76633a449c65db Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Mon, 8 Dec 2025 14:23:13 +0100 Subject: [PATCH 5/8] Add staging and production redeploy actions for API and worker services --- .github/workflows/hash-backend-cd.yml | 136 ++++++++++++++++++++------ 1 file changed, 106 insertions(+), 30 deletions(-) diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index 871693e9ebd..8c202d20874 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -54,6 +54,11 @@ env: STAGING_APP_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-app-deploy STAGING_APP_GRAPH_SERVICE_NAME: h-stage-euc1-app-graph STAGING_APP_TYPE_FETCHER_SERVICE_NAME: h-stage-euc1-app-type-fetcher + STAGING_APP_API_SERVICE_NAME: h-stage-euc1-app-api + STAGING_WORKER_CLUSTER_NAME: h-stage-euc1-worker + STAGING_WORKER_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-worker-deploy + STAGING_WORKER_AI_TS_SERVICE_NAME: h-stage-euc1-worker-ai-ts + STAGING_WORKER_INTEGRATION_SERVICE_NAME: h-stage-euc1-worker-integration STAGING_AUTH_CLUSTER_NAME: h-stage-euc1-auth STAGING_AUTH_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-auth-deploy STAGING_AUTH_KRATOS_SERVICE_NAME: h-stage-euc1-auth-kratos @@ -64,6 +69,11 @@ env: PRODUCTION_APP_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-app-deploy PRODUCTION_APP_GRAPH_SERVICE_NAME: h-prod-euc1-app-graph PRODUCTION_APP_TYPE_FETCHER_SERVICE_NAME: h-prod-euc1-app-type-fetcher + PRODUCTION_APP_API_SERVICE_NAME: h-prod-euc1-app-api + PRODUCTION_WORKER_CLUSTER_NAME: h-prod-euc1-worker + PRODUCTION_WORKER_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-prod-euc1-worker-deploy + PRODUCTION_WORKER_AI_TS_SERVICE_NAME: h-prod-euc1-worker-ai-ts + PRODUCTION_WORKER_INTEGRATION_SERVICE_NAME: h-prod-euc1-worker-integration PRODUCTION_AUTH_CLUSTER_NAME: h-prod-euc1-auth PRODUCTION_AUTH_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-auth-deploy PRODUCTION_AUTH_KRATOS_SERVICE_NAME: h-prod-euc1-auth-kratos @@ -496,8 +506,8 @@ jobs: deploy-graph: name: Deploy HASH graph images runs-on: ubuntu-latest - # needs: - # - build-graph + needs: + - build-graph permissions: id-token: write contents: read @@ -577,9 +587,9 @@ jobs: name: Deploy HASH app images runs-on: ubuntu-latest needs: - # - build-api - # - build-kratos - # - build-hydra + - build-api + - build-kratos + - build-hydra # Technically not needed but it's good if the graph has been finished already - deploy-graph permissions: @@ -613,6 +623,17 @@ jobs: ECS_CLUSTER_NAME: ${{ env.HASH_ECS_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.HASH_APP_SERVICE_NAME }} + - name: Redeploy API staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_APP_API_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_APP_DEPLOY_ROLE_ARN }} + - name: Redeploy kratos staging service uses: ./.github/actions/redeploy-ecs-service with: @@ -635,6 +656,17 @@ jobs: ECS_SERVICE_NAME: ${{ env.STAGING_AUTH_HYDRA_SERVICE_NAME }} ROLE_ARN: ${{ env.STAGING_AUTH_DEPLOY_ROLE_ARN }} + - name: Redeploy API production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_APP_API_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_APP_DEPLOY_ROLE_ARN }} + - name: Redeploy kratos production service uses: ./.github/actions/redeploy-ecs-service with: @@ -661,8 +693,8 @@ jobs: name: Deploy HASH worker images runs-on: ubuntu-latest needs: - # - build-ts-worker - # - build-integration-worker + - build-ts-worker + - build-integration-worker # Technically not needed but it's good if the graph has been finished already - deploy-graph permissions: @@ -696,12 +728,56 @@ jobs: ECS_CLUSTER_NAME: ${{ env.HASH_ECS_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.HASH_WORKER_SERVICE_NAME }} + - name: Redeploy AI-TS staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_WORKER_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_WORKER_AI_TS_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_WORKER_DEPLOY_ROLE_ARN }} + + - name: Redeploy Integration staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_WORKER_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_WORKER_INTEGRATION_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_WORKER_DEPLOY_ROLE_ARN }} + + - name: Redeploy AI-TS production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_WORKER_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_WORKER_AI_TS_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_WORKER_DEPLOY_ROLE_ARN }} + + - name: Redeploy Integration production service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.PRODUCTION_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.PRODUCTION_WORKER_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.PRODUCTION_WORKER_INTEGRATION_SERVICE_NAME }} + ROLE_ARN: ${{ env.PRODUCTION_WORKER_DEPLOY_ROLE_ARN }} + deploy-temporal: name: Deploy Temporal images runs-on: ubuntu-latest - # needs: - # - build-temporal-migrate - # - build-temporal-setup + needs: + - build-temporal-migrate + - build-temporal-setup permissions: id-token: write contents: read @@ -733,23 +809,23 @@ jobs: ECS_CLUSTER_NAME: ${{ env.HASH_TEMPORAL_ECS_CLUSTER_NAME }} ECS_SERVICE_NAME: ${{ env.HASH_TEMPORAL_SERVICE_NAME }} - # notify-slack: - # name: Notify Slack on failure - # needs: - # - deploy-app - # - deploy-graph - # - deploy-workers - # - deploy-temporal - # runs-on: ubuntu-latest - # if: ${{ failure() }} - # steps: - # - name: Slack Notification - # uses: rtCamp/action-slack-notify@07cbdbfd6c6190970778d8f98f11d073b2932aae - # env: - # SLACK_LINK_NAMES: true - # SLACK_MESSAGE: "Error deploying the HASH backend " # Notifies @devops - # SLACK_TITLE: Backend deployment failed - # SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} - # SLACK_USERNAME: GitHub - # VAULT_ADDR: "" - # VAULT_TOKEN: "" + notify-slack: + name: Notify Slack on failure + needs: + - deploy-app + - deploy-graph + - deploy-workers + - deploy-temporal + runs-on: ubuntu-latest + if: ${{ failure() }} + steps: + - name: Slack Notification + uses: rtCamp/action-slack-notify@07cbdbfd6c6190970778d8f98f11d073b2932aae + env: + SLACK_LINK_NAMES: true + SLACK_MESSAGE: "Error deploying the HASH backend " # Notifies @devops + SLACK_TITLE: Backend deployment failed + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_USERNAME: GitHub + VAULT_ADDR: "" + VAULT_TOKEN: "" From 4d4a870db79d010943d4363231903b59f29a07f8 Mon Sep 17 00:00:00 2001 From: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:28:15 +0100 Subject: [PATCH 6/8] Update hash-backend-cd.yml --- .github/workflows/hash-backend-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index 8c202d20874..4a120eaea23 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -71,7 +71,7 @@ env: PRODUCTION_APP_TYPE_FETCHER_SERVICE_NAME: h-prod-euc1-app-type-fetcher PRODUCTION_APP_API_SERVICE_NAME: h-prod-euc1-app-api PRODUCTION_WORKER_CLUSTER_NAME: h-prod-euc1-worker - PRODUCTION_WORKER_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-prod-euc1-worker-deploy + PRODUCTION_WORKER_DEPLOY_ROLE_ARN: arn:aws:iam::597482567121:role/h-prod-euc1-worker-deploy PRODUCTION_WORKER_AI_TS_SERVICE_NAME: h-prod-euc1-worker-ai-ts PRODUCTION_WORKER_INTEGRATION_SERVICE_NAME: h-prod-euc1-worker-integration PRODUCTION_AUTH_CLUSTER_NAME: h-prod-euc1-auth From 32bc513865dc6bfc413265333418eae65600e399 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 11 Dec 2025 13:30:01 +0100 Subject: [PATCH 7/8] Add healthcheck endpoint and enable test server build argument --- .github/workflows/hash-backend-cd.yml | 2 ++ apps/hash-graph/package.json | 4 ++-- apps/hash-graph/src/subcommand/server.rs | 2 +- apps/hash-graph/src/subcommand/test_server.rs | 2 +- libs/@local/graph/api/src/rest/mod.rs | 14 ++++++++------ libs/@local/graph/test-server/src/lib.rs | 5 +++-- libs/@local/telemetry/src/traces/sentry.rs | 2 ++ 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index 4a120eaea23..e053e2648e6 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -134,6 +134,8 @@ jobs: ROLE_ARN: ${{ env.ARTIFACTS_ECR_ROLE_ARN }} IMAGE_NAME: ${{ github.repository }}/graph GITHUB_TOKEN: ${{ github.token }} + BUILD_ARGS: | + ENABLE_TEST_SERVER=yes build-api: name: Build and push HASH api image diff --git a/apps/hash-graph/package.json b/apps/hash-graph/package.json index 0d10d62af37..e7f9b4533b8 100644 --- a/apps/hash-graph/package.json +++ b/apps/hash-graph/package.json @@ -4,8 +4,8 @@ "private": true, "license": "AGPL-3", "scripts": { - "build:docker": "docker buildx build --build-arg PROFILE=production --tag hash-graph --file docker/Dockerfile ../../ --load", - "build:docker:dev": "docker buildx build --build-arg PROFILE=dev --tag hash-graph --file docker/Dockerfile ../../ --load", + "build:docker": "docker buildx build --build-arg PROFILE=production --build-arg ENABLE_TEST_SERVER=yes --tag hash-graph --file docker/Dockerfile ../../ --load", + "build:docker:dev": "docker buildx build --build-arg PROFILE=dev --build-arg ENABLE_TEST_SERVER=yes --tag hash-graph --file docker/Dockerfile ../../ --load", "compile": "cargo build --bin hash-graph --all-features", "compile:release": "cargo build --bin hash-graph --all-features --release", "doc:dependency-diagram": "cargo run -p hash-repo-chores -- dependency-diagram --output docs/dependency-diagram.mmd --root hash-graph --root-deps-and-dependents --link-mode non-roots --include-dev-deps --include-build-deps --logging-console-level info", diff --git a/apps/hash-graph/src/subcommand/server.rs b/apps/hash-graph/src/subcommand/server.rs index 85f9cc8a742..afd95a89650 100644 --- a/apps/hash-graph/src/subcommand/server.rs +++ b/apps/hash-graph/src/subcommand/server.rs @@ -376,7 +376,7 @@ pub async fn server(args: ServerArgs) -> Result<(), Report> { } pub async fn healthcheck(address: HttpAddress) -> Result<(), Report> { - let request_url = format!("http://{address}/api-doc/openapi.json"); + let request_url = format!("http://{address}/health"); timeout( Duration::from_secs(10), diff --git a/apps/hash-graph/src/subcommand/test_server.rs b/apps/hash-graph/src/subcommand/test_server.rs index 94af85a5663..bc151d57e86 100644 --- a/apps/hash-graph/src/subcommand/test_server.rs +++ b/apps/hash-graph/src/subcommand/test_server.rs @@ -91,7 +91,7 @@ pub async fn test_server(args: TestServerArgs) -> Result<(), Report> } pub async fn healthcheck(address: HttpAddress) -> Result<(), Report> { - let request_url = format!("http://{address}/snapshot"); + let request_url = format!("http://{address}/health"); timeout( Duration::from_secs(10), diff --git a/libs/@local/graph/api/src/rest/mod.rs b/libs/@local/graph/api/src/rest/mod.rs index 7031cab4252..1fc64e27714 100644 --- a/libs/@local/graph/api/src/rest/mod.rs +++ b/libs/@local/graph/api/src/rest/mod.rs @@ -336,12 +336,14 @@ where pub fn openapi_only_router() -> Router { let open_api_doc = OpenApiDocumentation::openapi(); - Router::new().nest( - "/api-doc", - Router::new() - .route("/openapi.json", get(|| async { Json(open_api_doc) })) - .route("/models/{*path}", get(serve_static_schema)), - ) + Router::new() + .route("/health", get(async || "Healthy".into_response())) + .nest( + "/api-doc", + Router::new() + .route("/openapi.json", get(|| async { Json(open_api_doc) })) + .route("/models/{*path}", get(serve_static_schema)), + ) } /// A [`Router`] that serves all of the REST API routes, and the `OpenAPI` specification. diff --git a/libs/@local/graph/test-server/src/lib.rs b/libs/@local/graph/test-server/src/lib.rs index b77f9c53425..04f980a675f 100644 --- a/libs/@local/graph/test-server/src/lib.rs +++ b/libs/@local/graph/test-server/src/lib.rs @@ -12,8 +12,8 @@ use std::collections::HashMap; use axum::{ Extension, Router, body::Body, - response::Response, - routing::{delete, post}, + response::{IntoResponse as _, Response}, + routing::{delete, get, post}, }; use error_stack::Report; use futures::TryStreamExt as _; @@ -32,6 +32,7 @@ use uuid::Uuid; pub fn routes(store_pool: PostgresStorePool) -> Router { Router::new() .layer(http_tracing_layer::HttpTracingLayer) + .route("/health", get(async || "Healthy".into_response())) .route("/snapshot", post(restore_snapshot)) .route("/accounts", delete(delete_accounts)) .route("/data-types", delete(delete_data_types)) diff --git a/libs/@local/telemetry/src/traces/sentry.rs b/libs/@local/telemetry/src/traces/sentry.rs index 290af3fb1a7..15262b391aa 100644 --- a/libs/@local/telemetry/src/traces/sentry.rs +++ b/libs/@local/telemetry/src/traces/sentry.rs @@ -28,6 +28,7 @@ use tracing_subscriber::{Layer, registry::LookupSpan}; pub enum SentryEnvironment { #[default] Development, + Staging, Production, } @@ -35,6 +36,7 @@ impl fmt::Display for SentryEnvironment { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Development => fmt.write_str("development"), + Self::Staging => fmt.write_str("staging"), Self::Production => fmt.write_str("production"), } } From f02c9a1ddb3cbb91f43857664573ccf522664e0b Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 11 Dec 2025 14:12:47 +0100 Subject: [PATCH 8/8] Add staging redeploy action for graph-test service and update environment variables --- .github/workflows/hash-backend-cd.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/hash-backend-cd.yml b/.github/workflows/hash-backend-cd.yml index e053e2648e6..64fab96b4b6 100644 --- a/.github/workflows/hash-backend-cd.yml +++ b/.github/workflows/hash-backend-cd.yml @@ -53,6 +53,7 @@ env: STAGING_APP_CLUSTER_NAME: h-stage-euc1-app STAGING_APP_DEPLOY_ROLE_ARN: arn:aws:iam::054238437032:role/h-stage-euc1-app-deploy STAGING_APP_GRAPH_SERVICE_NAME: h-stage-euc1-app-graph + STAGING_APP_GRAPH_TEST_SERVICE_NAME: h-stage-euc1-app-graph-test STAGING_APP_TYPE_FETCHER_SERVICE_NAME: h-stage-euc1-app-type-fetcher STAGING_APP_API_SERVICE_NAME: h-stage-euc1-app-api STAGING_WORKER_CLUSTER_NAME: h-stage-euc1-worker @@ -552,6 +553,17 @@ jobs: ECS_SERVICE_NAME: ${{ env.STAGING_APP_GRAPH_SERVICE_NAME }} ROLE_ARN: ${{ env.STAGING_APP_DEPLOY_ROLE_ARN }} + - name: Redeploy graph-test staging service + uses: ./.github/actions/redeploy-ecs-service + with: + AWS_ACCESS_KEY_ID: ${{ steps.secrets.outputs.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ steps.secrets.outputs.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ steps.secrets.outputs.AWS_SESSION_TOKEN }} + AWS_REGION: ${{ env.STAGING_AWS_REGION }} + ECS_CLUSTER_NAME: ${{ env.STAGING_APP_CLUSTER_NAME }} + ECS_SERVICE_NAME: ${{ env.STAGING_APP_GRAPH_TEST_SERVICE_NAME }} + ROLE_ARN: ${{ env.STAGING_APP_DEPLOY_ROLE_ARN }} + - name: Redeploy type-fetcher staging service uses: ./.github/actions/redeploy-ecs-service with: