mirror of
https://github.com/wagoodman/dive
synced 2026-03-14 22:35:50 +01:00
port makefile to taskfile (#584)
This commit is contained in:
parent
2342d85e26
commit
dd450a7474
7 changed files with 484 additions and 416 deletions
64
.binny.yaml
Normal file
64
.binny.yaml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
tools:
|
||||
# we want to use a pinned version of binny to manage the toolchain (so binny manages itself!)
|
||||
- name: binny
|
||||
version:
|
||||
want: v0.9.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: anchore/binny
|
||||
|
||||
# used for linting
|
||||
- name: golangci-lint
|
||||
version:
|
||||
want: v1.64.8
|
||||
method: github-release
|
||||
with:
|
||||
repo: golangci/golangci-lint
|
||||
|
||||
# used for showing the changelog at release
|
||||
- name: glow
|
||||
version:
|
||||
want: v2.1.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: charmbracelet/glow
|
||||
|
||||
# used to release all artifacts
|
||||
- name: goreleaser
|
||||
version:
|
||||
want: v2.8.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: goreleaser/goreleaser
|
||||
|
||||
# used at release to generate the changelog
|
||||
- name: chronicle
|
||||
version:
|
||||
want: v0.8.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: anchore/chronicle
|
||||
|
||||
# used during static analysis for license compliance
|
||||
- name: bouncer
|
||||
version:
|
||||
want: v0.4.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: wagoodman/go-bouncer
|
||||
|
||||
# used for running all local and CI tasks
|
||||
- name: task
|
||||
version:
|
||||
want: v3.42.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: go-task/task
|
||||
|
||||
# used for triggering a release
|
||||
- name: gh
|
||||
version:
|
||||
want: v2.69.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: cli/cli
|
||||
38
.github/actions/bootstrap/action.yaml
vendored
38
.github/actions/bootstrap/action.yaml
vendored
|
|
@ -5,18 +5,10 @@ inputs:
|
|||
description: "Go version to install"
|
||||
required: true
|
||||
default: "1.24.x"
|
||||
use-go-cache:
|
||||
description: "Restore go cache"
|
||||
required: true
|
||||
default: "true"
|
||||
cache-key-prefix:
|
||||
description: "Prefix all cache keys with this value"
|
||||
required: true
|
||||
default: "efa04b89c1b1"
|
||||
build-cache-key-prefix:
|
||||
description: "Prefix build cache key with this value"
|
||||
required: true
|
||||
default: "f8b6d31dea"
|
||||
bootstrap-apt-packages:
|
||||
description: "Space delimited list of tools to install via apt"
|
||||
default: ""
|
||||
|
|
@ -35,39 +27,15 @@ runs:
|
|||
path: ${{ github.workspace }}/.tmp
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('Makefile') }}
|
||||
|
||||
# note: we need to keep restoring the go mod cache before bootstrapping tools since `go install` is used in
|
||||
# some installations of project tools.
|
||||
- name: Restore go module cache
|
||||
id: go-mod-cache
|
||||
if: inputs.use-go-cache == 'true'
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ inputs.cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-
|
||||
|
||||
- name: (cache-miss) Bootstrap project tools
|
||||
shell: bash
|
||||
if: steps.tool-cache.outputs.cache-hit != 'true'
|
||||
run: make bootstrap-tools
|
||||
|
||||
- name: Restore go build cache
|
||||
id: go-cache
|
||||
if: inputs.use-go-cache == 'true'
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ inputs.build-cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ inputs.cache-key-prefix }}-${{ inputs.build-cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-
|
||||
run: make tools
|
||||
|
||||
- name: (cache-miss) Bootstrap go dependencies
|
||||
shell: bash
|
||||
if: steps.go-mod-cache.outputs.cache-hit != 'true' && inputs.use-go-cache == 'true'
|
||||
run: make bootstrap-go
|
||||
if: steps.go-mod-cache.outputs.cache-hit != 'true'
|
||||
run: go mod download -x
|
||||
|
||||
- name: Install apt packages
|
||||
if: inputs.bootstrap-apt-packages != ''
|
||||
|
|
|
|||
11
.github/scripts/ci-check.sh
vendored
11
.github/scripts/ci-check.sh
vendored
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
red=$(tput setaf 1)
|
||||
bold=$(tput bold)
|
||||
normal=$(tput sgr0)
|
||||
|
||||
# assert we are running in CI (or die!)
|
||||
if [[ -z "$CI" ]]; then
|
||||
echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}"
|
||||
exit 1
|
||||
fi
|
||||
31
.github/scripts/go-mod-tidy-check.sh
vendored
31
.github/scripts/go-mod-tidy-check.sh
vendored
|
|
@ -1,31 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
|
||||
ORIGINAL_STATE_DIR=$(mktemp -d "TEMP-original-state-XXXXXXXXX")
|
||||
TIDY_STATE_DIR=$(mktemp -d "TEMP-tidy-state-XXXXXXXXX")
|
||||
|
||||
trap "cp -v ${ORIGINAL_STATE_DIR}/* ./ && rm -fR ${ORIGINAL_STATE_DIR} ${TIDY_STATE_DIR}" EXIT
|
||||
|
||||
echo "Capturing original state of files..."
|
||||
cp -v go.mod go.sum "${ORIGINAL_STATE_DIR}"
|
||||
|
||||
echo "Capturing state of go.mod and go.sum after running go mod tidy..."
|
||||
go mod tidy
|
||||
cp -v go.mod go.sum "${TIDY_STATE_DIR}"
|
||||
echo ""
|
||||
|
||||
set +e
|
||||
|
||||
# Detect difference between the git HEAD state and the go mod tidy state
|
||||
DIFF_MOD=$(diff -u "${ORIGINAL_STATE_DIR}/go.mod" "${TIDY_STATE_DIR}/go.mod")
|
||||
DIFF_SUM=$(diff -u "${ORIGINAL_STATE_DIR}/go.sum" "${TIDY_STATE_DIR}/go.sum")
|
||||
|
||||
if [[ -n "${DIFF_MOD}" || -n "${DIFF_SUM}" ]]; then
|
||||
echo "go.mod diff:"
|
||||
echo "${DIFF_MOD}"
|
||||
echo "go.sum diff:"
|
||||
echo "${DIFF_SUM}"
|
||||
echo ""
|
||||
printf "FAILED! go.mod and/or go.sum are NOT tidy; please run 'go mod tidy'.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -12,6 +12,9 @@ VERSION
|
|||
/bin
|
||||
/.tool-versions
|
||||
/.tmp
|
||||
/.tool
|
||||
/.mise.toml
|
||||
/.task
|
||||
|
||||
# builds
|
||||
/dist
|
||||
|
|
|
|||
371
Makefile
371
Makefile
|
|
@ -1,354 +1,47 @@
|
|||
BIN = dive
|
||||
TEMP_DIR = ./.tmp
|
||||
PWD := ${CURDIR}
|
||||
SHELL = /bin/bash -o pipefail
|
||||
TEST_IMAGE = busybox:latest
|
||||
OWNER = wagoodman
|
||||
PROJECT = dive
|
||||
|
||||
# Tool versions #################################
|
||||
GOLANG_CI_VERSION = v1.64.5
|
||||
GOBOUNCER_VERSION = v0.4.0
|
||||
GORELEASER_VERSION = v2.4.4
|
||||
GOSIMPORTS_VERSION = v0.3.8
|
||||
CHRONICLE_VERSION = v0.8.0
|
||||
GLOW_VERSION = v1.5.1
|
||||
DOCKER_CLI_VERSION = 28.0.0
|
||||
|
||||
# Command templates #################################
|
||||
LINT_CMD = $(TEMP_DIR)/golangci-lint run --tests=false --timeout=2m --config .golangci.yaml
|
||||
GOIMPORTS_CMD = $(TEMP_DIR)/gosimports -local github.com/wagoodman
|
||||
RELEASE_CMD = DOCKER_CLI_VERSION=$(DOCKER_CLI_VERSION) $(TEMP_DIR)/goreleaser release --clean
|
||||
SNAPSHOT_CMD = $(RELEASE_CMD) --skip=publish --skip=sign --snapshot
|
||||
CHRONICLE_CMD = $(TEMP_DIR)/chronicle
|
||||
GLOW_CMD = $(TEMP_DIR)/glow
|
||||
|
||||
# Formatting variables #################################
|
||||
BOLD := $(shell tput -T linux bold)
|
||||
PURPLE := $(shell tput -T linux setaf 5)
|
||||
GREEN := $(shell tput -T linux setaf 2)
|
||||
CYAN := $(shell tput -T linux setaf 6)
|
||||
RED := $(shell tput -T linux setaf 1)
|
||||
RESET := $(shell tput -T linux sgr0)
|
||||
TITLE := $(BOLD)$(PURPLE)
|
||||
SUCCESS := $(BOLD)$(GREEN)
|
||||
|
||||
# Test variables #################################
|
||||
# the quality gate lower threshold for unit test total % coverage (by function statements)
|
||||
COVERAGE_THRESHOLD := 30
|
||||
|
||||
## Build variables #################################
|
||||
DIST_DIR = dist
|
||||
SNAPSHOT_DIR = snapshot
|
||||
OS=$(shell uname | tr '[:upper:]' '[:lower:]')
|
||||
SNAPSHOT_BIN=$(realpath $(shell pwd)/$(SNAPSHOT_DIR)/$(OS)-build_$(OS)_amd64_v1/$(BIN))
|
||||
CHANGELOG := CHANGELOG.md
|
||||
VERSION=$(shell git describe --dirty --always --tags)
|
||||
|
||||
ifeq "$(strip $(VERSION))" ""
|
||||
override VERSION = $(shell git describe --always --tags --dirty)
|
||||
endif
|
||||
|
||||
## Variable assertions
|
||||
|
||||
ifndef TEMP_DIR
|
||||
$(error TEMP_DIR is not set)
|
||||
endif
|
||||
|
||||
ifndef DIST_DIR
|
||||
$(error DIST_DIR is not set)
|
||||
endif
|
||||
|
||||
ifndef SNAPSHOT_DIR
|
||||
$(error SNAPSHOT_DIR is not set)
|
||||
endif
|
||||
|
||||
define title
|
||||
@printf '$(TITLE)$(1)$(RESET)\n'
|
||||
endef
|
||||
|
||||
|
||||
.PHONY: all
|
||||
all: clean static-analysis test ## Run all static analysis and tests
|
||||
@printf '$(SUCCESS)All checks pass!$(RESET)\n'
|
||||
|
||||
.PHONY: test
|
||||
test: unit ## Run all tests (currently unit and cli tests)
|
||||
|
||||
$(TEMP_DIR):
|
||||
mkdir -p $(TEMP_DIR)
|
||||
TOOL_DIR = .tool
|
||||
BINNY = $(TOOL_DIR)/binny
|
||||
TASK = $(TOOL_DIR)/task
|
||||
|
||||
.DEFAULT_GOAL := make-default
|
||||
|
||||
## Bootstrapping targets #################################
|
||||
|
||||
.PHONY: bootstrap-tools
|
||||
bootstrap-tools: $(TEMP_DIR)
|
||||
$(call title,Bootstrapping tools)
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/chronicle/main/install.sh | sh -s -- -b $(TEMP_DIR)/ $(CHRONICLE_VERSION)
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMP_DIR)/ $(GOLANG_CI_VERSION)
|
||||
curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMP_DIR)/ $(GOBOUNCER_VERSION)
|
||||
GOBIN="$(realpath $(TEMP_DIR))" go install github.com/goreleaser/goreleaser/v2@$(GORELEASER_VERSION)
|
||||
GOBIN="$(realpath $(TEMP_DIR))" go install github.com/rinchsan/gosimports/cmd/gosimports@$(GOSIMPORTS_VERSION)
|
||||
GOBIN="$(realpath $(TEMP_DIR))" go install github.com/charmbracelet/glow@$(GLOW_VERSION)
|
||||
# note: we need to assume that binny and task have not already been installed
|
||||
$(BINNY):
|
||||
@mkdir -p $(TOOL_DIR)
|
||||
@curl -sSfL https://raw.githubusercontent.com/anchore/binny/main/install.sh | sh -s -- -b $(TOOL_DIR)
|
||||
|
||||
.PHONY: bootstrap-go
|
||||
bootstrap-go:
|
||||
$(call title,Bootstrapping go dependencies)
|
||||
go mod download
|
||||
# note: we need to assume that binny and task have not already been installed
|
||||
.PHONY: task
|
||||
$(TASK) task: $(BINNY)
|
||||
@$(BINNY) install task -q
|
||||
|
||||
.PHONY: bootstrap
|
||||
bootstrap: bootstrap-go bootstrap-tools ## Download and install all go dependencies (+ prep tooling in the ./tmp dir)
|
||||
# this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again
|
||||
%:
|
||||
@make --silent $(TASK)
|
||||
@$(TASK) $@
|
||||
|
||||
## Shim targets #################################
|
||||
|
||||
## Development targets ###################################
|
||||
.PHONY: make-default
|
||||
make-default: $(TASK)
|
||||
@# run the default task in the taskfile
|
||||
@$(TASK)
|
||||
|
||||
#run: build
|
||||
# $(BUILD_PATH) build -t dive-example:latest -f .data/Dockerfile.example .
|
||||
#
|
||||
#run-large: build
|
||||
# $(BUILD_PATH) amir20/clashleaders:latest
|
||||
#
|
||||
#run-podman: build
|
||||
# podman build -t dive-example:latest -f .data/Dockerfile.example .
|
||||
# $(BUILD_PATH) localhost/dive-example:latest --engine podman
|
||||
#
|
||||
#run-podman-large: build
|
||||
# $(BUILD_PATH) docker.io/amir20/clashleaders:latest --engine podman
|
||||
#
|
||||
#run-ci: build
|
||||
# CI=true $(BUILD_PATH) dive-example:latest --ci-config .data/.dive-ci
|
||||
#
|
||||
#dev:
|
||||
# docker run -ti --rm -v $(PWD):/app -w /app -v dive-pkg:/go/pkg/ golang:1.13 bash
|
||||
#
|
||||
#build: gofmt
|
||||
# go build -o $(BUILD_PATH)
|
||||
# for those of us that can't seem to kick the habit of typing `make ...` lets wrap the superior `task` tool
|
||||
TASKS := $(shell bash -c "test -f $(TASK) && $(TASK) -l | grep '^\* ' | cut -d' ' -f2 | tr -d ':' | tr '\n' ' '" ) $(shell bash -c "test -f $(TASK) && $(TASK) -l | grep 'aliases:' | cut -d ':' -f 3 | tr '\n' ' ' | tr -d ','")
|
||||
|
||||
.PHONY: generate-test-data
|
||||
generate-test-data:
|
||||
docker build -t dive-test:latest -f .data/Dockerfile.test-image . && \
|
||||
docker image save -o .data/test-docker-image.tar dive-test:latest && \
|
||||
echo 'Exported test data!'
|
||||
.PHONY: $(TASKS)
|
||||
$(TASKS): $(TASK)
|
||||
@$(TASK) $@
|
||||
|
||||
.PHONY: generate-compressed-test-images
|
||||
generate-compressed-test-images:
|
||||
for alg in uncompressed gzip estargz zstd; do \
|
||||
for exporter in docker image; do \
|
||||
docker buildx build \
|
||||
-f .data/Dockerfile.minimal \
|
||||
--tag test-dive-$${exporter}:$${alg} \
|
||||
--output type=$${exporter},force-compression=true,compression=$${alg} . ; \
|
||||
done ; \
|
||||
done && \
|
||||
echo 'Exported test data!'
|
||||
## actual targets
|
||||
|
||||
.PHONY: generate-compressed-test-data
|
||||
generate-compressed-test-data:
|
||||
for alg in uncompressed gzip estargz zstd; \
|
||||
do \
|
||||
docker buildx build \
|
||||
-f .data/Dockerfile.minimal \
|
||||
--output type=tar,dest=.data/test-$${alg}-image.tar,force-compression=true,compression=$${alg} . ; \
|
||||
docker buildx build \
|
||||
-f .data/Dockerfile.minimal \
|
||||
--output type=oci,dest=.data/test-oci-$${alg}-image.tar,force-compression=true,compression=$${alg} . ; \
|
||||
done && \
|
||||
echo 'Exported test data!'
|
||||
|
||||
|
||||
## Static analysis targets #################################
|
||||
|
||||
.PHONY: static-analysis
|
||||
static-analysis: lint check-go-mod-tidy check-licenses
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Run gofmt + golangci lint checks
|
||||
$(call title,Running linters)
|
||||
# ensure there are no go fmt differences
|
||||
@printf "files with gofmt issues: [$(shell gofmt -l -s .)]\n"
|
||||
@test -z "$(shell gofmt -l -s .)"
|
||||
|
||||
# run all golangci-lint rules
|
||||
$(LINT_CMD)
|
||||
@[ -z "$(shell $(GOIMPORTS_CMD) -d .)" ] || (echo "goimports needs to be fixed" && false)
|
||||
|
||||
# go tooling does not play well with certain filename characters, ensure the common cases don't result in future "go get" failures
|
||||
$(eval MALFORMED_FILENAMES := $(shell find . | grep -e ':'))
|
||||
@bash -c "[[ '$(MALFORMED_FILENAMES)' == '' ]] || (printf '\nfound unsupported filename characters:\n$(MALFORMED_FILENAMES)\n\n' && false)"
|
||||
|
||||
.PHONY: format
|
||||
format: ## Auto-format all source code
|
||||
$(call title,Running formatters)
|
||||
gofmt -w -s .
|
||||
$(GOIMPORTS_CMD) -w .
|
||||
go mod tidy
|
||||
|
||||
.PHONY: lint-fix
|
||||
lint-fix: format ## Auto-format all source code + run golangci lint fixers
|
||||
$(call title,Running lint fixers)
|
||||
$(LINT_CMD) --fix
|
||||
|
||||
.PHONY: check-licenses
|
||||
check-licenses:
|
||||
$(TEMP_DIR)/bouncer check ./...
|
||||
|
||||
check-go-mod-tidy:
|
||||
@ .github/scripts/go-mod-tidy-check.sh && echo "go.mod and go.sum are tidy!"
|
||||
|
||||
|
||||
## Testing targets #################################
|
||||
|
||||
.PHONY: unit
|
||||
unit: $(TEMP_DIR) ## Run unit tests (with coverage)
|
||||
$(call title,Running unit tests)
|
||||
go test -race -coverprofile $(TEMP_DIR)/unit-coverage-details.txt ./...
|
||||
@.github/scripts/coverage.py $(COVERAGE_THRESHOLD) $(TEMP_DIR)/unit-coverage-details.txt
|
||||
|
||||
|
||||
## Acceptance testing targets (CI only) #################################
|
||||
|
||||
# todo: add --pull=never when supported by host box
|
||||
.PHONY: ci-test-docker-image
|
||||
ci-test-docker-image:
|
||||
docker run \
|
||||
--rm \
|
||||
-t \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
'docker.io/wagoodman/dive:latest-amd64' \
|
||||
'${TEST_IMAGE}' \
|
||||
--ci
|
||||
|
||||
.PHONY: ci-test-deb-package-install
|
||||
ci-test-deb-package-install:
|
||||
docker run \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /${PWD}:/src \
|
||||
-w /src \
|
||||
ubuntu:latest \
|
||||
/bin/bash -x -c "\
|
||||
apt update && \
|
||||
apt install -y curl && \
|
||||
curl -L 'https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_CLI_VERSION}.tgz' | \
|
||||
tar -vxzf - docker/docker --strip-component=1 && \
|
||||
mv docker /usr/local/bin/ &&\
|
||||
docker version && \
|
||||
apt install ./snapshot/dive_*_linux_amd64.deb -y && \
|
||||
dive --version && \
|
||||
dive '${TEST_IMAGE}' --ci \
|
||||
"
|
||||
|
||||
.PHONY: ci-test-deb-package-install
|
||||
ci-test-rpm-package-install:
|
||||
docker run \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /${PWD}:/src \
|
||||
-w /src \
|
||||
fedora:latest \
|
||||
/bin/bash -x -c "\
|
||||
curl -L 'https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_CLI_VERSION}.tgz' | \
|
||||
tar -vxzf - docker/docker --strip-component=1 && \
|
||||
mv docker /usr/local/bin/ &&\
|
||||
docker version && \
|
||||
dnf install ./snapshot/dive_*_linux_amd64.rpm -y && \
|
||||
dive --version && \
|
||||
dive '${TEST_IMAGE}' --ci \
|
||||
"
|
||||
|
||||
.PHONY: ci-test-linux-run
|
||||
ci-test-linux-run: generate-compressed-test-images
|
||||
ls -la $(SNAPSHOT_DIR)
|
||||
ls -la $(SNAPSHOT_DIR)/dive_linux_amd64_v1
|
||||
chmod 755 $(SNAPSHOT_DIR)/dive_linux_amd64_v1/dive && \
|
||||
$(SNAPSHOT_DIR)/dive_linux_amd64_v1/dive '${TEST_IMAGE}' --ci && \
|
||||
$(SNAPSHOT_DIR)/dive_linux_amd64_v1/dive --source docker-archive .data/test-kaniko-image.tar --ci --ci-config .data/.dive-ci
|
||||
for alg in uncompressed gzip estargz zstd; do \
|
||||
for exporter in docker image; do \
|
||||
$(SNAPSHOT_DIR)/dive_linux_amd64_v1/dive "test-dive-$${exporter}:$${alg}" --ci ; \
|
||||
done && \
|
||||
$(SNAPSHOT_DIR)/dive_linux_amd64_v1/dive --source docker-archive .data/test-oci-$${alg}-image.tar --ci --ci-config .data/.dive-ci; \
|
||||
done
|
||||
|
||||
# we're not attempting to test docker, just our ability to run on these systems. This avoids setting up docker in CI.
|
||||
.PHONY: ci-test-mac-run
|
||||
ci-test-mac-run:
|
||||
chmod 755 $(SNAPSHOT_DIR)/dive_darwin_amd64_v1/dive && \
|
||||
$(SNAPSHOT_DIR)/dive_darwin_amd64_v1/dive --source docker-archive .data/test-docker-image.tar --ci --ci-config .data/.dive-ci
|
||||
|
||||
# we're not attempting to test docker, just our ability to run on these systems. This avoids setting up docker in CI.
|
||||
.PHONY: ci-test-windows-run
|
||||
ci-test-windows-run:
|
||||
dive.exe --source docker-archive .data/test-docker-image.tar --ci --ci-config .data/.dive-ci
|
||||
dive.exe --source docker-archive .data/test-docker-image.tar --ci --ci-config .data/.dive-ci
|
||||
|
||||
|
||||
## Build-related targets #################################
|
||||
|
||||
.PHONY: build
|
||||
build: $(SNAPSHOT_DIR) ## Build release snapshot binaries and packages
|
||||
|
||||
$(SNAPSHOT_DIR): ## Build snapshot release binaries and packages
|
||||
$(call title,Building snapshot artifacts)
|
||||
|
||||
@# create a config with the dist dir overridden
|
||||
@echo "dist: $(SNAPSHOT_DIR)" > $(TEMP_DIR)/goreleaser.yaml
|
||||
@cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml
|
||||
|
||||
@# build release snapshots
|
||||
@bash -c "\
|
||||
VERSION=$(VERSION:v%=%) \
|
||||
$(SNAPSHOT_CMD) --config $(TEMP_DIR)/goreleaser.yaml \
|
||||
"
|
||||
|
||||
.PHONY: cli
|
||||
cli: $(SNAPSHOT_DIR) ## Run CLI tests
|
||||
chmod 755 "$(SNAPSHOT_BIN)"
|
||||
$(SNAPSHOT_BIN) version
|
||||
go test -count=1 -timeout=15m -v ./test/cli
|
||||
|
||||
.PHONY: changelog
|
||||
changelog: clean-changelog ## Generate and show the changelog for the current unreleased version
|
||||
$(CHRONICLE_CMD) -vvv -n --version-file VERSION > $(CHANGELOG)
|
||||
@$(GLOW_CMD) $(CHANGELOG)
|
||||
|
||||
$(CHANGELOG):
|
||||
$(CHRONICLE_CMD) -vvv > $(CHANGELOG)
|
||||
|
||||
.PHONY: release
|
||||
release: ## Cut a new release
|
||||
@.github/scripts/trigger-release.sh
|
||||
|
||||
.PHONY: ci-release
|
||||
ci-release: ci-check clean-dist $(CHANGELOG)
|
||||
$(call title,Publishing release artifacts)
|
||||
|
||||
# create a config with the dist dir overridden
|
||||
echo "dist: $(DIST_DIR)" > $(TEMP_DIR)/goreleaser.yaml
|
||||
cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml
|
||||
|
||||
bash -c "$(RELEASE_CMD) --release-notes <(cat CHANGELOG.md) --config $(TEMP_DIR)/goreleaser.yaml"
|
||||
|
||||
.PHONY: ci-check
|
||||
ci-check:
|
||||
@.github/scripts/ci-check.sh
|
||||
|
||||
|
||||
## Cleanup targets #################################
|
||||
|
||||
.PHONY: clean
|
||||
clean: clean-dist clean-snapshot ## Remove previous builds, result reports, and test cache
|
||||
|
||||
.PHONY: clean-snapshot
|
||||
clean-snapshot:
|
||||
rm -rf $(SNAPSHOT_DIR) $(TEMP_DIR)/goreleaser.yaml
|
||||
|
||||
.PHONY: clean-dist
|
||||
clean-dist: clean-changelog
|
||||
rm -rf $(DIST_DIR) $(TEMP_DIR)/goreleaser.yaml
|
||||
|
||||
.PHONY: clean-changelog
|
||||
clean-changelog:
|
||||
rm -f $(CHANGELOG) VERSION
|
||||
|
||||
|
||||
## Help! #################################
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(BOLD)$(CYAN)%-25s$(RESET)%s\n", $$1, $$2}'
|
||||
help: $(TASK)
|
||||
@$(TASK) -l
|
||||
|
|
|
|||
382
Taskfile.yaml
Normal file
382
Taskfile.yaml
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
|
||||
version: "3"
|
||||
vars:
|
||||
OWNER: wagoodman
|
||||
PROJECT: dive
|
||||
|
||||
# static file dirs
|
||||
TOOL_DIR: .tool
|
||||
TMP_DIR: .tmp
|
||||
|
||||
# TOOLS
|
||||
BINNY: "{{ .TOOL_DIR }}/binny"
|
||||
CHRONICLE: "{{ .TOOL_DIR }}/chronicle"
|
||||
GORELEASER: "{{ .TOOL_DIR }}/goreleaser"
|
||||
GOLANGCI_LINT: "{{ .TOOL_DIR }}/golangci-lint"
|
||||
TASK: "{{ .TOOL_DIR }}/task"
|
||||
BOUNCER: "{{ .TOOL_DIR }}/bouncer"
|
||||
GLOW: "{{ .TOOL_DIR }}/glow"
|
||||
|
||||
# used for changelog generation
|
||||
CHANGELOG: CHANGELOG.md
|
||||
NEXT_VERSION: VERSION
|
||||
|
||||
# note: the snapshot dir must be a relative path starting with ./
|
||||
SNAPSHOT_DIR: ./snapshot
|
||||
SNAPSHOT_CMD: "{{ .GORELEASER }} release --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --skip=publish --skip=sign"
|
||||
BUILD_CMD: "{{ .GORELEASER }} build --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --single-target"
|
||||
RELEASE_CMD: "{{ .GORELEASER }} release --clean --release-notes {{ .CHANGELOG }}"
|
||||
VERSION:
|
||||
sh: git describe --dirty --always --tags
|
||||
|
||||
# used for acceptance tests
|
||||
TEST_IMAGE: busybox:latest
|
||||
DOCKER_CLI_VERSION: 28.0.0
|
||||
|
||||
env:
|
||||
GNUMAKEFLAGS: '--no-print-directory'
|
||||
DOCKER_CLI_VERSION: "{{ .DOCKER_CLI_VERSION }}"
|
||||
|
||||
tasks:
|
||||
|
||||
## High-level tasks #################################
|
||||
|
||||
default:
|
||||
desc: Run all validation tasks
|
||||
aliases:
|
||||
- pr-validations
|
||||
- validations
|
||||
cmds:
|
||||
- task: static-analysis
|
||||
- task: test
|
||||
|
||||
static-analysis:
|
||||
desc: Run all static analysis tasks
|
||||
cmds:
|
||||
- task: check-go-mod-tidy
|
||||
- task: check-licenses
|
||||
- task: lint
|
||||
|
||||
test:
|
||||
desc: Run all levels of test
|
||||
cmds:
|
||||
- task: unit
|
||||
|
||||
## Bootstrap tasks #################################
|
||||
|
||||
binny:
|
||||
internal: true
|
||||
# desc: Get the binny tool
|
||||
generates:
|
||||
- "{{ .BINNY }}"
|
||||
status:
|
||||
- "test -f {{ .BINNY }}"
|
||||
cmd: "curl -sSfL https://raw.githubusercontent.com/anchore/binny/main/install.sh | sh -s -- -b .tool"
|
||||
silent: true
|
||||
|
||||
tools:
|
||||
desc: Install all tools needed for CI and local development
|
||||
deps: [binny]
|
||||
aliases:
|
||||
- bootstrap
|
||||
generates:
|
||||
- ".binny.yaml"
|
||||
- "{{ .TOOL_DIR }}/*"
|
||||
status:
|
||||
- "{{ .BINNY }} check -v"
|
||||
cmd: "{{ .BINNY }} install -v"
|
||||
silent: true
|
||||
|
||||
update-tools:
|
||||
desc: Update pinned versions of all tools to their latest available versions
|
||||
deps: [binny]
|
||||
generates:
|
||||
- ".binny.yaml"
|
||||
- "{{ .TOOL_DIR }}/*"
|
||||
cmd: "{{ .BINNY }} update -v"
|
||||
silent: true
|
||||
|
||||
list-tools:
|
||||
desc: List all tools needed for CI and local development
|
||||
deps: [binny]
|
||||
cmd: "{{ .BINNY }} list"
|
||||
silent: true
|
||||
|
||||
list-tool-updates:
|
||||
desc: List all tools that are not up to date relative to the binny config
|
||||
deps: [binny]
|
||||
cmd: "{{ .BINNY }} list --updates"
|
||||
silent: true
|
||||
|
||||
tmpdir:
|
||||
silent: true
|
||||
generates:
|
||||
- "{{ .TMP_DIR }}"
|
||||
cmd: "mkdir -p {{ .TMP_DIR }}"
|
||||
|
||||
## Static analysis tasks #################################
|
||||
|
||||
format:
|
||||
desc: Auto-format all source code
|
||||
deps: [tools]
|
||||
cmds:
|
||||
- gofmt -w -s .
|
||||
- go mod tidy
|
||||
|
||||
lint-fix:
|
||||
desc: Auto-format all source code + run golangci lint fixers
|
||||
deps: [tools]
|
||||
cmds:
|
||||
- task: format
|
||||
- "{{ .GOLANGCI_LINT }} run --tests=false --fix"
|
||||
|
||||
lint:
|
||||
desc: Run gofmt + golangci lint checks
|
||||
vars:
|
||||
BAD_FMT_FILES:
|
||||
sh: gofmt -l -s .
|
||||
BAD_FILE_NAMES:
|
||||
sh: "find . | grep -e ':' || true"
|
||||
deps: [tools]
|
||||
cmds:
|
||||
# ensure there are no go fmt differences
|
||||
- cmd: 'test -z "{{ .BAD_FMT_FILES }}" || (echo "files with gofmt issues: [{{ .BAD_FMT_FILES }}]"; exit 1)'
|
||||
silent: true
|
||||
# ensure there are no files with ":" in it (a known back case in the go ecosystem)
|
||||
- cmd: 'test -z "{{ .BAD_FILE_NAMES }}" || (echo "files with bad names: [{{ .BAD_FILE_NAMES }}]"; exit 1)'
|
||||
silent: true
|
||||
# run linting
|
||||
- "{{ .GOLANGCI_LINT }} run --tests=false"
|
||||
|
||||
check-licenses:
|
||||
# desc: Ensure transitive dependencies are compliant with the current license policy
|
||||
deps: [tools]
|
||||
cmd: "{{ .BOUNCER }} check ./..."
|
||||
|
||||
check-go-mod-tidy:
|
||||
# desc: Ensure go.mod and go.sum are up to date
|
||||
cmds:
|
||||
- cmd: |
|
||||
if ! go mod tidy -diff; then
|
||||
echo "go.mod and/or go.sum need updates. Please run 'go mod tidy'"
|
||||
exit 1
|
||||
fi
|
||||
silent: true
|
||||
|
||||
|
||||
## Testing tasks #################################
|
||||
|
||||
unit:
|
||||
desc: Run unit tests
|
||||
deps:
|
||||
- tmpdir
|
||||
vars:
|
||||
TEST_PKGS:
|
||||
sh: "go list ./... | tr '\n' ' '"
|
||||
|
||||
# unit test coverage threshold (in % coverage)
|
||||
COVERAGE_THRESHOLD: 30
|
||||
cmds:
|
||||
- "go test -coverprofile {{ .TMP_DIR }}/unit-coverage-details.txt {{ .TEST_PKGS }}"
|
||||
- cmd: ".github/scripts/coverage.py {{ .COVERAGE_THRESHOLD }} {{ .TMP_DIR }}/unit-coverage-details.txt"
|
||||
silent: true
|
||||
|
||||
|
||||
## Acceptance tests #################################
|
||||
|
||||
ci-test-linux:
|
||||
cmds:
|
||||
- task: ci-test-linux-run
|
||||
- task: ci-test-docker-image
|
||||
- task: ci-test-deb-package-install
|
||||
- task: ci-test-rpm-package-install
|
||||
|
||||
ci-test-docker-image:
|
||||
desc: Test using the docker image
|
||||
cmds:
|
||||
- |
|
||||
docker run \
|
||||
--rm \
|
||||
-t \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
'docker.io/wagoodman/dive:latest' \
|
||||
'{{ .TEST_IMAGE }}' \
|
||||
--ci
|
||||
|
||||
ci-test-deb-package-install:
|
||||
desc: Test debian package installation
|
||||
cmds:
|
||||
- |
|
||||
docker run \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /${PWD}:/src \
|
||||
-w /src \
|
||||
ubuntu:latest \
|
||||
/bin/bash -x -c "\
|
||||
apt update && \
|
||||
apt install -y curl && \
|
||||
curl -L 'https://download.docker.com/linux/static/stable/x86_64/docker-{{ .DOCKER_CLI_VERSION }}.tgz' | \
|
||||
tar -vxzf - docker/docker --strip-component=1 && \
|
||||
mv docker /usr/local/bin/ &&\
|
||||
docker version && \
|
||||
apt install ./snapshot/dive_*_linux_amd64.deb -y && \
|
||||
dive --version && \
|
||||
dive '{{ .TEST_IMAGE }}' --ci \
|
||||
"
|
||||
|
||||
ci-test-rpm-package-install:
|
||||
desc: Test RPM package installation
|
||||
cmds:
|
||||
- |
|
||||
docker run \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /${PWD}:/src \
|
||||
-w /src \
|
||||
fedora:latest \
|
||||
/bin/bash -x -c "\
|
||||
curl -L 'https://download.docker.com/linux/static/stable/x86_64/docker-{{ .DOCKER_CLI_VERSION }}.tgz' | \
|
||||
tar -vxzf - docker/docker --strip-component=1 && \
|
||||
mv docker /usr/local/bin/ &&\
|
||||
docker version && \
|
||||
dnf install ./snapshot/dive_*_linux_amd64.rpm -y && \
|
||||
dive --version && \
|
||||
dive '{{ .TEST_IMAGE }}' --ci \
|
||||
"
|
||||
|
||||
generate-compressed-test-images:
|
||||
desc: Generate compressed test images for testing
|
||||
cmds:
|
||||
- |
|
||||
for alg in uncompressed gzip estargz zstd; do \
|
||||
for exporter in docker image; do \
|
||||
docker buildx build \
|
||||
-f .data/Dockerfile.minimal \
|
||||
--tag test-dive-${exporter}:${alg} \
|
||||
--output type=${exporter},force-compression=true,compression=${alg} . ; \
|
||||
done ; \
|
||||
done && \
|
||||
echo 'Exported test data!'
|
||||
|
||||
generate-compressed-test-data:
|
||||
desc: Generate compressed test data for testing
|
||||
cmds:
|
||||
- |
|
||||
for alg in uncompressed gzip estargz zstd; \
|
||||
do \
|
||||
docker buildx build \
|
||||
-f .data/Dockerfile.minimal \
|
||||
--output type=tar,dest=.data/test-${alg}-image.tar,force-compression=true,compression=${alg} . ; \
|
||||
docker buildx build \
|
||||
-f .data/Dockerfile.minimal \
|
||||
--output type=oci,dest=.data/test-oci-${alg}-image.tar,force-compression=true,compression=${alg} . ; \
|
||||
done && \
|
||||
echo 'Exported test data!'
|
||||
|
||||
ci-test-linux-run:
|
||||
desc: Test Linux binary execution (CI only)
|
||||
deps: [ci-check, generate-compressed-test-images]
|
||||
cmds:
|
||||
- |
|
||||
ls -la {{ .SNAPSHOT_DIR }}
|
||||
ls -la {{ .SNAPSHOT_DIR }}/dive_linux_amd64_v1
|
||||
chmod 755 {{ .SNAPSHOT_DIR }}/dive_linux_amd64_v1/dive && \
|
||||
{{ .SNAPSHOT_DIR }}/dive_linux_amd64_v1/dive '{{ .TEST_IMAGE }}' --ci && \
|
||||
{{ .SNAPSHOT_DIR }}/dive_linux_amd64_v1/dive --source docker-archive .data/test-kaniko-image.tar --ci --ci-config .data/.dive-ci
|
||||
- |
|
||||
for alg in uncompressed gzip estargz zstd; do \
|
||||
for exporter in docker image; do \
|
||||
{{ .SNAPSHOT_DIR }}/dive_linux_amd64_v1/dive "test-dive-${exporter}:${alg}" --ci ; \
|
||||
done && \
|
||||
{{ .SNAPSHOT_DIR }}/dive_linux_amd64_v1/dive --source docker-archive .data/test-oci-${alg}-image.tar --ci --ci-config .data/.dive-ci; \
|
||||
done
|
||||
|
||||
ci-test-mac-run:
|
||||
desc: Test macOS binary execution (CI only)
|
||||
deps: [ci-check]
|
||||
cmds:
|
||||
- |
|
||||
chmod 755 {{ .SNAPSHOT_DIR }}/dive_darwin_amd64_v1/dive && \
|
||||
{{ .SNAPSHOT_DIR }}/dive_darwin_amd64_v1/dive --source docker-archive .data/test-docker-image.tar --ci --ci-config .data/.dive-ci
|
||||
|
||||
|
||||
## Build-related targets #################################
|
||||
|
||||
build:
|
||||
desc: Build the project
|
||||
deps: [tools, tmpdir]
|
||||
generates:
|
||||
- "{{ .PROJECT }}"
|
||||
cmds:
|
||||
- silent: true
|
||||
cmd: |
|
||||
echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml
|
||||
cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml
|
||||
|
||||
- "{{ .BUILD_CMD }}"
|
||||
|
||||
snapshot:
|
||||
desc: Create a snapshot release
|
||||
aliases:
|
||||
- build
|
||||
deps: [tools, tmpdir]
|
||||
sources:
|
||||
- "**/*.go"
|
||||
method: checksum
|
||||
cmds:
|
||||
- silent: true
|
||||
cmd: |
|
||||
echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml
|
||||
cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml
|
||||
|
||||
- "{{ .SNAPSHOT_CMD }}"
|
||||
|
||||
changelog:
|
||||
desc: Generate a changelog
|
||||
deps: [tools]
|
||||
generates:
|
||||
- "{{ .CHANGELOG }}"
|
||||
- "{{ .NEXT_VERSION }}"
|
||||
cmds:
|
||||
- "{{ .CHRONICLE }} -vv -n --version-file {{ .NEXT_VERSION }} > {{ .CHANGELOG }}"
|
||||
- "{{ .GLOW }} -w 200 {{ .CHANGELOG }}"
|
||||
|
||||
|
||||
## Release targets #################################
|
||||
|
||||
release:
|
||||
desc: Create a release
|
||||
interactive: true
|
||||
deps: [tools]
|
||||
cmds:
|
||||
- cmd: .github/scripts/trigger-release.sh
|
||||
silent: true
|
||||
|
||||
|
||||
## CI-only targets #################################
|
||||
|
||||
ci-check:
|
||||
preconditions:
|
||||
- sh: test -n "$CI"
|
||||
msg: "This step should ONLY be run in CI. Exiting..."
|
||||
cmds:
|
||||
- echo "Running in CI environment"
|
||||
silent: true
|
||||
internal: true
|
||||
|
||||
ci-release:
|
||||
# desc: "[CI only] Create a release"
|
||||
deps: [ci-check, tools]
|
||||
cmds:
|
||||
- "{{ .CHRONICLE }} -vvv > CHANGELOG.md"
|
||||
- cmd: "cat CHANGELOG.md"
|
||||
silent: true
|
||||
- "{{ .RELEASE_CMD }}"
|
||||
|
||||
|
||||
## Cleanup targets #################################
|
||||
|
||||
clean-snapshot:
|
||||
desc: Remove any snapshot builds
|
||||
cmds:
|
||||
- "rm -rf {{ .SNAPSHOT_DIR }}"
|
||||
- "rm -rf {{ .TMP_DIR }}/goreleaser.yaml"
|
||||
Loading…
Add table
Add a link
Reference in a new issue