{% $goversion := 1.15 %} cmd: {% .name %}: main.go: | package main func main() { println("hello world") } version: version.go: | package version var ( Package = "{% .gopkg %}" Revision = "" Version = "0.0.0+unknown" ) go.mod: | module {% .gopkg %} go {% $goversion %} Dockerfile: | # syntax=docker/dockerfile:1.2 # vim: ft=dockerfile ARG GO_VERSION={% $goversion %} FROM --platform=${BUILDPLATFORM:?err} docker.io/tonistiigi/xx:golang AS xx FROM --platform=${BUILDPLATFORM:?err} docker.io/library/golang:${GO_VERSION:?err}-alpine AS buildenv COPY --from=xx / / ARG TARGETPLATFORM WORKDIR /src RUN apk --update-cache --no-cache add make FROM buildenv AS gotestsum RUN go get gotest.tools/gotestsum@0.6.0 FROM buildenv AS golangcilint RUN go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0 FROM buildenv AS test COPY --from=gotestsum /go/bin/gotestsum /usr/local/bin/ COPY --from=golangcilint /go/bin/golangci-lint /usr/local/bin/ RUN --mount=target=/src,rw \ --mount=type=cache,target=/go/pkg \ --mount=type=cache,target=/root/.cache \ make DESTDIR=/out clean validate test FROM buildenv AS build RUN --mount=target=/src,rw \ --mount=type=cache,target=/go/pkg \ --mount=type=cache,target=/root/.cache \ make DESTDIR=/out clean build FROM scratch AS final COPY --from=build /out/{% .name %} / FROM --platform=${TARGETPLATFORM:?err} docker.io/library/alpine:3.11 AS runtime-base RUN apk --update-cache --no-cache add ca-certificates FROM runtime-base AS run COPY --from=build /out/{% .name %} /usr/local/bin/ ENTRYPOINT [ "{% .name %}" ] Makefile: | .POSIX: all: validate test {% .name %} DESTDIR ?= . PREFIX ?= VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='+dev' --always --tags) REVISION ?= $(shell git rev-parse HEAD) GO ?= go GO_PKG ?= {% .gopkg %} GO_BUILDTAGS ?= netgo osusergo static_build GO_LDFLAGS ?= -s -w -extldflags "-static" GO_VERSIONFLAGS = -X $(GO_PKG)/version.Version=$(VERSION) -X $(GO_PKG)/version.Revision=$(REVISION) .PHONY: build build: {% .name %} {% .name %}: $(GO) build \ -tags '$(GO_BUILDTAGS)' -ldflags '$(GO_LDFLAGS) $(GO_VERSIONFLAGS)' \ -o $(DESTDIR)$(PREFIX)/{% .name %} \ ./cmd/{% .name %} PLATFORM ?= linux/amd64 REPO ?= {% .name %} TAG ?= $(VERSION) .PHONY: container-build container-build: DOCKER_BUILDKIT=1 \ docker build --platform $(PLATFORM) --target final -o . . .PHONY: container-test container-test: DOCKER_BUILDKIT=1 \ docker build --platform $(PLATFORM) --target test -o type=tar,dest=/dev/null . .PHONY: container-image container-image: DOCKER_BUILDKIT=1 \ docker build --platform $(PLATFORM) --target run -t $(REPO):$(TAG) . .PHONY: cross cross: docker run --rm -it --privileged \ --mount type=bind,src=$(PWD),dst=/src \ --entrypoint buildctl-daemonless.sh \ moby/buildkit:latest \ buildctl build --frontend=dockerfile.v0 \ --local context=/src --local dockerfile=/src \ --opt filename=Dockerfile \ --opt platform=$(PLATFORM) \ --opt target=run \ --output type=image,name=$(REPO):$(TAG),push=true GOLANGCI_LINT ?= golangci-lint .PHONY: validate validate: $(GOLANGCI_LINT) run --build-tags "$(GO_BUILDTAGS)" GOTEST_FLAGS ?= ifneq ($(shell which gotestsum),) GOTEST ?= gotestsum --format=testname -- else GOTEST ?= go test endif .PHONY: test test: $(GOTEST) \ -tags '$(GO_BUILDTAGS)' \ -cover \ -covermode=atomic \ $(GOTEST_FLAGS) RM ?= rm -f .PHONY: clean clean: $(RM) {% .name %} .PHONY: help help: @printf "usage:\n" @printf "\n" @printf " build local build\n" @printf " validate linter\n" @printf " test tests\n" @printf " container-build build w/ docker\n" @printf " container-image image build\n" @printf " cross build w/ buildkit (multi-platform support)\n" @printf "\n" @printf " DESTDIR, PREFIX output location (default: $(DESTDIR)/$(PREFIX))\n" @printf " PLATFORM output platform (default: $(PLATFORM))\n" @printf " REPO, TAG image repository:tag (default: $(REPO):$(TAG))\n" @printf "\n" .editorconfig: | ; http://editorconfig.org/ root = true [*] insert_final_newline = true charset = utf-8 trim_trailing_whitespace = true indent_style = space indent_size = 2 [{Makefile,go.mod,go.sum,*go}] indent_style = tab indent_size = 8 [*.md] trim_trailing_whitespace = false [Dockerfile] indent_size = 4 README.md: | # {% .name %} TODO