Description

gitlabsearch is not an scm you clone from - it is a generator. Before anything else runs, Updatecli lists the projects of the configured GitLab group, lists the branches of each of them, keeps the branches matching branch, and turns each surviving project/branch pair into a regular gitlab scm.

Your manifest is then duplicated once per pair, each copy pinned to one project and one branch. Ten matches mean ten pipelines, ten working branches, and (if the manifest declares a gitlab/mergerequest action) ten merge requests. Everything the gitlab documentation says about cloning, working branches, commits, and signing applies unchanged to each copy.

Its behavior depends on the stage referencing it:

source and condition

Each discovered project is cloned and the resource works on the files from the matched branch. Nothing is pushed.

target

Updatecli creates a working branch in each discovered project, commits the changes there, and pushes it.

Important
Like the gitlab scm, this plugin does not open merge requests (that is the job of an actions block of kind gitlab/mergerequest, documented on the "GitLab Merge Request" page).

Parameters

NameTypeDescriptionRequired
branchstring

“branch” defines a regular expression matching the git branches to work on.

default: ^main$

remark:

  • one GitLab scm is generated for each matching branch of each discovered repository.
  • when a generated scm is used by a source or a condition, files are read from the matching branch.
  • when a generated scm is used by a target, Updatecli pushes changes to a working branch based on the matching branch, named “updatecli__” by default.
  • set “workingbranch” to false to push changes directly to the matching branch.

example:

  • branch: ^main$
  • branch: ^release/.*$
commitmessageobject

“commitmessage” defines the settings used to generate commit messages.

remark:

  • the settings apply to every target using this scm.
    bodystring

“body” defines the conventional commit body.

default: empty, which means the body is generated by Updatecli.

remark:

  • see https://www.conventionalcommits.org/en/
    deprecatedtitlestring

“title” is ignored.

deprecated:

  • the commit title is always generated from the target name or description.
    footersstring

“footers” defines the conventional commit footers.

default: empty

remark:

  • see https://www.conventionalcommits.org/en/
    hidecreditboolean

“hidecredit” defines whether the Updatecli credit line is left out of the commit message body.

default: false

remark:

  • if you disable the credit line, please consider sponsoring the Updatecli project, https://github.com/updatecli/updatecli
    scopestring

“scope” defines the conventional commit scope.

default: empty

remark:

  • see https://www.conventionalcommits.org/en/
    squashboolean

“squash” defines whether the commits are squashed into a single commit.

default: false

remark:

  • squashing loses the other commit messages, so setting a meaningful “body” is recommended.
  • when “body” is empty, the squashed commit message is generated from the most recent squashed commit. The title is always generated from the target name or description.
    titlestringTitle is the parsed commit message title (not configurable via YAML). The title is automatically generated from the target name or description.
    typestring

“type” defines the conventional commit type, such as “chore”, “fix” or “feat”.

default: chore

remark:

  • see https://www.conventionalcommits.org/en/
depthinteger

“depth” defines the depth used when cloning the git repository.

default: empty, which means a full clone.

remark:

  • a value greater than 0 creates a shallow clone, so Updatecli cannot see the full git history. Pushing changes may then fail, in which case setting “force” to true may be needed.
  • a negative value is rejected.

example:

  • depth: 1
directorystring

“directory” defines the local path where the git repository is cloned.

default: a directory under the Updatecli temporary directory, such as “/tmp/updatecli/gitlab//” on Linux.

remark:

  • keep the default value unless you have a good reason to change it, as Updatecli may delete the directory after a pipeline run.
  • the value is passed as is to every generated scm., so every repository then uses the same directory.
emailstring

“email” defines the email address used to author commits.

default: updatecli-bot@updatecli.io

forceboolean

“force” defines whether Updatecli runs git push --force when pushing changes.

default: true

remark:

  • when true, Updatecli also recreates the working branches that diverged from their base branch.
  • when “workingbranch” is false and “force” is not set, each generated GitLab scm returns an error, to avoid force pushing to “branch” by mistake. Set “force” explicitly to confirm the behavior.
gpgobject“gpg” defines the GPG key and passphrase used to sign commits.
    passphrasestring“passphrase” defines the passphrase that unlocks “signingkey”.
    signingkeystring

“signingkey” defines the armored GPG private key used to sign commits.

default: empty, which means commits are not signed.

remark:

  • the value is the key content, not a key ID.
  • a private key is sensitive, so avoid writing it in the manifest.
groupstring

“group” defines the GitLab group, or subgroup, to search repositories in.

remark:

  • nested groups use the slash notation.

example:

  • group: myorg/myteam
includesubgroupsboolean

“includesubgroups” defines whether repositories from subgroups are included in the search results.

default: true

limitinteger

“limit” defines the maximum number of GitLab scm generated from the search results.

default: 10

remark:

  • 0 means no limit.
  • one scm is generated for each matching branch of each repository, so the limit counts repository branches, not repositories.
searchstring

“search” filters the repositories of the group by name.

remark:

  • when empty, every repository of the group is returned.
submodulesboolean

“submodules” defines whether Updatecli clones the git submodules of the repository.

default: true

tokenstring

“token” defines the credential used to authenticate with GitLab.

remark:

  • a token is sensitive information. Do not set it directly in the manifest, use an environment variable or a SOPS file instead.
  • {{ requiredEnv "GITLAB_TOKEN" }} retrieves the token from the environment variable GITLAB_TOKEN.
  • {{ .gitlab.token }} retrieves the token from a SOPS file.
  • for more information about SOPS files, see https://github.com/getsops/sops

example:

  • token: ‘{{ requiredEnv “GITLAB_TOKEN” }}’
urlstring

“url” defines the GitLab url to interact with.

default: gitlab.com

remark:

  • “https://” is added when the url has no “http://” or “https://” scheme.

example:

  • url: gitlab.com
  • url: https://gitlab.example.com
userstring

“user” defines the name used to author commits.

default: updatecli-bot

usernamestring“username” defines the username used to authenticate with GitLab.
workingbranchboolean

“workingbranch” defines whether Updatecli pushes changes to a temporary working branch based on “branch”, instead of pushing to “branch” directly.

default: true

workingbranchprefixstring

“workingbranchprefix” defines the prefix of the working branch name.

default: updatecli

remark:

  • the working branch name joins the prefix, the target branch and the pipeline ID, separated by “workingbranchseparator”.
  • when set to an empty string, the name starts with the separator, for example “main”.
workingbranchseparatorstring

“workingbranchseparator” defines the separator between the parts of the working branch name.

default: _

group is the only mandatory parameter; without it the run aborts with GitLab group is required for gitlabsearch SCM.

Apart from group, search, includeSubgroups, branch, and limit, every parameter is passed through untouched to each generated gitlab scm; see the "GitLab" page for what they do. One consequence is worth spelling out: directory is copied verbatim, so every discovered project would be cloned into the same path. Leave it unset and let Updatecli derive one path per project.

Selecting projects

group

The group path. Nested groups use slash notation:

group: "myorg/myteam"
includeSubgroups

Defaults to true, so projects of nested subgroups are discovered too. Set it to false to stay in the group itself.

search

An optional GitLab project-name filter, passed to the API as-is. Omitted, every project of the group is returned. It is a substring search, not a regular expression, unlike branch.

Each discovered project’s full path is split at the last slash: myorg/myteam/myproject becomes owner: myorg/myteam and repository: myproject on the generated scm.

Branch selection

branch is a regular expression matched against every branch name of every discovered project, not a branch name. It defaults to ^main$.

branch: "^main$"          # main only (default)
branch: "^main$|^v2$"     # main or v2
branch: "^release/"       # every release branch

Anchors matter. An unanchored expression such as main also matches maintenance, and . matches every branch in the project.

Limit

limit caps the number of generated pipelines, that is project/branch pairs - not the number of projects. It defaults to 10; 0 means no cap.

A project with three matching branches therefore consumes three slots, and can exhaust the limit before the second project is reached. Projects and branches are consumed in the order the API returns them, so a limit that truncates the set gives you an arbitrary subset rather than a chosen one. Tighten branch and search instead of relying on limit to keep a run small.

Authentication

url defaults to gitlab.com; for a self-managed instance, give its hostname with or without a scheme. token authenticates both the API calls used for discovery and the git operations on each discovered project, together with username.

# url: gitlab.example.com   # defaults to gitlab.com
username: '{{ requiredEnv "GITLAB_USERNAME" }}'
token: '{{ requiredEnv "GITLAB_TOKEN" }}'

The token must be able to list the group’s projects, on top of the permissions each project needs. As with the gitlab scm, a group or project access token has no user identity of its own (set user and email accordingly, or the merge requests can stay stuck in the "Your merge request is almost ready!" state).

Working branch and commit message

Both work exactly as on the "GitLab" page: a working branch named <workingBranchPrefix><separator><branch><separator><pipelineID>, force defaulting to true with its "better safe than sorry" safeguard, and conventional commit messages driven by commitMessage.

The pipelineID component is derived from the manifest, not from the project, so all copies share it and every discovered project ends up with an identically named working branch (convenient when you later need to find or clean up the branches a group-wide run created).

Note
commitMessage.title is deprecated and ignored. The commit title comes from the target name.

Example

This manifest bumps the Golang version across the projects of the myorg/myteam group. Each discovered project/branch pair gets its own working branch, its own squashed commit, and its own merge request.

# updatecli.yaml
name: "Updatecli Golang - GitLab group"
pipelineid: "golang/version"

scms:
  default:
    kind: gitlabsearch
    spec:
      # url defaults to gitlab.com
      # url: gitlab.example.com
      group: "myorg/myteam"
      # optional project name filter, every project of the group otherwise
      search: "service"
      # discover projects of nested subgroups too, true by default
      includesubgroups: true
      # maximum number of project/branch pairs to process
      limit: 3
      # "branch" is a regular expression matched against every branch name
      branch: "^main$"
      username: '{{ requiredEnv "GITLAB_USERNAME" }}'
      token: '{{ requiredEnv "GITLAB_TOKEN" }}'
      # a group or project access token has no identity of its own,
      # name the bot user explicitly so GitLab can attribute the commits
      user: updatecli-bot
      email: updatecli-bot@updatecli.io
      commitmessage:
        squash: true
        type: chore
        scope: deps

actions:
  default:
    kind: gitlab/mergerequest
    scmid: default
    spec:
      title: 'deps(golang): Bump Golang version'
      labels:
        - dependencies

sources:
  golang:
    name: Get the latest Golang version
    kind: golang
    spec:
      versionfilter:
        kind: semver
        pattern: "1.24.x"

targets:
  gitlab-ci:
    # the commit title is generated from this name
    name: 'deps(golang): Bump Golang version to {{ source "golang" }}'
    kind: yaml
    scmid: default
    spec:
      file: .gitlab-ci.yml
      key: $.variables.GOLANG_VERSION