A campaign can be created from a set of patches, one per repository. For each patch, a changeset (what code hosts call pull request or merge request) will be created on the code host on which the repository is hosted.
Here is the short version for how to create a patch set and turn that into changesets by creating a campaign:
action.json
) that contains an action definition.src actions scope-query -f action.json
src actions exec -f action.json > patches.json
src campaign patchset create-from-patches < patches.json
src campaigns create -branch=<branch-name> -patchset=<patchset-ID-returned-by-previous-command>
Read on detailed steps and documentation.
If you have not done so already, first install, set up and configure the src
CLI to point to your Sourcegraph instance.
The first thing we need is a definition of an "action". An action contains a list of steps to run in each repository returned by the results of the scopeQuery
search string.
There are two types of steps: docker
and command
. See src actions exec -help
for more information.
Here is an example of a multi-step action definition using the docker
and command
types:
{ "scopeQuery": "repo:go-* -repohasfile:INSTALL.md", "steps": [ { "type": "command", "args": ["sh", "-c", "echo '# Installation' > INSTALL.md"] }, { "type": "command", "args": ["sed", "-i", "", "s/No install instructions/See INSTALL.md/", "README.md"] }, { "type": "docker", "dockerfile": "FROM alpine:3 \n CMD find /work -iname '*.md' -type f | xargs -n 1 sed -i s/this/that/g" }, { "type": "docker", "image": "golang:1.13-alpine", "args": ["go", "fix", "/work/..."] } ] }
This action will execute on every repository that has go-
in its name and doesn't have an INSTALL.md
file.
The first step (a command
step) creates an INSTALL.md
file in the root directory of each repository by running sh
in a temporary copy of each repository. This is executed on the machine on which src
is being run. Note that the first element in "args"
is the command itself.
The second step, again a "command"
step, runs the sed
command to replace text in the README.md
file in the root of each repository (the -i ''
argument is only necessary for BSD versions of sed
that usually come with macOS). Please note that the executed command is simply sed
which means its arguments are not expanded, as they would be in a shell. To achieve that, execute the sed
as part of a shell invocation (using sh -c
and passing in a single argument, for example, like in the first step).
The third step builds a Docker image from the specified "dockerfile"
and starts a container with this image in which the repository is mounted under /work
.
The fourth step starts a Docker container based on the golang:1.13-alpine
image and runs go fix /work/...
in it.
As you can see from these examples, the "output" of an action is the modified, local copy of a repository.
Save that definition in a file called action.json
(or any other name of your choosing).
With our action file defined, we can now execute it:
src actions exec -f action.json
This command is going to:
"scopeQuery"
from the Sourcegraph instance to a local temporary directory in /tmp
.-j
, the default is number of cores on the machine), with each step in an action being executed sequentially on the same copy of a repository. If a step in an action is of type "command"
the command will be executed in the temporary directory that contains the copy of the repository. If the type is "docker"
then a container will be launched in which the repository is mounted under /work
.The output can either be saved into a file by redirecting it:
src actions exec -f action.json > patches.json
Or it can be piped straight into the next command we're going to use to save the patches on the Sourcegraph instance:
src actions exec -f action.json | src campaign patchset create-from-patches
The patches for a campaign are generated on the machine where the
src
CLI is executed, which in turn, downloads zip archives and runs each step against each repository. For most usecases we recommend thatsrc
CLI should be run on a Linux machine with considerable CPU, RAM, and network bandwidth to reduce the execution time. Putting this machine in the same network as your Sourcegraph instance will also improve performance.
Another factor affecting execution time is the number of jobs executed in parallel, which is by default the number of cores on the machine. This can be adjusted using the
-j
parameter.
The next step is to save the set of patches on the Sourcegraph instance so they can be turned into a campaign.
To do that, run:
src campaign patchset create-from-patches < patches.json
Or, again, pipe the patches directly into it:
src actions exec -f action.json | src campaign patchset create-from-patches
Once completed, the output will contain:
src
SLI to create a campaign from the patch set.If you're happy with the preview of the campaign, it's time to trigger the creation of changesets (pull requests) on the code host(s) by creating and publishing the campaign:
src campaigns create -name='My campaign name' \ -desc='My first CLI-created campaign' \ -patchset=Q2FtcGFpZ25QbGFuOjg= \ -branch=my-first-campaign
Creating this campaign will asynchronously create a pull request for each repository that has a patch in the patch set. You can check the progress of campaign completion by viewing the campaign on your Sourcegraph instance.
The -branch
flag specifies the branch name that will be used for each pull request. If a branch with that name already exists for a repository, a fallback will be generated by appending a counter at the end of the name, e.g.: my-first-campaign-1
.
If you have defined the $EDITOR
environment variable, the configured editor will be used to edit the name and Markdown description of the campaign:
src campaigns create -patchset=Q2FtcGFpZ25QbGFuOjg= -branch=my-first-campaign