Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build release binaries for all platforms #24

Merged
merged 49 commits into from Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f6deedd
add 'make build/<platform>' targets
samsalisbury Nov 22, 2022
48fd97d
update log message
samsalisbury Nov 22, 2022
5f1c07c
split out release build binaries by platform
samsalisbury Nov 23, 2022
59a325c
simplify zipping: skip subdirectories
samsalisbury Nov 23, 2022
9f210cd
rename RELEASE_BUILD -> FINAL_BUILD
samsalisbury Nov 23, 2022
4fcd699
rename TMP_BUILD -> BOOTSTRAP_BUILD
samsalisbury Nov 23, 2022
1ba9831
fix some comments
samsalisbury Nov 23, 2022
daa92ae
extract build logic from makefile
samsalisbury Nov 28, 2022
88b90c4
update dev/build
samsalisbury Nov 28, 2022
57fafdc
update dev/build
samsalisbury Nov 28, 2022
cdc2334
update dev/build
samsalisbury Nov 28, 2022
dcdcd1d
update dev/build
samsalisbury Nov 28, 2022
3e9174a
update dev/build
samsalisbury Nov 28, 2022
ee76b40
update dev/build
samsalisbury Nov 28, 2022
5dc00c8
update dev/build
samsalisbury Nov 28, 2022
748e8e9
dev/build builds for any platform
samsalisbury Nov 28, 2022
9ada09a
always start with an empty TARGET_DIR
samsalisbury Nov 29, 2022
7121e51
dev/build: separate out bootstrap chain
samsalisbury Nov 29, 2022
705fea6
add build all from scratch target
samsalisbury Nov 29, 2022
d8cebc0
makefile: use dev/build script
samsalisbury Nov 30, 2022
ab7e2ee
build process: rename things
samsalisbury Dec 5, 2022
bccc149
update comment
samsalisbury Dec 5, 2022
116d156
add release build targets
samsalisbury Dec 5, 2022
3c327e3
set development version to v0.2.0-beta
samsalisbury Dec 5, 2022
278f70d
add release zips as release dep
samsalisbury Dec 5, 2022
ba2a2a6
make release lists zips
samsalisbury Dec 5, 2022
0cf1a7e
backfill v0.1.7 release notes
samsalisbury Jan 11, 2023
f6e3e27
set development version to v0.1.8
samsalisbury Jan 11, 2023
0d69a8c
update changelog for v0.1.8
samsalisbury Jan 11, 2023
7efc955
revert changes to zipper lib
samsalisbury Jan 11, 2023
48c67a5
revert version bump
samsalisbury Jan 11, 2023
22639cd
Merge branch 'main' into release-binaries
samsalisbury Jan 11, 2023
ad9b565
Merge branch 'set-version-0.1.8' into release-binaries
samsalisbury Jan 11, 2023
d56ec38
update changelog for v0.1.8
samsalisbury Jan 11, 2023
5419e32
make release lists built zips
samsalisbury Jan 11, 2023
2c61048
whitespace
samsalisbury Jan 11, 2023
4b324ca
update comment for accuracy
samsalisbury Jan 11, 2023
7dd5c09
fix source-id generation on Darwin
samsalisbury Jan 11, 2023
c7abf40
ensure TMPDIR set in GHA
samsalisbury Jan 11, 2023
a54ec59
ensure TMPDIR is set for action-setup
samsalisbury Jan 11, 2023
d5a339c
fix 'make install' for GHA
samsalisbury Jan 11, 2023
39098e4
debug GITHUB_PATH
samsalisbury Jan 12, 2023
58a7f40
debug PATH
samsalisbury Jan 12, 2023
6c571f8
debug
samsalisbury Jan 12, 2023
2e21e63
fix gha installation path
samsalisbury Jan 12, 2023
61fb157
Merge branch 'main' into release-binaries
samsalisbury Jan 12, 2023
e18961e
remove redundant doc comment
samsalisbury Jan 12, 2023
11cc8a2
add explanatory comments to makefile
samsalisbury Jan 12, 2023
5fc5b1e
remove unused line
samsalisbury Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

150 changes: 93 additions & 57 deletions Makefile
@@ -1,5 +1,7 @@
SHELL := /usr/bin/env bash -euo pipefail -c

MAKEFLAGS := --jobs=10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This speeds things up by default, on later versions of GNU Make.


PRODUCT_NAME := actions-go-build
DESTDIR ?= /usr/local/bin

Expand All @@ -12,10 +14,17 @@ else
CLEAR :=
endif

SOURCE_ID := .git/source-id
SOURCE_ID_VALUE := $(shell SOURCE_ID=$(SOURCE_ID) ./dev/update-source-id)

# Uncomment to show the source ID.
# $(info SOURCE_ID=$(SOURCE_ID_VALUE))

default: run

ifeq ($(TMPDIR),)
TMPDIR := $(RUNNER_TEMP)
export TMPDIR
endif
ifeq ($(TMPDIR),)
$(error Neither TMPDIR nor RUNNER_TEMP are set.)
Expand Down Expand Up @@ -52,50 +61,51 @@ CLINAME := $(PRODUCT_NAME)

# Release versions of the CLI are built in three phases:
#
# 1) TMP_BUILD - No build metadata.
# 1) INITIAL_BUILD - No build metadata.
# 2) INTERMEDIATE_BUILD - Some build metadata.
# 3) RELEASE_BUILD - All build metadata.
# 3) BOOTSTRAPPED_BUILD - All build metadata.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed all these for hopefully the last time... I think we're consistent with naming everywhere now.

#
# See comments below for more explanation.

# TMP_BUILD is a build of the CLI done using just `go build ...`. This is used to bootstrap
# compiling the CLI using itself, for dogfooding purposes. The TMP_BUILD contains none of the
TMP_BASE := $(TMPDIR)/actions-go-build.builds/$(SOURCE_ID_VALUE)

# INITIAL_BUILD is a build of the CLI done using just `go build ...`. This is used to bootstrap
# compiling the CLI using itself, for dogfooding purposes. The INITIAL_BUILD contains none of the
# automatically generated metadata like the version or revision. It is used to build the
# intermediate build...
TMP_BUILD := $(TMPDIR)/temp-build/$(CLINAME)
INITIAL_BUILD := $(TMP_BASE)/initial/$(CLINAME)

# INTERMEDIATE_BUILD is a build of the CLI done using the TMP_BUILD build. Because it used
# TMP_BUILD (i.e. the code in this repo) to build itself, it contains automatically generated
# INTERMEDIATE_BUILD is a build of the CLI done using the INITIAL_BUILD build. Because it used
# INITIAL_BUILD (i.e. the code in this repo) to build itself, it contains automatically generated
# metadata like the version and revision. However, it does not contain the metadata about the
# version of actions-go-build that built it because TMP_BUILD doesn't have that metadata
# version of actions-go-build that built it because INITIAL_BUILD doesn't have that metadata
# available to inject.
INTERMEDIATE_BUILD := $(TMPDIR)/intermediate-build/$(CLINAME)
INTERMEDIATE_BUILD := $(TMP_BASE)/intermediate/$(CLINAME)

# RELEASE_BUILD is the final build of the CLI, done using the INTERMEDIATE_BUILD. Because
# BOOTSTRAPPED_BUILD is the final build of the CLI, done using the INTERMEDIATE_BUILD. Because
# INTERMEDIATE_BUILD contains build metadata (e.g. version and revision), it is able to inject
# that information, into this final build as "tool metadata". Thus we can track the provanance of
# this binary just like we are able to with any product binaries also built using this tool.
RELEASE_BUILD := dist/$(CLINAME)
BOOTSTRAPPED_BUILD := $(TMP_BASE)/bootstrapped/$(CLINAME)

# HOST_PLATFORM_TARGETS are targets that must always produce output compatible with
# the current host platform. We therefore unset the GOOS and GOARCH variable to allow
# the defaults to shine through.
HOST_PLATFORM_TARGETS := $(TMP_BUILD) $(INTERMEDIATE_BUILD) test/go
HOST_PLATFORM_TARGETS := $(INITIAL_BUILD) $(INTERMEDIATE_BUILD) test/go
$(HOST_PLATFORM_TARGETS): export GOOS :=
$(HOST_PLATFORM_TARGETS): export GOARCH :=

HOST_PLATFORM_TARGET_ENV := GOOS= GOARCH= OS= ARCH=

#
# Targets
#

build:
go build ./...

test: test/go

.PHONY: test/go
test/go: compile
go test $(GO_TEST_FLAGS) ./...
@$(HOST_PLATFORM_TARGET_ENV) go test $(GO_TEST_FLAGS) ./...

cover: GO_TEST_FLAGS := -coverprofile=coverage.profile
cover: test/go
Expand All @@ -120,41 +130,27 @@ env:
@echo " PRODUCT_REVISION=$$PRODUCT_REVISION"
@echo " PRODUCT_REVISION_TIME=$$PRODUCT_REVISION_TIME"

# When building the binary, we first do a plain 'go build' to build a temporary
# binary that contains no version info. Then we use that version of the binary
# to build this product with all the version info added automatically from the
# build context.
#
# We then use _that_ binary to build yet another binary, this time with the
# correct tool version injected into the build.
#
# Thus, each version of actions-go-build is built using itself.
# The targets below invoke the ./dev/build script. Please see that script for more docs
# on how actions-go-build is built using itself.

.PHONY: $(TMP_BUILD)
$(TMP_BUILD):
$(INITIAL_BUILD): $(SOURCE_ID)
@echo "# Running tests..." 1>&2
@$(RUN_TESTS_QUIET)
@echo "# Creating temporary build..." 1>&2
@rm -f "$(TMP_BUILD)"
@mkdir -p "$(dir $(TMP_BUILD))"
@go build -o "$(TMP_BUILD)"

.PHONY: $(INTERMEDIATE_BUILD)
$(INTERMEDIATE_BUILD): export TARGET_DIR := $(dir $(INTERMEDIATE_BUILD))
$(INTERMEDIATE_BUILD): $(TMP_BUILD)
@echo "# Creating intermediate build..." 1>&2
@$(TMP_BUILD) build -rebuild

.PHONY: $(RELEASE_BUILD)
$(RELEASE_BUILD): $(INTERMEDIATE_BUILD)
@echo "# Creating final build." 1>&2
@$(INTERMEDIATE_BUILD) build -rebuild
@echo "# Verifying reproducibility of self..." 1>&2
@./$@ verify

cli: $(RELEASE_BUILD)
@BIN_PATH="$@" ./dev/build initial > /dev/null

RUN_QUIET = OUT="$$($(1) 2>&1)" || { \
echo "Command Failed: $(notdir $(1))"; echo "$$OUT"; exit 1; \
}

$(INTERMEDIATE_BUILD): $(INITIAL_BUILD)
@BIN_PATH="$@" ./dev/build intermediate "$<" > /dev/null

$(BOOTSTRAPPED_BUILD): $(INTERMEDIATE_BUILD)
@BIN_PATH="$@" ./dev/build bootstrapped "$<" > /dev/null

cli: $(BOOTSTRAPPED_BUILD)
@echo "Build successful."
$(RELEASE_BUILD) --version
$(BOOTSTRAPPED_BUILD) --version

.PHONY: install
# Ensure install always targets the host platform.
Expand All @@ -163,13 +159,13 @@ install: export GOARCH :=

ifneq ($(GITHUB_PATH),)
# install for GitHub Actions.
install: $(RELEASE_BUILD)
@echo "$(dir $(CURDIR)/$(RELEASE_BUILD))" >> "$(GITHUB_PATH)"
@echo "Command '$(CLINAME)' installed to GITHUB_PATH"
@PATH="$$(cat $(GITHUB_PATH))" $(CLINAME) --version
install: $(BOOTSTRAPPED_BUILD)
@echo "$(dir $(BOOTSTRAPPED_BUILD))" >> "$(GITHUB_PATH)"
@echo "Command '$(CLINAME)' installed to GITHUB_PATH ($(GITHUB_PATH))"
@export PATH="$$(cat $(GITHUB_PATH))" && $(CLINAME) --version
else
# install for local use.
install: $(RELEASE_BUILD)
install: $(BOOTSTRAPPED_BUILD)
@mv "$<" "$(DESTDIR)"
@V="$$($(CLINAME) version -short)" && \
echo "# $(CLINAME) v$$V installed to $(DESTDIR)"
Expand All @@ -184,10 +180,10 @@ mod/framework/update:
# which is usful for quickly seeing its output whilst developing.

.PHONY: run
run: $(TMP_BUILD)
run: $(INITIAL_BUILD)
@$${QUIET:-false} || $(CLEAR)
@$${QUIET:-false} || echo "\$$ $(notdir $<) $(RUN)"
@$(TMP_BUILD) $(RUN)
@$(INITIAL_BUILD) $(RUN)

.PHONY: docs
docs: readme changelog
Expand Down Expand Up @@ -235,9 +231,49 @@ ifneq ($(GH_AUTHED),true)
endif
endif

.PHONY: release
release:
@./dev/release/create
#
# Release build targets
#
# FINAL_BUILD_TARGETS defines all the targets for platform-specific "final" builds.
# It's a macro so that we get a consistent set of targets for each platform.
define FINAL_BUILD_TARGETS

# Inside this define, $(1) is a platform string, like "linux/amd64" or "darwin/arm64"

# build/<platform> does not require a clean worktree and results in a "Development" build.
build/$(1): $$(BOOTSTRAPPED_BUILD)
@./dev/build dev "$$<" "$1" > /dev/null

DEV_BUILDS := $$(DEV_BUILDS) build/$(1)

dist/$1/actions-go-build \
out/actions-go-build_$(CURR_VERSION)_$(subst /,_,$1).zip \
zip/$(1) \
release/build/$(1): $$(BOOTSTRAPPED_BUILD)
@./dev/build release "$$<" "$1" > /dev/null
RELEASE_BUILDS := $$(RELEASE_BUILDS) release/build/$(1)
RELEASE_ZIPS := $$(RELEASE_ZIPS) out/actions-go-build_$(CURR_VERSION)_$(subst /,_,$1).zip

endef

# Get the list of supported platforms defined in the build script.
TARGET_PLATFORMS := $(shell ./dev/build platforms)

# For each supported platform, call FINAL_BUILD_TARGETS to create the needed targets.
$(eval $(foreach P,$(TARGET_PLATFORMS),$(call FINAL_BUILD_TARGETS,$(P))))

.PHONY: $(RELEASE_BUILDS)
.PHONY: $(DEV_BUILDS)

# build builds a dev build for each platform.
build: $(DEV_BUILDS)

# release/build builds a release build for each platform.
release/build: $(RELEASE_BUILDS)

# release builds zip-packaged builds for each platform.
release: $(RELEASE_ZIPS)
@for Z in $^; do echo $$Z; done

version: version/check
@LATEST="$(shell $(GH) release list -L 1 --exclude-drafts | grep Latest | cut -f1)"; \
Expand Down
8 changes: 8 additions & 0 deletions action-setup
Expand Up @@ -9,6 +9,14 @@ die() { echo "$*"; exit 1; }
# It defaults to "." meaning the repo root itself.
SUB_ACTION="${1:-.}"

if [[ -z "${TMPDIR:-}" ]]; then
if [[ -z "$RUNNER_TEMP" ]]; then
die "Neither TMPDIR nor RUNNER_TEMP are set."
fi
TMPDIR="$RUNNER_TEMP"
export TMPDIR
fi

# This script exports some environment variables for later steps,
# and clones this entire repository into the action path.
#
Expand Down