From 4761b415a2d06b559a799910f73ffbcc6f826f3a Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 17 Aug 2026 21:37:45 +0530 Subject: [PATCH 1/2] feat: run migrations as an explicit ECS one-off task before deploy Bumps aws-actions/amazon-ecs-deploy-task-definition v1 -> v2 (purely additive per its changelog) to use its built-in run-task support: runs a standalone task on the new task definition, waits for it to stop, and fails the whole action on a non-zero container exit -- before the service update ever happens. Network config (subnets, security groups, public-IP assignment) is read from the currently running service via describe-services rather than hardcoded, so the migration task always runs in the same network context as the app. --- .github/workflows/deploy-to-ecs.yml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-to-ecs.yml b/.github/workflows/deploy-to-ecs.yml index 5487b8f..bab2d4c 100644 --- a/.github/workflows/deploy-to-ecs.yml +++ b/.github/workflows/deploy-to-ecs.yml @@ -103,13 +103,33 @@ jobs: container-name: dataspace image: ${{ steps.build-image.outputs.image }} - - name: Deploy main application ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + - name: Get running service's network configuration + id: network-config + run: | + NETWORK_CONFIG=$(aws ecs describe-services \ + --cluster "${{ env.ECS_CLUSTER }}" \ + --services "${{ secrets.ECS_SERVICE }}" \ + --query 'services[0].networkConfiguration.awsvpcConfiguration' \ + --output json) + { + echo "subnets=$(echo "$NETWORK_CONFIG" | jq -r '.subnets | join(",")')" + echo "security_groups=$(echo "$NETWORK_CONFIG" | jq -r '.securityGroups | join(",")')" + echo "assign_public_ip=$(echo "$NETWORK_CONFIG" | jq -r '.assignPublicIp')" + } >> "$GITHUB_OUTPUT" + + - name: Run migrations, then deploy the ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: task-definition: ${{ steps.task-def-app.outputs.task-definition }} service: ${{ secrets.ECS_SERVICE }} cluster: ${{ env.ECS_CLUSTER }} wait-for-service-stability: true + run-task: true + run-task-container-overrides: '[{"name":"dataspace","command":["python","manage.py","migrate","--noinput"]}]' + run-task-subnets: ${{ steps.network-config.outputs.subnets }} + run-task-security-groups: ${{ steps.network-config.outputs.security_groups }} + run-task-assign-public-IP: ${{ steps.network-config.outputs.assign_public_ip }} + wait-for-task-stopped: true deploy-otel: name: Deploy OpenTelemetry Collector From dd9a68c6245c68df4f8bbf732643057636323dbc Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 17 Aug 2026 21:37:45 +0530 Subject: [PATCH 2/2] chore: drop the now-dead migrations-directory scaffolding mkdir/chmod/touch on api/migrations existed only to let the runtime makemigrations step (removed earlier) write new migration files. migrate doesn't need to write to that directory, just read committed migrations, so this block has been dead weight since makemigrations was dropped. --- docker-entrypoint.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 96033e9..a54011c 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -39,13 +39,12 @@ while True: time.sleep(2) END -# Ensure migrations directory exists with proper permissions -echo "Ensuring migrations directory exists..." -mkdir -p /code/api/migrations -chmod -R 777 /code/api/migrations -touch /code/api/migrations/__init__.py - -# Run migrations +# Run migrations. In the ECS pipeline this also runs earlier as an explicit +# one-off task before this service is deployed (see deploy-to-ecs.yml) so a +# broken migration fails the deploy loudly and visibly instead of surfacing +# only once containers are already shipping; this call is then a no-op +# (migrate is idempotent). Kept here unconditionally too, since this same +# entrypoint/image is what `docker compose up` uses for local dev. echo "Running migrations..." python manage.py migrate --noinput