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.
It is not intended to be a complete application but a starting point for your projects.
It is all based on pushes and pull requests. Here is the list of actions triggered based on each event:
- When a tag is pushed:
lint
,release
, andsecurity
actions are triggered. - When a commit is pushed to the
main
branch or a pull request is opened:build
,lint
,security
, andtest
actions are triggered.
Note
You need to configure the following secrets in the repository settings:
DOCKERHUB_USERNAME
: The username of the Docker Hub account.DOCKERHUB_TOKEN
: The token of the Docker Hub account.GITLEAKS_NOTIFY_USER_LIST
: The list of users to notify when a secret leak is found.
- The build action builds the binaries for checking the code.
- The lint action runs
golangci-lint
on the code andbuf
on the protobuf files (example). - The release action runs
goreleaser
to build and publish the binaries (examples). - The security action runs
gitleaks
to check for secret leaks (example). - The test action runs the unit tests.
Note
You can use act to run GitHub Actions locally.
goreleaser
is the core of the release process. It is configured in the .goreleaser.yaml
file.
For multiple architectures, all Docker images are pushed to the GitHub Container Registry and Docker Hub.
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.
There are also a few completion scripts for the bash
, zsh
, and fish
shells in the released archives.
Note
The releases are created as drafts. You need to manually publish them, allowing you to review the release notes before publishing.
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.
You can either run the application locally or in a Docker container.
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.
Note
There is a sample configuration file in the
configs
directory.
Using environment variables:
export PLAYGROUND_LOG_LEVEL=info
export PLAYGROUND_GRPC_SERVER_ADDRESS=:50051
export PLAYGROUND_GRPC_SERVER_NETWORK=tcp
go run ./cmd/playground/main.go
Using a configuration file:
go run ./cmd/playground/main.go --config-file ./configs/development.yaml
The 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.
First, we need to build the image:
docker build -t playground .
Then we can run the container:
docker run \
-e PLAYGROUND_LOG_LEVEL=info \
-e PLAYGROUND_GRPC_SERVER_ADDRESS=:50051 \
-e PLAYGROUND_GRPC_SERVER_NETWORK=tcp \
-p 50051:50051 \
playground
Note
There is a
docker-compose.yml
that you can use as well.docker-compose up -dYou can switch from
docker
tonerdctl
if you use Containerd.
You will need to install a few tools before you can start developing the application.
sh ./scripts/install-tools.sh
Buf is used to lint the protobuf definitions and generate source code from them.
You can find the protobuf definitions in the proto
directory.
Before we continue, let us verify that everything is set up correctly:
buf build
You can run all of the configured lint rules by running this command:
buf lint
Now we can generate the source code for our service:
buf generate -o pkg/proto proto/internal
Here is a list of tools used in this repository:
Warning
I might have missed some, so feel free to open a pull request if you think something is missing. 🤓
It would be best if you used pre-commit to run linting and testing on your project; this way, you can catch problems before they are committed.
---
repos:
- repo: https://github.com/golangci/golangci-lint
rev: v1.49.0
hooks:
- id: golangci-lint
- repo: https://github.com/zricethezav/gitleaks
rev: v8.13.0
hooks:
- id: gitleaks
default_install_hook_types: [pre-commit]
minimum_pre_commit_version: 2.20.0
This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code.