Skip to content

Commit 8a470c1

Browse files
authored
test: add more integration tests to CI (#15419)
Co-authored-by: German Jablonski <GermanJablo@users.noreply.github.com>
1 parent a7cc58b commit 8a470c1

3 files changed

Lines changed: 147 additions & 0 deletions

File tree

.github/workflows/main.yml

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,142 @@ jobs:
482482
- name: Generate GraphQL schema file
483483
run: pnpm dev:generate-graphql-schema graphql-schema-gen
484484

485+
# Test content-api integration with packed packages. Each job runs its own
486+
# ephemeral Content API instance pulled from Figma's ECR, backed by a Postgres
487+
# service container and a LocalStack container for S3 storage tests. This
488+
# gives each run an isolated sandbox, avoiding data collisions between
489+
# concurrent CI runs and removing the need for shared credentials.
490+
tests-content-api:
491+
name: Content API Tests
492+
runs-on: ubuntu-24.04
493+
needs: [changes, build]
494+
# Skip fork PRs: this job uses credentials fork workflows must not reach.
495+
if: needs.changes.outputs.needs_tests == 'true' && github.event.pull_request.head.repo.fork == false
496+
# Non-blocking while adapter coverage is incomplete. Once the full suite
497+
# passes, migrate to the `tests-int` matrix pattern (`pnpm test:int`
498+
# with --shard); `test:int:summary` cannot shard.
499+
continue-on-error: true
500+
permissions:
501+
id-token: write
502+
contents: read
503+
services:
504+
postgres:
505+
image: postgres:13
506+
env:
507+
POSTGRES_DB: figma_content_api
508+
POSTGRES_USER: postgres
509+
POSTGRES_PASSWORD: postgres
510+
ports:
511+
- 5432:5432
512+
options: >-
513+
--health-cmd "pg_isready -U postgres"
514+
--health-interval 10s
515+
--health-timeout 5s
516+
--health-retries 5
517+
localstack:
518+
image: localstack/localstack:4.10.0
519+
env:
520+
SERVICES: s3
521+
ports:
522+
- 4566:4566
523+
options: >-
524+
--health-cmd "curl -f http://localhost:4566/_localstack/health || exit 1"
525+
--health-interval 10s
526+
--health-timeout 5s
527+
--health-retries 10
528+
steps:
529+
- uses: actions/checkout@v5
530+
531+
- name: Node setup
532+
uses: ./.github/actions/setup
533+
with:
534+
restore-build: true
535+
536+
- name: Configure AWS credentials
537+
uses: aws-actions/configure-aws-credentials@v4
538+
with:
539+
role-to-assume: arn:aws:iam::060562746757:role/content-api-external-ci-pull
540+
aws-region: us-west-2
541+
542+
- name: Login to Amazon ECR
543+
uses: aws-actions/amazon-ecr-login@v2
544+
545+
# Figma publishes ECR tags as the 40-char SHA of the figma/figma commit
546+
# that built the image. There is no reliable floating alias, so pick the
547+
# most recently pushed SHA tag (skipping cosign `.sig` signatures).
548+
# `--max-results 100 --no-paginate` bounds the call to a single page;
549+
# without it the CLI pages through the full history and takes ~50s.
550+
- name: Resolve latest Content API image tag
551+
id: resolve-image
552+
run: |
553+
TAG=$(aws ecr describe-images \
554+
--repository-name payload/content-api \
555+
--region us-west-2 \
556+
--max-results 100 \
557+
--no-paginate \
558+
--query 'reverse(sort_by(imageDetails,& imagePushedAt))[].imageTags[]' \
559+
--output text | tr '\t' '\n' | grep -E '^[a-f0-9]{40}$' | head -n1)
560+
if [ -z "$TAG" ]; then
561+
echo "::error::No git-SHA-like tag found in payload/content-api ECR"
562+
exit 1
563+
fi
564+
echo "Using tag: $TAG"
565+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
566+
567+
# Cache the image tarball by resolved SHA so repeated runs on the same
568+
# figma/figma image skip the ~55s ECR pull.
569+
- name: Cache Content API image
570+
id: cache-content-api-image
571+
uses: actions/cache@v4
572+
with:
573+
path: /tmp/content-api-image.tar
574+
key: content-api-image-${{ steps.resolve-image.outputs.tag }}
575+
576+
- name: Start Content API
577+
run: |
578+
IMAGE=060562746757.dkr.ecr.us-west-2.amazonaws.com/payload/content-api:${{ steps.resolve-image.outputs.tag }}
579+
if [ -f /tmp/content-api-image.tar ]; then
580+
echo "Loading Content API image from cache"
581+
docker load -i /tmp/content-api-image.tar
582+
else
583+
echo "Pulling Content API image from ECR"
584+
docker pull "$IMAGE"
585+
docker save -o /tmp/content-api-image.tar "$IMAGE"
586+
fi
587+
docker run -d \
588+
--name content-api \
589+
--network host \
590+
-e DATABASE_URL="postgresql://postgres:postgres@localhost:5432/figma_content_api" \
591+
-e NODE_ENV=development \
592+
-e TARGET_ENV=development \
593+
-e CONTENT_API_PORT=8080 \
594+
-e S3_ENDPOINT=http://localhost:4566 \
595+
"$IMAGE"
596+
597+
- name: Wait for Content API to be ready
598+
run: |
599+
for i in $(seq 1 60); do
600+
if curl -sf http://localhost:8080/health > /dev/null; then
601+
echo "Content API is ready"
602+
exit 0
603+
fi
604+
sleep 2
605+
done
606+
echo "Content API failed to start within timeout"
607+
docker logs content-api || true
608+
exit 1
609+
610+
- name: Run Content API Integration Tests
611+
continue-on-error: true
612+
run: pnpm test:int:summary
613+
env:
614+
NODE_OPTIONS: --max-old-space-size=8096
615+
PAYLOAD_DATABASE: content-api
616+
617+
- name: Dump Content API logs on failure
618+
if: failure()
619+
run: docker logs content-api || true
620+
485621
all-green:
486622
name: All Green
487623
if: always()
@@ -496,6 +632,7 @@ jobs:
496632
tests-e2e,
497633
tests-types,
498634
tests-type-generation,
635+
tests-content-api,
499636
]
500637

501638
steps:

test/setupProd.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const tgzToPkgNameMap = {
1818
'@payloadcms/email-resend': 'payloadcms-email-resend-*',
1919
'@payloadcms/eslint-config': 'payloadcms-eslint-config-*',
2020
'@payloadcms/eslint-plugin': 'payloadcms-eslint-plugin-*',
21+
'@payloadcms/figma': 'payloadcms-figma-*',
2122
'@payloadcms/graphql': 'payloadcms-graphql-*',
2223
'@payloadcms/live-preview': 'payloadcms-live-preview-*',
2324
'@payloadcms/live-preview-react': 'payloadcms-live-preview-react-*',

vitest.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ export default defineConfig({
6161
hookTimeout: 90000,
6262
testTimeout: 90000,
6363
setupFiles: ['./test/vitest.setup.ts'],
64+
// Root-level `server.deps.inline` is not inherited by projects. Without
65+
// this, @payloadcms/figma (used by PAYLOAD_DATABASE=content-api) is
66+
// externalized, and its static `import ... from 'payload'` falls to
67+
// Node's loader, which cannot read payload's .ts source exports.
68+
server: {
69+
deps: {
70+
inline: [/@payloadcms\/figma/],
71+
},
72+
},
6473
},
6574
},
6675
{

0 commit comments

Comments
 (0)