ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ci: hard-fail e2e job and coverage gate - #358

Merged
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error
May 21, 2026
Merged

ci: hard-fail e2e job and coverage gate#358
moonming merged 3 commits into
mainfrom
fix/ci-flip-continue-on-error

Conversation

@moonming

@moonmingmoonming commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove continue-on-error: true from the e2e job (hard-fail on e2e regressions)
  • Flip the coverage-gate awk failure branch from exit 0 to exit 1 (gate becomes load-bearing)
  • Keep continue-on-error: true on the coverage-gate's coverage-e2e download with an explanatory comment, pending a follow-up that makes e2e actually emit coverage

Audit revision (commit fb5c415)

The first commit (57b7f03) also removed continue-on-error: true from the coverage-gate's coverage-e2e artifact download. An independent audit caught that the coverage-e2e artifact does not exist in this codebase: the e2e job runs pnpm test (vitest run) with no --coverage flag, so tests/e2e/coverage/lcov.info is never written; the upload step's if-no-files-found: ignore makes the absence silent. The "92.24% combined coverage" observed historically is unit-only coverage (the merge step's || cp "${files[0]}" "$merged" fallback collapses to it).

Removing the soft flag on that download would have hard-failed every CI run on Artifact not found for name: coverage-e2e — the same error the prior soft-failed runs were silently hiding. Commit fb5c415 restores that one soft flag with a comment.

The other two changes — hard-failing the e2e job and flipping the awk to exit 1 — stay. Unit coverage at 92.24% above the 90% threshold means the gate is meaningful for unit regressions.

Follow-up (separate PR)

Tracked in api7/AISIX-Cloud#398:

  1. Make the e2e job invoke pnpm coverage (or pass --coverage to pnpm test)
  2. Flip the e2e upload's if-no-files-found: ignoreerror so a missing artifact fails loudly
  3. After that lands, remove the restored soft flag from this PR

Risk

Low for the changes that remain. The e2e job has not actually failed in any of the last 19 real runs (the 20th was skipped because build-bin failed first). The audit confirmed those greens were real e2e successes, not soft-fails — only the coverage-gate's coverage-e2e download was relying on the soft flag.

Test plan

  • Diff is exactly 3 net changes (e2e continue-on-error removed, coverage-gate awk exit 1, coverage-e2e soft flag retained with explanatory comment)
  • Line numbers verified against origin/main
  • Independent audit performed (BLOCK → fix → new audit)
  • CI run on this PR is green
  • If e2e or coverage-gate goes red, investigate the underlying issue rather than reverting

Tracking

Closes 2 of 3 (v2-HIGH) items in Tier 1 of api7/AISIX-Cloud#398:

  • ci.yml:142continue-on-error: true on e2e job — closed
  • ci.yml:215 coverage-gate exit 0exit 1 — closed
  • ci.yml:200continue-on-error: true on coverage-e2e download — deferred to the follow-up PR (needs e2e to emit coverage first)

Refs #353.

Summary by CodeRabbit

  • Chores
    • CI updated to use a specific protoc setup action and tightened quality gates so e2e failures now fail the workflow.
    • Clarified e2e coverage handling: missing e2e coverage files are expected and tolerated during collection.
    • Combined coverage check now fails when coverage is below the configured threshold.

Review Change Stack

The e2e job has been gated by `continue-on-error: true` since the
harness landed; the comment said "flip to false once we have ~5
consecutive green runs on main". Recent CI history shows the last 20
runs of the e2e job at 19/19 success where the job actually executed
(1 skipped because build-bin failed first). The masking is no longer
load-bearing.
The coverage-gate's awk `exit 0` was likewise marked "soft during
scaffold milestones; flip to `exit 1` at PR #5". Current main hits
92.24% line coverage against the 90% default threshold — 2.24pp
margin, the gate is meaningful, the soft-fail is now a stale
no-op.
Three changes:
1. Remove `continue-on-error: true` from the e2e job (line 142).
2. Remove `continue-on-error: true` from the coverage-gate's
download-artifact step for coverage-e2e (line 200) — the
missing-artifact path is no longer reachable now that e2e is
hard-fail.
3. Flip the coverage-gate awk failure branch from `exit 0` to
`exit 1`. Drop the stale "flip at PR #5" comment.
Stale guidance comments at lines 139-141 and 214 are also removed so
reviewers don't re-add them on cargo-cult.
Tracking: api7/AISIX-Cloud#398 (Tier 1 v2-HIGH × 2).
CopilotAI review requested due to automatic review settings May 21, 2026 06:17
@coderabbitai

coderabbitaiBot commented May 21, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9ba095b7-a9b8-4137-ac0e-58474894c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between fb5c415 and 6ef6439.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Pin arduino/setup-protoc to v3.0.0 across several jobs, remove continue-on-error from the e2e job so failures fail the workflow, document that e2e runs without producing coverage artifacts, and make the coverage-gate exit with status 1 when combined coverage is below the threshold.

Changes

CI Workflow Hard Gates

Layer / File(s)Summary
Pin arduino/setup-protoc in jobs
.github/workflows/ci.yml
Bumped arduino/setup-protoc from @v3 to @v3.0.0 in lint, schema-drift, rust-unit, and build-bin jobs (four updated references).
E2E and coverage hard-gate enforcement
.github/workflows/ci.yml
Removed continue-on-error: true from the e2e job, added comments noting e2e runs vitest run without coverage/artifact, and changed the coverage-threshold failure exit to 1 so the workflow fails when combined coverage is below COVERAGE_THRESHOLD.

🎯 2 (Simple) | ⏱️ ~10 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens CI enforcement by converting the existing “soft” e2e and coverage checks into hard gates, so failures (or below-threshold coverage) will reliably fail the workflow instead of being silently tolerated.

Changes:

  • Removes continue-on-error: true from the e2e job so e2e failures fail CI.
  • Removes continue-on-error: true from the coverage-gate’s coverage-e2e artifact download so missing e2e coverage blocks the gate.
  • Makes the coverage threshold check fail the job (exit 1) when coverage is below the configured threshold.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 135 to 138
e2e:
name: e2e (vitest) + coverage
needs: [build-bin]
runs-on: ubicloud-standard-2
Comment on lines 193 to 196
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
The previous commit removed three `continue-on-error: true` instances
plus the `exit 0` soft-fail in the coverage gate. The audit agent
caught a real defect in one of those changes:
The `coverage-e2e` artifact does not actually exist on this
codebase. The e2e job invokes `pnpm test` which expands to
`vitest run` with NO `--coverage` flag (--coverage is only on the
separate `coverage` script), so `tests/e2e/coverage/lcov.info` is
never written. The e2e upload step has `if-no-files-found: ignore`
so the absence has always been silent: 3 sampled main runs
(26208667877, 26200775176, 26202404786) all show zero
coverage-e2e artifacts produced. The "92.24% combined coverage"
observed historically is in fact unit-only coverage; the merge
step's `|| cp "${files[0]}" "$merged"` fallback collapses to it.
Removing `continue-on-error: true` from the coverage-gate's
coverage-e2e download therefore would fail the gate's first step on
every run with `Artifact not found for name: coverage-e2e` — the
exact error visible in the prior soft-failed runs.
Restore the soft flag on that ONE download step with an explanatory
comment that the right fix is to make the e2e job emit coverage. The
other two changes from the previous commit stay:
- e2e job no longer has continue-on-error (this was always sound)
- coverage-gate awk failure branch stays `exit 1` (the threshold
is 90%, unit-only coverage is 92.24%, gate is meaningful)
Follow-up tracked separately: change e2e's `pnpm test` to invoke
coverage AND flip the upload's `if-no-files-found` from `ignore` to
`error` so a missing artifact fails loudly. After that lands, this
soft flag can also be removed.
The lint job has been intermittently failing on
`arduino/setup-protoc@v3` with `Error: unable to get latest version`.
The major-only `@v3` reference makes the action query the GitHub
releases API for the latest patch each run; that lookup is flaky
under GitHub API contention. Pin to v3.0.0 across all four use
sites to skip the latest-lookup entirely.
This is the same theme as the previous two commits — make CI
signal trustworthy. A lint job that fails on marketplace flake is
indistinguishable from a real lint failure and erodes trust in the
red signal we just made load-bearing.
CopilotAI review requested due to automatic review settings May 21, 2026 06:39

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +198 to +202
# written and no `coverage-e2e` artifact is produced. The upload
# step at ~L182 has `if-no-files-found: ignore` so the absence
# is silent. Until the e2e job actually emits coverage (tracked
# follow-up), this download must remain soft — otherwise the
# coverage-gate hard-fails every run on `Artifact not found`.
@moonming
moonming merged commit 5db8503 into mainMay 21, 2026
11 checks passed
@moonming
moonming deleted the fix/ci-flip-continue-on-error branch May 21, 2026 06:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@moonming