Uh oh!
There was an error while loading. Please reload this page.
ci: give the turbo test task something that can genuinely fail - #112
Merged
Conversation
`pnpm turbo run test` — the last step of the required `build` job — executed zero tasks, because no package in the workspace declared a `test` script. A green step that cannot go red reads in CI exactly like one that is protecting something. Add `@objectos/ci-scripts`, a workspace package whose `test` script runs the self-tests the repository's CI scripts declare — today that is `check-translation-output.mjs --self-test`, 20 fixtures asserting every rule it enforces has a case able to make it fail. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Yaqu7kmKZM3tRPd9Y4xivo
This was referenced Aug 18, 2026
os-elon
marked this pull request as ready for review
August 18, 2026 15:58
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#72
The problem, reproduced on this branch's base
pnpm turbo run test— the last of the three steps in the requiredbuildjob — executed zero tasks. No package in the workspace declared atestscript, so the step passed by having nothing to do:What this does
Adds
@objectos/ci-scripts(tools/ci-scripts/), a workspace package whosetestscript runs the self-tests the repository's CI scripts declare. Today that is one:check-translation-output.mjs --self-test, which drives 20 fixtures and asserts both that every case fires exactly the rules it declares and that every rule the script enforces has a fixture able to make it fail.pnpm turbo run testnow reports 1 task, and the step exits 1 when the self-test does.ci.ymlis not touched. The step was already correct; it had nothing to find.Where the runner lives, and why
The scripts stay at
.github/scripts/— the workflows invoke them by that path. Turbo only discovers tasks in workspace packages, so the runner needs a package. Atestscript onapps/docswould claim to test the docs site, which is the same species of misleading signal this card is about, so the runner gets a package of its own andpnpm-workspace.yamlgrows atools/*entry. The only lockfile change is the new importer (2 lines).Turbo caching
Turbo hashes a package's own directory by default, so an edit under
.github/scripts/would have replayed a cached green. Thetesttask now names the dependency explicitly, following the patternturbo.jsonalready uses forcontent/docs/**:i18n.tsis in there because the self-test reads it for the locale list. Verified by hash rather than by reading the config: editing the script moved@objectos/ci-scripts#testfromcc46e783b02e6cfcto9cde36a4a663c5bc, and restoring it brought the hash back.Keeping the step from going inert again
Two guards in the runner, both loud rather than skipping:
.github/scripts/that dispatches a self-test flag but is not listed is a failure naming the file, so a future self-test joins the CI step by being written rather than by someone remembering the list.The second guard is best-effort by construction and says so in the source: it matches the quoted flag literal, not the words in a comment, and a script spelling its flag some third way goes unnoticed. It narrows the gap; the empty-list guard is the one that closes it.
Proof it can go red
Not inferred — reproduced. Weakening a rule the step covers (making
checkUnsafereturn no findings):Restoring the file:
Tasks: 1 successful, 1 total, exit 0.Both inertness guards were reproduced the same way — emptying the list fails; a fixture script under
.github/scripts/that dispatches the flag without being listed fails and names itself; a script that only mentions the flag in a comment does not fire it.What this does not claim
The self-test is not newly executed in CI.
translations.ymlhas run it since it landed, and its path filter includes.github/scripts/check-translation*.mjs. What changes is where it runs:Translationsis not a required check —buildis the only one — so a red self-test there does not block a merge today;translations.ymlhas nomerge_group:trigger, so nothing runs it inside the merge queue.ci.ymldoes.So the honest description of the gain is enforcement and merge-queue coverage, not new coverage. The duplication is deliberate and costs about half a second; whether
translations.ymlshould keep its own copy of the step is a maintainer call and is not made here.Deliberately not run by this step:
check-translations.mjsandcheck-translation-ownership.mjs. Neither declares a self-test mode, and running them for real would make the requiredbuildjob fail on the corpus's translation debt — which is theTranslationsworkflow's job, and reported-not-blocking there by design.Gates
Clean install, then the
buildjob's steps in order, all on34a8f00:pnpm install --frozen-lockfilepnpm turbo run type-check --continuepnpm turbo run buildpnpm turbo run testTranslation checks unaffected:
check-translations.mjsexit 0,check-translation-ownership.mjswith a changed-files list exit 0,check-translation-output.mjs --reportexit 0.Generated by Claude Code