OpsNexus

Pipeline syntax

Complete reference for the OpsNexus YAML pipeline file, with every key, type, default, limit and expression.

On this page

An OpsNexus pipeline file is a YAML file that lists stages and steps. A build agent checks out your code, runs each step in a shell and streams the output back to OpsNexus. This page describes every key the server accepts. The same reference, with a live validator, is in the app under CI/CD → Pipeline syntax.

The file

  • The file is YAML. It can have any name ending in .yml or .yaml and can live in any folder of the repository.
  • The default path is .opsnexus.yml. You can set another path per pipeline, for example ci/build.yaml.
  • If the file is not found, OpsNexus also tries the other extension (.opsnexus.yml also finds .opsnexus.yaml, and the other way round).
  • The path must be inside the repository: no leading / and no ...
  • The file can be at most 256 KB.
  • The top level must be a mapping with a stages: list.
  • Unknown keys are errors. OpsNexus lists every problem it finds, with the place it found it (for example stages[2].steps[0].shell).

Instead of keeping the file in Git, you can paste it into the pipeline's settings (Pipeline script). The format is the same. See Pipelines.

Limits

Item Limit
File size 256 KB
Stages 50
Steps per stage (and per post list) 100
artifacts patterns 50, each at most 300 characters
timeout_minutes (anywhere) Whole number from 1 to 1440
Stage name 120 characters (longer names are cut)
Parameter value 10,000 characters
Console output stored per build 5 MB (the rest is not stored)

Complete example

yaml
# .opsnexus.yml  (any name ending in .yml or .yaml)
name: web-app

agent:                      # which build agent runs it (optional)
  labels: [linux, docker]   # every label must match; os, name and pool count as labels
  # pool: linux-build

parameters:                 # shown on "Build with parameters"
  - name: DEPLOY_ENV
    type: choice            # string | text | choice | boolean | password
    options: [dev, staging, prod]
    default: dev
    description: Where to deploy

environment: ${{ params.DEPLOY_ENV }}   # vars.* are read for this environment

env:                        # environment variables for every step
  NODE_ENV: production
  API_URL: ${{ vars.API_URL }}          # Secrets & variables → Variables
  NPM_TOKEN: ${{ secrets.npm-token }}   # Secrets & variables → Secrets (masked in logs)

options:
  timeout_minutes: 45       # whole build (approval waits don't count)
  clean_workspace: false

stages:
  - name: Install
    steps:
      - run: npm ci

  - name: Test
    steps:
      - name: Unit tests
        run: npm test
        continue_on_error: true     # carry on even if it fails
      - run: npm run lint
        timeout_minutes: 5

  - name: Build
    steps:
      - run: |
          npm run build
          tar czf dist.tgz dist

  - name: Approve production
    when:
      branch: [main, release/*]     # also: not_branch, environment, params
      params: { DEPLOY_ENV: prod }
    approval:
      message: Deploy build ${{ run.number }} to production?
    steps:
      - run: echo "approved"

  - name: Deploy
    environment: ${{ params.DEPLOY_ENV }}
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.aws-deployer.access_key_id }}       # one field of a secret
      AWS_SECRET_ACCESS_KEY: ${{ secrets.aws-deployer.secret_access_key }}
    steps:
      - run: ./scripts/deploy.sh "$DEPLOY_ENV"
        shell: bash                 # bash | sh | pwsh | powershell | cmd | python
        working_directory: infra

artifacts:                  # files to keep with the build
  - dist.tgz

post:                       # after the stages
  always:
    - run: echo "done"
  success:
    - run: echo "it worked"
  failure:
    - run: echo "it failed"

Top-level keys

Key Type Default Description
name text none Display name. Optional.
agent any, a label, or a mapping any agent Which build agent may run the build. See agent.
parameters list none Inputs shown on Build with parameters. See parameters.
environment text the pipeline's Variables environment setting The environment that ${{ vars.* }} values are read from, for example dev, staging or prod. Expressions are allowed.
env mapping none Environment variables for every step. See env.
options mapping see options timeout_minutes and clean_workspace.
stages list required At least one stage. See stages.
post mapping none Steps that run after the stages. See post.
artifacts text or list none Files to archive after the build. See artifacts.
triggers any none Accepted by the parser but not used. Set triggers on the pipeline's Configure tab.

agent

agent decides which build agents can take the build.

Form Meaning
agent: any or no agent key Any agent with free executors.
agent: linux Agents that have the label linux.
agent: { labels: [linux, docker] } Agents that have every listed label.
agent: { pool: linux-build } Agents in the pool linux-build.
agent: { pool: linux-build, labels: [docker] } Both conditions.

Rules:

  • labels can be one text value or a list.
  • An agent matches only if it has all the labels. Label matching ignores case.
  • An agent's operating system (linux, windows, macos), its name and its pool also count as labels.
  • pool must match the agent's pool exactly.
  • The pipeline's own agent settings (Build environment → Agent pool / Agent labels) still apply. Labels from both places are combined. A pool in the file replaces the pool from the settings.
  • For a file read from Git, the labels are known only after checkout. If the agent that checked out the code does not match, the build goes back to the queue for a matching agent.

options

Key Type Default Description
timeout_minutes whole number, 1 to 1440 the pipeline's Timeout (minutes) setting (60 if not set) Limit for the whole build. Time spent waiting for an approval does not count.
clean_workspace true / false false Delete the workspace before the build. It is also cleaned when the pipeline setting Delete the workspace before each build is on.

env

env is a mapping of NAME: value.

  • Names use letters, digits and _, and do not start with a digit.
  • Values must be text, a number or true/false. Lists and mappings are errors. true/false become the text true/false. An empty value becomes an empty string.
  • Values can use expressions.

env can appear at the top level, on a stage and on a step. When the same name is set in several places, the most specific one wins:

  1. Built-in variables and parameter values (see Built-in environment variables)
  2. Top-level env
  3. Stage env
  4. Step env

WORKSPACE and ONX_WORKSPACE are always set by the agent and cannot be overridden.

parameters

Each parameter is a mapping:

Key Type Default Description
name text required Letters, digits and _, not starting with a digit. Must be unique.
type string, text, choice, boolean, password string text is multi-line. password is hidden in the form and masked in the log.
options list of text none Required for choice.
default depends on type see below The value used when nobody sets one.
description text empty Shown under the field on Build with parameters.

Defaults:

  • string, text, password: empty text when default is missing.
  • boolean: false when default is missing.
  • choice: the first option when default is missing or is not one of the options.

How parameter values reach your steps:

  • Every parameter is an environment variable in every step, with the parameter's name (for example $DEPLOY_ENV).
  • ${{ params.NAME }} inserts the value into run, env and the other places expressions work.
  • Boolean values are the text true or false.
  • A choice value that is not one of the options is rejected when the build starts.
  • password values are stored encrypted, shown as •••••• on the build page and masked in the console output.

Parameters can also be set on the pipeline's Configure → General tab. If the file declares a parameter with the same name, the file's definition wins. For a file kept in Git, OpsNexus learns its parameters when a build reads the file, so they appear in the Build dialog from the next build on.

yaml
parameters:
  - name: TAG
    type: string
    default: latest
    description: Image tag to push
  - name: RUN_E2E
    type: boolean
    default: true
  - name: REGION
    type: choice
    options: [ap-south-1, eu-west-1, us-east-1]
  - name: RELEASE_NOTES
    type: text
  - name: SIGNING_PASSWORD
    type: password

stages

stages is a list. Stages run in order. Each stage is a mapping:

Key Type Default Description
name text Stage <n> Must be unique in the file. Shown in the stage view.
steps list required At least one step. See steps.
when mapping none Run the stage only when the conditions hold. See when.
approval true, false or mapping none Pause before the stage until someone approves. See approval.
env mapping none Environment variables for this stage's steps.
environment text the top-level environment Read ${{ vars.* }} from another environment in this stage. Expressions are allowed.
timeout_minutes whole number, 1 to 1440 none Limit for this stage.

When a step fails (and does not have continue_on_error: true), the stage fails, the remaining steps are skipped, and every later stage is skipped. post steps still run.

when

when makes a stage conditional. If a condition does not hold, the stage is skipped and the build page shows the reason (for example branch feature/x doesn't match main, release/*). When you give several conditions, all of them must hold.

Key Type Description
branch text or list Run only when the branch matches one of the patterns.
not_branch text or list Skip when the branch matches one of the patterns.
environment text or list Run only when the stage's environment is one of these.
params mapping NAME: value Run only when each parameter has exactly this value. Write booleans as true / false.

Branch patterns are wildcards: * matches any characters (including /), ? matches one character. Matching is case-sensitive. release/* matches release/1.4.

yaml
- name: Publish
  when:
    branch: [main, release/*]
    not_branch: release/experimental
    params: { PUBLISH: true }
  steps:
    - run: ./publish.sh

approval

An approval pauses the build before the stage's steps run. The build status becomes Waiting for approval, and OpsNexus sends the build.approval notification event. Someone then approves or rejects it on the build page.

Form Meaning
approval: true Ask with the message Continue to <stage name>?
approval: { message: Deploy to production? } Ask with your own message. Expressions are allowed.
approval: false or no approval key No approval.
  • Approving runs the stage.
  • Rejecting stops the build. The stage and the build are marked cancelled, and the post.failure steps run.
  • There is no approval timeout. The build waits until someone decides or stops it. Waiting time does not count towards timeout_minutes.
  • A stage with an approval still needs at least one step. A placeholder such as - run: echo "Approved" is fine.
  • If the stage's when conditions skip it, there is no approval.

Who can approve, and where, is described in Builds and approvals.

steps

A step is either a command (run) or a plugin (uses), never both.

Command steps

Key Type Default Description
run text required The command or script. Use a YAML block scalar for several lines (see the example above). Expressions are allowed.
name text the first line of run (up to 60 characters) Label in the stage view and console.
shell bash, sh, pwsh, powershell, cmd, python see below The interpreter for run.
working_directory text the workspace root A folder inside the workspace. No ...
env mapping none Environment variables for this step only.
continue_on_error true / false false When true, a failure is logged and the stage carries on.
timeout_minutes whole number, 1 to 1440 none Limit for this step. A step that times out fails.

A step can also be written as plain text. These two steps are the same:

yaml
steps:
  - npm ci
  - run: npm ci

A step fails when its command exits with a non-zero code.

Shells

shell Runs as
not set bash on Linux and macOS (sh if bash is missing); pwsh on Windows (powershell if pwsh is missing)
bash bash with -e -o pipefail: the step stops at the first failing command, including inside pipes
sh sh -e
pwsh PowerShell 7 with $ErrorActionPreference = 'Stop'; the step exits with $LASTEXITCODE
powershell Windows PowerShell, same rules as pwsh
cmd Windows cmd
python The agent's Python 3, with run as the script
yaml
stages:
  - name: Build
    steps:
      - run: dotnet build --configuration Release
        shell: pwsh
      - name: Summarise
        shell: python
        run: |
          import json
          print(json.dumps({"ok": True}))

Plugin steps

A plugin step runs a reusable plugin with inputs under with:.

Key Type Default Description
uses text required name@version, for example slack-notify@1.
with mapping none The plugin's inputs. Unknown inputs are errors.
name text the plugin's title Label in the stage view.
env mapping none Extra environment variables.
continue_on_error true / false false Same as for command steps.
timeout_minutes whole number, 1 to 1440 none Same as for command steps.
working_directory text the workspace root Same as for command steps.

Plugin steps do not take shell or run. Version references:

uses: Picks
slack-notify@1 The newest installed 1.x version
slack-notify@1.2 The newest installed 1.2.x version
slack-notify@1.2.3 Exactly 1.2.3
slack-notify@latest or slack-notify The newest installed version

The version is resolved when the build starts, and the build page shows the exact version it used.

yaml
post:
  failure:
    - uses: slack-notify@1
      with:
        webhook: slack-webhook          # the name of a Secret text credential
        status: failure
        message: "Build #${{ run.number }} of ${{ job.name }} failed on ${{ git.branch }}"

Every input, and how plugins check them, is described in Plugins.

post

post steps run after the stages, also after a failure, a timeout or a stop.

Key Runs when
always After every build
success When every stage succeeded
failure When the build failed, timed out, was stopped or an approval was rejected
  • Each key is a list of steps, written like stage steps (command or plugin steps).
  • always steps run first, then success or failure.
  • Every post step runs, even when an earlier post step fails.
  • Post steps get at least 15 more minutes, even when the build already reached its timeout.
  • Post steps see the top-level env and environment, not a stage's.
  • Any other key under post is an error.

artifacts

artifacts lists files to keep with the build. They are uploaded after the build, including failed builds, and appear on the build page and on Artifacts → Build artifacts.

yaml
artifacts:
  - dist/*.zip
  - reports/**/*.xml
  - coverage/summary.json
  • One text value or a list of workspace-relative paths or globs.
  • No leading / and no ...
  • At most 50 patterns.
  • Expressions are allowed, for example dist/app-${{ run.number }}.zip.
  • Files under .onx/ (the agent's own folder) are never archived.
  • Plugins can declare their own report files; those are archived too.
  • Server limits apply: ARTIFACT_MAX_MB per file (default 100) and at most 200 files per build.

See Artifacts.

Expressions

Expressions have the form ${{ context.key }}. They are filled in when an agent picks up the build. Values are never stored with the build.

Expression Value
${{ secrets.NAME }} A secret from Secrets & variables. For a secret with one field, its value. Always masked as •••••• in the console.
${{ secrets.NAME.field }} One field of a multi-field secret, for example secrets.aws-deployer.access_key_id.
${{ vars.KEY }} A variable for the pipeline's environment, or one set for all.
${{ params.NAME }} A build parameter. The parameter must be declared.
${{ git.branch }} The branch being built.
${{ git.commit }} The commit SHA.
${{ git.short_commit }} The first 7 characters of the commit SHA.
${{ git.message }} The commit message.
${{ run.number }} The build number.
${{ run.id }} The build's unique ID.
${{ run.url }} A link to the build in OpsNexus.
${{ run.trigger }} What started it: manual, webhook, cron, poll, scan or replay.
${{ run.triggered_by }} Who or what started it.
${{ job.name }} The pipeline's name.
${{ job.full_name }} The full name, including folders (for example acme/web/main).

Where expressions are filled in: run, env values (top level, stage and step), environment (top level and stage), approval.message, artifacts, and plugin with: inputs. name values are plain labels and are never evaluated.

Errors:

  • An unknown context (anything other than secrets, vars, params, git, run, job) or a malformed ${{ is a validation error.
  • A missing secret, variable or undeclared parameter fails the build when it starts, with a message that says what to add.

Secrets

  • Secrets come from Settings → Secrets & variables: the project's own secrets and the ones shared with all projects. See Secrets and variables.
  • Secret names can contain dots. OpsNexus first looks for a secret with the full name, then treats the last part as a field.
  • If a secret has several fields and you do not name one, the build fails and asks you to use ${{ secrets.NAME.<field> }}.
  • For a Secret file credential, ${{ secrets.NAME }} (or .path) is the path of a file the agent writes for the build. ${{ secrets.NAME.content }} is the file's text.
  • Every secret value, and every line of a multi-line secret, is masked in the console output.

Variables

  • ${{ vars.KEY }} looks for a variable with that key in the build's environment, or in the environment all. A variable for the exact environment wins over all, and a project variable wins over a shared one.
  • The environment is the stage's environment, else the top-level environment, else the pipeline's Variables environment setting.
  • A variable whose value is vault:<secret> or vault:<secret>.<field> is read from that secret and masked like one.

Built-in environment variables

Every step gets these variables:

Variable Value
CI, OPSNEXUS Always true
BUILD_NUMBER, ONX_RUN_NUMBER Build number
BUILD_ID Build number
ONX_RUN_ID The build's unique ID
JOB_NAME, ONX_JOB_NAME Full pipeline name, for example acme/web/main
BRANCH_NAME, GIT_BRANCH, ONX_BRANCH Branch being built (when there is one)
GIT_COMMIT, ONX_COMMIT Commit SHA after checkout (when there is one)
BUILD_URL, ONX_RUN_URL Link to this build in OpsNexus
ONX_TRIGGER What started the build (manual, webhook, cron, poll, scan, replay)
WORKSPACE, ONX_WORKSPACE The checkout folder on the agent
Each parameter name The parameter's value, for example DEPLOY_ENV

Templates

The editor offers four starting points under Start from a template…: Node.js build & test, Docker image build & push, Build, approve, deploy and Windows (.NET). The Docker template:

yaml
name: api-image
agent:
  labels: [docker]
parameters:
  - name: TAG
    type: string
    default: latest
    description: Image tag to push
env:
  IMAGE: ${{ vars.REGISTRY }}/api
stages:
  - name: Build image
    steps:
      - run: docker build -t "$IMAGE:${{ params.TAG }}" .
  - name: Push
    when:
      branch: [main, release/*]
    env:
      REGISTRY_USER: ${{ secrets.registry.username }}
      REGISTRY_PASSWORD: ${{ secrets.registry.password }}
    steps:
      - run: echo "$REGISTRY_PASSWORD" | docker login "${{ vars.REGISTRY }}" -u "$REGISTRY_USER" --password-stdin
      - run: docker push "$IMAGE:${{ params.TAG }}"

The build, approve, deploy template:

yaml
name: release
parameters:
  - name: DEPLOY_ENV
    type: choice
    options: [dev, staging, prod]
    default: dev
environment: ${{ params.DEPLOY_ENV }}
options:
  timeout_minutes: 45
stages:
  - name: Build
    steps:
      - run: make build
  - name: Approve
    when:
      params:
        DEPLOY_ENV: prod
    approval:
      message: Deploy build ${{ run.number }} to production?
    steps:
      - run: echo "Approved"
  - name: Deploy
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.aws-deployer.access_key_id }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.aws-deployer.secret_access_key }}
      AWS_REGION: ${{ vars.AWS_REGION }}
    steps:
      - name: Deploy
        run: ./scripts/deploy.sh "${{ params.DEPLOY_ENV }}"
        timeout_minutes: 20

Validating a file

  • On CI/CD → Pipeline syntax, paste a file into Try it: validate a pipeline file and press Validate. Nothing runs.
  • In the Pipeline script editor on a pipeline's Configure tab, press Validate.
  • From a script, call POST /api/ci/validate with {"content": "<yaml>"}. The answer is {"ok": true, "summary": {...}} or {"ok": false, "problems": [...]}.

A valid result shows the stages, parameters, secrets, variables, approvals and plugins the file uses. Plugin steps are checked against the plugins installed in the current project.

bash
curl -s -X POST "https://opsnexus.example.com/api/ci/validate" \
  -H "X-API-Key: $OPSNEXUS_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -Rs '{content: .}' .opsnexus.yml)"

Coming from Jenkins

Jenkins OpsNexus
agent { label 'x' } agent: { labels: [x] }
stage('X') { steps { sh '…' } } - name: X with steps: [- run: …]
withCredentials / credentials() ${{ secrets.NAME }}, or Credential bindings in a Freestyle project
parameters { choice(...) } parameters: - { name, type: choice, options }
when { branch 'main' } when: { branch: [main] }
input message: '…' approval: { message: … }
post { always / success / failure } post: { always, success, failure }
triggers { cron('H 2 * * *') } Build periodically on the pipeline's Configure tab (same cron syntax, H included)
Plugins such as slackSend, junit, withAWS - uses: slack-notify@1, junit-report@1, aws-cli@1