Repository navigation
feat: run node-based actions from a uses reference on the host - #82
Conversation
A node action's action.yml names a runtime under runs.using, an entry file under runs.main, and optional entries around the job under runs.pre and runs.post with their pre-if and post-if conditions. The schema accepts the runtimes the runner itself names, node20, node16, node12 and node24, and shares the declared inputs and branding with the composite form so the two cannot drift apart. Anything else a runs.using can hold, docker included, is left to the expansion to reject with the file and pointer, because it names no execution this package performs.
A uses step naming a node action now expands like a composite one does. Its main entry becomes one neutral run step whose command is the host's node invocation followed by the entry's path, quoted word by word for a POSIX shell, with the mapped inputs in the environment as INPUT_ names, spaces to underscores and upper-cased the way the runner derives them, and GITHUB_ACTION_PATH injected as for a composite action's commands. The node binary itself comes from an injected port, so the library names no binary and the host decides what runs the entry. runs.pre and runs.post become run steps the caller places: pre before the job's own steps, post concatenated in expansion order and reversed after them, which is the order the runner's own phases use. A pre a local action declares is rejected, as GitHub documents it unsupported; metadata whose runs.using names neither a composite action nor a node runtime is rejected with the file and pointer wherever the expansion meets it, so only a docker:// reference, which resolves no tree, stays a provider step. The entry point is renamed expandAction for the two forms it now expands, and the error renamed ActionExpansionError to match.
Fixtures hold node20 and node16 metadata with inputs, defaults and hyphenated names, the INPUT_ derivation including a name with spaces, pre and post with pre-if evaluated through the base evaluator, the rejections for a local pre, an unknown interpreter and malformed node metadata, and an end-to-end run: a real entry file executed through the expanded command with the host's node, writing GITHUB_OUTPUT.
|
@codex security review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex security review |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
🎉 This PR is included in version 0.5.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Adds node-action execution to
@pipewright/pipeline-github-actions: the second half of running auses:step without a container (#71), on top of #81's composite expansion. The runner and CLI wiring is #76; this changes no consumer yet.runs.usingofnode20,node16,node12ornode24, withruns.mainand the optionalruns.pre,runs.pre-if,runs.postandruns.post-if, is modelled beside the composite schema, sharing the declared inputs and branding so the two forms cannot drift. The live metadata syntax documents onlynode20andnode24;node16andnode12are gone from the docs but remain runtimes actions/runner names, so an action pinned to them still expands. Anything else aruns.usingcan hold is rejected with the metadata file and pointer, docker with its own message naming the container runtime it needs.A node action expands like a composite one, at the workflow's own step or nested in one. Its
mainentry becomes one neutral run step whose command is the host's node invocation followed by the entry's path under the action's directory, each word quoted for a POSIX shell, because every host of this tool runs a step's command through one POSIX shell of its own. The mapped inputs ride in the step's environment asINPUT_<NAME>, spaces to underscores and upper-cased, which is the derivation the runner's ownAddInputsToEnvironmentapplies, andGITHUB_ACTION_PATHis injected as for a composite action's commands. The node binary comes from an injected port (NodeRunner, a peer ofActionResolver) returning the command and its leading arguments, so the library names no binary and a host decides whether an entry runs under thenodeonPATH, a pinned install or an absolute path.runs.preandruns.postbecome run steps the caller places rather than steps in the list:prebefore the job's own steps,postconcatenated in expansion order and reversed after them, which is how the runner's own phases order them (pre steps join the job before its steps inJobExtension.cs, post steps pop off a stack inStepsRunner.cs). An enclosing composite action propagates a nested action's pre and post the same way, so a phase declared at any depth reaches the job's phases rather than the middle of a step list. The conditions default to the documentedalways()and evaluate through the base evaluator against the caller's context. Aprea local action declares is rejected with the pointer, because GitHub documentspreas not supported for local actions; a post needs no such rule.The entry point is renamed
expandActionwith a richer return (ActionExpansion: steps, pre, post), andCompositeActionErrorbecomesActionExpansionError, since both now cover two forms of action. Nested handling changed with it: a nested node action now expands, where previously every non-composite nested action stayed a provider step, so only adocker://reference, which resolves no tree to read, remains a provider step; metadata naming docker or an unknown interpreter is rejected at any depth, as the issue states.Tests cover node20 and node16 fixtures and every runtime, the
INPUT_derivation including a name with spaces, pre and post with pre-if, the local-pre, docker, unknown-interpreter and malformed-document rejections by pointer, nested expansion carrying a post, and an end-to-end run: a real entry file executed through the expanded command with the host's node, writingGITHUB_OUTPUT.Fixes #75