Skip to content

Workflow Concepts

The lexicon provides 2 resource types and several property types:

TypeDescription
WorkflowTop-level workflow configuration — name, triggers, permissions, concurrency
JobA job within a workflow — runs-on, steps, strategy, needs, outputs
TypeUsed inDescription
StepJobA single step — run command or action usage
StrategyJobMatrix strategy for parallel job execution
PermissionsWorkflow, JobGITHUB_TOKEN permission scopes
ConcurrencyWorkflow, JobConcurrency group and cancel-in-progress settings
PushTriggerWorkflow (on)Push event trigger with branch/tag/path filters
PullRequestTriggerWorkflow (on)Pull request event trigger with filters
ScheduleTriggerWorkflow (on)Cron-based schedule trigger
WorkflowDispatchTriggerWorkflow (on)Manual dispatch with typed inputs
EnvironmentJobDeployment environment with protection rules
OutputJobJob output values for downstream jobs

Triggers define when a workflow runs. Pass them in the on: field:

import { Workflow } from "@intentius/chant-lexicon-github";
export const workflow = new Workflow({
name: "CI",
on: {
push: { branches: ["main", "release/*"] },
pull_request: {
branches: ["main"],
types: ["opened", "synchronize"],
},
schedule: [{ cron: "0 0 * * 1" }], // Weekly on Monday
workflow_dispatch: { // Manual trigger
inputs: {
environment: {
description: "Deploy target",
required: true,
type: "choice",
options: ["staging", "production"],
},
},
},
},
});

Each exported Job becomes a job entry under jobs:. Steps run sequentially within a job:

import { Job, Step, Checkout, SetupNode } from "@intentius/chant-lexicon-github";
export const test = new Job({
"runs-on": "ubuntu-latest",
timeoutMinutes: 10,
steps: [
Checkout({}).step,
SetupNode({ nodeVersion: "22", cache: "npm" }).step,
new Step({ name: "Install", run: "npm ci" }),
new Step({ name: "Test", run: "npm test" }),
],
});

Key job properties:

  • runs-onrequired. Runner label (ubuntu-latest, macos-latest, windows-latest).
  • stepsrequired. Array of Step objects.
  • timeoutMinutes — maximum job duration (recommended, flagged by GHA014 if missing).
  • needs — job dependencies for execution ordering.
  • if — conditional execution using Expressions.
  • strategy — matrix builds for parallel execution.

Run a job across multiple configurations:

import { Job, Step, Checkout, SetupNode } from "@intentius/chant-lexicon-github";
export const test = new Job({
"runs-on": "ubuntu-latest",
strategy: {
matrix: {
"node-version": ["18", "20", "22"],
os: ["ubuntu-latest", "macos-latest"],
},
"fail-fast": false,
},
steps: [
Checkout({}).step,
SetupNode({ nodeVersion: "${{ matrix.node-version }}", cache: "npm" }).step,
new Step({ name: "Test", run: "npm test" }),
],
});

Control GITHUB_TOKEN permissions at the workflow or job level:

import { Workflow, Job, Step } from "@intentius/chant-lexicon-github";
// Workflow-level (applies to all jobs)
export const workflow = new Workflow({
name: "Release",
on: { push: { tags: ["v*"] } },
permissions: {
contents: "write",
packages: "write",
"id-token": "write",
},
});
// Job-level (overrides workflow permissions for this job)
export const publish = new Job({
"runs-on": "ubuntu-latest",
permissions: { contents: "read", packages: "write" },
steps: [
new Step({ name: "Publish", run: "npm publish" }),
],
});

Available permission scopes: actions, checks, contents, deployments, id-token, issues, packages, pages, pull-requests, repository-projects, security-events, statuses. Values: "read", "write", "none".

Prevent concurrent runs of the same workflow or job:

import { Workflow } from "@intentius/chant-lexicon-github";
export const workflow = new Workflow({
name: "Deploy",
on: { push: { branches: ["main"] } },
concurrency: {
group: "deploy-${{ github.ref }}",
"cancel-in-progress": true,
},
});

Use needs to order jobs and pass outputs between them:

import { Job, Step } from "@intentius/chant-lexicon-github";
export const build = new Job({
"runs-on": "ubuntu-latest",
outputs: { version: "${{ steps.version.outputs.value }}" },
steps: [
new Step({
id: "version",
name: "Get version",
run: 'echo "value=$(node -p \"require('./package.json').version\")" >> $GITHUB_OUTPUT',
}),
],
});
export const deploy = new Job({
"runs-on": "ubuntu-latest",
needs: ["build"],
steps: [
new Step({
name: "Deploy",
run: "echo Deploying version ${{ needs.build.outputs.version }}",
}),
],
});