This repository provides example code for setting up an empty Go project following best practices. For more information on recommended project structure, please look at this info Golang Standards Project Layout.
The template project uses the following external packages:
- A CLI based on the Cobra framework. This framework is used by many other Golang project, e.g Kubernetes, Docker etc.
- Logging via Logrus
-
cmd/
Contains the application's main executable logic. This is wheremain.golives. -
internal/
Contains private application code. Anything insideinternal/cannot be imported from outside the project (enforced by the Go compiler). -
pkg/
Contains public libraries or utilities that can be imported by other projects if needed. -
bin/
Stores built binaries, generated via theMakefile. -
Makefile
Automates build tasks such as compiling, building Docker images, running tests, etc. -
go.modandgo.sum
Define module requirements and manage dependencies.
go mod tidy
make build./bin/helloworld talkor type:
go run cmd/main.go talkERRO[0000] Error detected Error="This is an error"
INFO[0000] Talking... Msg="Hello, World!" OtherMsg="Logging is cool!"
Hello, World!make containerOr without Makefile:
docker build -t test/helloworld .Sending build context to Docker daemon 4.503MB
Step 1/4 : FROM alpine
---> b0c9d60fc5e3
Step 2/4 : WORKDIR /
---> Using cache
---> 813578363918
Step 3/4 : COPY ./bin/helloworld /bin
---> 8bf1ce271011
Step 4/4 : CMD ["helloworld", "talk"]
---> Running in 5dbb96d0225d
Removing intermediate container 5dbb96d0225d
---> 0d4933ba1303
Successfully built 0d4933ba1303
Successfully tagged test/helloworld:latestdocker run --rm test/helloworlddocker run --rm test/helloworld
Hello, World!
time="2025-04-29T19:15:27Z" level=error msg="Error detected" Error="This is an error"
time="2025-04-29T19:15:27Z" level=info msg=Talking... Msg="Hello, World!" OtherMsg="Logging is cool!"To run all tests;
make test Remember to update Makefile if adding more source directories with tests.
To run all tests in a directory:
cd pkg/helloworld
go test -v --raceAlways use the --race flag when running tests to detect race conditions during execution.
The --race flag enables the Go race detector, helping you catch concurrency issues early during development.
To run individual test:
cd pkg/helloworld
go test -v --race -test.run=TestNewHelloWorld=== RUN TestNewHelloWorld
ERRO[0000] Error detected Error="This is an error"To customize the project name, follow these steps:
-
Create a new Git repo.
-
Edit
go.modChange the module path from:module github.com/eislab-cps/go-templateto your new project path. -
Update Import Paths
Modify the import paths in the following files:
-
internal/cli/version.go
Line 6:"github.com/eislab-cps/go-template/pkg/build" -
internal/cli/talk.go
Line 4:"github.com/eislab-cps/go-template/pkg/helloworld" -
cmd/main.go
Lines 4–5:"github.com/eislab-cps/go-template/internal/cli" "github.com/eislab-cps/go-template/pkg/build"
Replace each instance of github.com/eislab-cps/go-template with your new module name.
-
Update Goreleaser Change the
binaryname tohelloworldin the.goreleaser.ymlfile. -
Update Dockerfile Change the
helloworldin theDockerfilefile. -
Update Makefile Change binary name, and container name:
BINARY_NAME := helloworld
BUILD_IMAGE ?= test/helloworld
PUSH_IMAGE ?= test/helloworld:v1.0.0GitHub will automatically run tests (make test) when pushing changes to the main branch.
Take a look at these configuration files for CI/CD setup:
.github/workflows/docker_master.yaml.github/workflows/go.yml.github/workflows/releaser.yaml.goreleaser.yml
Note:
The Goreleaser workflow can be used to automatically build and publish binaries on GitHub.
Click the Draft a new release button to create a new release.
Published releases will appear here: GitHub Releases - go-template
The Docker workflow will automatically build and publish a Docker image on GitHub.
See this page: GitHub Packages - go-template
-
Run
go mod tidyto clean up and verify dependencies. -
To store all dependencies in the
./vendordirectory, run:go mod vendor
-
Install and use Github Co-pilot! It is very good at generating logging statement.
-
Note that build time and current Github take is injected into the binary. Very useful for debugging to know which version you are using.
./bin/helloworld version 21:53:42
ab76edd
2025-04-29T19:35:04Z