Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://gitlab.com/naufraghi/gitlab-butler

Gitlab cli to automate the boring stuff
https://gitlab.com/naufraghi/gitlab-butler

bot cli gitlab hacktoberfest

Last synced: 3 months ago
JSON representation

Gitlab cli to automate the boring stuff

Awesome Lists containing this project

README

        

[![GitLab pipeline](https://img.shields.io/gitlab/pipeline/naufraghi/gitlab-butler)](https://gitlab.com/naufraghi/gitlab-butler)
[![Crates.io](https://img.shields.io/crates/v/gitlab-butler)](https://crates.io/crates/gitlab-butler)
[![Gitter](https://badges.gitter.im/gitlab-butler/community.svg)](https://gitter.im/gitlab-butler/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

# Gitlab Butler

## What is gitlab-butler

`gitlab-butler` is a GitLab cli, that wraps a growing number of GitLab APIs.

Most options can be given as command line arguments or through environment variables.

### Example usage

[![asciicast](https://asciinema.org/a/6EcgFY0eFXQ2XWJWXuyaX0ueG.svg)](https://asciinema.org/a/6EcgFY0eFXQ2XWJWXuyaX0ueG)

## Usage

`.env` is supported, a special `.private.env` is also loaded to allow private uncommited entries
beside the common ones:

- `.env` may contain `GITLAB_BUTLER_PROJECT` and `GITLAB_BUTLER_API_SERVER` (committed)
- `.private.env` may contain `GITLAB_BUTLER_PRIVATE_TOKEN` (uncommitted / upper directory)

You can also mix `dotenv` and [`direnv`](https://direnv.net/) as you like.

### Getting a private token

One can get a private token from the [Gitlab personal Profile page](https://gitlab.com/-/profile/personal_access_tokens), or using `ssh`:

```raw
$ ssh [email protected] personal_access_token
remote:
remote: ========================================================================
remote:
remote: Usage: personal_access_token [ttl_days]
remote:
remote: ========================================================================
remote:
$ ssh [email protected] personal_access_token cli-friendly-token read_repository,read_api 10
Token: 7...ixvzoW...szp
Scopes: read_repository,read_api
Expires: 2020-11-08
```

Create an `api` scoped token with the command `ssh [email protected] personal_access_token gitlab-butler api` and put it in a `.private.env` file, like:

```ini
GITLAB_BUTLER_PRIVATE_TOKEN=7...ixvzoW...szp
```

And create a standard `.env` file to point the right server and project, for example:

```ini
GITLAB_BUTLER_API_SERVER=https://gitlab.com/
GITLAB_BUTLER_PROJECT=naufraghi/gitlab-butler
```

## Example help

Use `gitlab-butler install` to create a `git-lab` symlink that allows the usage as `git lab `

Most commands will print a colored response, but if issued with the `-x` / `--execute` option, will spawn
a subshell with a set of environment variables about the current command. See the list below in the `git lab issues list --help` message.

```raw
gitlab-butler-issue-list 0.9.0
List issues

USAGE:
gitlab-butler issue list [OPTIONS]

FLAGS:
-h, --help
Prints help information

-V, --version
Prints version information

OPTIONS:
-x, --execute
Execute command for each returned issue (in a bash subshell)

The current issue is exported as environment variables:
- `issue_id`: 234
- `issue_title`: Resolve some problem
- `issue_description` (optional): Long description
- `issue_slug`: 234-resolve-some-problem
- `issue_reference`: #234
- `issue_full_reference`: group/project#234
- `issue_web_url`: http://gitlab.com/group/project/issues/234

Example:
- `... issue list -x 'echo ${issue_reference}: ${issue_title}'`

Or to use the fully qualified reference:
- `... issue list -x 'echo ${issue_full_reference}: ${issue_title}'`
-l, --labels
Filter issues by comma-separated list of label names

Issues must have all labels to be returned.
- `None` lists all issues with no labels. `Any` lists all issues with at least one label.
- `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive.
-n, --limit
[default: 100]

-m, --milestone
Filter issues by the milestone title. `None` lists all issues with no milestone.

- `Any` lists all issues that have an assigned milestone.
-p, --project
Project name or id (defaults to CI_PROJECT_PATH) [env: GITLAB_BUTLER_PROJECT=naufraghi/gitlab-butler]

-s, --state
Filter issues by state: all, opened, closed [default: opened]
```

This features allows the creation of complex pipelines, like `backport` command, that, from the current branch (which maps to a specific issue):

1. creates a new issue with a back reference in the description
2. creates a new local branch with the canonical `-` name
3. creates a new MR, that starts from the current branch and targets the provided branch

Here the implementation using the [`just` command runner](https://github.com/casey/just):

```makefile
backport TARGET:
git lab issue get -x "just _backport-issue {{TARGET}}"
_backport-issue TARGET:
git lab issue new "$issue_title ({{TARGET}})" -d "Backport of issue $issue_reference" -x "just _backport-mr {{TARGET}}"
_backport-mr TARGET:
git branch $issue_slug origin/{{TARGET}}
git push origin $issue_slug
git lab mr new "Resolve \"$issue_title\"" -d "Closes $issue_reference" -s $issue_slug -t {{TARGET}}
```

Here the execution log:

![image](https://gitlab.com/naufraghi/gitlab-butler/uploads/46d36dc4c6a88f72850120cc1bcd5629/image.png)

### `merge-ready` subcommand

The `merge-ready` subcommand tries to merge a marked MR in the queue, rebasing and waiting for the pipeline to complete successfully.

Very like [Marge-bot](https://smarketshq.com/marge-bot-for-gitlab-keeps-master-always-green-6070e9d248df) but made to run inside the CI itself (in fact, `gitlab-butler` is still in alpha and may eat your repos).

TL;DR: you have a project, you'd like an _always green_ master and a _semi linear_ history, so if your team is big enough you'll end up fighting to be the first to rebase and merge. An initial solution can be to make someone the _merger_, and the TL can in fact do this, having a second look[^1] on the code before, but the rebase/merge work is tedious.

Here enters `gitlab-butler`:

1. Alice works on a feature and creates MR1, and assign it to Bob
2. Bob does the review and eventually adds the ~"Merge ready 🐙" label to the MR, and assigns the MR to the Tech Lead,
3. The TL does the final review and eventually adds the :octopus: emoji
4. `gitlab-butler` triggers a rebase and/or merge actions

### `merge-ready` CI Usage

You can run `gitlab-butler` in a `while` loop or directly in the CI itself (you'll need to export some variables, and set up a schedule), like:

```yaml
gitlab-butler:
image: registry.gitlab.com/naufraghi/gitlab-butler:latest
variables:
GIT_STRATEGY: none
script:
- /run/gitlab-butler mr merge-ready
only:
- schedules
- master
```

The current implementation does not use the _Approved_ feature, but relies only
on a label / emoji convention because I started using it before unlocking the
feature.

## Notes

[^1]: [Modern Code Review: A Case Study at Google](https://sback.it/publications/icse2018seip.pdf), 2 reviews seems a good number:

![image](https://gitlab.com/naufraghi/gitlab-butler/uploads/81406eba257a0ceb1105b9c5454b7235/image.png)

## License

Licensed under either of
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you shall be dual licensed as above, without any
additional terms or conditions.