# GitLab<no value>

// <!-- Required for asciidoctor -->
:toc:
// Set toclevels to be at least your hugo [markup.tableOfContents.endLevel] config key
:toclevels: 4

== Description

The `gitlab` scm plugin clones a repository hosted on GitLab (gitlab.com or a self-managed instance) and pushes changes back to it. It is referenced by a resource through its `scmid`, as described on the link:/docs/core/scm/["SCM" page].

Its behavior depends on the stage referencing it:

**source** and **condition**::
The repository is cloned and the resource works on the files from the branch defined by `branch`. Nothing is pushed.

**target**::
Updatecli creates a *working branch* based on `branch`, commits the changes to it, and pushes that branch. The `branch` value itself is left untouched.

IMPORTANT: This plugin does not open merge requests. Pushing a working branch and opening a merge request are two distinct steps: the merge request comes from an `actions` block of kind `gitlab/mergerequest`, documented on the link:/docs/plugins/actions/gitlab/["GitLab Merge Request" page]. Without such an action, the branch is pushed and nothing else happens.

== Parameters

{{< resourceparameters "scms" "gitlab" >}}

`owner` and `repository` are mandatory, a missing one aborts the run with `wrong gitlab configuration`. For a project nested in subgroups, `owner` carries the full group path:

[source,yaml]
----
owner: "mygroup/mysubgroup"
repository: "myproject"
----

NOTE: The table is generated from the Updatecli JSON schema, refreshed by a bot after each release. A recently added parameter (currently `singleBranch`, which restricts clone and fetch to the configured branch) may work in the binary before it appears there.

=== Authentication

`url` defaults to `gitlab.com`. For a self-managed instance, give its hostname with or without a scheme; `https://` is assumed when none is given.

`token` is used both for the GitLab API and, together with `username`, as the HTTP credentials for git operations. Keep it out of the manifest:

[source,yaml]
----
# url: gitlab.example.com   # defaults to gitlab.com
username: '{{ requiredEnv "GITLAB_USERNAME" }}'
token: '{{ requiredEnv "GITLAB_TOKEN" }}'
----

The token needs read access for a source or a condition, and write access to the repository for a target. Reading from a public repository works without any credential.

==== Personal vs group or project access tokens

A personal access token carries the identity of the user it belongs to, so GitLab attributes the commits to that account.

Group and project access tokens do not. Combined with the default commit identity (`updatecli-bot <updatecli-bot@updatecli.io>`, which matches no GitLab account), the commits end up attributed to nobody, and the merge request Updatecli opens can remain stuck in the *"Your merge request is almost ready!"* state. Set `user` and `email` to the identity the token acts as:

[source,yaml]
----
user: "<the bot user name shown by GitLab for that token>"
email: "<the bot user email shown by GitLab for that token>"
----

=== Working branch

For a target, the working branch is derived from three components joined by a separator:

[source,text]
----
<workingBranchPrefix><workingBranchSeparator><branch><workingBranchSeparator><pipelineID>
----

With the defaults (`updatecli` and `_`), a pipeline based on `main` produces `updatecli_main_<pipelineID>`, where `pipelineID` is a hash derived from the manifest - so the same pipeline reuses the same branch instead of piling up new ones. Characters git refuses in a ref are stripped, and the name is truncated to 255 characters. Setting `workingBranchPrefix: ""` gives `<branch>_<pipelineID>`.

`branch` defaults to `main`, with a warning in the logs when it is left unset.

==== Disabling the working branch

`workingBranch: false` makes Updatecli commit and push straight to `branch`. Since `force` defaults to `true` (meaning `git push --force`), that combination is refused unless `force` is also set explicitly:

[source,text]
----
Better safe than sorry.

Updatecli may be pushing unwanted changes to the branch "main".
----

Set `force: false` to push without forcing, or `force: true` to acknowledge the force push. When `force` is `true`, Updatecli also recreates working branches that diverged from their base branch.

TIP: `updatecli apply --clean-git-branches` deletes, at the end of a run, the working branches that ended up identical to their base branch (those left behind by pipelines that had nothing to change).

=== Commit message

Updatecli generates link:https://www.conventionalcommits.org/[conventional commits]. The `commitMessage` parameters (`type`, `scope`, `body`, `footers`, `hideCredit`, `squash`) shape the result.

The commit title always comes from the target's `name`, or from its description when `name` is unset. It is capped at 72 characters minus the room taken by `type` and `scope`; the overflow moves into the body. With the default type `chore`:

[source,text]
----
Author: updatecli-bot <updatecli-bot@updatecli.io>
Date:   Tue May 4 15:41:44 2021 +0200

    chore: Update key "dependencies[0].version" from file "charts/jenkins/r...

    ... equirements.yaml"

    Made with ❤️️  by updatecli
----

Setting `body` replaces the generated body entirely, including that overflow. `hideCredit: true` drops the credit line. `squash: true` collapses the commits of the working branch into one (set `body` when you use it, since the individual messages are lost).

[WARNING]
====
`commitMessage.title` is deprecated and ignored. Rename the target instead; Updatecli logs a warning when the field is present.
====

NOTE: `commitMessage` applies to every target linked to the same scm.

=== Commit signing

`gpg.signingkey` takes an *armored private* GPG key and `gpg.passphrase` its passphrase. Both are secrets:

[source,yaml]
----
gpg:
  signingkey: '{{ requiredEnv "GPG_SIGNING_KEY" }}'
  passphrase: '{{ requiredEnv "GPG_PASSPHRASE" }}'
----

=== Clone behavior

Left unset, `directory` defaults to `<tmp>/updatecli/gitlab/<owner>/<repository>` - `/tmp/updatecli/gitlab/olblak/updatecli` on Linux. Overriding it is rarely useful, as Updatecli may clean that directory up after a run.

`submodules`:: Defaults to `true`; set it to `false` to skip submodule checkout.
`depth`:: Number of commits to fetch. Unset means a full clone. A shallow clone leaves an incomplete history, which can break pushes; `force: true` is often needed alongside.
`singleBranch`:: Defaults to `false`, meaning every branch, tag, and ref is fetched. `true` fetches only `branch` (much faster on repositories with many refs, at the cost of Updatecli sometimes failing to notice an already published working branch and opening a duplicate merge request).

TIP: To run the same manifest against every project of a group instead of a single repository, use the link:/docs/plugins/scm/gitlabsearch/[`gitlabsearch`] scm.

== Example

[source,yaml]
----
# updatecli.yaml
{{<include "assets/code_example/docs/plugins/gitlab/updatecli.yaml">}}
----
