Skip to content

ci: add L4 plugin-integration and sidecar-integration CI jobs#1840

Merged
liangshuo-1 merged 21 commits into
mainfrom
ci/plugin-integration
Jul 16, 2026
Merged

ci: add L4 plugin-integration and sidecar-integration CI jobs#1840
liangshuo-1 merged 21 commits into
mainfrom
ci/plugin-integration

Conversation

@zhaojunlin0405

@zhaojunlin0405 zhaojunlin0405 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds two offline, real-binary (L4) integration CI jobs that build a customer-style fork of the CLI and assert the observable command envelope:

  • plugin-integration — builds forks that register plugins through the extension/platform contract and checks the denial / observe / wrap / install / degrade behavior a real binary produces. This path only exists in a built binary, so unit tests cannot cover it.
  • sidecar-integration — builds the authsidecar-tagged binary and proves the transport interceptor signs outbound requests and that the resolved token reaches the upstream, using an in-test sidecar and a mock upstream.

The plugin job is motivated by #1764: a plugin integrated through the Go-module path was built without embedded API metadata and surfaced a confusing schema error. The new job exercises that exact real-binary path.

Changes

  • tests/plugin_e2e/ — new fork-build harness (harness.go) plus tests: registration smoke, Restrict denials (readonly / identity / denylist / multi-rule), install-time reason codes on broken forks, observe/wrap hooks, and offline degrade when a fork is built without embedded metadata.
  • tests/sidecar_e2e/roundtrip_test.goauthsidecar build-tag HMAC round-trip test with an in-test sidecar and mock upstream.
  • Makefile — add a sidecar-test target that builds and runs the authsidecar-tagged suite.
  • sidecar/server-demo/handler_test.go — repair compilation of the demo server test.
  • .github/workflows/ci.yml — add the plugin-integration and sidecar-integration jobs (run on pull_request, offline, no secrets, read-only GITHUB_TOKEN) and wire them into the results gate as observe-only (non-blocking).

Test Plan

  • go test ./tests/plugin_e2e/... — builds customer forks and asserts the denial / observe / wrap / install / degrade envelopes; verified green locally.
  • make sidecar-test (equivalently go test -tags authsidecar ./tests/sidecar_e2e/...) — HMAC round-trip; verified green locally.
  • Both jobs run offline in CI with a read-only token.
  • Regression check: reverting the fix: resolve schema against runtime metadata in plugin builds; gate cache overlay by version #1764 metadata fix makes TestDegradeStubMetadataSchema fail with the pre-fix error, confirming the job catches the regression.

Related Issues

Summary by CodeRabbit

  • Tests

    • Expanded end-to-end coverage for plugin diagnostics, restriction rules, observer/wrapper behavior (including panic/abort isolation), install failure modes, runtime degradation, credential-block scenarios, and smoke startup.
    • Added a Go-based plugin E2E harness that runs forked binaries in an isolated offline setup.
    • Added auth-sidecar E2E round-trip validation to confirm correct signing, verification, and header/token handling.
  • Chores

    • Updated CI with observe-only Level-4 integration jobs for plugin and sidecar scenarios.
    • Added a sidecar-test target for running sidecar-tagged checks.

The two new L4 jobs (plugin-integration, sidecar-integration) still run
on every PR and report status in the results summary, but their failure
no longer blocks the merge gate during the initial soak. Once they prove
stable, add them back to the results FAILED loop to make them required.
Merge the byte-identical assertInstallEnvelope into a single neutral
assertReasonCodeEnvelope shared by both policy-denial and install-time
reason_code tests. Reword the observer-panic-isolation comment to describe
the baseline-relative assertion instead of a hardcoded exit 0, and the
auditPlugin comment to say it is based on (not mirrors) the shipped example.
Extract the 230-line TestSidecarHMACRoundTrip into a short top-level flow
(start stubs -> build+run fork -> assert) backed by focused helpers: the
in-test sidecar handler splits into verifyProxyRequest (steps 0-4) and
forwardWithInjectedToken; the two httptest stand-ins become mockUpstream /
inTestSidecar types sharing a requestSink; build/run/assert move into
buildAuthsidecarFork, runFork, and the two assert* helpers. Behavior unchanged.
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds CI wiring for plugin and sidecar integration jobs, a shared plugin fork-testing harness with behavioral suites, and an authsidecar HMAC roundtrip test with a demo handler input update.

Changes

Plugin and sidecar integration coverage

Layer / File(s) Summary
CI and test command wiring
.github/workflows/ci.yml, Makefile
Adds observe-only integration jobs, result aggregation, and the sidecar-test target.
Plugin fork build and execution harness
tests/plugin_e2e/harness.go, tests/plugin_e2e/smoke_test.go
Builds committed-tree customer forks, runs isolated subprocesses, and verifies fork startup.
Plugin policy and lifecycle behavior tests
tests/plugin_e2e/restrict_test.go, tests/plugin_e2e/install_test.go, tests/plugin_e2e/observe_wrap_test.go, tests/plugin_e2e/diagnostics_test.go
Covers Restrict decisions, diagnostics, installation failures, lifecycle panics, observers, wrappers, and structured error envelopes.
Metadata and credential degradation tests
tests/plugin_e2e/degrade_subsystem_test.go
Tests missing metadata, seeded catalog resolution, and credential blocking under isolated execution.
Sidecar protocol roundtrip coverage
tests/sidecar_e2e/roundtrip_test.go, sidecar/server-demo/handler_test.go
Validates sidecar HMAC verification, header filtering, token injection, and core.Endpoints test inputs.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: feature

Suggested reviewers: liangshuo-1, liuxinyanglxy

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding plugin and sidecar integration CI jobs.
Description check ✅ Passed The description follows the template with Summary, Changes, Test Plan, and Related Issues sections.
Docstring Coverage ✅ Passed Docstring coverage is 90.48% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/plugin-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the size/M Single-domain feat or fix with limited business impact label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@064b3cb98880d2bb5f60b943185a2b201c9d3dbe

🧩 Skill update

npx skills add larksuite/cli#ci/plugin-integration -y -g

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (3)
.github/workflows/ci.yml (1)

54-54: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Set persist-credentials: false on the new checkouts.

Neither new job pushes or needs the credential after checkout, so persisting the token in .git/config is unnecessary attack surface. Static analysis (zizmor artipacked) flags both steps.

🔒 Proposed hardening (apply to both jobs)
       - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
+        with:
+          persist-credentials: false

Also applies to: 67-67

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 54, The checkout steps used by both CI jobs
need to disable credential persistence. Update the actions/checkout usage in the
workflow so the new checkouts set persist-credentials to false, since these jobs
do not push or need the token after checkout. Apply the change to each affected
checkout step in the workflow to remove the token from .git/config and match the
hardening guidance.

Source: Linters/SAST tools

tests/plugin_e2e/restrict_test.go (1)

49-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use assertReasonCodeEnvelope in TestReadonlyDenial to avoid duplicated assertion logic.

Lines 52-66 manually check the same envelope shape (exit 2, valid JSON, error.type=="validation", error.subtype=="failed_precondition", hint contains reason_code <X>) that assertReasonCodeEnvelope (lines 168-185) already encapsulates. If the envelope contract changes, both sites need updating.

♻️ Proposed refactor
 	for _, tc := range cases {
 		t.Run(tc.name, func(t *testing.T) {
 			res := run(t, bin, tc.args...)
-			if res.exit != 2 {
-				t.Fatalf("exit=%d stdout=%s stderr=%s", res.exit, res.stdout, res.stderr)
-			}
-			if !gjson.Valid(res.stderr) {
-				t.Fatalf("stderr not JSON: %s", res.stderr)
-			}
-			if got := gjson.Get(res.stderr, "error.type").String(); got != "validation" {
-				t.Errorf("error.type=%q want validation", got)
-			}
-			if got := gjson.Get(res.stderr, "error.subtype").String(); got != "failed_precondition" {
-				t.Errorf("error.subtype=%q want failed_precondition", got)
-			}
-			if hint := gjson.Get(res.stderr, "error.hint").String(); !strings.Contains(hint, "reason_code "+tc.reasonCode) {
-				t.Errorf("hint=%q want to contain reason_code %s", hint, tc.reasonCode)
-			}
+			assertReasonCodeEnvelope(t, res, tc.reasonCode)
 		})
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plugin_e2e/restrict_test.go` around lines 49 - 67, `TestReadonlyDenial`
is duplicating the reason-code envelope checks that already exist in
`assertReasonCodeEnvelope`; replace the inline assertions in the test loop with
a call to that helper using the `run` result and the expected `reasonCode`. Keep
the test focused on the readonly-denial cases and rely on
`assertReasonCodeEnvelope` for verifying exit code, JSON shape, `error.type`,
`error.subtype`, and the hint content.
tests/plugin_e2e/harness.go (1)

54-58: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Avoid shell invocation in gitArchive to eliminate command-injection pattern.

dst is internally constructed (os.MkdirTemp + filepath.Join) and shellQuote properly escapes it, so this is not exploitable. However, the bash -c + string-concatenation pattern is flagged by static analysis and sets a poor precedent. Use StdoutPipe to pipe git archive directly into tar without a shell:

♻️ Proposed refactor
 func gitArchive(root, dst string) error {
-	c := exec.Command("bash", "-c", "git archive HEAD | tar -x -C "+shellQuote(dst))
-	c.Dir = root
-	return runCmd(c)
+	gitCmd := exec.Command("git", "archive", "HEAD")
+	gitCmd.Dir = root
+	stdout, err := gitCmd.StdoutPipe()
+	if err != nil {
+		return err
+	}
+	tarCmd := exec.Command("tar", "-x", "-C", dst)
+	tarCmd.Stdin = stdout
+	if err := gitCmd.Start(); err != nil {
+		return err
+	}
+	if err := tarCmd.Start(); err != nil {
+		gitCmd.Process.Kill()
+		return err
+	}
+	if err := tarCmd.Wait(); err != nil {
+		gitCmd.Process.Kill()
+		return err
+	}
+	return gitCmd.Wait()
 }

Note: shellQuote, runCmd, and cmdError become dead code in this file after the refactor — consider removing them or confirming they're used elsewhere.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plugin_e2e/harness.go` around lines 54 - 58, Replace the shell-based
implementation in gitArchive with a direct process pipeline so it no longer uses
bash -c or string concatenation. Launch git archive with exec.Command, connect
its StdoutPipe to a tar process that extracts into dst, and run both commands
with proper error handling. After the refactor, check whether shellQuote,
runCmd, and cmdError are still referenced in harness.go and remove them if they
are now unused.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/ci.yml:
- Line 54: The checkout steps used by both CI jobs need to disable credential
persistence. Update the actions/checkout usage in the workflow so the new
checkouts set persist-credentials to false, since these jobs do not push or need
the token after checkout. Apply the change to each affected checkout step in the
workflow to remove the token from .git/config and match the hardening guidance.

In `@tests/plugin_e2e/harness.go`:
- Around line 54-58: Replace the shell-based implementation in gitArchive with a
direct process pipeline so it no longer uses bash -c or string concatenation.
Launch git archive with exec.Command, connect its StdoutPipe to a tar process
that extracts into dst, and run both commands with proper error handling. After
the refactor, check whether shellQuote, runCmd, and cmdError are still
referenced in harness.go and remove them if they are now unused.

In `@tests/plugin_e2e/restrict_test.go`:
- Around line 49-67: `TestReadonlyDenial` is duplicating the reason-code
envelope checks that already exist in `assertReasonCodeEnvelope`; replace the
inline assertions in the test loop with a call to that helper using the `run`
result and the expected `reasonCode`. Keep the test focused on the
readonly-denial cases and rely on `assertReasonCodeEnvelope` for verifying exit
code, JSON shape, `error.type`, `error.subtype`, and the hint content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b4ac0c7c-c256-45a0-bff1-7003a8f8367d

📥 Commits

Reviewing files that changed from the base of the PR and between 519a600 and 15eaaae.

📒 Files selected for processing (11)
  • .github/workflows/ci.yml
  • Makefile
  • sidecar/server-demo/handler_test.go
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/diagnostics_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/install_test.go
  • tests/plugin_e2e/observe_wrap_test.go
  • tests/plugin_e2e/restrict_test.go
  • tests/plugin_e2e/smoke_test.go
  • tests/sidecar_e2e/roundtrip_test.go

…ma catalog

Two plugin_e2e tests resolved differently on a clean CI runner than on a
developer box because they used run(), which inherits the host's ~/.lark-cli
metadata cache and network. On CI (cold cache, offline) they failed; locally
they passed.

- Replace TestSubsystemTransportAbort with TestRuntimeCatalogResolvesSchema.
  The transport round-trip it targeted is unreachable in a bare-module fork
  offline (credential resolution fails first); the transport path is covered
  end-to-end by the sidecar suite and the credential-block test. The new test
  seeds an obviously-synthetic service into a bare-module fork's on-disk cache
  and asserts `schema` resolves it from the runtime catalog -- the primary
  fix for #1764 (module builds now consult the runtime catalog instead of
  returning "Unknown service"). It complements the existing cold-cache degrade
  test, pinning both branches, and runs fully offline.
- Drop the readonly parent-group sub-case: mixed_children_policy needs a
  metadata-enumerated child tree the bare-module fork does not have, so offline
  it collapses to domain_not_allowed; that reason_code is covered by cmdpolicy
  unit tests.
- Fix errorlint in run() (errors.As), and stream `git archive` into `tar`
  through an explicit pipe instead of a shell in gitArchive.
- Set persist-credentials: false on the two new job checkouts and reuse
  assertReasonCodeEnvelope in TestReadonlyDenial.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/plugin_e2e/harness.go`:
- Around line 67-69: The shared stderr buffer in the test harness causes a data
race because `archive.Stderr` and `extract.Stderr` both write to the same
`strings.Builder`. Update `harness.go` so `archive.Run()` and `extract.Run()`
each use their own stderr buffer or a concurrency-safe writer, and then combine
or inspect the results after both commands finish. Use the `archive`, `extract`,
and `errBuf` setup in the harness to locate and split the shared writer.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b748ce86-3e34-41e4-bf09-43b4e97df1a6

📥 Commits

Reviewing files that changed from the base of the PR and between 15eaaae and eee38bb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/restrict_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci.yml
  • tests/plugin_e2e/restrict_test.go

Comment thread tests/plugin_e2e/harness.go Outdated
The previous run() inherited the host environment, so a fork's startup
metadata behavior depended on the developer machine's ~/.lark-cli cache
and live network. Tests passed locally but flaked on CI (e.g.
TestSubsystemCredentialBlock reaching a metadata fetch instead of the
credential block). Move the isolated, offline environment (fresh empty
LARKSUITE_CLI_CONFIG_DIR + LARKSUITE_CLI_REMOTE_META=off) into run()
itself and fold the per-file runEnv/runIsolated helpers into the shared
runWithEnv, so every test reproduces the bare-module customer state on
any machine, including CI. Tests needing runtime metadata still seed it
explicitly via runWithSeededCatalog.
archive.Stderr and extract.Stderr shared one strings.Builder; os/exec
spawns a stderr-copy goroutine per command, so git archive and tar (which
run concurrently) could write the builder simultaneously. strings.Builder
is not concurrency-safe, so go test -race would flag it on any run where
both processes emit stderr. Give each process its own buffer and report
the relevant one on failure. Flagged by CodeRabbit on PR #1840.
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.66%. Comparing base (f495cbb) to head (064b3cb).
⚠️ Report is 35 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1840      +/-   ##
==========================================
+ Coverage   74.40%   74.66%   +0.26%     
==========================================
  Files         860      878      +18     
  Lines       89215    91764    +2549     
==========================================
+ Hits        66384    68520    +2136     
- Misses      17701    17930     +229     
- Partials     5130     5314     +184     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Review feedback on the sidecar round-trip test surfaced two gaps:

1. False-green window: docs +fetch --as user routes TWO requests through
   the proxy — the mandatory /open-apis/authen/v1/user_info identity
   probe (enrichUserInfo verifies the sentinel UAT) and then the docs
   call. The sinks kept only the last request, so assertions could pass
   against the auxiliary probe. Capture every request per stub, track
   the HMAC verify outcome per request, and scope all assertions to the
   docs request (POST /open-apis/docs_ai/v1/documents/<doc>/fetch),
   additionally checking method and X-Lark-Proxy-Target=open.feishu.cn.

2. Real network egress: runFork did not set LARKSUITE_CLI_REMOTE_META=off,
   so the fork's startup metadata refresh hit the real
   open.feishu.cn/api/tools/open/api_definition, contradicting the
   offline/secret-free contract. Set it; the run is now fully offline.

runFork now also returns the fork's outcome and the test asserts exit 0
with an ok:true envelope, so the round trip must be a genuine end-to-end
success rather than bytes that happened to flow. The mock upstream
answers the identity probe with a parseable user_info body to keep the
user resolution clean.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/sidecar_e2e/roundtrip_test.go (1)

597-617: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Assert that proxy protocol headers never reach upstream.

The test validates token injection but would still pass if forwarding leaked HMAC signatures, timestamps, target, identity, or body-digest headers. Explicitly assert every sidecar.HeaderProxy* field and HeaderBodySHA256 is absent upstream.

Proposed assertion
 	if gotAuth != wantAuth {
 		t.Fatalf("mock upstream Authorization = %q, want %q", gotAuth, wantAuth)
 	}
+	for _, h := range []string{
+		sidecar.HeaderProxyVersion,
+		sidecar.HeaderProxyTarget,
+		sidecar.HeaderProxyIdentity,
+		sidecar.HeaderProxySignature,
+		sidecar.HeaderProxyTimestamp,
+		sidecar.HeaderProxyAuthHeader,
+		sidecar.HeaderBodySHA256,
+	} {
+		if value := got.headers.Get(h); value != "" {
+			t.Fatalf("mock upstream received proxy header %s: %q", h, value)
+		}
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/sidecar_e2e/roundtrip_test.go` around lines 597 - 617, Extend
assertInjectedTokenReachedUpstream to verify that every proxy protocol header
represented by sidecar.HeaderProxy* and sidecar.HeaderBodySHA256 is absent from
got.headers, failing with the header name and received value when any is
present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/sidecar_e2e/roundtrip_test.go`:
- Around line 82-90: Replace the strings.Contains-based request selectors
associated with docsReqMarker, including the additional selectors around the
referenced request-handling blocks, with exact path equality checks against
docsReqMarker. Ensure only the expected "/documents/<testDocToken>/fetch"
endpoint matches, rejecting incorrect prefixes, versions, document IDs, or
suffixes.

---

Outside diff comments:
In `@tests/sidecar_e2e/roundtrip_test.go`:
- Around line 597-617: Extend assertInjectedTokenReachedUpstream to verify that
every proxy protocol header represented by sidecar.HeaderProxy* and
sidecar.HeaderBodySHA256 is absent from got.headers, failing with the header
name and received value when any is present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5f6a0113-874f-442e-b2d3-d1d73140261f

📥 Commits

Reviewing files that changed from the base of the PR and between 5b23513 and 2487355.

📒 Files selected for processing (1)
  • tests/sidecar_e2e/roundtrip_test.go

Comment thread tests/sidecar_e2e/roundtrip_test.go Outdated
…ff upstream

Two CodeRabbit findings on the previous commit:

1. The docs-request selectors used strings.Contains, so a wrong API
   prefix or version (e.g. docs_ai/v2) could still match while the mock
   answers any path with a generic success. Select by the full exact
   path /open-apis/docs_ai/v1/documents/<doc>/fetch instead.

2. The upstream assertion proved token injection but would not notice
   the forward leaking sidecar wire-protocol headers. Assert every
   X-Lark-Proxy-* header and X-Lark-Body-Sha256 is absent from the
   forwarded docs request.
The coverage job's filter only excluded tests/cli_e2e, so the new
tests/plugin_e2e (no build tag) survived go list ./... and ran a second
time inside coverage — and since coverage sits in the results blocking
loop, a plugin_e2e failure would have blocked merges, defeating the
observe-only soft launch this PR establishes for plugin-integration.
Exclude the whole tests/ subtree: everything under it is an L3/L4 suite
with a dedicated job, the same rationale cli_e2e was excluded under.
(sidecar_e2e is tag-gated and never entered go list; verified
tests/plugin_e2e was the only survivor.)
- plugin_e2e/sidecar_e2e: strip the host's LARKSUITE_CLI_* namespace
  before composing fork environments. Appending overrides to a raw
  os.Environ() only isolated the variables we set; a developer machine
  exporting e.g. LARKSUITE_CLI_AUTH_PROXY leaked it into the fork,
  contradicting the determinism the harness comments claim. Verified by
  running both suites with hostile LARKSUITE_CLI_* exports.
- plugin_e2e: guard builtForks with a mutex — the map was safe only
  under the unstated convention that no test uses t.Parallel().
- plugin_e2e: name the 60s timeout in run()'s failure message instead
  of surfacing a bare exit=-1.
- sidecar_e2e: replace the overstated "mirrors steps 0-8 exactly"
  comment with a per-step coverage accounting (mirrored / replaced by
  assertion / not covered), renumber the in-test handler's step comments
  to match server-demo's, and mirror server-demo's step 1 timestamp
  presence check (server-demo enforces presence only; no freshness
  window exists there either).
- Makefile: document that integration-test builds ~20 plugin_e2e forks
  (~1 min warm, GOPROXY downloads when cold).
The results-job comment promised to add plugin-integration and
sidecar-integration back into the blocking loop "once they have proven
stable" with nothing holding that promise. Point it at issue #1894,
which carries the graduation criteria (4 consecutive weeks with zero
false positives).
@liangshuo-1
liangshuo-1 merged commit a6bc815 into main Jul 16, 2026
26 checks passed
@liangshuo-1
liangshuo-1 deleted the ci/plugin-integration branch July 16, 2026 05:47
@liangshuo-1 liangshuo-1 mentioned this pull request Jul 16, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants