ship every cmd binary in the release
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful

Take the binary list from cmd/ in the Makefile, the RPM packaging and the
release pipeline so a new tool ships without a pipeline edit.
This commit is contained in:
2026-09-12 16:46:51 +10:00
parent 2e2562018f
commit 6551ab9f13
7 changed files with 68 additions and 66 deletions
+2 -4
View File
@@ -1,5 +1,3 @@
# built binaries (repo root only — not the cmd/ source dirs) # build output: binaries, completions, cross-compiled release artifacts and
/catalog-diff # packages all land under dist/
# cross-compiled release artifacts (e.g. catalog-diff-linux-amd64)
/catalog-diff-*
dist/ dist/
+10 -8
View File
@@ -17,8 +17,8 @@ steps:
memory: 2Gi memory: 2Gi
cpu: 2 cpu: 2
# Build every binary into dist/ (consumed by the RPM step) plus the # Build every binary into dist/bin (consumed by the RPM step) plus the
# cross-platform binaries attached to the Gitea release. # cross-platform binaries attached to the Gitea release, in dist/release.
- name: build - name: build
image: git.unkin.net/unkin/almalinux9-gobuilder:20260606 image: git.unkin.net/unkin/almalinux9-gobuilder:20260606
commands: commands:
@@ -27,12 +27,13 @@ steps:
# for the shell instead of substituting them (as pipeline vars) at parse # for the shell instead of substituting them (as pipeline vars) at parse
# time. ${CI_COMMIT_TAG} is a real Woodpecker var and stays single-$. # time. ${CI_COMMIT_TAG} is a real Woodpecker var and stays single-$.
- | - |
for name in catalog-diff; do mkdir -p dist/release
for name in $$(make print-binaries); do
for osarch in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64; do for osarch in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64; do
os="$${osarch%/*}"; arch="$${osarch#*/}" os="$${osarch%/*}"; arch="$${osarch#*/}"
GOOS="$$os" GOARCH="$$arch" \ GOOS="$$os" GOARCH="$$arch" \
go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" \ go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" \
-o "$${name}-$${os}-$${arch}" "./cmd/$${name}" -o "dist/release/$${name}-$${os}-$${arch}" "./cmd/$${name}"
done done
done done
depends_on: [test] depends_on: [test]
@@ -126,11 +127,12 @@ steps:
NOTES=$$(git log --pretty=format:"- %s") NOTES=$$(git log --pretty=format:"- %s")
fi fi
tea releases create --tag "${CI_COMMIT_TAG}" --title "${CI_COMMIT_TAG}" --note "$${NOTES}" --login gitea --repo "${CI_REPO}" tea releases create --tag "${CI_COMMIT_TAG}" --title "${CI_COMMIT_TAG}" --note "$${NOTES}" --login gitea --repo "${CI_REPO}"
# Everything to attach lives in dist/release, so the asset list is the
# directory rather than a hand-kept list of binary names.
RPM=$$(ls dist/*.rpm 2>/dev/null | head -1) RPM=$$(ls dist/*.rpm 2>/dev/null | head -1)
ASSETS="catalog-diff-linux-amd64 catalog-diff-linux-arm64 catalog-diff-darwin-amd64 catalog-diff-darwin-arm64" if [ -n "$$RPM" ]; then cp "$$RPM" dist/release/; fi
[ -n "$$RPM" ] && ASSETS="$$ASSETS $$RPM" (cd dist/release && sha256sum * >../sha256sums.txt && mv ../sha256sums.txt .)
sha256sum $$ASSETS > sha256sums.txt tea releases assets create "${CI_COMMIT_TAG}" dist/release/* \
tea releases assets create "${CI_COMMIT_TAG}" $$ASSETS sha256sums.txt \
--login gitea --repo "${CI_REPO}" --login gitea --repo "${CI_REPO}"
depends_on: [upload-rpm] depends_on: [upload-rpm]
backend_options: backend_options:
+3 -3
View File
@@ -30,9 +30,9 @@ scripts/build-rpm.sh # completions + nfpm packaging
.woodpecker/ # CI: build, test, pre-commit (PR) + release (tag) .woodpecker/ # CI: build, test, pre-commit (PR) + release (tag)
``` ```
Adding a binary: create `cmd/<name>/`, add the name to `BINARIES` in the Adding a binary: create `cmd/<name>/`. The Makefile, `scripts/build-rpm.sh`,
Makefile and to `scripts/build-rpm.sh`, and add its files to `packaging/nfpm.yaml` and the release pipeline all take the shipped list from
`packaging/nfpm.yaml`. `cmd/`, so nothing else needs editing.
## Transport ## Transport
+19 -12
View File
@@ -1,25 +1,31 @@
# All shipped binaries. Every tool is a separate main package under cmd/, so # All shipped binaries, discovered from cmd/. Every tool is a separate main
# adding one is a matter of adding its name here. # package there, so adding one needs no edit here.
BINARIES := catalog-diff catalog-impact BINARIES := $(notdir $(wildcard cmd/*))
DIST := dist DIST := dist
BINDIR := $(DIST)/bin
COMPDIR := $(DIST)/completions
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo dev) VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
GOFLAGS := -ldflags="-s -w -X main.version=$(VERSION)" GOFLAGS := -ldflags="-s -w -X main.version=$(VERSION)"
OS ?= $(shell go env GOOS) OS ?= $(shell go env GOOS)
ARCH ?= $(shell go env GOARCH) ARCH ?= $(shell go env GOARCH)
.PHONY: all build test lint fmt pre-commit clean install completions rpm rpm-package patch minor major _tag .PHONY: all build test lint fmt pre-commit clean install completions print-binaries rpm rpm-package patch minor major _tag
all: build all: build
# Build every binary into dist/ so the nfpm packaging step # Build every binary into dist/bin so the nfpm packaging step
# (scripts/build-rpm.sh) can find them. Each main package needs its own -o, so # (scripts/build-rpm.sh) can find them. Each main package needs its own -o, so
# they are built individually rather than with a single ./... invocation. # they are built individually rather than with a single ./... invocation.
build: build:
@for b in $(BINARIES); do \ @for b in $(BINARIES); do \
echo "building $$b"; \ echo "building $$b"; \
CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build $(GOFLAGS) -o $(DIST)/$$b ./cmd/$$b || exit 1; \ CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build $(GOFLAGS) -o $(BINDIR)/$$b ./cmd/$$b || exit 1; \
done done
# The binary list, for CI steps that cross-compile the same set.
print-binaries:
@echo $(BINARIES)
test: test:
go test -v -race ./... go test -v -race ./...
@@ -33,18 +39,19 @@ pre-commit:
pre-commit run --all-files pre-commit run --all-files
clean: clean:
rm -rf $(DIST) $(BINARIES) rm -rf $(DIST)
install: install:
go install $(GOFLAGS) ./... go install $(GOFLAGS) ./...
# Generate bash/zsh/fish completions for every binary into dist/completions. # Generate bash/zsh/fish completions for every binary into dist/completions,
# named and laid out exactly as they install (the RPM globs these directories).
completions: build completions: build
@mkdir -p $(DIST)/completions @mkdir -p $(COMPDIR)/bash $(COMPDIR)/zsh $(COMPDIR)/fish
@for b in $(BINARIES); do \ @for b in $(BINARIES); do \
$(DIST)/$$b completion bash > $(DIST)/completions/$$b.bash; \ $(BINDIR)/$$b completion bash > $(COMPDIR)/bash/$$b; \
$(DIST)/$$b completion zsh > $(DIST)/completions/_$$b; \ $(BINDIR)/$$b completion zsh > $(COMPDIR)/zsh/_$$b; \
$(DIST)/$$b completion fish > $(DIST)/completions/$$b.fish; \ $(BINDIR)/$$b completion fish > $(COMPDIR)/fish/$$b.fish; \
done done
# Build the binaries then package them (with completions) into an RPM via nfpm. # Build the binaries then package them (with completions) into an RPM via nfpm.
+1 -1
View File
@@ -16,7 +16,7 @@ persisted on the server.
```bash ```bash
dnf install puppet-catalog-tools # from the artifactapi rpm-internal repo dnf install puppet-catalog-tools # from the artifactapi rpm-internal repo
# or # or
make build # -> dist/ make build # -> dist/bin/
``` ```
# catalog-diff # catalog-diff
+11 -29
View File
@@ -22,44 +22,26 @@ replaces:
provides: provides:
- puppet-catalog-tools - puppet-catalog-tools
# Globs, so a new tool under cmd/ ships without editing this file.
contents: contents:
- src: dist/catalog-diff - src: dist/bin/*
dst: /usr/bin/catalog-diff dst: /usr/bin
file_info: file_info:
mode: 0755 mode: 0755
owner: root owner: root
group: root group: root
- src: dist/catalog-impact # Shell completions (generated by scripts/build-rpm.sh before packaging,
dst: /usr/bin/catalog-impact # already named as they install).
file_info: - src: dist/completions/bash/*
mode: 0755 dst: /usr/share/bash-completion/completions
owner: root
group: root
# Shell completions (generated by scripts/build-rpm.sh before packaging).
- src: dist/completions/catalog-diff.bash
dst: /usr/share/bash-completion/completions/catalog-diff
file_info: file_info:
mode: 0644 mode: 0644
- src: dist/completions/_catalog-diff - src: dist/completions/zsh/*
dst: /usr/share/zsh/site-functions/_catalog-diff dst: /usr/share/zsh/site-functions
file_info: file_info:
mode: 0644 mode: 0644
- src: dist/completions/catalog-diff.fish - src: dist/completions/fish/*
dst: /usr/share/fish/vendor_completions.d/catalog-diff.fish dst: /usr/share/fish/vendor_completions.d
file_info:
mode: 0644
- src: dist/completions/catalog-impact.bash
dst: /usr/share/bash-completion/completions/catalog-impact
file_info:
mode: 0644
- src: dist/completions/_catalog-impact
dst: /usr/share/zsh/site-functions/_catalog-impact
file_info:
mode: 0644
- src: dist/completions/catalog-impact.fish
dst: /usr/share/fish/vendor_completions.d/catalog-impact.fish
file_info: file_info:
mode: 0644 mode: 0644
+22 -9
View File
@@ -12,24 +12,37 @@ cd "${ROOT_DIR}"
VERSION="${1:-${CI_COMMIT_TAG:-0.0.0-dev}}" VERSION="${1:-${CI_COMMIT_TAG:-0.0.0-dev}}"
VERSION="${VERSION#v}" # strip a leading v VERSION="${VERSION#v}" # strip a leading v
PACKAGE="puppet-catalog-tools" PACKAGE="puppet-catalog-tools"
BINARIES=(catalog-diff catalog-impact)
DIST="dist" DIST="dist"
BIN_DIR="${DIST}/bin"
COMP_DIR="${DIST}/completions"
# Every tool is a main package under cmd/, so the shipped list is the contents
# of cmd/ — the same list the Makefile builds.
BINARIES=()
for dir in cmd/*/; do
BINARIES+=("$(basename "${dir}")")
done
if [ ${#BINARIES[@]} -eq 0 ]; then
echo "ERROR: no binaries found under cmd/" >&2
exit 1
fi
for b in "${BINARIES[@]}"; do for b in "${BINARIES[@]}"; do
if [ ! -f "${DIST}/${b}" ]; then if [ ! -f "${BIN_DIR}/${b}" ]; then
echo "ERROR: ${DIST}/${b} not found; run 'make build' first" >&2 echo "ERROR: ${BIN_DIR}/${b} not found; run 'make build' first" >&2
exit 1 exit 1
fi fi
done done
# Generate shell completions from the freshly built binaries so they always # Generate shell completions from the freshly built binaries so they always
# match the shipped flags/subcommands. # match the shipped flags/subcommands. They are written under the name and
COMP_DIR="${DIST}/completions" # directory they install as, because nfpm globs these directories.
mkdir -p "${COMP_DIR}" rm -rf "${COMP_DIR}"
mkdir -p "${COMP_DIR}/bash" "${COMP_DIR}/zsh" "${COMP_DIR}/fish"
for b in "${BINARIES[@]}"; do for b in "${BINARIES[@]}"; do
"./${DIST}/${b}" completion bash >"${COMP_DIR}/${b}.bash" "./${BIN_DIR}/${b}" completion bash >"${COMP_DIR}/bash/${b}"
"./${DIST}/${b}" completion zsh >"${COMP_DIR}/_${b}" "./${BIN_DIR}/${b}" completion zsh >"${COMP_DIR}/zsh/_${b}"
"./${DIST}/${b}" completion fish >"${COMP_DIR}/${b}.fish" "./${BIN_DIR}/${b}" completion fish >"${COMP_DIR}/fish/${b}.fish"
done done
export PACKAGE_NAME="${PACKAGE}" export PACKAGE_NAME="${PACKAGE}"