Skip to content

fix: keep publish-profile CLI tests deterministic - #1659

Merged
kang-heewon merged 5 commits into
trunkfrom
fix/1652-cli-publish-tests
Aug 1, 2026
Merged

fix: keep publish-profile CLI tests deterministic#1659
kang-heewon merged 5 commits into
trunkfrom
fix/1652-cli-publish-tests

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jul 31, 2026

Copy link
Copy Markdown
Member

Outcome

  • Keeps the default @croco/cli test task deterministic by preventing the shell from expanding its integration-test exclusion into unintended Vitest include paths.
  • Preserves integration coverage through the separate cli-e2e publish gate.
  • Makes failed, timed-out, and interrupted verification commands diagnosable through complete downloadable stdout/stderr artifacts while retaining bounded report excerpts and memory use.
  • Finalizes partial evidence on interruption and escalates non-cooperative child processes after a bounded grace period.

Verification

  • NPM_CONFIG_PROVENANCE=true pnpm verify:publish -- --base origin/trunk --head HEAD --allow-pending-release-metadata — 40/47 passed, 7 not applicable, 0 failed.
  • pnpm --filter @croco/cli test — 30 files and 274 tests passed; integration files were not selected.
  • pnpm exec vitest run scripts/tests/release-spine-evidence.spec.ts scripts/tests/verification-manifest.spec.ts --config vitest.config.ts — 39 tests passed.
  • Interruption regression — 10 consecutive focused runs passed with a SIGTERM-ignoring child.
  • Pre-push repository gates — 234 test tasks and 233 typecheck tasks passed.
  • Targeted Oxlint, Oxfmt, and git diff --check passed.

Review gates

Correctness

  • Claim: the publish-profile CLI failure came from unquoted shell glob expansion, and the fix does not remove integration coverage.
  • Evidence: the old command expanded to three integration paths and caused two e2e files to run as includes; the quoted command runs only the 30-file unit suite, while cli-e2e passes independently.
  • Verdict: pass.

API, security, and release

  • Claim: no public API, dependency, lockfile, or package-boundary contract changes.
  • Evidence: the publish public-API gate passed, a patch changeset covers @croco/cli, and failure logs use the existing access-controlled verification artifact upload.
  • Verdict: pass.

Maintainability

  • Claim: evidence remains memory-bounded without losing complete failure diagnostics.
  • Evidence: report buffers stay bounded, command output streams to per-check files, successful files are discarded, and failure/timeout/interruption lifecycle tests cover cleanup and forced termination.
  • Verdict: pass.

Residual risk

Failure artifacts contain the output emitted by repository verification commands. They are retained only for unsuccessful or interrupted checks and inherit the existing GitHub Actions artifact visibility.

Fixes #1652

Summary by CodeRabbit

  • 개선 사항

    • 명령 실행 중 오류, 시간 초과 또는 중단이 발생해도 전체 표준 출력과 오류 로그를 증거 아티팩트로 보존합니다.
    • 실행 중 출력 메모리를 제한해 대용량 로그에서도 안정성을 높였습니다.
    • 중단 신호를 감지하면 프로세스를 정상적으로 종료한 뒤 필요 시 강제 종료하며, 결과 보고서와 종료 코드에 반영합니다.
    • 성공한 실행의 임시 로그는 자동으로 정리됩니다.
  • 검증

    • 패키지 바이너리 및 CLI 테스트 범위를 확대하고 릴리스 검증의 일관성을 높였습니다.
    • 게시 설정을 반영한 패키지 매니페스트와 빌드 대상을 자동으로 검증합니다.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

CLI 테스트 계약과 패키지 바이너리 검증 범위를 확장했습니다. 릴리스 증거 실행기는 stdout/stderr 로그 보존, 출력 버퍼 제한, 파일 쓰기 오류 처리, 인터럽트 종료 및 종료 코드 보고를 지원합니다. 관련 동작 검증 테스트도 추가했습니다.

Changes

검증 계약 및 패키지 범위

Layer / File(s) Summary
CLI 테스트 실행 계약
packages/cli/src/tests/CliTestContract.spec.ts, .changeset/327f9106.md
일반 테스트가 통합 테스트를 제외하고 test:e2e가 통합 테스트를 실행하는지 검증합니다. CLI 패치 릴리스 기록도 추가했습니다.
패키지 바이너리 검증 범위
scripts/package-manifest-contracts.mjs, scripts/package-bin-smoke.mts, scripts/verification-manifest.mts, scripts/tests/package-manifest-contracts.spec.ts, scripts/tests/verification-manifest.spec.ts
publishConfig를 반영한 유효 게시 매니페스트를 공통 함수로 계산합니다. 바이너리 패키지 목록과 Turbo 빌드 필터를 동적으로 관리하고 검증합니다.

릴리스 증거 실행기

Layer / File(s) Summary
명령 출력 캡처 및 정리
scripts/release-spine-evidence.mts
stdout/stderr를 파일에 스트리밍하고 메모리 버퍼 길이를 제한합니다. 파일 초기화, 부분 쓰기, writer 오류 및 로그 완전성 상태를 처리합니다.
인터럽트 및 증거 아티팩트 처리
scripts/release-spine-evidence.mts
활성 명령에 신호를 전달하고 유예 후 강제 종료합니다. 실패·타임아웃·중단 로그를 보존하고 인터럽트 상태와 종료 코드를 보고합니다.
출력 및 인터럽트 동작 검증
scripts/tests/release-spine-evidence.spec.ts
출력 파일 생성, 전체 로그 보존, 메모리 발췌 제한, 성공 로그 삭제, 파일 오류, 부분 쓰기, 타임아웃 및 중단 상태를 검증합니다.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant interruptActiveCommand
  participant CommandRunner
  participant runChecks
  participant ArtifactDirectory
  CLI->>interruptActiveCommand: 인터럽트 신호 전달
  interruptActiveCommand->>CommandRunner: 활성 명령 종료 요청
  runChecks->>CommandRunner: 명령 실행 및 출력 수집
  CommandRunner->>ArtifactDirectory: stdout/stderr 로그 기록
  runChecks->>ArtifactDirectory: 실패·타임아웃·중단 로그 보존
  runChecks->>CLI: 보고서와 종료 코드 반환
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 publish-profile에서 CLI 테스트를 결정적으로 실행하는 PR의 주요 변경을 정확히 설명합니다.
Linked Issues check ✅ Passed #1652의 결정적 CLI 테스트 실행과 전체 실패 증거 보존 요구를 구현하고 관련 회귀 테스트로 검증했습니다.
Out of Scope Changes check ✅ Passed 모든 변경은 publish-profile 검증, 실패 증거 보존, CLI 테스트 결정성 또는 관련 계약 검증에 해당합니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1652-cli-publish-tests

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 commented Jul 31, 2026

Copy link
Copy Markdown

📊 Benchmark Results

✅ All benchmarks passed

Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 9.2μs 30.0ms 8.2μs +12.7% -
CrocoApp lambdaHandler (10 controllers) 322.9μs 50.0ms 258.4μs +24.9% -
Lambda cold-start simulation 456.2μs 80.0ms 418.1μs +9.1% -
Lambda cold-start with headers 401.3μs 80.0ms 369.7μs +8.6% -
Lambda cold-start with binary body 379.9μs 80.0ms 339.1μs +12.0% -
Lambda cold-start with query params 322.0μs 80.0ms 301.3μs +6.9% -
Lambda cold-start with authorizer context 321.6μs 80.0ms 299.8μs +7.3% -
Lambda cold-start realistic scenario 321.4μs 80.0ms 299.2μs +7.4% -
EventBusConfig.start (10 handlers) 1.6μs 10.0ms 1.4μs +14.0% -
EventPublisher.publishNow single event 1.8μs 2.0ms 1.7μs +7.8% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.1μs +0.0% -
Container.get singleton (cold) 80.0μs 5.0ms 70.3μs +13.9% -
Container.register × 50 components 3.5ms 10.0ms 3.2ms +7.6% -
Container.validate (50 components) 4.0ms 20.0ms 3.4ms +16.7% -
Container.get singleton (warm) 1.7μs 500.0μs 1.6μs +6.7% -
TelemetryRuntime.init (lambda preset) 2.3μs 200.0ms 1.1ms -99.8% -
lambdaPreset config creation 1.5μs 2.0ms 1.4μs +5.7% -

Updated: 2026-08-01T12:40:55.716Z · Commit: 6cac67b

@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: 2

🤖 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 `@scripts/release-spine-evidence.mts`:
- Around line 477-478: Update openCommandOutput and the
child.stdout/child.stderr data handlers in defaultCommandRunner to catch
filesystem errors from mkdirSync, openSync, and writeSync, converting them into
the command’s handled failure path rather than uncaught exceptions. Ensure a
single runner() failure is contained by runReleaseSpineEvidence so remaining
checks and final report generation still execute, including during
interruption/finalization.
- Around line 668-700: Update persistFailedCommandOutput so each stdout.log and
stderr.log is overwritten with the current result output regardless of whether
the file already exists. Preserve the existing artifact-reference construction,
including fresh: true, only after replacing any stale log contents.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cbe1cad4-2796-4c0a-9a2d-fff86f597f32

📥 Commits

Reviewing files that changed from the base of the PR and between 889bacd and 883f753.

📒 Files selected for processing (5)
  • .changeset/steady-cli-unit-tests.md
  • packages/cli/package.json
  • packages/cli/src/tests/CliTestContract.spec.ts
  • scripts/release-spine-evidence.mts
  • scripts/tests/release-spine-evidence.spec.ts

Comment thread scripts/release-spine-evidence.mts Outdated
Comment thread scripts/release-spine-evidence.mts
@kang-heewon
kang-heewon force-pushed the fix/1652-cli-publish-tests branch from 883f753 to 85e004c Compare July 31, 2026 16:24
@kang-heewon

Copy link
Copy Markdown
Member Author

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@kang-heewon
kang-heewon force-pushed the fix/1652-cli-publish-tests branch 2 times, most recently from 546ad8d to 3f9138a Compare July 31, 2026 17:21
@kang-heewon
kang-heewon force-pushed the fix/1652-cli-publish-tests branch from 3f9138a to 6beb2f0 Compare July 31, 2026 18:26

@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: 6

Caution

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

⚠️ Outside diff range comments (1)
scripts/release-spine-evidence.mts (1)

1446-1481: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

interruptSignalnull로 좁혀져 종료 코드 분기가 타입 오류가 됩니다.

interruptSignalmain 본문에서 초기값 null만 가집니다. 중첩 클로저 interrupt는 후속 호출로서 변수 타입 변경을 가능하게 만드는 것처럼 보여, 그後の 참조가 재확정됩니다. 따라서 interruptSignal === "SIGINT" 비교가 TS2367을 발생시킬 수 있습니다.

가변 홀더 객체를 사용하면 이 좁혀짐을 피할 수 있습니다.

🐛 홀더 객체 적용 제안
-  let interruptSignal: NodeJS.Signals | null = null;
-  const interrupt = (signal: string) => {
-    interruptSignal = signal as NodeJS.Signals;
-    interruptActiveCommand(interruptSignal);
+  const interruptState: { signal: NodeJS.Signals | null } = { signal: null };
+  const interrupt = (signal: string) => {
+    interruptState.signal = signal as NodeJS.Signals;
+    interruptActiveCommand(interruptState.signal);
     console.error(`release-spine-evidence: interrupted by ${signal}`);
   };
-    getInterruptSignal: () => interruptSignal,
+    getInterruptSignal: () => interruptState.signal,
   exit(
-    interruptSignal
-      ? interruptSignal === "SIGINT"
+    interruptState.signal
+      ? interruptState.signal === "SIGINT"
         ? 130
         : 143
       : report.status === "passed"
         ? 0
         : 1,
   );
🤖 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 `@scripts/release-spine-evidence.mts` around lines 1446 - 1481, Update the
interrupt state used by main and the nested interrupt callback to store the
signal in a mutable holder object rather than a directly captured
interruptSignal variable, preventing TypeScript from narrowing it to null. Read
the holder’s current signal when passing getInterruptSignal and when selecting
the final exit code, preserving the existing SIGINT, SIGTERM, and report-status
behavior.
🤖 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 `@scripts/release-spine-evidence.mts`:
- Around line 800-824: Mark fallback artifacts as truncated when fileComplete is
false so consumers can distinguish them from complete streamed logs. Update the
artifact result construction near wroteCurrentOutput to include a clear
truncation indicator in the label or copyError, while preserving normal metadata
for fileComplete === true and existing write-error reporting.
- Around line 786-799: Update the array passed to map in
persistFailedCommandOutput with an explicit tuple type so each entry preserves
string, string, string, and boolean-or-undefined positions; use that typed
collection for the existing destructuring and file-writing logic so join,
writeFileSync, and EvidenceArtifactReference assignments receive their expected
types.
- Around line 828-836: Update discardCommandOutput so cleanup failures from
removing stdout.log or stderr.log are absorbed instead of escaping to
runReleaseSpineEvidence; use a force-enabled removal operation or catch and
ignore unlinkSync errors while preserving cleanup attempts for both files.

In `@scripts/tests/release-spine-evidence.spec.ts`:
- Around line 753-768: Update the commandOutputWriter callback’s stdout
detection to use the chunk-independent payload distinction described by the
test, such as identifying stdout via its character content rather than requiring
the full “stdout diagnostics” phrase in one chunk. Keep the ENOSPC throw and
partial stdout artifact assertion unchanged.

In `@scripts/tests/verification-manifest.spec.ts`:
- Around line 289-293: In the filter callback of the verification-manifest test,
remove the duplicated type-predicate declarations and retain exactly one valid
`pkg is ...` predicate before the arrow body. Preserve the existing private,
bin, and name checks and the narrowed package type.

In `@scripts/verification-manifest.mts`:
- Around line 417-420: affectsPackageBins()의 경로 판정에
packages/openapi-spec/src/**, packages/migration-runner/src/**,
packages/rpc-codegen/src/**를 추가해 해당 변경이 packageBinBuildArguments에 필터를 포함하도록
수정하세요. 각 패키지 변경 시 build 및 package-bins-smoke 명령이 적용되는지 검증하는 계약 테스트를 추가하고, 기존 경로의
동작은 유지하세요.

---

Outside diff comments:
In `@scripts/release-spine-evidence.mts`:
- Around line 1446-1481: Update the interrupt state used by main and the nested
interrupt callback to store the signal in a mutable holder object rather than a
directly captured interruptSignal variable, preventing TypeScript from narrowing
it to null. Read the holder’s current signal when passing getInterruptSignal and
when selecting the final exit code, preserving the existing SIGINT, SIGTERM, and
report-status behavior.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 91cd8a57-7c76-4ead-8ef3-2b1e54539d39

📥 Commits

Reviewing files that changed from the base of the PR and between 883f753 and 6beb2f0.

📒 Files selected for processing (6)
  • .changeset/327f9106.md
  • packages/cli/src/tests/CliTestContract.spec.ts
  • scripts/release-spine-evidence.mts
  • scripts/tests/release-spine-evidence.spec.ts
  • scripts/tests/verification-manifest.spec.ts
  • scripts/verification-manifest.mts

Comment thread scripts/release-spine-evidence.mts
Comment thread scripts/release-spine-evidence.mts
Comment thread scripts/release-spine-evidence.mts Outdated
Comment thread scripts/tests/release-spine-evidence.spec.ts Outdated
Comment thread scripts/tests/verification-manifest.spec.ts Outdated
Comment thread scripts/verification-manifest.mts
@kang-heewon

Copy link
Copy Markdown
Member Author

Addressed the actionable review findings in fc4b24e.

  • Added explicit stream tuple typing and clear bounded-fallback/truncation labels.
  • Made successful-command cleanup failure an observable per-check failure with COMMAND_OUTPUT_CLEANUP_FAILED, preserved fallback artifacts, and continued final report generation.
  • Made the partial-write regression independent of stream chunk boundaries.
  • Expanded package-bin applicability to every current public bin package and centralized publishConfig manifest override handling so the contract and smoke runner cannot drift.
  • The duplicate type-predicate report was not present on the reviewed source: the file contained exactly one predicate and the focused suite parsed and passed.
  • The outside-diff interruptSignal TS2367 report was reproduced against the repository TypeScript 6.0.3 toolchain and produced no TS2367, so the existing signal behavior was preserved.

Validation for fc4b24e: 53 focused tests passed; full release gates passed 43 files / 1,120 tests; Oxlint and repository Oxfmt checks passed; pre-push passed 234/234 test tasks and 233/233 typecheck tasks. Current-head GitHub CI is running.

@kang-heewon

Copy link
Copy Markdown
Member Author

@coderabbitai resolve

@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 `@scripts/release-spine-evidence.mts`:
- Around line 835-850: Update discardCommandOutput so it does not attempt to
delete the second log after the first deletion fails, and preferably validate
that both stdout.log and stderr.log are removable before deleting either file.
Preserve complete command evidence when cleanup cannot be completed, including
the failure path that invokes persistFailedCommandOutput.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 033c940a-534e-47b4-9c16-c6098e44023f

📥 Commits

Reviewing files that changed from the base of the PR and between 6beb2f0 and fc4b24e.

📒 Files selected for processing (7)
  • scripts/package-bin-smoke.mts
  • scripts/package-manifest-contracts.mjs
  • scripts/release-spine-evidence.mts
  • scripts/tests/package-manifest-contracts.spec.ts
  • scripts/tests/release-spine-evidence.spec.ts
  • scripts/tests/verification-manifest.spec.ts
  • scripts/verification-manifest.mts

Comment thread scripts/release-spine-evidence.mts
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@kang-heewon
kang-heewon merged commit 7b5e9e4 into trunk Aug 1, 2026
12 checks passed
@kang-heewon
kang-heewon deleted the fix/1652-cli-publish-tests branch August 1, 2026 12:54
Sign up for free to 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.

[ci] Keep publish-profile CLI tests deterministic and diagnosable

1 participant