Repository navigation
test(harness): silence the :: runner-command output of the unit suite's call-through @actions/core spies - #605
Conversation
…emitting workflow commands
setup.ts mocks @actions/core with spy: true, so the real implementation still
runs and core.debug/info/warning/error/setFailed/setSecret write ::debug::,
::warning::, ::error:: and ::add-mask:: lines straight to process.stdout,
bypassing vitest's console capture. Under GitHub Actions the runner parses
them as workflow commands: the test:coverage step of a green build-test run
(job 121828647038) contained 61 ##[warning] and 18 ##[error] lines and the
check run carried ten failure and ten warning annotations, all test fixtures
("Codertocat is not a org member or collaborator", "status=500"), while
::add-mask::secret-key redacted a fixture string from the rest of the log and
setFailed set process.exitCode inside the worker. Locally the same lines were
~3k of the ~12.8k lines a run printed, burying the one genuine warning in the
output (a MaxListenersExceededWarning from @mswjs/interceptors in meow.test.ts).
A second setup file re-installs a no-op implementation on the output
functions before every test (mockReset: true restores the originals), keeping
the spies tests assert on while dropping the writes. 191 files / 2473 tests
pass unchanged and a full run now prints no :: line.
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Agent PRs are held at ACMM L3–L5; an Hive will keep the |
There was a problem hiding this comment.
Read the tree at b7ae47a and reproduced the mechanism rather than taking the body's word for it:
__tests__/setup.ts:4mocks@actions/corewith{ spy: true }, so the real output functions run and write::-prefixed workflow commands toprocess.stdout. Confirmed locally: withmain'svitest.config.mjs,npx vitest run __tests__/label/kind.test.tsalone emits 64 raw::lines; with this PR's config, the same files emit zero.- The per-test
beforeEachreinstall (__tests__/setupQuietActionsCore.ts:30-32) is required, not defensive:vitest.config.mjs:13setsmockReset: true, which restores a spy's original implementation between tests. A one-time install would silence only the first test per file. - Spy assertions survive: a no-op
mockImplementationstill records calls, and__tests__/issueCommentTest/meow.test.ts:249-260(setSecretspy +toHaveBeenCalledWith('secret-key')) passes — ranmeow.test.ts,authGuards.test.ts,kind.test.ts: 62/62 green. - The
__tests__/bundlesuite asserts on literal::warning::stdout (__tests__/bundle/meow.test.ts:142etc.), but it runsdist/index.jsin a child process (vitest.e2e-coverage.config.mjs:19: "The bundle only ever runs in a child process; vitest never imports it"), so the in-process mock cannot reach it. Not affected. - No test reads
process.exitCodeorGITHUB_OUTPUT, so neuteringsetFailed/setOutputside effects breaks nothing.
One deliberate trade-off worth naming, not a defect: no-oping setSecret means fixture strings are no longer ::add-mask::-ed in CI logs. Everything the suite passes to it is a hard-coded fixture (secret-key), so nothing real loses masking.
Looks correct to me — small, well-scoped, and it removes the false failure/warning annotations the runner was attaching to green runs. A human should do the final approve/merge.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
|
/kind cleanup 🐝 Hive Agent: — hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
|
Keeps #615's globalSetup entry in vitest.config.mjs alongside the new setup file. Unit suite on main writes 3218 '::' workflow-command lines to stdout; with setupQuietActionsCore.ts it writes none, 110 files pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Re-merged Verified locally: the unit suite on |
There was a problem hiding this comment.
Verified against the tree and by running the suite — looks correct to me.
The red build-test is not this PR's fault. Run 40905577513 fails only __tests__/adapters/app/webhookGuards.test.ts:126 ("expected { jobs: 'lgtm', 'dry-run': '' } to strictly equal { 'dry-run': '' }") — the pre-existing main breakage from #612+#614, which #616 fixes. Once #616 merges, a rebase/rerun should go green; nothing in this diff needs to change.
What I checked:
__tests__/setup.ts:7is indeedvi.mock('@actions/core', { spy: true }), so the real output functions run and write::workflow commands to stdout — the mechanism the body describes is real.vitest.config.mjs:13-15setsclearMocks/mockReset/restoreMocks, and vitest'smockResetrestores a spy's original implementation, so the per-testbeforeEachreinstall in__tests__/setupQuietActionsCore.ts:30-32is required, not defensive.- No test asserts
process.exitCode(onlysrc/server/main.ts:7sets it), so no-opingsetFailedloses nothing. - Ran
__tests__/label/kind.test.ts,handleIssueComment.test.ts,authGuards.test.ts,approveReview.test.tswith this PR applied: 124/124 pass and the output contains zero::lines; theexpect(core.warning/...)call assertions still work becausemockImplementation(() => {})keeps the spy recording.
Suggestion for whoever lands the queue: merge #616 first, then rerun this PR's checks.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Test Improvement
Stops the unit suite's call-through
@actions/corefrom emitting workflow commands. The shared setup file mocks@actions/corewithspy: true, socore.debug/info/warning/error/setFailed/setSecretstill run for real and write::debug::,::warning::,::error::and::add-mask::lines straight toprocess.stdout, bypassing vitest's console capture. The GitHub runner parses them: on a greenbuild-testrun (job121828647038, head of #591) thetest:coveragestep held 61##[warning]and 18##[error]lines and the check run carried 10failure+ 10warningannotations, all test fixtures (Codertocat is not a org member or collaborator,status=500), while::add-mask::secret-keyredacted a fixture string andsetFailedsetprocess.exitCodeinside the worker. Locally those lines were ~3k of the ~12.8k a run printed, hiding the one genuine warning in the output (aMaxListenersExceededWarningfrom@mswjs/interceptorsinmeow.test.ts).Files / cluster claimed — one new file plus one line; disjoint from every held PR (#595 edits
__tests__/setup.tsand #595/#598/#599/#603 editdocs/contributing.md, so neither is touched here; no held PR editsvitest.config.mjs):__tests__/setupQuietActionsCore.ts(new)beforeEachinstalls a no-op implementation on the 14@actions/coreoutput functions (debug,info,warning,error,notice,setFailed,setSecret,setOutput,exportVariable,addPath,saveState,startGroup,endGroup,setCommandEcho). Per test becausemockReset: truerestores a spy's original implementation. Spies stay — the 36expect(core.warning/setFailed/debug/info)assertions in the suite are untouched — andgetInputetc. remain real. Header comment carries the rationale.vitest.config.mjssetupFilesafter__tests__/setup.ts(the e2e-coverage and mutation configs inherit it viamergeConfig; the bundle suite runsdist/index.jsin a child process and was never affected)Testing
npx vitest run— 191 files, 2473 passed, 75 skipped; the full run now prints no::line (before: 2946::debug::, 57::warning::, 17::error::, 1::add-mask::), so theMaxListenersExceededWarningis the only stray output leftnpx vitest run __tests__/label/kind.test.ts __tests__/issueCommentTest/handleIssueComment.test.ts __tests__/utils/authGuards.test.ts __tests__/plugins/approveReview.test.ts __tests__/issueCommentTest/meow.test.ts(the files asserting oncore.*calls) — 164 passednpx eslint __tests__/setupQuietActionsCore.ts vitest.config.mjs— clean;npx tsc --noEmit— cleanRelated Issue
Closes #604
Filed by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88