API surface¶
Hollywood's current application programming interface (API) surface is intentionally small.
Parallel workflow steps¶
Use GitHubParallelStep to group independent work explicitly. Hollywood renders
each command and preserves the group. GitHub runs those steps concurrently
and waits at the end of the group before continuing.
Use Node.js 24 or later to run the .ts scripts with
built-in TypeScript support.
import { command } from "@dedalus-labs/hollywood";
import type { GitHubParallelStep } from "@dedalus-labs/hollywood";
const checks = {
parallel: [
{ run: command({ file: "node", args: ["lint.ts"] }) },
{ run: command({ file: "node", args: ["test.ts"] }) },
],
} satisfies GitHubParallelStep;
Place checks in a job's steps array after checkout and dependency setup.
Both commands run on the same runner, so they share its CPU, memory, and files.
The author must establish independence, including shared files and environment
changes. Hollywood does not infer it or remove declared needs edges. A group
cannot also have run, uses, or if, and groups cannot be nested.
This workflow syntax is not available inside composite actions.
The GitHub contract defines scheduling and the concurrency limit. Native parallel-step support must be enabled in GitHub. Older workflow linters may reject the syntax. The repository's pinned Actionlint 1.7.12 does, so its own validation workflow keeps its existing step order.
The bounded join model in models/README.md checks the wait and failure
contract. It does not verify the GitHub runner.
Background workflow steps¶
Use background: true when a command should overlap later steps. Give it an
id, then wait for that ID before using its result. In this example, the
project provides ci/build.ts, ci/lint.ts, and ci/check-build.ts.
Linting can run while the build writes its output. Checking that output must
wait for the build to finish.
Save the workflow in gha/checks.ts:
import { command, workflow } from "@dedalus-labs/hollywood";
const checkoutAction = "actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1"; // v7
const setupNodeAction = "actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38"; // v6
export const checks = workflow({
name: "Checks",
on: { push: {} },
permissions: { contents: "read" },
jobs: {
check: {
"runs-on": "ubuntu-latest",
steps: [
{ uses: checkoutAction },
{ uses: setupNodeAction, with: { "node-version": "24" } },
{ run: command({ file: "npm", args: ["ci"] }) },
{
id: "build",
background: true,
run: command({ file: "node", args: ["ci/build.ts"] }),
},
{ run: command({ file: "node", args: ["ci/lint.ts"] }) },
{ wait: "build" },
{ run: command({ file: "node", args: ["ci/check-build.ts"] }) },
],
},
},
});
Run npx hollywood generate to write .github/workflows/checks.yml.
Hollywood renders and validates the steps. GitHub starts, waits for, and stops
the background processes.
| Step | Use |
|---|---|
{ wait: "build" } |
Wait for one earlier background step. |
{ wait: ["build", "test"] } |
Wait for several earlier background steps. |
{ "wait-all": true } |
Wait for all active background steps. null is also accepted. |
{ cancel: "server" } |
Stop one earlier background step. |
Outputs and environment changes become available after the matching wait.
A failed background step fails that wait unless continue-on-error permits
the failure. Wait and cancel steps always run and cannot have an if condition.
The workflow types reject mixed step kinds and explicit background fields
inside a parallel group. GitHub's parser rejects unknown wait targets and
nested groups during generation.
A background server still needs a readiness check before clients connect.
Use cancel when the server is no longer needed. Waiting for a server that
runs indefinitely would keep the job waiting too.
GitHub permits ten active background steps per job and queues additional work. Parallel groups share this limit. This syntax is unavailable inside composite actions. See GitHub's workflow syntax for scheduling, cleanup, and failure behavior.
Script authoring¶
| API | Purpose |
|---|---|
action |
Define a typed script action. |
stringInput |
Read a required or defaulted string input. |
integerInput |
Parse a string input into an integer. |
booleanInput |
Parse a string input into a boolean. |
choiceInput |
Restrict a string input to a closed set of values. |
pathInput |
Mark an input as a filesystem path. |
stringOutput |
Declare a string output. |
call |
Invoke a child action with typed inputs inside run. |
exec |
Run an executable plus argument array inside run. |
summary.table |
Write a sanitized GitHub step-summary table inside run. |
summaryCode |
Render a summary cell as escaped inline code. |
summaryText |
Render a summary cell as escaped plain text. |
expr |
Validate and wrap a GitHub Actions expression. |
Step Summary Tables¶
summary.table(title, rows) writes one table to the GitHub step summary. The
title and each row label are escaped plain text. Row values must be
summaryText(value) for plain text or summaryCode(value) for inline code.
Hollywood does not accept raw HTML, Markdown, or bare string values in table
cells.
Expressions¶
| API | Purpose |
|---|---|
gh |
Namespace for typed github.* and runner.* refs. |
github |
Typed references to common github.* context names. |
runner |
Typed references to common runner.* context names. |
format |
Build a validated format(...) expression. |
contains |
Build a validated contains(...) expression. |
hashFiles |
Build a validated hashFiles(...) expression. |
eq / ne |
Build validated equality expressions. |
and / or |
Compose validated boolean expressions. |
selectString |
Select between typed string expression values. |
valueOr |
Compose typed value expressions with OR. |
not |
Negate a validated expression. |
input |
Reference inputs.<name>. |
matrix |
Reference matrix.<name>. |
needsOutput |
Reference needs.<job>.outputs.<name>. |
needsResult |
Reference needs.<job>.result. |
needsResultIs / needsResultIn |
Compare job results. |
stepOutput |
Reference steps.<step>.outputs.<name>. |
defineMatrix |
Keep matrix values and typed matrix refs together. |
| Status helpers | always, cancelled, failure, success. |
Expression helpers are also exported from @dedalus-labs/hollywood/expr so workflow
authoring can keep orchestration imports separate from script/action imports.
Runtime adapters¶
| API | Purpose |
|---|---|
runAction |
Run a script with explicit filesystem, executor, logger, and runner context. |
runGitHubAction |
Run a script through @actions/core and @actions/exec. |
RunGitHubActionOptions.logColor |
Control command-log color: auto, always, or never. |
nodeExec |
Execute commands on the local machine. |
nodeFs |
Read local files. |
nodeLog |
Write local logs to stdout and stderr. |
withContainer |
Own one Docker, Podman, or Apple container action session. |
parseEncodedGitHubJitConfig |
Validate and brand a GitHub JIT runner configuration. |
readEncodedGitHubJitConfig |
Read and validate a GitHub JIT runner configuration file. |
parseGitHubRepository |
Validate and brand an OWNER/REPOSITORY name. |
parseGitHubApiToken |
Validate and brand a GitHub API token. |
defineGitHubRunnerJitRegistration |
Validate and brand JIT runner registration options. |
generateGitHubRepositoryRunnerJitConfig |
Request a repository JIT configuration with GitHub OpenAPI types. |
writeEncodedGitHubJitConfig |
Create a mode-0600 JIT file without replacing an existing file. |
runGitHubRunner |
Run one GitHub-scheduled job with the official runner. |
probeRunner |
Capture a sanitized, typed runner inventory. |
defineRunnerContract |
Define the required operating system, paths, and tools. |
verifyRunner |
Compare a runner probe with its required contract. |
compareRunnerProbes |
Classify contract, inventory, and provider drift. |
Action runtime import¶
GitHub JavaScript actions should import the smaller action runtime surface:
This subpath exports script authoring primitives and the GitHub adapter without pulling workflow generation or YAML validation code into every bundled action.
Generation¶
| API | Purpose |
|---|---|
generateActionMetadata |
Convert a script action into action.yml metadata. |
generateActionFile |
Produce a generated action.yml file object. |
generateActionEntrypointFile |
Produce a generated TypeScript entrypoint file object. |
generateActionFiles |
Generate action metadata files with duplicate path checks. |
generateUsesStep |
Convert typed script inputs into GitHub with: names. |
uses |
Reference a generated local action from a workflow step. |
generateWorkflowFile |
Produce a flattened workflow file object. |
workflow |
Type a GitHub workflow definition without extra runtime. |
job |
Type a GitHub workflow job without extra runtime. |
writeGeneratedFiles |
Write generated files under an explicit output directory. |
GitHubWorkflow types cover the orchestration fields Hollywood emits today:
permissions, concurrency, job needs, matrix strategy, services,
env, if, and mutually exclusive run/uses steps. queue: max is typed
so it cannot be combined with cancel-in-progress.
CLI¶
| Command | Purpose |
|---|---|
hollywood generate |
Discover exported actions and workflows from source files. |
hollywood run |
Run one exported Hollywood action locally. |
hollywood runner jit-config |
Create one repository JIT runner configuration. |
hollywood runner listen |
Run one GitHub job with the official Actions runner. |
hollywood runner probe |
Write a sanitized runner inventory. |
hollywood runner verify |
Verify a probe against a runner contract. |
hollywood runner compare |
Classify drift between two runner probes. |
The command infers gha/**/*.ts or ci/**/*.ts from the repository:
Supported override flags:
| Flag | Default | Purpose |
|---|---|---|
--output |
. |
Repository root where files are written. |
--actions-dir |
.github/actions |
Destination for generated local actions. |
--workflows-dir |
.github/workflows |
Destination for generated workflows. |
--source-root |
inferred | Prefix removed before workflow flattening. |
--root-import-alias |
inferred | Import alias for generated action entrypoints. |
The source root, root import alias, and generated output directories are CLI
options, not hardcoded paths. Hollywood infers @ from a tsconfig.json
@/* path alias when present.
Run an action with an explicit provider:
The default image is GitHub's official minimal Actions runner image, pinned by digest. Override it only with another digest-pinned image:
npx hollywood run gha/s3-cache.ts \
--export s3Cache \
--provider podman \
--image ghcr.io/acme/runner@sha256:<digest> \
--with mode=restore
The exact lifecycle and compatibility boundary are documented in Execution Backends. The reproducible image and its publication contract are documented in Runner Image.
Validation¶
| API | Purpose |
|---|---|
validateActionMetadataContent |
Return parser diagnostics for an action metadata file. |
validateWorkflowContent |
Return parser diagnostics for a workflow file. |
assertValidActionMetadataContent |
Throw if action metadata is invalid. |
assertValidWorkflowContent |
Throw if workflow YAML is invalid. |
Dependency advice¶
A deployment can need a test job to finish without reading its outputs. Keep that
needs edge. Hollywood emits declared dependencies unchanged, including their
start ordering and success/skip behavior.
validateWorkflowModel(workflow, { rules: ["no-unnecessary-needs"] }) returns
{ warnings } for edges with no detected expression or artifact use. Each
LintIssue contains ruleId, jobId, and message. ValidationOptions.rules
accepts the LintRule type. Unknown rules and malformed expressions encountered
during analysis throw.
The rule reads expressions in conditions, commands, environment values, and inputs. It recognizes standard GitHub artifact uploads/downloads and Pages handoffs. Wildcard or dynamic references, artifact names, and download patterns suppress advice conservatively. These checks do not prove an edge is unnecessary.
Run this advisory check explicitly:
The CLI prints warn[no-unnecessary-needs] with the source file, workflow, and
job. Warnings do not fail the command or write generated files. Add --generated
or --workflow-security to run those checks too. Invalid options or expressions
encountered during analysis fail the command. The rule has no severity option
or error mode.