Workflow API
The CI workflow API: defineWorkflow, triggers, helpers, and the run context.
Everything importable from @plainalpha/ci in a .plain/workflows file. For the guided introduction, start with Workflows.
defineWorkflow
defineWorkflow(name: string, {
on: Trigger[],
run: async ({ ctx }) => void,
network?: { allow: string[] },
concurrency?: { group: string; cancelInProgress?: boolean },
timeoutMs?: number,
});
Registration is by call, so one file can define several workflows; identity is the name, not the filename.
Triggers
on.push({ branches?: string[], tags?: string[], paths?: string[] })
on.pullRequest({ branches?: string[], paths?: string[],
actions?: ("opened"|"updated"|"reopened"|"ready_for_review")[] })
on.schedule(cron: string)
on.manual()
on.comment(command: string) // "/command" in a PR or issue conversation
on.issueLabeled(label: string)
Details and examples: Triggers.
Shell helpers
await sh(command, { cwd?, env?, allowFailure? }) // streamed to the run log
await pm.install() // pnpm/npm/yarn/bun by lockfile
await pm.run(script)
await pm.exec(bin, args)
await git.clone(...); await git.checkout(...); await git.commit(...)
sh rejects on a non-zero exit unless allowFailure: true, in which case it resolves with the exit code for you to inspect.
Secrets, env, and artifacts
secret.get(name) // decrypted CI secret; throws if missing
secret.has(name)
env.get(name) // base environment
await ctx.artifact.write(name, data) // run-scoped storage
await ctx.artifact.read(name)
See Secrets and environment for where secrets are managed and how redaction works.
The run context
run receives { ctx }:
| Field | Contents |
|---|---|
ctx.org | Organisation id and slug |
ctx.git | ref, branch, sha, and baseRef on PR runs |
ctx.trigger | The event that started the run |
ctx.pr, ctx.issue, ctx.commit | The triggering entity, when there is one |
ctx.issues, ctx.comments, ctx.docs, ctx.labels, ctx.relations | Write surfaces into the platform |
ctx.artifact | Run-scoped artifact storage |
The write surfaces are what make workflows more than build scripts: a run can file the issue it found, comment on the PR that triggered it, or update a doc, with the run as the attributed author.
AI in workflows
const answer = await ai.chat(prompt);
ai.chat gives a run model access for steps like summarising a diff or drafting a changelog entry. Hosted runs meter it against the organisation's AI budget; locally it explains what to configure.