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.go
lives. -
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.mod
andgo.sum
Define module requirements and manage dependencies.
go mod tidy
make build
./bin/helloworld talk
or type:
go run cmd/main.go talk
ERRO[0000] Error detected Error="This is an error"
INFO[0000] Talking... Msg="Hello, World!" OtherMsg="Logging is cool!"
Hello, World!
make container
Or 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:latest
docker run --rm test/helloworld
docker 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 --race
Always 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.mod
Change the module path from:module github.com/eislab-cps/go-template
to 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
binary
name tohelloworld
in the.goreleaser.yml
file. -
Update Dockerfile Change the
helloworld
in theDockerfile
file. -
Update Makefile Change binary name, and container name:
BINARY_NAME := helloworld
BUILD_IMAGE ?= test/helloworld
PUSH_IMAGE ?= test/helloworld:v1.0.0
GitHub 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 tidy
to clean up and verify dependencies. -
To store all dependencies in the
./vendor
directory, 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