Campaign spec YAML reference
Sourcegraph campaigns use campaign specs to define campaigns.
This page is a reference guide to the campaign spec YAML format in which campaign specs are defined. If you're new to YAML and want a short introduction, see "Learn YAML in five minutes."
name
The name of the campaign, which is unique among all campaigns in the namespace. A campaign's name is case-preserving.
Examples
name: update-go-import-statements
name: update-node.js
description
The description of the campaign. It's rendered as Markdown.
Examples
description: This campaign changes all `fmt.Sprintf` calls to `strconv.Iota`.
description: | This campaign changes all imports from `gopkg.in/sourcegraph/sourcegraph-in-x86-asm` to `github.com/sourcegraph/sourcegraph-in-x86-asm`
on
The set of repositories (and branches) to run the campaign on, specified as a list of search queries (that match repositories) and/or specific repositories.
Examples
on: - repositoriesMatchingQuery: lang:go fmt.Sprintf("%d", :[v]) patterntype:structural - repository: github.com/sourcegraph/sourcegraph
on.repositoriesMatchingQuery
A Sourcegraph search query that matches a set of repositories (and branches). Each matched repository branch is added to the list of repositories that the campaign will be run on.
See "Code search" for more information on Sourcegraph search queries.
Examples
on: - repositoriesMatchingQuery: file:README.md -repo:github.com/sourcegraph/src-cli
on: - repositoriesMatchingQuery: lang:typescript file:web const changesetStatsFragment
on.repository
A specific repository (and branch) that is added to the list of repositories that the campaign will be run on.
A branch
attribute specifies the branch on the repository to propose changes to. If unset, the repository's default branch is used. If set, it overwrites earlier values to be used for the repository's branch.
Examples
on: - repository: github.com/sourcegraph/src-cli
on: - repository: github.com/sourcegraph/sourcegraph branch: 3.19-beta - repository: github.com/sourcegraph/src-cli
In the following example, the repositoriesMatchingQuery
returns both repositories with their default branch, but the 3.23
branch is used for github.com/sourcegraph/sourcegraph
, since it is more specific:
on: - repositoriesMatchingQuery: repo:sourcegraph\/(sourcegraph|src-cli)$ - repository: github.com/sourcegraph/sourcegraph branch: 3.23
In this example, 3.19-beta
branch is used, since it was named last:
on: - repositoriesMatchingQuery: repo:sourcegraph\/(sourcegraph|src-cli)$ - repository: github.com/sourcegraph/sourcegraph branch: 3.23 - repository: github.com/sourcegraph/sourcegraph branch: 3.19-beta
steps
The sequence of commands to run (for each repository branch matched in the on
property) to produce the campaign's changes.
Examples
steps: - run: echo "Hello World!" >> README.md container: alpine:3
steps: - run: comby -in-place 'fmt.Sprintf("%d", :[v])' 'strconv.Itoa(:[v])' .go -matcher .go -exclude-dir .,vendor container: comby/comby - run: gofmt -w ./ container: golang:1.15-alpine
steps: - run: ./update_dependency.sh container: our-custom-image env: OLD_VERSION: 1.31.7 NEW_VERSION: 1.33.0
steps.run
The shell command to run in the container. It can also be a multi-line shell script. The working directory is the root directory of the repository checkout.
steps.container
The Docker image used to launch the Docker container in which the shell command is run.
The image has to have either the /bin/sh
or the /bin/bash
shell.
It is executed using docker
on the machine on which the Sourcegraph CLI (src
) is executed. If the image exists locally, that is used. Otherwise it's pulled using docker pull
.
steps.env
Environment variables to set in the environment when running this command.
These may be defined either as an object or (in Sourcegraph 3.23 and later) as an array.
Environment object
In this case, steps.env
is an object, where the key is the name of the environment variable and the value is the value.
Examples
steps: - run: echo $MESSAGE >> README.md container: alpine:3 env: MESSAGE: Hello world!
Environment array
In this case, steps.env
is an array. Each array item is either:
- An object with a single property, in which case the key is used as the environment variable name and the value the value, or
- A string that defines an environment variable to include from the environment
src
is being run within. This is useful to define secrets that you don't want to include in the spec file, but this makes the spec dependent on your environment, means that the local execution cache will be invalidated each time the environment variable changes, and means that the campaign spec file is no longer the sole source of truth intended by the campaigns design.
Examples
This example is functionally the same as the object example above:
steps: - run: echo $MESSAGE >> README.md container: alpine:3 env: - MESSAGE: Hello world!
This example pulls in the USER
environment variable and uses it to construct the line that will be appended to README.md
:
steps: - run: echo $MESSAGE from $USER >> README.md container: alpine:3 env: - MESSAGE: Hello world! - USER
For instance, if USER
is set to adam
, this would append Hello world! from adam
to README.md
.
steps.files
Files to create on the host machine and mount into the container when running steps.run
.
steps.files
is an object, where the key is the name of the file inside the container and the value is the content of the file.
Examples
steps: - run: cat /tmp/my-temp-file.txt >> README.md container: alpine:3 files: /tmp/my-temp-file.txt: Hello world!
steps: - run: cat /tmp/global-gitignore >> .gitignore container: alpine:3 files: /tmp/global-gitignore: | # Vim *.swp # JetBrains/IntelliJ .idea # Emacs *~ \#*\# /.emacs.desktop /.emacs.desktop.lock .\#* .dir-locals.el
importChangesets
An array describing which already-existing changesets should be imported from the code host into the campaign.
Examples
importChangesets: - repository: github.com/sourcegraph/sourcegraph externalIDs: [13323, "13343", 13342, 13380] - repository: github.com/sourcegraph/src-cli externalIDs: [260, 271]
importChangesets.repository
The repository name as configured on your Sourcegraph instance.
importChangesets.externalIDs
The changesets to import from the code host. For GitHub this is the pull request number, for GitLab this is the merge request number, for Bitbucket Server this is the pull request number.
changesetTemplate
A template describing how to create (and update) changesets with the file changes produced by the command steps.
This defines what the changesets on the code hosts (pull requests on GitHub, merge requests on Gitlab, ...) will look like.
Examples
changesetTemplate: title: Replace equivalent fmt.Sprintf calls with strconv.Itoa body: This campaign replaces `fmt.Sprintf("%d", integer)` calls with semantically equivalent `strconv.Itoa` calls branch: campaigns/sprintf-to-itoa commit: message: Replacing fmt.Sprintf with strconv.Iota author: name: Lisa Coder email: [email protected] published: false
changesetTemplate: title: Update rxjs in package.json to newest version body: This pull request updates rxjs to the newest version, `6.6.2`. branch: campaigns/update-rxjs commit: message: Update rxjs to 6.6.2 published: true
changesetTemplate: title: Run go fmt over all Go files body: Regular `go fmt` run over all our Go files. branch: go-fmt commit: message: Run go fmt author: name: Anna Wizard email: [email protected] published: # Do not meddle in the affairs of wizards, for they are subtle and quick to anger. - git.istari.example/*: false - git.istari.example/anna/*: true
changesetTemplate.title
The title of the changeset on the code host.
changesetTemplate.body
The body (description) of the changeset on the code host. If the code supports Markdown you can use it here.
changesetTemplate.branch
The name of the Git branch to create or update on each repository with the changes.
changesetTemplate.commit
The Git commit to create with the changes.
changesetTemplate.commit.message
The Git commit message.
changesetTemplate.commit.author
The name
and email
of the Git commit author.
Examples
changesetTemplate: commit: author: name: Alan Turing email: [email protected]
changesetTemplate.published
Whether to publish the changeset. This may be a boolean value (ie true
or false
), 'draft'
, or an array to only publish some changesets within the campaign.
An unpublished changeset can be previewed on Sourcegraph by any person who can view the campaign, but its commit, branch, and pull request aren't created on the code host.
When published
is set to draft
a commit, branch, and pull request / merge request are being created on the code host in draft mode. This means:
- On GitHub the changeset will be a draft pull request.
- On GitLab the changeset will be a merge request whose title is be prefixed with
'WIP: '
to flag it as a draft merge request. - On BitBucket Server draft pull requests are not supported and changesets published as
draft
won't be created.
A published changeset results in a commit, branch, and pull request being created on the code host.
Publishing only specific changesets
To publish only specific changesets within a campaign, an array of single-element objects can be provided. For example:
published: - github.com/sourcegraph/sourcegraph: true - github.com/sourcegraph/src-cli: false - github.com/sourcegraph/campaignutils: draft
Each key will be matched against the repository name using glob syntax. The gobwas/glob library is used for matching, with the key operators being:
Term | Meaning |
---|---|
* |
Match any sequence of characters |
? |
Match any single character |
[ab] |
Match either a or b |
[a-z] |
Match any character between a and z , inclusive |
{abc,def} |
Match either abc or def |
If multiple entries match a repository, then the last entry will be used. For example, github.com/a/b
will not be published given this configuration:
published: - github.com/a/*: true - github.com/*: false
If no entries match, then the repository will not be published. To make the default true, add a wildcard entry as the first item in the array:
published: - "*": true - github.com/*: false
Examples
To publish all changesets created by a campaign:
changesetTemplate: published: true
To publish all changesets created by a campaign as drafts:
changesetTemplate: published: draft
To only publish changesets within the sourcegraph
GitHub organization:
changesetTemplate: published: - github.com/sourcegraph/*: true
To publish all changesets that are not on GitLab:
changesetTemplate: published: - "*": true - gitlab.com/*: false
To publish all changesets on GitHub as draft:
changesetTemplate: published: - "*": true - github.com/*: draft
transformChanges
A description of how to transform the changes (diffs) produced in each repository before turning them into separate changeset specs by inserting them into the changesetTemplate
.
This allows the creation of multiple changeset specs (and thus changesets) in a single repository.
Examples
# Transform the changes produced in each repository. transformChanges: # Group the file diffs by directory and produce an additional changeset per group. group: # Create a separate changeset for all changes in the top-level `go` directory - directory: go branch: my-campaign-go # will replace the `branch` in the `changesetTemplate` - directory: internal/codeintel branch: my-campaign-codeintel # will replace the `branch` in the `changesetTemplate` repository: github.com/sourcegraph/src-cli # optional: only apply the rule in this repository
transformChanges: group: - directory: go/utils/time branch: my-campaign-go-time # The *last* matching directory is used, not the most specific one, # so only this changeset would be opened. - directory: go/utils branch: my-campaign-go-date
transformChanges.group
A list of groups to define which file diffs to group together to create an additional changeset in the given repository.
The order of the list matters, since each file diff's filepath is matched against the directory
of a group and the last match is used.
If no changes have been produced in a directory
then no changeset will be created.
transformChanges.group.directory
The name of the directory in which file diffs should be grouped together.
The name is relative to the root of the repository.
transformChanges.group.branch
The branch that should be used for this additional changeset. This overwrites the changesetTemplate.branch
when creating the additional changeset.
Important: the branch can not be nested under the changesetTemplate.branch
, i.e. if the changesetTemplate.branch
is my-campaign
then this can not be my-campaign/my-subdirectory
since git doesn't allow that.
transformChanges.group.repository
Optional: the file diffs matching the given directory will only be grouped in a repository with that name, as configured on your Sourcegraph instance.