Skip to content

Commit

Permalink
Use docker environment to build the actors reproducibly (#1606)
Browse files Browse the repository at this point in the history
* Basic docker build environment.

* Dockerfile: Run scripts by default.

* Add makefile rule for dockerized build.

* Tweak Dockerfile

* Add make *-repro commands for all networks

* Switch to reproducible build in github actions

* Remove -it from reproducible docker run commands

* git ignore everything in output

* Update rust image and specify a index digest.

* remove the deps-build target

* don't try to install anything else

We should try to use the exact image from dockerhub. This means updating
rust will require two steps, but that's not a huge deal IMO.

* do install the rust toolchain before copying

This lets us take advantage of docker layers.

* Make a clean checkout of the repo

This means it isn't possible to reproducibly build a dirty repo but...
nobody wants to do that anyways. It does mean that the reproducible
build won't be affected by other files in the tree.

* Minor improvements to repro builds with Docker (#1607)

* exclude `target` (mine was >40G when I first ran this, not needed for a container build)
* extract common variables in Makefile
* restore missing `all-bundles` target
* make `.PHONY` readable

* Chown after the fact instead of adding a user to the container

This works with both rootless and root docker/podman modes. Otherwise,
when running in rootless mode, the outer user's UID gets mapped to a
temporary UID on the outside, leading to permissions issues when writing
to the output directory.

---------

Co-authored-by: David Himmelstrup <lemmih@gmail.com>
Co-authored-by: Ian Davis <jungziege@gmail.com>
Co-authored-by: Rod Vagg <rod@vagg.org>
  • Loading branch information
4 people authored Jan 28, 2025
1 parent 9b779d0 commit 5aad41b
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ jobs:
env:
BUILD_FIL_NETWORK: ${{ matrix.network }}
run: |
cargo run --locked -- -o output/builtin-actors.car
make bundle-repro
2 changes: 1 addition & 1 deletion .github/workflows/release-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
env:
BUILD_FIL_NETWORK: ${{ matrix.network }}
run: |
cargo run --locked -- -o output/builtin-actors.car
make bundle-repro
- name: Upload release assets to GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ target
.idea/
.vscode/
**/.DS_Store
output/*.car
output/*
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM rust:1.81.0-bookworm@sha256:7b7f7ae5e49819e708369d49925360bde2af4f1962842e75a14af17342f08262

WORKDIR /usr/src/builtin-actors

# Install the compiler. Unfortunately, the rust docker container doesn't actually contain the rust
# compiler...
COPY ./rust-toolchain.toml .
RUN rustup show

# Then checkout a clean copy of the repo.
RUN --mount=type=bind,rw,target=/tmp/repo \
echo "Building $(git -C /tmp/repo rev-parse HEAD)" && \
git --git-dir /tmp/repo/.git --work-tree . checkout -f HEAD

ENTRYPOINT ["./scripts/docker-entrypoint.sh"]
36 changes: 35 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
SHELL=/usr/bin/env bash

DOCKER := docker
DOCKER_IMAGE_NAME := builtin-actors-builder
DOCKER_RUN_OPTS := --rm -v $(PWD)/output:/output
DOCKER_PLATFORM := --platform linux/amd64

# Run cargo fmt
rustfmt:
cargo fmt --all --check
Expand All @@ -16,32 +21,58 @@ check:
test:
cargo test --workspace

docker-builder:
$(DOCKER) buildx build $(DOCKER_PLATFORM) . -t $(DOCKER_IMAGE_NAME); \

# Create a bundle in a deterministic location
bundle:
cargo run -- -o output/builtin-actors.car

bundle-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) -e BUILD_FIL_NETWORK $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME)

# Create all canonical network bundles
all-bundles: bundle-mainnet bundle-caterpillarnet bundle-butterflynet bundle-calibrationnet bundle-devnet bundle-testing bundle-testing

all-bundles-repro: bundle-mainnet-repro bundle-caterpillarnet-repro bundle-butterflynet-repro bundle-calibrationnet-repro bundle-devnet-repro bundle-testing-repro

bundle-mainnet:
BUILD_FIL_NETWORK=mainnet cargo run -- -o output/builtin-actors-mainnet.car

bundle-mainnet-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME) "mainnet"

bundle-caterpillarnet:
BUILD_FIL_NETWORK=caterpillarnet cargo run -- -o output/builtin-actors-caterpillarnet.car

bundle-caterpillarnet-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME) "caterpillarnet"

bundle-butterflynet:
BUILD_FIL_NETWORK=butterflynet cargo run -- -o output/builtin-actors-butterflynet.car

bundle-butterflynet-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME) "butterflynet"

bundle-calibrationnet:
BUILD_FIL_NETWORK=calibrationnet cargo run -- -o output/builtin-actors-calibrationnet.car

bundle-calibrationnet-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME) "calibrationnet"

bundle-devnet:
BUILD_FIL_NETWORK=devnet cargo run -- -o output/builtin-actors-devnet.car

bundle-devnet-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME) "devnet"

bundle-testing:
BUILD_FIL_NETWORK=testing cargo run -- -o output/builtin-actors-testing.car
BUILD_FIL_NETWORK=testing-fake-proofs cargo run -- -o output/builtin-actors-testing-fake-proofs.car

bundle-testing-repro: docker-builder
$(DOCKER) run $(DOCKER_PLATFORM) $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE_NAME) "testing"

# Check if the working tree is clean.
check-clean:
@git diff --quiet || { \
Expand All @@ -50,4 +81,7 @@ check-clean:
}

.PHONY: rustfmt check check-clean test bundle
.PHONY: all-bundles bundle-mainnet bundle-caterpillarnet bundle-butterflynet bundle-calibrationnet bundle-devnet bundle-testing
.PHONY: all-bundles bundle-mainnet bundle-caterpillarnet bundle-butterflynet bundle-calibrationnet \
bundle-devnet bundle-testing all-bundles-repro bundle-mainnet-repro bundle-caterpillarnet-repro \
bundle-butterflynet-repro bundle-calibrationnet-repro bundle-devnet-repro bundle-testing-repro \
docker-builder
14 changes: 14 additions & 0 deletions scripts/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

set -e

if [[ -n "$1" ]]; then
SUFFIX="-$1"
else
SUFFIX=""
fi

make "bundle${SUFFIX}"
install -o "$(stat -c '%u' /output)" -g "$(stat -c '%g' /output)" \
-m 0644 \
-t "/output" "output/builtin-actors${SUFFIX}.car"

0 comments on commit 5aad41b

Please sign in to comment.