Goal of go-make is to provide a simple, versioned build and test
environment for "common go-projects" to make standard development tasks
easy (see also Standard go-project for details). To
accomplish this goal go-make provides default targets, tools, and
configs for testing, linting, building, installing, updating, running, and
releasing libraries, binaries, and container images.
go-make can be either run as command line tool or hooked into an
existing project via a minimal Makefile. Technically
go-make is a thin versioning wrapper for a very generic
Makefile and configs supporting different tools and
unix platforms, i.e. Linux & MacOS (Darwin):
gomock- go generating mocks.codacy- for code quality documentation.golangci-lint- for pre-commit linting.zally- for pre-commit API linting.gitleaks- for sensitive data scanning.grype- for security scanning.syft- for material listing.
The go-make wrapper provides the necessary version control for the
Makefile and the config of the tools. The
tools are automatically installed or updated when needed in the configured (or
latest) available version using a default or custom config file. All config
files can be installed and customized (see
Setup and customization).
Note: For many tools go-make accepts the risk that using the
latest versions of tools, e.g. for linting, may break the build to allow
continuous upgrading of dependencies by default. For tools were this is not
desireable, e.g. for revive and golangci-lint the
default import is version. Other tools can be versioned if needed (see
manual for more information).
To install go-make simply use go install command
(or any other means, e.g. curl to obtain a released binary):
go install github.com/tkrop/go-make@latestThe scripts and configs are automatically checked out in the version matching
the wrapper. go-make has the following dependencies, that must be
satisfied by the runtime environment, e.g. using ubuntu-20.04,
ubuntu-22.04, ubunut-24.04, or
MacOSX:
- GNU
make(^4.1). - GNU
bash(^5.0). - GNU
coreutils(^8.30) - GNU
findutils(^4.7) - GNU
awk(^5.0). - GNU
sed(^4.7) curl(^7)
For non-core-features it requires docker/podman and
curl.
Note: Since MacOSX comes with heavily outdated GNU tools.
go-make ensures that recent versions are installed using the
brew package manager. As a consequence it only requires go
and [GNU make] in a decent version that is usually satisfied by the standard
MacOS installation. docker/podman are not supported
out-of-the-box.
After installing go-make, all provided targets can executed by
simply calling go-make <target> in the project repository on the command
line, in another Makefile, in a github action, or any other delivery pipeline
config script:
go-make all # execute a whole build pipeline depending on the project.
go-make test lint # execute only test 'test' and 'lint' steps of a pipeline.
go-make image # execute minimal steps to create all container images.
go-make init # initialize a new go-make project from scratch.For further examples see go-make manual.
Note: Many go-make targets can be customized via environment
variables, that by default are defined via Makefile.vars
(see also Modifying variables).
If you like to integrate go-make into another Makefile you may
find the Makefile provided in the config
helpful that automatically installs go-make creates a set of phony
targets to allow auto-completion and delegates the execution (see also
Makefile).
The default Makefile can also be installed to a project
from the config via go-make init-make to boot strap a project.
Other available config files can be installed one by one using
go-make init/<file>.
If you use go-make in your project, you may want to copy the
following Project build/requirement notice
into your [README.md].
This project is using a custom build system called go-make, that provides default targets for most common tasks. Makefile rules are generated based on the project structure and files for common tasks, to initialize, build, test, and run the components in this repository.
To get started, run one of the following commands.
make help
make show-targetsRead the go-make manual for more information about targets and configuration options.
Not: go-make installs pre-commit and commit-msg
hooks calling make commit to enforce successful testing and
linting and make git-verify message to validate whether the commit message
is following the conventional commit best practice.
For being able to efficiently work with go-make a proper shell integration is
important. Most linux systems come with a good sell integration that supports
auto-completion for make showing the targets provided via the wrapper
Makefile. However, the vanilla MacOS has its limits.
To set up command TAB-completion for go-make, add the following
snippet to your .bashrc or your .zshrc - also
for MacOS.
source <(go-make --completion=bash)
source <(go-make --completion=zsh)To extend the Makefile, you develop own receipts in a custom file called
Makefile.ext that is included automatically. If you want to
extend original receipts, you can use make install-make! to automatically
replace the wrapper Makefile against the original
Makefile.base and adding a local
MANUAL.md to your project.
The Makefile.base provided in this project is based
on a standard go-project setting some limitations. The standard
go-project is defined to meet Zalando in-house requirements, but is
general enough to be useful in open source projects too. It adheres to the
following conventions:
-
All commands (services, jobs) are provided by a
main.goplaced as usual undercmdusing the patterncmd/<name>/main.goor in the root folder. In the latter case the project name is used as command name. -
All source code files and package names following the
go-standard only consist of lower case ASCII letters, hyphens (-), underscores (_), and dots (.). Files are ending with.goto be eligible. -
Modules are placed in any sub-path of the repository, e.g. in
pkg,app,internalare commonly used patterns, except forbuildandrun. These are used bygo-makeas temporary folders to build commands and run commands and are cleaned up regularly. -
The
buildtarget creates an extended build context that is provisioned via the ldflag-Xand can be accessed providing the following variables in themainpackage:Path- the formal package path of the command build.Version- the version as provided by theVERSION-file in project root or via the(BUILD_)VERSIONenviron variables.Revision- the actual full commit hash (git rev-parse HEAD).Build- the current timestamp of the build (date --iso-8601=seconds).Commit- the timestamp of the actual commit timestamp (git log -1 --date=iso8601-strict --format=%cd).Dirty- the information whether build repository had uncommitted changes.
-
All container image build files must start with a common prefix (default is
Dockerfile). The image name is derived from the organization and repository names and can contain an optional suffix, i.e<org>/<repo-name>(-<suffix>). -
For running a command in a container image, make sure that the command is installed in the default execution directory of the container image - usually the root directory. The container image must either be generated with suffix matching the command or without suffix in common container.
All targets in the Makefile are designated to set up
the go-project automatically, installing the necessary tools - except
for the golang compiler and build environment -, and triggering the required
targets as necessary.
If we have published a non-working version of go-make and your
project is not able to build, test, run, etc, the quickest way to reset the
project's Makefile to a working go-make version
is to run:
go install github.com/tkrop/go-make@latest; go-make update;If the latest version is not fixed yet, you can also try to move backward finding the last working tagged version.
Note: After updating a project to the latest version you may need to
cleanup the installed tools using make clean-all before the new tool
version are automatically supported correctly.
The project is using itself for building as a proof of concept. So either run
make all or go-make all.
Note: If you break the go-make installation, it is always
possible to directly use the core Makefile calling:
make -f config/Makefile.base <target>...You can also test the current version by installing go-make via
make install. This allows you to test the new binary with the current local
config in other project before releasing it.
This software is open source under the MIT license. You can use it without
restrictions and liabilities. Please give it a star, so that I know. If the
project has more than 25 Stars, I will introduce semantic versions v1.
If you like to contribute, please create an issue and/or pull request with a proper description of your proposal or contribution. I will review it and provide feedback on it as fast as possible.