Skip to content

Commit

Permalink
git: add docs for usage with Gerrit
Browse files Browse the repository at this point in the history
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
  • Loading branch information
aryan9600 committed Aug 22, 2023
1 parent e216fa2 commit e29ae1d
Showing 1 changed file with 87 additions and 5 deletions.
92 changes: 87 additions & 5 deletions docs/spec/v1beta1/imageupdateautomations.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ spec:
name: fluxcdbot
```
There are over 70 available functions. Some of them are defined by the [Go template language](https://pkg.go.dev/text/template) itself. Most of the others are part of the [Sprig template library](http://masterminds.github.io/sprig/).

### Push

The optional `push` field defines how commits are pushed to the origin.
Expand Down Expand Up @@ -439,8 +440,10 @@ Note that without force push in push branches, if the target branch is stale, th
be able to conclude the operation and will consistently fail until the branch is either deleted or
refreshed.

If both `push.refspec` and `push.branch` are specified, then the reconciler will perform two push
operations, one to the specified branch and another using the specified refspec.
If both `push.refspec` and `push.branch` are specified, then the reconciler will perform
two push operations, one to the specified branch and another using the specified refspec.
This is particularly useful for working with Gerrit servers. Please see below for more
details aboout Gerrit.

**Note:** If both `push.refspec` and `push.branch` are essentially equal to each
other (for e.g.: `push.refspec: refs/heads/main:refs/heads/main` and
Expand All @@ -461,21 +464,100 @@ spec:
branch: auto
```
In the following snippet, updates and commits will be made on the `auto` branch locally.
The commits will be then pushed to the `auto` branch and then using the `refs/heads/auto:refs/heads/main`
refspec:
In the following snippet, updates and commits will be made on the `main` branch locally.
The commits will be then pushed using the `refs/heads/main:refs/heads/auto` refspec:

```yaml
spec:
git:
checkout:
ref:
branch: main
push:
refspec: refs/heads/main:refs/heads/auto
```

#### Gerrit

[Gerrit](https://www.gerritcodereview.com/) doesn't behave like a standard Git
server. Instead of pushing all your changes to a branch in the form of one or
more commits, you push all your changes as a single commit. This commit must
have a unique identifier which is different from the commit SHA. Furthermore,
instead of a Pull Request being opened from one branch to another, you push your
commit using a refspec: `HEAD:refs/for/main`. Since image-automation-controller
is primarily supposed to work with standard Git servers, these special
characteristics necessitate a few workarounds. Let's take a look at an example
configuration that plays nicely with Gerrit:

```yaml
spec:
git:
checkout:
ref:
branch: main
commit:
author:
email: flux@localdomain
name: flux
messageTemplate: |
Perform automatic image update
Automation name: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Updated.Files -}}
- {{ $filename }}
{{ end }}
Objects:
{{ range $resource, $_ := .Updated.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end }}
Images:
{{ range .Updated.Images -}}
- {{ . }}
{{ end }}
{{- $ChangeId := .AutomationObject -}}
{{- $ChangeId = printf "%s%s" $ChangeId ( .Updated.Files | toString ) -}}
{{- $ChangeId = printf "%s%s" $ChangeId ( .Updated.Objects | toString ) -}}
{{- $ChangeId = printf "%s%s" $ChangeId ( .Updated.Images | toString ) }}
Change-Id: {{ printf "I%s" ( sha256sum $ChangeId | trunc 40 ) }}
push:
branch: auto
refspec: refs/heads/auto:refs/heads/main
```

This tells image-automation-controller to clone the repo using the `main` branch
but, run its update logic and make any commits using the provided message
template on the `auto` branch. It pushes them to the `auto` branch and then,
pushes the `HEAD` of the `auto` branch to the `HEAD` of the remote `main`
branch. The message template ensures that we introduce a [Change-Id](https://gerrit-review.googlesource.com/Documentation/concept-changes.html#change-id)
at the bottom of the commit message.

The reason behind pushing the commit to a branch initially is to avoid multiple
[Patch Sets](https://gerrit-review.googlesource.com/Documentation/concept-patch-sets.html).
If we omitted `push.branch` and just specified
`push.refspec: refs/heads/main:refs/heads/main`, then we would be able to open
a [Change](https://gerrit-review.googlesource.com/Documentation/concept-changes.html)
as intended. But, every time the reconciler does a fresh clone of the `main`
branch while the Change is still open, it'll run its update logic against the
files in the `main` branch resulting in a new commit being pushed with the same
changes to the already open Change. Specifying a `push.branch` lets us work
around this since, it tells the reconciler to run the update logic against
the `auto` branch, which already contains the desired commit. This pattern
is also recommended in the [Gerrit docs](https://gerrit-review.googlesource.com/Documentation/intro-gerrit-walkthrough-github.html#create-change).

Another thing to note here is the syntax of `push.refspec`. Instead of it being
`HEAD:refs/for/main`, which is what most Gerrit users use, we specify the full
refname `refs/heads/auto` in the source part of the refpsec.

**Note:** A known limitation of using image-automation-controller with Gerrit is
multiple open Changes at the same time. Since the Change-Id is calculated
using information like the name of the files and the image tags, if the
reconciler updates a new file or changes the previously updated image tag to a
different tag, the resulting commit will have a different Change-Id.
Consequently, this will open another Change while there is an already open
Change with obsolete changes.

## Update strategy

The `.spec.update` field specifies how to carry out updates on the git repository. There is one
Expand Down

0 comments on commit e29ae1d

Please sign in to comment.