[CHORE] Support reproducible builds
This is a step towards making Forgejo's binaries (the one listed in the release tab) reproducible. In order to make the actual binary reproducible, we have to ensure that the release workflow has the correct configuration to produce such reproducible binaries. The release workflow currently uses the Dockerfile to produce binaries, as this is one of the easiest ways to do cross-compiling for Go binaries with CGO enabled (due to SQLite). In the Dockerfile, two new arguments are being given to the build command. `-trimpath` ensures that the workpath directory doesn't get included in the binary; this means that file names (such as for panics) are relative (to the workpath) and not absolute, which shouldn't impact debugging. `-buildid=` is added to the linker flag; it sets the BuildID of the Go linker to be empty; the `-buildid` hashes the input actions and output content; these vary from build to build for unknown reasons, but likely because of the involvement of temporary file names, this doesn't have any effect on the behavior of the resulting binary. The Makefile receives a new command, `reproduce-build#$VERSION` which can be used by people to produce a reproducible Forgejo binary of a particular release; it roughly does what the release workflow also does. Build the Dockerfile and extract the Forgejo binary from it. This doesn't allow to produce a reproducible version for every release, only for those that include this patch, as it needs to call the makefile of that version in order to make a reproducible binary. There's one thing left to do: the Dockerfile pins the Go version to a minor level and not to a patch level. This means that if a new Go patch version is released, that will be used instead and will result in a different binary that isn't bit to bit the same as the one that Forgejo has released.
This commit is contained in:
parent
f9ba752140
commit
be46795975
2 changed files with 22 additions and 1 deletions
|
@ -36,7 +36,7 @@ WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||||
RUN make clean
|
RUN make clean
|
||||||
RUN make frontend
|
RUN make frontend
|
||||||
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
|
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
|
||||||
RUN make RELEASE_VERSION=$RELEASE_VERSION go-check generate-backend static-executable && xx-verify gitea
|
RUN make RELEASE_VERSION=$RELEASE_VERSION GOFLAGS="-trimpath" LDFLAGS="-buildid=" go-check generate-backend static-executable && xx-verify gitea
|
||||||
|
|
||||||
# Copy local files
|
# Copy local files
|
||||||
COPY docker/root /tmp/local
|
COPY docker/root /tmp/local
|
||||||
|
|
21
Makefile
21
Makefile
|
@ -268,6 +268,7 @@ help:
|
||||||
@echo " - tidy run go mod tidy"
|
@echo " - tidy run go mod tidy"
|
||||||
@echo " - test[\#TestSpecificName] run unit test"
|
@echo " - test[\#TestSpecificName] run unit test"
|
||||||
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
|
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
|
||||||
|
@echo " - reproduce-build\#version build a reproducible binary for the specified release version"
|
||||||
|
|
||||||
###
|
###
|
||||||
# Check system and environment requirements
|
# Check system and environment requirements
|
||||||
|
@ -890,6 +891,26 @@ release-sources: | $(DIST_DIRS)
|
||||||
release-docs: | $(DIST_DIRS) docs
|
release-docs: | $(DIST_DIRS) docs
|
||||||
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs .
|
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs .
|
||||||
|
|
||||||
|
.PHONY: reproduce-build
|
||||||
|
reproduce-build:
|
||||||
|
# Start building the Dockerfile with the RELEASE_VERSION tag set. GOPROXY is set
|
||||||
|
# for convience, because the default of the Dockerfile is `direct` which can be
|
||||||
|
# quite slow.
|
||||||
|
@docker build --build-arg="RELEASE_VERSION=$(RELEASE_VERSION)" --build-arg="GOPROXY=$(shell $(GO) env GOPROXY)" --tag "forgejo-reproducibility" .
|
||||||
|
@id=$$(docker create forgejo-reproducibility); \
|
||||||
|
docker cp $$id:/app/gitea/gitea ./forgejo; \
|
||||||
|
docker rm -v $$id; \
|
||||||
|
docker image rm forgejo-reproducibility:latest
|
||||||
|
|
||||||
|
.PHONY: reproduce-build\#%
|
||||||
|
reproduce-build\#%:
|
||||||
|
@git switch -d "$*"
|
||||||
|
# All the current variables are based on information before the git checkout happened.
|
||||||
|
# Call the makefile again, so these variables are correct and can be used for building
|
||||||
|
# a reproducible binary. Always execute git switch -, to go back to the previous branch.
|
||||||
|
@make reproduce-build; \
|
||||||
|
(code=$$?; git switch -; exit $${code})
|
||||||
|
|
||||||
###
|
###
|
||||||
# Dependency management
|
# Dependency management
|
||||||
###
|
###
|
||||||
|
|
Loading…
Reference in a new issue