Skip to content

Optimize CI: engine-grouped testing (42 jobs to 8)#1939

Open
bpamiri wants to merge 14 commits intodevelopfrom
peter/ci-engine-grouped-testing
Open

Optimize CI: engine-grouped testing (42 jobs to 8)#1939
bpamiri wants to merge 14 commits intodevelopfrom
peter/ci-engine-grouped-testing

Conversation

@bpamiri
Copy link
Collaborator

@bpamiri bpamiri commented Mar 12, 2026

Summary

Restructures the GitHub Actions test matrix from 42 independent jobs (cfengine × dbengine) to 8 engine-grouped jobs that start each CF engine once and run all database test suites sequentially.

  • ~75% compute reduction — CF engine startup, CFPM install (Adobe), and container build happen once per engine instead of 6× per database
  • Oracle sleep 120 replaced with sqlplus health check loop (saves ~90s per occurrence)
  • Full test coverage preserved — all engine × database combinations still tested
  • JUnit XML output for PR annotations via EnricoMi/publish-unit-test-result-action
  • Engine × Database summary grid rendered in $GITHUB_STEP_SUMMARY
  • SQL Server memory reduced from 4GB to 2GB (fits all DBs in 7GB runner simultaneously)
  • Oracle memory reduced from 2GB to 1.5GB
  • BoxLang volumes re-enabled for local dev parity

How it works

Each engine job:

  1. Starts the CF engine + all compatible databases in parallel
  2. Waits for readiness (health checks, CFPM install)
  3. Loops through each database: ?db=mysql&reload=true&format=json?db=postgres&reload=true&format=json → ...
  4. Converts JSON results to JUnit XML locally (no second HTTP request — runner.cfm doesn't cache)
  5. Continues even if one database fails (all DBs always run)
  6. Uploads per-database JUnit artifacts

Summary jobs download all artifacts and render a matrix grid + PR annotations.

Database exclusions (preserved)

Engine Excluded
adobe2018 sqlite, h2
adobe2021/2023/2025, boxlang h2
lucee5/6/7 (none)

Test plan

  • Verify all 8 engine jobs start and run correctly
  • Verify database health checks work (especially Oracle sqlplus loop)
  • Verify reload=true clears model cache between DB switches
  • Verify JUnit XML artifacts are uploaded
  • Verify publish-results job creates PR annotations
  • Verify test-matrix-summary renders the grid
  • Verify memory budget: all DBs fit in 7GB runner simultaneously

🤖 Generated with Claude Code

Plan to restructure the GitHub Actions test matrix from 42 independent jobs
(cfengine x dbengine) to 8 engine-grouped jobs. Each CF engine starts once
and runs all database test suites sequentially, reducing total CI compute
by ~75%.

Key changes planned:
- Engine-only matrix (8 jobs vs 42)
- CFPM install once per Adobe engine instead of 6x
- Oracle sleep 120 replaced with sqlplus health check
- SQL Server memory 4GB->2GB, Oracle 2GB->1.5GB
- JUnit XML reporting via JSON-to-XML conversion
- Engine x database summary grid on workflow runs
- BoxLang volume mounts re-enabled for local dev parity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added the docs label Mar 12, 2026
bpamiri and others added 6 commits March 12, 2026 12:19
The test dataset is tiny (5 users, 8 authors, 40 photos). 4GB was excessive
and prevents running all databases simultaneously on a 7GB GitHub runner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows running all databases simultaneously within 7GB GitHub runner budget.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Volumes were commented out in 9790880 when Dockerfile was changed to COPY
all code at build time. This broke local dev (code changes required rebuild).
Re-enabling volumes restores live-reload behavior matching other CF engines.
Docker gives volumes precedence over COPY, so CI still works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces cfengine x dbengine matrix (42 jobs) with cfengine-only matrix (8 jobs).
Each job starts one CF engine + all databases, runs test suites sequentially.

Key changes:
- CF engine starts once per job instead of 6x (saves 5 startups per engine)
- CFPM install runs once per Adobe engine instead of 6x (saves ~50 min compute)
- Oracle sleep 120 replaced with sqlplus health check loop
- All databases start in parallel during engine warmup
- Tests continue after individual database failures (all DBs always run)
- JUnit XML output uploaded for each engine-database pair
- Summary jobs render engine x database grid on workflow run page
- PR annotations via EnricoMi/publish-unit-test-result-action

Total compute reduction: ~75% (from ~840 min to ~200 min)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Required by EnricoMi/publish-unit-test-result-action to post test
result annotations and PR comments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bpamiri bpamiri marked this pull request as ready for review March 12, 2026 19:26
bpamiri and others added 7 commits March 12, 2026 12:57
…rect

Wheels returns HTTP 302 after reload=true completes. The test curl was
capturing this 302 as a failure instead of following the redirect.

Fix: issue the reload as a separate curl with -L (follow redirects),
then run the actual test request without reload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous fix split reload and test into two requests. But the reload
request without format=json would run the full test suite in HTML format,
then the second request would run it again — doubling execution time.

Better approach: include reload=true AND format=json in one curl with -L.
Wheels' redirectAfterReload strips reload/password but preserves db= and
format=, so the redirect lands on ?db=X&format=json — exactly what we need.
Single request, single test execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ?db= parameter switches application.wheels.dataSourceName directly
(runner.cfm:70-80). No reload needed because:
- $_setTestboxEnv() handles datasource switching per HTTP request
- populate.cfm creates identical table schemas across all databases
- The old 42-job workflow never used reload=true either

reload=true was breaking Adobe CF engines because $handleRestartAppRequest
passes "application" as a component reference to cfinvoke, which Adobe CF
can't resolve. Removing it fixes all Adobe engines and simplifies the curl.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v5 uses Node.js 20 which is deprecated and will be forced to Node.js 24
on June 2, 2026. v6 natively supports Node.js 24.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Action version bumps (Node.js 24 support):
- actions/checkout v4 → v5
- actions/upload-artifact v4 → v5
- actions/download-artifact v4 → v5

Restart CF engine container between database runs to prevent cross-DB
contamination. Without restart, cached model metadata and association
methods from one database's test run leak into subsequent runs:
- BoxLang: shallow copy in runner.cfm causes datasource name to not
  actually switch (duplicate key errors on 2nd+ database)
- Adobe CF: stale association methods cause "method not found" errors
  on later databases (e.g. hasAuthor missing on 4th DB)

Container restart takes ~10-15s — much cheaper than a full rebuild,
and guarantees clean application state per database.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes remaining Node.js 20 deprecation warnings in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cast count attributes to int() in JUnit XML generation (CFML returns
  floats for numeric values, causing ValueError in publish action)
- Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 on publish-results and
  test-matrix-summary jobs (download-artifact@v6 still ships Node 20)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

Wheels Test Results

    42 files   3 696 suites   22m 11s ⏱️
 1 831 tests  1 828 ✅   3 💤 0 ❌
79 548 runs  79 167 ✅ 381 💤 0 ❌

Results for commit 1aa54ec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant