|
1 | 1 | # Go CI/CD Playground
|
2 | 2 |
|
3 |
| -> This documentation is being completely rewritten explaining better the purpose of this repository and how to use it. |
| 3 | +This repository is a playground for experimenting with CI/CD in Go. It is a well-structured command-line application that serves a gRPC service and is an excellent example of how to structure a Go project. |
| 4 | + |
| 5 | +It is not intended to be a complete application but a starting point for your projects. |
| 6 | + |
| 7 | +## Table of Contents |
| 8 | + |
| 9 | +- [CI/CD](#cicd) |
| 10 | + - [Actions](#actions) |
| 11 | + - [Release](#release) |
| 12 | +- [Application](#application) |
| 13 | + - [Running the application](#running-the-application) |
| 14 | + - [Running locally](#running-locally) |
| 15 | + - [Running in a Docker container](#running-in-a-docker-container) |
| 16 | + - [Development](#development) |
| 17 | + - [Protobuf](#protobuf) |
| 18 | +- [Tools](#tools) |
| 19 | +- [Tips](#tips) |
| 20 | +- [Code of Conduct](#code-of-conduct) |
| 21 | + |
| 22 | +## CI/CD |
| 23 | + |
| 24 | +It is all based on pushes and pull requests. Here is the list of actions triggered based on each event: |
| 25 | + |
| 26 | +- When a tag is pushed: `lint`, `release`, and `security` actions are triggered. |
| 27 | +- When a commit is pushed to the `main` branch or a pull request is opened: `build`, `lint`, `security`, and `test` actions are triggered. |
| 28 | + |
| 29 | +> **Note** |
| 30 | +> |
| 31 | +> You need to configure the following secrets in the repository settings: |
| 32 | +> |
| 33 | +> - `DOCKERHUB_USERNAME`: The username of the Docker Hub account. |
| 34 | +> - `DOCKERHUB_TOKEN`: The token of the Docker Hub account. |
| 35 | +> - `GITLEAKS_NOTIFY_USER_LIST`: The list of users to notify when a secret leak is found. |
| 36 | +
|
| 37 | +### Actions |
| 38 | + |
| 39 | +- The [build action](.github/workflows/build.yml) builds the binaries for checking the code. |
| 40 | +- The [lint action](.github/workflows/lint.yml) runs `golangci-lint` on the code and `buf` on the protobuf files ([example](https://github.com/calmonr/cicd/pull/3)). |
| 41 | +- The [release action](.github/workflows/release.yml) runs `goreleaser` to build and publish the binaries ([examples](https://github.com/calmonr/cicd/releases)). |
| 42 | +- The [security action](.github/workflows/security.yml) runs `gitleaks` to check for secret leaks ([example](https://github.com/calmonr/cicd/pull/2)). |
| 43 | +- The [test action](.github/workflows/test.yml) runs the unit tests. |
| 44 | + |
| 45 | +> **Note** |
| 46 | +> |
| 47 | +> You can use [act](https://github.com/nektos/act) to run GitHub Actions locally. |
| 48 | +
|
| 49 | +#### Release |
| 50 | + |
| 51 | +`goreleaser` is the core of the release process. It is configured in the [`.goreleaser.yaml`](.goreleaser.yaml) file. |
| 52 | + |
| 53 | +For multiple architectures, all Docker images are pushed to the GitHub Container Registry and Docker Hub. |
| 54 | + |
| 55 | +The binary is built using the `ldflags` flag to embed the version, commit and build time in the binary. The `version` command or the `--version` can print this information. |
| 56 | + |
| 57 | +There are also a few completion scripts for the `bash`, `zsh`, and `fish` shells in the released archives. |
| 58 | + |
| 59 | +> **Note** |
| 60 | +> |
| 61 | +> The releases are created as drafts. You need to manually publish them, allowing you to review the release notes before publishing. |
| 62 | +
|
| 63 | +## Application |
| 64 | + |
| 65 | +The application is a **simple** gRPC server with a greeting service. It has a single endpoint, `Hi`, which takes a `HiRequest` and returns a `HiResponse`. The `HiRequest` contains a `name` field, which is used to construct the `HiResponse` message. |
| 66 | + |
| 67 | +### Running the application |
| 68 | + |
| 69 | +You can either run the application locally or in a Docker container. |
| 70 | + |
| 71 | +#### Running locally |
| 72 | + |
| 73 | +It can be configured using environment variables or a configuration file. The configuration file will only be used if the `--config-file` flag is provided. |
| 74 | + |
| 75 | +> **Note** |
| 76 | +> |
| 77 | +> There is a sample configuration file in the `configs` directory. |
| 78 | +
|
| 79 | +Using environment variables: |
| 80 | + |
| 81 | +```bash |
| 82 | +export PLAYGROUND_LOG_LEVEL=info |
| 83 | +export PLAYGROUND_GRPC_SERVER_ADDRESS=:50051 |
| 84 | +export PLAYGROUND_GRPC_SERVER_NETWORK=tcp |
| 85 | + |
| 86 | +go run ./cmd/playground/main.go |
| 87 | +``` |
| 88 | + |
| 89 | +Using a configuration file: |
| 90 | + |
| 91 | +```bash |
| 92 | +go run ./cmd/playground/main.go --config-file ./configs/development.yaml |
| 93 | +``` |
| 94 | + |
| 95 | +#### Running in a Docker container |
| 96 | + |
| 97 | +The [Dockerfile](./Dockerfile) is located at the repository's root. It is a multi-stage build that builds the binary and then copies it to a scratch image. |
| 98 | + |
| 99 | +First, we need to build the image: |
| 100 | + |
| 101 | +```bash |
| 102 | +docker build -t playground . |
| 103 | +``` |
| 104 | + |
| 105 | +Then we can run the container: |
| 106 | + |
| 107 | +```bash |
| 108 | +docker run \ |
| 109 | + -e PLAYGROUND_LOG_LEVEL=info \ |
| 110 | + -e PLAYGROUND_GRPC_SERVER_ADDRESS=:50051 \ |
| 111 | + -e PLAYGROUND_GRPC_SERVER_NETWORK=tcp \ |
| 112 | + -p 50051:50051 \ |
| 113 | + playground |
| 114 | +``` |
| 115 | + |
| 116 | +> **Note** |
| 117 | +> |
| 118 | +> There is a `docker-compose.yml` that you can use as well. |
| 119 | +> |
| 120 | +> ```bash |
| 121 | +> docker-compose up -d |
| 122 | +> ``` |
| 123 | +> |
| 124 | +> You can switch from `docker` to `nerdctl` if you use Containerd. |
| 125 | +
|
| 126 | +### Development |
| 127 | +
|
| 128 | +You will need to install a few tools before you can start developing the application. |
| 129 | +
|
| 130 | +```bash |
| 131 | +sh ./scripts/install-tools.sh |
| 132 | +``` |
| 133 | +
|
| 134 | +#### Protobuf |
| 135 | +
|
| 136 | +[Buf](https://docs.buf.build/introduction) is used to lint the protobuf definitions and generate source code from them. |
| 137 | +
|
| 138 | +You can find the protobuf definitions in the `proto` directory. |
| 139 | +
|
| 140 | +Before we continue, let us verify that everything is set up correctly: |
| 141 | +
|
| 142 | +```console |
| 143 | +buf build |
| 144 | +``` |
| 145 | +
|
| 146 | +You can run all of the configured lint rules by running this command: |
| 147 | +
|
| 148 | +```console |
| 149 | +buf lint |
| 150 | +``` |
| 151 | +
|
| 152 | +Now we can generate the source code for our service: |
| 153 | +
|
| 154 | +```console |
| 155 | +buf generate -o pkg/proto proto/internal |
| 156 | +``` |
| 157 | +
|
| 158 | +## Tools |
| 159 | +
|
| 160 | +Here is a list of tools used in this repository: |
| 161 | +
|
| 162 | +> **Warning** |
| 163 | +> |
| 164 | +> I might have missed some, so feel free to open a pull request if you think something is missing. :nerd_face: |
| 165 | +
|
| 166 | +- [x] [GoReleaser](https://goreleaser.com/) |
| 167 | +- [x] [golangci-lint](https://golangci-lint.run/) |
| 168 | +- [x] [EditorConfig](https://editorconfig.org/) |
| 169 | +- [x] [Gitleaks](https://gitleaks.io/) |
| 170 | +- [x] [Cobra](https://cobra.dev/) |
| 171 | +- [x] [Viper](https://github.com/spf13/viper) |
| 172 | +- [x] [zap](https://github.com/uber-go/zap) |
| 173 | +- [x] [gRPC](https://grpc.io/) |
| 174 | + - [x] [Buf](https://buf.build/) |
| 175 | +
|
| 176 | +## Tips |
| 177 | +
|
| 178 | +It would be best if you used [pre-commit](https://pre-commit.com/) to run linting and testing on your project; this way, you can catch problems before they are committed. |
| 179 | +
|
| 180 | +```yaml |
| 181 | +--- |
| 182 | +repos: |
| 183 | + - repo: https://github.com/golangci/golangci-lint |
| 184 | + rev: v1.49.0 |
| 185 | + hooks: |
| 186 | + - id: golangci-lint |
| 187 | + - repo: https://github.com/zricethezav/gitleaks |
| 188 | + rev: v8.13.0 |
| 189 | + hooks: |
| 190 | + - id: gitleaks |
| 191 | +default_install_hook_types: [pre-commit] |
| 192 | +minimum_pre_commit_version: 2.20.0 |
| 193 | +``` |
| 194 | +
|
| 195 | +## Code of Conduct |
| 196 | +
|
| 197 | +This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. |
0 commit comments