Repository navigation
Conversation
The new `published` job runs only when the caller's workflow ran on `schedule` or `workflow_dispatch`. It reads the caller's own package name, installs `<name>@latest` from npm into a clean directory outside the workspace as an anonymous user, loads every entry point by name with `import` and with `require`, and runs the synthetic smoke sample the caller names in the new optional `published-smoke-sample` input (default empty: the import only). An entry that is not JavaScript, such as a tsconfig or prettier config JSON file, is resolved and not parsed. The ESM arm stats what it resolved, because `import.meta.resolve` does not check that the file exists. `scripts/published-check.mjs` reuses install-check.mjs's clean room, anonymous npm environment and allow-listed probe environment rather than restating them. It fails closed: nothing is published by this job, so a red run is the finding, and the annotation leads with npm's own error code. test/published-check.test.mjs runs the step's own command from ci.yml in copies of fixture callers against a registry on localhost: the good caller passes, a deliberately wrong name fails on E404, a failing sample, a dropped ESM build and a missing JSON entry fail, and a config package passes with its entries resolved. The job-id and input pins in three suites record `published` and `published-smoke-sample` as additions. No caller has a `schedule` trigger today, so this changes no caller's runs until one adds it. Harness-Task: 109 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Escape backslashes before pipes in the step summary's table cells (js/incomplete-sanitization). A `\|` already in a check's detail would otherwise end the cell early. A test now pins the escaped form. - Run the probes and the copied smoke sample by constant file names with the clean room as `cwd`, so no path built from `RUNNER_TEMP`, `tmpdir()` or the command line is passed to a child process as an argument (js/indirect-command-line-injection and js/shell-command-injection-from-environment, both reported at the shared runner's `spawn` in install-check.mjs). - Tell sample authors to prefer `.mjs` or `.cjs`. The clean room has no `"type"`, so a `.js` sample in ESM syntax relies on Node's module detection (a reviewer note). Harness-Task: 109 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 free
to 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.
What changed
ci.ymlgains apublishedjob that tests the caller's published package the way users install it, on the days between releases.release.yml's install gate asks that question once, right after a publish. This job asks it again on every scheduled run, because a dependency or a Node release can break an install when nothing in the caller changed.scheduleorworkflow_dispatch(if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}). In a called workflowgithubis the caller's context. On a push or a pull request the job is skipped, so callers see a new skippedpublishedcontext that no ruleset requires. It has noneeds:and nocontinue-on-error.scripts/published-check.mjs):package.json(a"private": trueroot fails, saying there is nothing published to test);npm install <name>@latestas an anonymous user in a clean room underRUNNER_TEMP, never inside the checkout. Nothing is installed in the workspace. The clean room, the anonymous npm environment,--ignore-scriptsand the allow-listed child environment are imported frominstall-check.mjs, not copied;importand once withrequire, each in its own process;.js/.mjs/.cjs(for example@cosyte/prettier-config's./index.json, or@cosyte/tsconfig's./base.jsonand./library.json, which has no.export) is resolved withimport.meta.resolveandrequire.resolveand not loaded. On Node 24.22.0,import.meta.resolvereturned a URL for an export map entry pointing at a missing file, so the ESM arm also stats the resolved file.published-smoke-sample(string, default""). It names one self-contained.mjs/.cjs/.jsfile in the caller's checkout. The file is copied into the clean room and run there. Empty means the job only installs and imports.::errorannotation starts with npm's own error code (E404 ...,ETIMEDOUT ...), so you can tell a missing package from a registry outage at a glance.node-versions, so a broken Node release is caught. It does not use theosaxis, because the clean room is built for GitHub-hosted Linux.ci.ymlrow documents the job and the input. A new section, "The scheduled check of the published package", shows a caller turning it on.Callers. None of the library callers has a
schedule:orworkflow_dispatch:trigger on its CI workflow today. I read each.github/workflows/ci.ymlonmainon 2026-10-19. Until a caller adds one, the job is skipped for every caller.scripts/reference-publish.mjsreports the change asinput-added(act: false) forpublished-smoke-sampleandjob-added(act: true) forpublished, which is a new check-run context.How it was checked
test/published-check.test.mjs(25 tests) takes the step's ownrun:command out ofci.ymland runs it in copies of fixture callers (test/fixtures/published-check/). It runs against a registry on localhost that serves the fixtures afternpm pack, so real npm installs a real tarball and Node imports it both ways. The only thing the test adds to the command is the registry URL.E404.import.if:, no workspace install, the tooling checked out atjob.workflow_sha,persist-credentials: falseon both checkouts, and the input's type and default. Widening theif:topushmakes this test fail.The job-id and input pins in
test/ci-docs-content.test.mjs,test/skipped-required-context.test.mjsandtest/workflow-sha.test.mjsnow includepublishedandpublished-smoke-sample, recorded as additions rather than renames.I also ran the script by hand against the live registry:
@cosyte/hl7,@cosyte/tsconfigand@cosyte/prettier-configatlatest(0.1.0) passed, and@cosyte/no-such-package-109failed onE404.One thing I found while writing the tests: the script compares real paths to decide whether it is the entry point. Comparing
import.meta.urlwith the rawprocess.argv[1]treats a script run through a symlinked directory as not the entry point, so it exits 0 having checked nothing. A real checkout has no symlink, but a silent pass is the wrong failure mode.I did not run any
workflow_dispatchor scheduled run of a caller.Harness-Task: 109
🤖 Generated with Claude Code