grgate, a git release gate utility which autopublish draft/unpublished releases based on commit status (aka checks). It can be triggered automatically using Git webhook or directly from the CLI.
Currently, only Github and Gitlab are supported, other provider could come in a near future.
GRGate is a CLI which can run a server and listen to Git webhook. When a release is published as draft, GRGate will wait for all the status check attached to the commit target of the release to succeed before merging it.
The following diagram represent a concret example where a CI/CD process generate/publish versionned artifacts and generate a draft release. Artifacts are then deployed by a third party to different environments running with different config. End-to-end tests are then run against these 2 environments and reports result to the draft release as commit status. When all tests pass, GRGate publish the Github release.
Different terminology is used by different provider:
- Github uses the term draft releases to prepare a release without publishing it.
- Gitlab uses the term upcoming releases, it is similar
to Github Pre-releases where a badge notify the upcoming release in the Gitlab
release page. The attribute
released_at
should be set to a future date to have it enabled and it is only possible to change it using the Gitlab API.
Create a Github APP or Gitlab token, then create a config.yaml
or a
values.yaml
file if using Helm charts.
A Helm chart is available in the FikaWorks Helm charts repository.
$ helm repo add fikaworks https://fikaworks.github.io/helm-charts
$ helm install --name grgate --f my-values.yaml fikaworks/grgate
Download latest release from the release page.
# check available commands
$ grgate --help
# run GRGate against the Github repository FikaWorks/grgate:
$ grgate run FikaWorks/grgate
# listen to Git webhook events on 0.0.0.0:8080
$ grgate serve -c config.yaml
# list status for a given commit in the FikaWorks/grgate repository
$ grgate status list FikaWorks/grgate \
--commit 93431f42d5a5abc2bb6703fc723b162a9d2f20c3
# set status of given commit (Github)
$ grgate status set FikaWorks/grgate \
--commit 93431f42d5a5abc2bb6703fc723b162a9d2f20c3 \
--name e2e-happyflow \
--status completed \
--state success
GRGate has 2 types of configuration:
- main config which define global, server settings and credentials to talk to external API like Github
- repo config which is a file stored in the repository and define the
merging rule. Fields are inherited from
main.globals:
, so if you need to override a setting you can define it in the repository itself
The main configuration file can be passed to the CLI via the --config
argument, by default it will try to read from /etc/grgate/config.yaml
.
# global configuration, this is the default
globals:
# enable GRGatem, if set to false release are not published
enabled: true
# filter release by tag, the tag associated to the draft/unpublished releases
# must match the regular expression defined by tagRegexp, default: .*
tagRegexp: .*
# list of statuses, default: []
statuses:
- e2e happy flow
# append statuses to release note
releaseNote:
enabled: true
template: |-
{{- .ReleaseNote -}}
<!-- GRGate start -->
<details><summary>Status check</summary>
{{ range .Statuses }}
- [{{ if or (eq .Status "completed" ) (eq .Status "success") }}x{{ else }} {{ end }}] {{ .Name }}
{{- end }}
</details>
<!-- GRGate end -->
# server configuration (webhook)
# webhook should be sent to /<provider>/webhook, where provider is either
# github or gitlab
server:
listenAddress: 0.0.0.0:8080
metricsAddress: 0.0.0.0:9101
probeAddress: 0.0.0.0:8086
webhookSecret: a-random-string
# number of workers to run, default: 1
workers: 1
# platform to use
platform: github # github|gitlab, default: github
# Github configuration
# when creating the Github app, make sure to set the following permissions:
# - Administration read/write
# - Checks read/write
# - Contents read/write
# - Metadata read-only
# - Commit statuses read/write
#
# subscribe to the following webhook events:
# - Check runs
# - Check suites
# - Releases
# - Statuses
github:
appID: 000000
installationID: 00000000
privateKeyPath: path-to-key.pem
# Gitlab configuration
# when creating the Gitlab token, make sure to set the following permissions:
# - read_repository
# subscribe to the following webhook events:
# - Release events
# - Pipeline events
gitlab:
token: gitlab-token
# configuration can be overriden in the repository itself, you can define the
# default path below, default: .grgate.yaml
repoConfigPath: .grgate.yaml
logLevel: info # trace|debug|info|warn|error|fatal|panic, default: info
logFormat: json # json|pretty, default: pretty
The globals:
section of the GRGate configuration can be overriden from the
repository itself. If you create a file named .grgate.yaml
at the root of the
repository, GRGate will read it before processing the repository.
# only process releases with tag matching a regular expression pattern
tagRegexp: v1.0.0-beta-\d*
# automerge release if the following status succeeded
statuses:
- e2e-with-feature-A-on
- e2e-with-feature-B-on
For local development, you can use ngrok to receive Github webhook events.
Start ngrok and forward requests to port 8080
:
$ ngrok http 8080
Create a new webhook from the Github organization or repository settings page.
Use the following settings:
- set the payload URL to your ngrok endpoint, ie:
http://bae0d008e18b.ngrok.io/github/webhook
- content type:
application/json
- select individual events:
- Check runs
- Check suites
- Releases
- Statuses
Run the server locally:
$ go run main.go serve
If you create/update a status check or create a draft release, you should see GRGate processing the triggering repository.
$ make build
$ ./grgate --help
$ make build-docker
$ docker run --ti -p 8080:8080 -v $PWD/config.yaml:/etc/grgate/config.yaml fikaworks/grgate
golangci-lint is used to lint the project, make sure to have the binary installed on your machine.
$ make lint
You can let golangci-lint
automatically fix linting issue using the following
command:
$ golangci-lint run --fix
Run unit tests:
$ make test
gomock mocking framework is used to generate mocks, you can regenerate all mocks by using the following command:
$ make mocks
Run integration tests against all platforms. The tests create temporary repositories and run a series of tests against them.
Create a Gitlab personnal access token with the following scopes:
api
read_api
write_repository
Create a Github personnal access token with the following scopes:
api
read_api
write_repository
$ export GITLAB_OWNER=<gitlab repository owner>
$ export GITLAB_TOKEN=<gitlab api token>
$ export GITHUB_OWNER=<github repository owner>
$ export GITHUB_PRIVATE_KEY_PATH=<github private key path>
$ export GITHUB_APP_ID=<github app id>
$ export GITHUB_INSTALLATION_ID=<github installation id>
$ make integration
GoReleaser is used to generate all the necessary binaries and attach them together with the changelog to the Github release. To release, create a tag then wait for Github Actions to publish the release.