Conditional execution of steps with `if:`
Created by: mrnugget
This extends the schema of the batch spec steps
to add a new field:
if: <string that can use templating to evaluate to "true" or "false">
(the corresponding schema changes sourcegraph/sourcegraph
are here: https://github.com/sourcegraph/sourcegraph/pull/20399)
if:
is evaluated in a best-effort partial-evaluation manner before the execution of the steps
. If we can statically evaluate it, we use the result of that evaluation to build a per-repository/per-workspace list of tasks, which increases cache utilisation.
See the comments in partial_eval.go
for more details.
It also extends the StepContext
in the templates to have the steps.{added,modified,deleted}_files
and steps.path
fields.
Example batch spec
name: conditional-exec
description: Testing conditional execution of steps
on:
- repository: github.com/sourcegraph-testing/mkcert
- repository: github.com/sourcegraph-testing/zap
- repository: github.com/sourcegraph/automation-testing
steps:
#
# Step 1.
# No `if:`, runs in every repository/workspace
#
- run: echo "This is ${{ repository.name }}" >> message.txt
container: alpine:3
#
# Step 2.
# `if:` checks for repository name. Only runs in github.com/sourcegraph/automation-testing
#
- run: echo "hello viewers! is the background noise from the landscapers too loud? leave a message after the beep" >> message.txt
if: "${{ eq repository.name \"github.com/sourcegraph/automation-testing\" }}"
container: alpine:3
#
# Step 3.
# `if:` checks repository name. Only runs in repos
#
- run: echo "repo name contains sourcegrap-testing" >> message.txt
# The new builtin function `matches` makes it easy to check for repository names:
if: "${{ matches repository.name \"*sourcegraph-testing*\" }}"
container: alpine:3
#
# Step 4.
# Checks for go.mod existance and saves to outputs
#
- run: if [[ -f "go.mod" ]]; then echo "true"; else echo "false"; fi
container: alpine:3
outputs:
goModExists:
value: ${{ step.stdout }}
#
# Step 5.
# `if:` checks whether the value just saved to outputs is true
#
- run: go fmt ./...
container: golang
# `if:` supports templating and has access to the full step context, including `previous_step.stdout`, `repository.name`, etc.
if: ${{ outputs.goModExists }}
#
# Step 6.
# `if:` checks whether the steps are executed in a workspace.
#
- run: echo "hello workspace" >> workspace.txt
container: golang
if: ${{ eq steps.path "sub/directory/in/repo" }}
changesetTemplate:
title: Testing conditional execution of steps
body: Testing conditional execution of steps
branch: thorsten/conditional-exec
published: false
commit:
message: Conditional exec of steps
Demo video
Click here