Skip to content

Commit 4912005

Browse files
authored
ci: consolidate docker service startup into start-services action (#16277)
# Overview CI jobs intermittently fail because `pnpm docker:start` uses `--profile all`, pulling every docker image regardless of which the job actually needs. When Docker Hub has transient auth timeouts on unneeded images (e.g. `mongodb/mongodb-community-search` in a postgres-only job), the entire `docker compose up` fails. **Example failed run:** [int-postgres-custom-schema](https://github.com/payloadcms/payload/actions/runs/24411041892/job/71308895281?pr=16275#step:5:1144) — `mongot` image pull timed out with `context deadline exceeded`, failing a job that doesn't need MongoDB at all. ## Key Changes - **Renamed `start-database` action to `start-services`** - The action now starts storage services (LocalStack, Azurite, fake-gcs, vercel-blob) unconditionally via `--profile storage`, then starts the requested database conditionally (existing behavior unchanged). - **Removed separate "Start LocalStack" steps from CI workflows** - `tests-int` no longer calls `pnpm docker:start` before the action — storage is handled by `start-services`. - `tests-e2e` no longer has a conditional "Start LocalStack" step — storage comes with `start-services` for all E2E jobs. - **Added retry wrapper for docker compose pulls** - Each `docker compose` step now separates `pull` (with 3 attempts, 10s backoff) from `up`. Transient Docker Hub timeouts on needed images are retried instead of failing the job immediately. ## Design Decisions Each CI job previously had two service startup phases: a blanket `pnpm docker:start` (`--profile all`) and then the `start-database` action with a targeted profile. The `start-database` action already used the correct profiles for databases, so the `--profile all` step was redundant and pulled unnecessary images. Merging storage into the action removes the redundancy and reduces the pull surface to only what each job needs. `docker compose pull` has no built-in retry. The daemon's `max-download-attempts` only retries individual layer downloads, not auth token requests (which is what timed out here). A shell retry loop around `pull` is the standard workaround. The `pnpm docker:start` script in `package.json` still uses `--profile all` for local development convenience. ## Overall Flow ```mermaid sequenceDiagram participant CI as CI Job participant SS as start-services action participant DC as docker compose CI->>SS: uses: start-services (database: postgres) SS->>DC: --profile storage pull (up to 3 attempts) SS->>DC: --profile storage up -d --wait Note over DC: LocalStack, Azurite, fake-gcs, vercel-blob SS->>DC: --profile postgres pull (up to 3 attempts) SS->>DC: --profile postgres up -d --wait Note over DC: PostgreSQL + replica SS-->>CI: POSTGRES_URL output ``` Previously, CI called `pnpm docker:start` (`--profile all`) before `start-database`, pulling all images including mongodb/mongot even for postgres jobs. Now only the needed profiles are pulled, with retry for transient failures.
1 parent 56325ef commit 4912005

3 files changed

Lines changed: 35 additions & 17 deletions

File tree

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
name: Start Database
2-
description: Starts the required database for tests
1+
name: Start Services
2+
description: Starts storage and database services for tests
33

44
inputs:
55
database:
@@ -20,11 +20,26 @@ outputs:
2020
runs:
2121
using: composite
2222
steps:
23+
- name: Start storage services
24+
shell: bash
25+
run: |
26+
for i in 1 2 3; do
27+
docker compose -f test/docker-compose.yml --profile storage pull && break
28+
echo "Pull attempt $i/3 for 'storage' profile failed, retrying in 10s..."
29+
sleep 10
30+
done
31+
docker compose -f test/docker-compose.yml --profile storage up -d --wait
32+
2333
- name: Start MongoDB
2434
id: mongodb
2535
if: contains(fromJSON('["mongodb", "cosmosdb", "documentdb", "firestore"]'), inputs.database)
2636
shell: bash
2737
run: |
38+
for i in 1 2 3; do
39+
docker compose -f test/docker-compose.yml --profile mongodb pull && break
40+
echo "Pull attempt $i/3 for 'mongodb' profile failed, retrying in 10s..."
41+
sleep 10
42+
done
2843
docker compose -f test/docker-compose.yml --profile mongodb up -d --wait
2944
echo "url=mongodb://payload:payload@localhost:27018/payload?authSource=admin&directConnection=true&replicaSet=rs0" >> $GITHUB_OUTPUT
3045
@@ -33,6 +48,11 @@ runs:
3348
if: inputs.database == 'mongodb-atlas'
3449
shell: bash
3550
run: |
51+
for i in 1 2 3; do
52+
docker compose -f test/docker-compose.yml --profile mongodb-atlas pull && break
53+
echo "Pull attempt $i/3 for 'mongodb-atlas' profile failed, retrying in 10s..."
54+
sleep 10
55+
done
3656
docker compose -f test/docker-compose.yml --profile mongodb-atlas up -d --wait
3757
echo "url=mongodb://localhost:27019/payload?directConnection=true&replicaSet=mongodb-atlas-local" >> $GITHUB_OUTPUT
3858
@@ -41,6 +61,11 @@ runs:
4161
if: startsWith(inputs.database, 'postgres')
4262
shell: bash
4363
run: |
64+
for i in 1 2 3; do
65+
docker compose -f test/docker-compose.yml --profile postgres pull && break
66+
echo "Pull attempt $i/3 for 'postgres' profile failed, retrying in 10s..."
67+
sleep 10
68+
done
4469
docker compose -f test/docker-compose.yml --profile postgres up -d --wait
4570
echo "url=postgresql://payload:payload@localhost:5433/payload" >> $GITHUB_OUTPUT
4671

.github/workflows/main.yml

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,13 @@ jobs:
182182
with:
183183
restore-build: true
184184

185-
- name: Start LocalStack
186-
run: pnpm docker:start
187-
188185
- name: Configure Redis
189186
run: |
190187
echo "REDIS_URL=redis://127.0.0.1:6379" >> $GITHUB_ENV
191188
192-
- name: Start database
189+
- name: Start services
193190
id: db
194-
uses: ./.github/actions/start-database
191+
uses: ./.github/actions/start-services
195192
with:
196193
database: ${{ matrix.database }}
197194

@@ -284,13 +281,9 @@ jobs:
284281
key: e2e-prep-${{ github.sha }}
285282
fail-on-cache-miss: true
286283

287-
- name: Start LocalStack
288-
run: pnpm docker:start
289-
if: contains(fromJson('["plugin-cloud-storage", "plugin-import-export"]'), matrix.suite) || contains(matrix.suite, 'storage-s3__client-uploads') || contains(matrix.suite, 'storage-vercel-blob__client-uploads')
290-
291-
- name: Start database
284+
- name: Start services
292285
id: db
293-
uses: ./.github/actions/start-database
286+
uses: ./.github/actions/start-services
294287
with:
295288
database: mongodb
296289

@@ -404,10 +397,10 @@ jobs:
404397
with:
405398
restore-build: true
406399

407-
- name: Start database
400+
- name: Start services
408401
id: db
409402
if: matrix.database
410-
uses: ./.github/actions/start-database
403+
uses: ./.github/actions/start-services
411404
with:
412405
database: ${{ matrix.database }}
413406

.github/workflows/post-release-templates.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ jobs:
5757

5858
- name: Start PostgreSQL
5959
id: postgres
60-
uses: ./.github/actions/start-database
60+
uses: ./.github/actions/start-services
6161
with:
6262
database: postgres
6363

6464
- name: Start MongoDB
6565
id: mongodb
66-
uses: ./.github/actions/start-database
66+
uses: ./.github/actions/start-services
6767
with:
6868
database: mongodb
6969

0 commit comments

Comments
 (0)