Skip to content

Latest commit

 

History

History
321 lines (241 loc) · 13.7 KB

README.md

File metadata and controls

321 lines (241 loc) · 13.7 KB

Make framework

Build Coverage Coverage Quality Report FOSSA License Docs

Introduction

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).

Installation

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@latest

The 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:

Note: Since MacOSX comes with heavily outdated GNU tools, go-make is ensures that these are available in recent verions 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.

Example usage

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.

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).

Project integration

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].

Project build/requirement notice

This project is using go-make, which provides default targets for most common tasks, to initialize, build, test, and run the software of this project. Read the go-make manual for more information about targets and configuration options.

The Makefile depends on a preinstalled go for version management, and makes heavy use of GNU tools, i.e. coretils, findutils, '(g)make', (g)awk, (g)sed, and not the least bash. For certain non-core-features it also requires docker/podman and curl. On MacOS, it uses brew to ensure that the latest versions with the exception docker/podman are.

Not: go-make automatically installs pre-commit and commit-msg hooks overwriting and deleting pre-existing hooks (see also Customizing Git - Git Hooks). The pre-commit hook calls make commit as an alias for executing test-go, test-unit, lint-<level>, and lint-markdown to enforce successful testing and linting. The commit-msg hook calls make git-verify message for validating whether the commit message is following the conventional commit best practice.

Shell integration

To set up command completion for go-make, add the following snippet to your .bashrc.

source <(go-make --completion=bash)

Makefile development

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.

Standard go-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:

  1. All commands (services, jobs) are provided by a main.go placed as usual under cmd using the pattern cmd/<name>/main.go or in the root folder. In the latter case the project name is used as command name.

  2. 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 .go to be eligible.

  3. Modules are placed in any sub-path of the repository, e.g. in pkg, app, internal are commonly used patterns, except for build and run. These are used by go-make as temporary folders to build commands and run commands and are cleaned up regularly.

  4. The build target provides build context values to set up global variables in main and config packages.

    • Path - the formal package path of the command build.
    • Version - the version as provided by the VERSION-file in project root or via the (BUILD_)VERSION environ 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.
  5. 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>).

  6. 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.

Trouble Shooting

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.

Building

The project is using itself for building as a proof of concept. So either run make all or go-make all. As fall back it is always possible to directly use the core Makefile calling:

make -f config/Makefile.base <target>...

You can also test the local build go-make application with the local config. The project compiles itself to use the local config by default.

Terms of usage

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.

Contributing

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.