Custom Steps
Write reusable steps and produce artifacts from workflow steps.
Workflow steps can reference reusable step definitions using the uses keyword. You can also write inline steps with run that produce artifacts.
The uses Format
The uses field references a step definition from a Git repository:
owner/repo/path@refFor example:
- name: lint
uses: airlock-hq/airlock/defaults/lint@mainThis fetches the step definition from the defaults/lint directory of the airlock-hq/airlock repo at the main ref.
Writing a Custom Step
A custom step is a directory in a Git repository containing a step.yml file and any scripts it needs:
my-org/my-steps/
custom-lint/
step.yml
run.shThe step.yml defines what the step does:
name: Custom Lint
run: bash run.sh
shell: bashReference it in your workflow:
- name: lint
uses: my-org/my-steps/custom-lint@mainEnvironment Variables
Steps have access to environment variables like AIRLOCK_WORKTREE, AIRLOCK_BRANCH, and AIRLOCK_FROZEN that provide context about the current run.
Producing Artifacts
Custom steps can produce artifacts — content, comments, and patches — using the airlock artifact commands.
Example: Custom Review Step
Here's a complete custom step that runs a linter and turns each finding into a review comment:
# my-org/my-steps/review/step.yml
name: Custom Review
shell: bash
run: |
set -euo pipefail
# Run a custom linter that outputs JSON
./bin/lint --json > results.json
# Loop through each finding and produce a comment artifact
COUNT=$(airlock exec json 'findings | length' < results.json)
for i in $(seq 0 $((COUNT - 1))); do
FILE=$(airlock exec json "findings[$i].file" < results.json)
LINE=$(airlock exec json "findings[$i].line" < results.json)
MSG=$(airlock exec json "findings[$i].message" < results.json)
SEV=$(airlock exec json "findings[$i].severity" < results.json)
airlock artifact comment \
--file "$FILE" \
--line "$LINE" \
--message "$MSG" \
--severity "$SEV"
doneSteps run in the worktree directory ($AIRLOCK_WORKTREE), so file paths in artifact commands should be relative to
the repo root.
Related
- Artifacts — The three artifact types in detail
- Custom Workflows — Assemble custom steps into workflows
- Default Steps — Built-in steps you can use or extend