Expand GitLab CI with functional test jobs from reference matrix #421

Closed
opened 2026-06-25 14:12:59 +00:00 by PlasticDigits · 14 comments
PlasticDigits commented 2026-06-25 14:12:59 +00:00 (Migrated from gitlab.com)

Parent

#411 — Updated Gap Analysis (recommendation 14)

Current codebase

.gitlab-ci.yml runs security + build only:

  • gitleaks, cargo-audit-smartcontracts, cargo-audit-indexer
  • Build jobs for contracts wasm check, indexer release, frontend production build

No contract unit tests, frontend Vitest, indexer integration, or Playwright E2E on merge.

Reference matrix: .github/workflows/test.yml (local automation per #234). docs/testing.md § CI documents Make targets. docs/qa-invariants.md still states "no hosted CI" — this issue expands GitLab CI toward the reference matrix.

Why needed

Gap analysis flagged Critical: "GitLab CI green ≠ functional test pass." Retail launch (#411) needs merge gates on functional regressions (cosmes patch, hybrid sim, slippage #293).

Constraints / guardrails

  • Phased rollout: start with fast gates (contracts unit, frontend unit, indexer cargo test --lib); E2E may stay manual/scheduled (DinD + LocalTerra is heavy).
  • Reuse scripts/ci/ patterns; pin images like existing GITLEAKS_IMAGE.
  • MR pipelines: use rules: changes: to avoid running full matrix on docs-only MRs.
  • Postgres for indexer integration: service container or job image with embedded Postgres.
  • Do not remove security stage jobs (#380).
  • Update docs/testing.md § CI and docs/qa-invariants.md when jobs land.

Relevant files

  • .gitlab-ci.yml
  • .github/workflows/test.yml (reference)
  • .github/workflows/README.md
  • Makefile (test-contracts, test-frontend, test-indexer-integration)
  • scripts/ci/
  • docs/testing.md § CI
  • docs/qa-invariants.md

Phase 1 (this issue):

  1. test-contracts job — make test-contracts on MR + default branch.
  2. test-frontend job — Node from .nvmrc, npm ci, make test-frontend.
  3. test-indexer-lib job — cd indexer && cargo test --lib.

Phase 2 (follow-up or stretch):

  1. test-indexer-integration with Postgres service.
  2. Scheduled E2E with DinD LocalTerra (optional; document cost).

Acceptance criteria

  • .gitlab-ci.yml includes at least contracts + frontend + indexer lib test jobs.
  • Jobs run on merge_request_event and default branch (with sensible rules: changes:).
  • Failed functional test blocks merge (no allow_failure).
  • docs/testing.md § CI lists new GitLab jobs alongside Make equivalents.

Test plan

  • Push MR to validate pipeline; confirm jobs pass on green main.
  • Intentionally break cosmesPatch127.test.ts in draft MR — pipeline must fail.

Attack / abuse test plan

  • Gitleaks still runs on same triggers.
  • CI secrets: no VITE_DEV_MNEMONIC in frontend build job (existing vite guard #118).

Verification criteria

  • GitLab pipeline on main shows functional test jobs green after #411 child-9 test fixes land.
  • Reference parity table in MR description mapping test.yml jobs → GitLab jobs.
## Parent [#411 — Updated Gap Analysis](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/411) (recommendation 14) ## Current codebase `.gitlab-ci.yml` runs **security + build only**: - `gitleaks`, `cargo-audit-smartcontracts`, `cargo-audit-indexer` - Build jobs for contracts wasm check, indexer release, frontend production build **No** contract unit tests, frontend Vitest, indexer integration, or Playwright E2E on merge. Reference matrix: `.github/workflows/test.yml` (local automation per #234). `docs/testing.md` § CI documents Make targets. `docs/qa-invariants.md` still states "no hosted CI" — this issue expands GitLab CI toward the reference matrix. ## Why needed Gap analysis flagged **Critical:** "GitLab CI green ≠ functional test pass." Retail launch (#411) needs merge gates on functional regressions (cosmes patch, hybrid sim, slippage #293). ## Constraints / guardrails - Phased rollout: start with fast gates (contracts unit, frontend unit, indexer `cargo test --lib`); E2E may stay manual/scheduled (DinD + LocalTerra is heavy). - Reuse `scripts/ci/` patterns; pin images like existing `GITLEAKS_IMAGE`. - MR pipelines: use `rules: changes:` to avoid running full matrix on docs-only MRs. - Postgres for indexer integration: service container or job image with embedded Postgres. - Do not remove security stage jobs (#380). - Update `docs/testing.md` § CI and `docs/qa-invariants.md` when jobs land. ## Relevant files - `.gitlab-ci.yml` - `.github/workflows/test.yml` (reference) - `.github/workflows/README.md` - `Makefile` (`test-contracts`, `test-frontend`, `test-indexer-integration`) - `scripts/ci/` - `docs/testing.md` § CI - `docs/qa-invariants.md` ## Recommended direction **Phase 1 (this issue):** 1. `test-contracts` job — `make test-contracts` on MR + default branch. 2. `test-frontend` job — Node from `.nvmrc`, `npm ci`, `make test-frontend`. 3. `test-indexer-lib` job — `cd indexer && cargo test --lib`. **Phase 2 (follow-up or stretch):** 4. `test-indexer-integration` with Postgres service. 5. Scheduled E2E with DinD LocalTerra (optional; document cost). ## Acceptance criteria - [ ] `.gitlab-ci.yml` includes at least contracts + frontend + indexer lib test jobs. - [ ] Jobs run on `merge_request_event` and default branch (with sensible `rules: changes:`). - [ ] Failed functional test blocks merge (no `allow_failure`). - [ ] `docs/testing.md` § CI lists new GitLab jobs alongside Make equivalents. ## Test plan - Push MR to validate pipeline; confirm jobs pass on green `main`. - Intentionally break `cosmesPatch127.test.ts` in draft MR — pipeline must fail. ## Attack / abuse test plan - Gitleaks still runs on same triggers. - CI secrets: no `VITE_DEV_MNEMONIC` in frontend build job (existing vite guard #118). ## Verification criteria - GitLab pipeline on `main` shows functional test jobs green after #411 child-9 test fixes land. - Reference parity table in MR description mapping `test.yml` jobs → GitLab jobs.
PlasticDigits commented 2026-06-25 14:13:23 +00:00 (Migrated from gitlab.com)

mentioned in issue #411

mentioned in issue #411
Brouie commented 2026-06-28 22:40:29 +00:00 (Migrated from gitlab.com)

mentioned in merge request !951

mentioned in merge request !951
Brouie commented 2026-06-29 07:52:30 +00:00 (Migrated from gitlab.com)

mentioned in merge request !953

mentioned in merge request !953
Brouie commented 2026-06-29 07:53:00 +00:00 (Migrated from gitlab.com)

Took the Phase-1 slice of this — wired the reference functional matrix into GitLab CI so a red functional test blocks merge instead of "GitLab green != functional pass." MR !953.

New test stage (MR + default branch, change-gated, no allow_failure):

  • test-contracts (cargo test)
  • test-indexer-lib (cargo test --lib)
  • test-frontend (lint + vitest)
  • test-frontend-build (npm run build = tsc -b + vite) — the gate that actually matters here. The pipeline never ran a cold tsc -b, which is why type-only breaks kept reaching main (#246 + four more across the #337 thread, the latest the spendableRaw bigint/string one this week). lint + vitest don't catch those; the build does. It also re-asserts #117 (no prod sourcemaps) for free.

Phase 2 (Postgres-backed indexer integration + Playwright E2E) is heavier — service containers / DinD — so I left it for a follow-up, noted in the MR.

Docs updated (testing.md § CI, qa-invariants.md). The "break a draft MR and watch it fail" check from the test plan is just the first pipeline run. One thing that run validates: test-frontend's vitest includes the known terraExplorer localhost/127.0.0.1 artifact — green in CI historically, but if it surfaces red in the runner it needs an env-pin (known quantity, not a new break).

@PlasticDigits this is the CI gap I've flagged a few times (the tsc-only breaks slipping to main); !953 closes it for the fast gates. Your merge.

Took the Phase-1 slice of this — wired the reference functional matrix into GitLab CI so a red functional test blocks merge instead of "GitLab green != functional pass." MR !953. New `test` stage (MR + default branch, change-gated, no allow_failure): - `test-contracts` (cargo test) - `test-indexer-lib` (cargo test --lib) - `test-frontend` (lint + vitest) - `test-frontend-build` (`npm run build` = tsc -b + vite) — the gate that actually matters here. The pipeline never ran a cold `tsc -b`, which is why type-only breaks kept reaching main (#246 + four more across the #337 thread, the latest the `spendableRaw` bigint/string one this week). lint + vitest don't catch those; the build does. It also re-asserts #117 (no prod sourcemaps) for free. Phase 2 (Postgres-backed indexer integration + Playwright E2E) is heavier — service containers / DinD — so I left it for a follow-up, noted in the MR. Docs updated (testing.md § CI, qa-invariants.md). The "break a draft MR and watch it fail" check from the test plan is just the first pipeline run. One thing that run validates: `test-frontend`'s vitest includes the known `terraExplorer` localhost/127.0.0.1 artifact — green in CI historically, but if it surfaces red in the runner it needs an env-pin (known quantity, not a new break). @PlasticDigits this is the CI gap I've flagged a few times (the tsc-only breaks slipping to main); !953 closes it for the fast gates. Your merge.
PlasticDigits commented 2026-06-29 09:07:14 +00:00 (Migrated from gitlab.com)

mentioned in commit 5ce57c415e

mentioned in commit 5ce57c415e99ce2c9ab27e23287008c721dad282
Brouie commented 2026-06-30 03:34:20 +00:00 (Migrated from gitlab.com)

Phase-2a: shipped the Postgres-backed indexer-integration job (the Phase-1 follow-up from !953).

Dry-ran the suite on origin/main (2a06048b) first — cargo test --tests -j1 -- --test-threads=1 = 542 passed / 0 failed across the full indexer/tests/ suite (incl api_limit_lower_bound 16, limit_clamp_guardrail 1, security 35, api_route_solve 24 + api_route_solve_db_hybrid 4). Gate is green on the current tree.

Then wired it in as test-indexer-integration:

  • postgres:16 service container (no DinD, no LocalTerra) — the harness (indexer/tests/common/mod.rs::setup_pool) runs sqlx::migrate!() itself, so the service just provisions the cl8y_legal role + dex_indexer_test DB
  • serial -j1 --test-threads=1 (the suite shares one dex_indexer_test DB; api_hooks false-fails under parallel access)
  • TCP readiness wait before cargo test (PgPool::connect does not retry, so it can race the service)
  • change-gated on indexer/** + .gitlab-ci.yml, no allow_failure — mirrors make test-indexer-integration
  • docs/testing.md CI parity row added

ci/lint on the merged config: valid, 0 errors / 0 warnings.

MR coming from my fork branch qa/421-ci-indexer-integration-phase2 (commit e64fc7d1). Cross-fork, so the target-side pipeline shows red / 0-jobs as usual — not a defect.

That leaves the last Phase-2 row — the scheduled DinD-LocalTerra Playwright E2E (heavier: browsers + a live chain). I'll scope that one separately; keep #421 open for it.

Phase-2a: shipped the Postgres-backed indexer-integration job (the Phase-1 follow-up from !953). Dry-ran the suite on origin/main (2a06048b) first — `cargo test --tests -j1 -- --test-threads=1` = 542 passed / 0 failed across the full indexer/tests/ suite (incl api_limit_lower_bound 16, limit_clamp_guardrail 1, security 35, api_route_solve 24 + api_route_solve_db_hybrid 4). Gate is green on the current tree. Then wired it in as test-indexer-integration: - postgres:16 service container (no DinD, no LocalTerra) — the harness (indexer/tests/common/mod.rs::setup_pool) runs sqlx::migrate!() itself, so the service just provisions the cl8y_legal role + dex_indexer_test DB - serial -j1 --test-threads=1 (the suite shares one dex_indexer_test DB; api_hooks false-fails under parallel access) - TCP readiness wait before cargo test (PgPool::connect does not retry, so it can race the service) - change-gated on indexer/** + .gitlab-ci.yml, no allow_failure — mirrors `make test-indexer-integration` - docs/testing.md CI parity row added ci/lint on the merged config: valid, 0 errors / 0 warnings. MR coming from my fork branch qa/421-ci-indexer-integration-phase2 (commit e64fc7d1). Cross-fork, so the target-side pipeline shows red / 0-jobs as usual — not a defect. That leaves the last Phase-2 row — the scheduled DinD-LocalTerra Playwright E2E (heavier: browsers + a live chain). I'll scope that one separately; keep #421 open for it.
Brouie commented 2026-06-30 03:35:00 +00:00 (Migrated from gitlab.com)

mentioned in merge request !971

mentioned in merge request !971
PlasticDigits commented 2026-06-30 03:54:27 +00:00 (Migrated from gitlab.com)

mentioned in commit 15b77176c6

mentioned in commit 15b77176c6814f6b30e4f9c66ce861e32632678e
Brouie commented 2026-06-30 11:06:55 +00:00 (Migrated from gitlab.com)

Phase-2a landed (15b77176), so the functional test stage is now fully wired on main — test-contracts, test-indexer-lib, test-indexer-integration, test-frontend, test-frontend-build, all change-gated, none allow_failure.

Heads up though: none of these have actually run green on main yet, and it's not the jobs' fault. The security stage sits ahead of test, and it's red on every recent main pipeline, so the whole test stage gets skipped before it can run. On the last completed main run (pipeline 2639532100, sha 4757f1a2):

  • security: gitleaks FAILED, cargo-audit-smartcontracts FAILED, cargo-audit-indexer FAILED, npm-audit-frontend FAILED (all allow_failure=false, script_failure); lint-indexer-log-secrets passed
  • test: test-contracts / test-indexer-lib / test-indexer-integration / test-frontend / test-frontend-build — all SKIPPED

Same shape going back ~12 pipelines. So the #421 verification criterion — "functional test jobs show green on hosted main" — can't be observed while the security stage is failing. The functional jobs themselves are fine: the integration suite dry-ran 542/0 locally and ci/lint is clean; this is purely that nothing downstream of a red security stage ever executes.

The failures are the advisory/scan gates from #380, not anything in the #421 jobs: cargo audit --deny warnings (both crates) and npm audit --audit-level=high are tripping on RUSTSEC/npm advisories, and gitleaks is failing its tracked-file scan. That's really a separate breakage from this issue, but right now it masks the entire point of #421 on the default branch — a red functional gate can never block a merge if the gate never runs.

Suggest triaging the security-stage failures on their own (likely their own issue) — pin/patch or risk-accept the advisories, and chase whatever gitleaks is catching. Once security goes green I'll confirm the test stage actually runs green on main and we can settle the non-E2E half of this. The scheduled DinD/LocalTerra Playwright E2E row is still the remaining open deliverable I'm keeping #421 open for.

@PlasticDigits

Phase-2a landed (15b77176), so the functional `test` stage is now fully wired on main — test-contracts, test-indexer-lib, test-indexer-integration, test-frontend, test-frontend-build, all change-gated, none allow_failure. Heads up though: none of these have actually run green on main yet, and it's not the jobs' fault. The `security` stage sits ahead of `test`, and it's red on every recent main pipeline, so the whole `test` stage gets skipped before it can run. On the last completed main run (pipeline 2639532100, sha 4757f1a2): - security: gitleaks FAILED, cargo-audit-smartcontracts FAILED, cargo-audit-indexer FAILED, npm-audit-frontend FAILED (all allow_failure=false, script_failure); lint-indexer-log-secrets passed - test: test-contracts / test-indexer-lib / test-indexer-integration / test-frontend / test-frontend-build — all SKIPPED Same shape going back ~12 pipelines. So the #421 verification criterion — "functional test jobs show green on hosted main" — can't be observed while the security stage is failing. The functional jobs themselves are fine: the integration suite dry-ran 542/0 locally and ci/lint is clean; this is purely that nothing downstream of a red security stage ever executes. The failures are the advisory/scan gates from #380, not anything in the #421 jobs: `cargo audit --deny warnings` (both crates) and `npm audit --audit-level=high` are tripping on RUSTSEC/npm advisories, and gitleaks is failing its tracked-file scan. That's really a separate breakage from this issue, but right now it masks the entire point of #421 on the default branch — a red functional gate can never block a merge if the gate never runs. Suggest triaging the security-stage failures on their own (likely their own issue) — pin/patch or risk-accept the advisories, and chase whatever gitleaks is catching. Once security goes green I'll confirm the `test` stage actually runs green on main and we can settle the non-E2E half of this. The scheduled DinD/LocalTerra Playwright E2E row is still the remaining open deliverable I'm keeping #421 open for. @PlasticDigits
Brouie commented 2026-06-30 18:38:11 +00:00 (Migrated from gitlab.com)

mentioned in merge request !980

mentioned in merge request !980
Brouie commented 2026-06-30 18:38:43 +00:00 (Migrated from gitlab.com)

Came back to the security-stage-red blocker I flagged before (note 3507509424). Two things going on, one I fixed and one that's on you.

The script failures — fixed, MR !980. The test stage never runs because the security stage exits non-zero first, and three real failures were stacking up there:

  • gitleaks was flagging the synthetic terra1ustcquote293 fixture in indexer/tests/common/mod.rs:384 as a leaked api-key. Widened the existing terra1 secret-allowlist bound in .gitleaks.toml from {38,} to {10,} so short test addresses are covered. Re-ran the tracked-tree scan, no leaks.
  • cargo-audit-indexer: anyhow 1.0.102 hit RUSTSEC-2026-0190 (downcast_mut unsoundness, published 06-25). Bumped to 1.0.103, lockfile only, indexer lib still 158/0.
  • npm-audit-frontend: ws <=7.5.10 (high-sev DoS) + undici + esbuild. npm audit fix, lockfile only, package.json untouched. The cosmjs/uuid moderate chain stays as the accepted risk in supply-chain-security.md (below the high gate).

All three verified locally: gitleaks clean, cargo audit --deny warnings exit 0, npm audit --audit-level=high --omit=dev exit 0, tsc -b clean.

The bigger blocker — needs you @PlasticDigits. Independent of the above, every main pipeline since ~14:50 is failing with failure_reason=ci_quota_exceeded on every job — the shared-runner CI minutes are exhausted. So even with !980 merged, nothing will run green until the runner minutes get topped up or a self-hosted runner gets wired in. The functional gates from this issue can't demonstrate green on main until that's resolved.

Came back to the security-stage-red blocker I flagged before (note 3507509424). Two things going on, one I fixed and one that's on you. **The script failures — fixed, MR !980.** The `test` stage never runs because the security stage exits non-zero first, and three real failures were stacking up there: - gitleaks was flagging the synthetic `terra1ustcquote293` fixture in `indexer/tests/common/mod.rs:384` as a leaked api-key. Widened the existing `terra1` secret-allowlist bound in `.gitleaks.toml` from `{38,}` to `{10,}` so short test addresses are covered. Re-ran the tracked-tree scan, no leaks. - cargo-audit-indexer: `anyhow` 1.0.102 hit RUSTSEC-2026-0190 (downcast_mut unsoundness, published 06-25). Bumped to 1.0.103, lockfile only, indexer lib still 158/0. - npm-audit-frontend: `ws` <=7.5.10 (high-sev DoS) + undici + esbuild. `npm audit fix`, lockfile only, package.json untouched. The cosmjs/uuid moderate chain stays as the accepted risk in supply-chain-security.md (below the high gate). All three verified locally: gitleaks clean, `cargo audit --deny warnings` exit 0, `npm audit --audit-level=high --omit=dev` exit 0, `tsc -b` clean. **The bigger blocker — needs you @PlasticDigits.** Independent of the above, every main pipeline since ~14:50 is failing with `failure_reason=ci_quota_exceeded` on *every* job — the shared-runner CI minutes are exhausted. So even with !980 merged, nothing will run green until the runner minutes get topped up or a self-hosted runner gets wired in. The functional gates from this issue can't demonstrate green on main until that's resolved.
PlasticDigits commented 2026-06-30 21:55:20 +00:00 (Migrated from gitlab.com)

mentioned in commit c1c5b9cf33

mentioned in commit c1c5b9cf339719921724081e02c342c2b98ecdcb
PlasticDigits commented 2026-07-01 05:22:50 +00:00 (Migrated from gitlab.com)

We are not using gitlab ci at this time due to cost

We are not using gitlab ci at this time due to cost
Brouie commented 2026-07-01 11:30:51 +00:00 (Migrated from gitlab.com)

Got it @PlasticDigits — parking this, no GitLab CI for now on cost.

The functional coverage this issue was after still lives in the Make targets, so nothing regresses: make test-contracts (456/0), make test-frontend (vitest), cd indexer && cargo test --lib (167/0) plus the integration suite (561/0 serial). If hosted CI ever comes back on the table, the Phase-1 jobs and the test-indexer-integration job I drafted are ready to wire in.

Got it @PlasticDigits — parking this, no GitLab CI for now on cost. The functional coverage this issue was after still lives in the Make targets, so nothing regresses: make test-contracts (456/0), make test-frontend (vitest), cd indexer && cargo test --lib (167/0) plus the integration suite (561/0 serial). If hosted CI ever comes back on the table, the Phase-1 jobs and the test-indexer-integration job I drafted are ready to wire in.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-07-07 06:37:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#421
No description provided.