Skip to content

Commit 192aa2c

Browse files
jsvisaDaniPopes
andauthored
feat: add arm64 docker image (#9614)
* feat(docker): build arm64 image Signed-off-by: jsvisa <[email protected]> * wip Signed-off-by: jsvisa <[email protected]> * Revert "wip" This reverts commit a152a4c. Signed-off-by: jsvisa <[email protected]> * Revert "feat(docker): build arm64 image" This reverts commit 09adcbc. Signed-off-by: jsvisa <[email protected]> * feat(make): add cross docker build Signed-off-by: jsvisa <[email protected]> * feat(make): multi tags Signed-off-by: jsvisa <[email protected]> * feat(github): use cross build Signed-off-by: jsvisa <[email protected]> * add Dockerfile.cross Signed-off-by: jsvisa <[email protected]> * fix(make): don't recreate cross-builder Signed-off-by: jsvisa <[email protected]> * make: add log Signed-off-by: jsvisa <[email protected]> * fix: missing \ Signed-off-by: jsvisa <[email protected]> * typo Signed-off-by: jsvisa <[email protected]> * Update docker-publish.yml Co-authored-by: DaniPopes <[email protected]> --------- Signed-off-by: jsvisa <[email protected]> Co-authored-by: DaniPopes <[email protected]>
1 parent af9ceec commit 192aa2c

File tree

3 files changed

+136
-86
lines changed

3 files changed

+136
-86
lines changed
Lines changed: 67 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,78 @@
11
name: docker
22

33
on:
4-
push:
5-
tags:
6-
- "v*.*.*"
7-
schedule:
8-
- cron: "0 0 * * *"
9-
# Trigger without any parameters a proactive rebuild
10-
workflow_dispatch: {}
11-
workflow_call:
4+
push:
5+
tags:
6+
- "v*.*.*"
7+
schedule:
8+
- cron: "0 0 * * *"
9+
# Trigger without any parameters a proactive rebuild
10+
workflow_dispatch: {}
11+
workflow_call:
1212

1313
env:
14-
REGISTRY: ghcr.io
15-
# Will resolve to foundry-rs/foundry
16-
IMAGE_NAME: ${{ github.repository }}
14+
REGISTRY: ghcr.io
15+
# Will resolve to foundry-rs/foundry
16+
IMAGE_NAME: ${{ github.repository }}
1717

1818
jobs:
19-
container:
20-
runs-on: Linux-20.04
21-
# https://docs.github.com/en/actions/reference/authentication-in-a-workflow
22-
permissions:
23-
id-token: write
24-
packages: write
25-
contents: read
26-
timeout-minutes: 120
27-
steps:
28-
- name: Checkout repository
29-
id: checkout
30-
uses: actions/checkout@v4
19+
build:
20+
name: build and push
21+
runs-on: Linux-20.04
22+
permissions:
23+
id-token: write
24+
packages: write
25+
contents: read
26+
timeout-minutes: 120
27+
steps:
28+
- uses: actions/checkout@v4
29+
- uses: dtolnay/rust-toolchain@stable
30+
- uses: Swatinem/rust-cache@v2
31+
with:
32+
cache-on-failure: true
33+
- uses: taiki-e/install-action@cross
34+
# Login against a Docker registry except on PR
35+
# https://github.com/docker/login-action
36+
- name: Login into registry ${{ env.REGISTRY }}
37+
# Ensure this doesn't trigger on PR's
38+
if: github.event_name != 'pull_request'
39+
uses: docker/login-action@v2
40+
with:
41+
registry: ${{ env.REGISTRY }}
42+
username: ${{ github.actor }}
43+
password: ${{ secrets.GITHUB_TOKEN }}
3144

32-
- name: Install Docker BuildX
33-
uses: docker/setup-buildx-action@v2
34-
id: buildx
35-
with:
36-
install: true
45+
# Extract metadata (tags, labels) for Docker
46+
# https://github.com/docker/metadata-action
47+
- name: Extract Docker metadata
48+
id: meta
49+
uses: docker/metadata-action@v4
50+
with:
51+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
3752

38-
# Login against a Docker registry except on PR
39-
# https://github.com/docker/login-action
40-
- name: Log into registry ${{ env.REGISTRY }}
41-
# Ensure this doesn't trigger on PR's
42-
if: github.event_name != 'pull_request'
43-
uses: docker/login-action@v2
44-
with:
45-
registry: ${{ env.REGISTRY }}
46-
username: ${{ github.actor }}
47-
password: ${{ secrets.GITHUB_TOKEN }}
53+
# Creates an additional 'latest' or 'nightly' tag
54+
# If the job is triggered via cron schedule, tag nightly and nightly-{SHA}
55+
# If the job is triggered via workflow dispatch and on a master branch, tag branch and latest
56+
# Otherwise, just tag as the branch name
57+
- name: Finalize Docker Metadata
58+
id: docker_tagging
59+
run: |
60+
if [[ "${{ github.event_name }}" == 'schedule' ]]; then
61+
echo "cron trigger, assigning nightly tag"
62+
echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${GITHUB_SHA}" >> $GITHUB_OUTPUT
63+
elif [[ "${GITHUB_REF##*/}" == "main" ]] || [[ ${GITHUB_REF##*/} == "master" ]]; then
64+
echo "manual trigger from master/main branch, assigning latest tag"
65+
echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_OUTPUT
66+
else
67+
echo "Neither scheduled nor manual release from main branch. Just tagging as branch name"
68+
echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/}" >> $GITHUB_OUTPUT
69+
fi
4870
49-
# Extract metadata (tags, labels) for Docker
50-
# https://github.com/docker/metadata-action
51-
- name: Extract Docker metadata
52-
id: meta
53-
uses: docker/metadata-action@v4
54-
with:
55-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
71+
# Log docker metadata to explicitly know what is being pushed
72+
- name: Inspect Docker Metadata
73+
run: |
74+
echo "TAGS -> ${{ steps.docker_tagging.outputs.docker_tags }}"
75+
echo "LABELS -> ${{ steps.meta.outputs.labels }}"
5676
57-
# Creates an additional 'latest' or 'nightly' tag
58-
# If the job is triggered via cron schedule, tag nightly and nightly-{SHA}
59-
# If the job is triggered via workflow dispatch and on a master branch, tag branch and latest
60-
# Otherwise, just tag as the branch name
61-
- name: Finalize Docker Metadata
62-
id: docker_tagging
63-
run: |
64-
if [[ "${{ github.event_name }}" == 'schedule' ]]; then
65-
echo "cron trigger, assigning nightly tag"
66-
echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${GITHUB_SHA}" >> $GITHUB_OUTPUT
67-
elif [[ "${GITHUB_REF##*/}" == "main" ]] || [[ ${GITHUB_REF##*/} == "master" ]]; then
68-
echo "manual trigger from master/main branch, assigning latest tag"
69-
echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_OUTPUT
70-
else
71-
echo "Neither scheduled nor manual release from main branch. Just tagging as branch name"
72-
echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/}" >> $GITHUB_OUTPUT
73-
fi
74-
75-
# Log docker metadata to explicitly know what is being pushed
76-
- name: Inspect Docker Metadata
77-
run: |
78-
echo "TAGS -> ${{ steps.docker_tagging.outputs.docker_tags }}"
79-
echo "LABELS -> ${{ steps.meta.outputs.labels }}"
80-
81-
# Build and push Docker image
82-
# https://github.com/docker/build-push-action
83-
# https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md
84-
- name: Build and push Docker image
85-
uses: docker/build-push-action@v3
86-
with:
87-
context: .
88-
push: true
89-
tags: ${{ steps.docker_tagging.outputs.docker_tags }}
90-
labels: ${{ steps.meta.outputs.labels }}
91-
cache-from: type=gha
92-
cache-to: type=gha,mode=max
93-
build-args: |
94-
BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
95-
VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
96-
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
77+
- name: Build and push foundry image
78+
run: make DOCKER_IMAGE_NAME=${{ steps.docker_tagging.outputs.docker_tags }} PROFILE=maxperf docker-build-push

Dockerfile.cross

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# This image is meant to enable cross-architecture builds.
2+
# It assumes the foundry binaries have already been compiled for `$TARGETPLATFORM` and are
3+
# locatable in `./dist/bin/$TARGETARCH`
4+
FROM ubuntu:22.04
5+
6+
# Filled by docker buildx
7+
ARG TARGETARCH
8+
9+
COPY ./dist/bin/$TARGETARCH/* /usr/local/bin/
10+
11+
ENTRYPOINT ["/bin/sh", "-c"]
12+
13+
LABEL org.label-schema.build-date=$BUILD_DATE \
14+
org.label-schema.name="Foundry" \
15+
org.label-schema.description="Foundry" \
16+
org.label-schema.url="https://getfoundry.sh" \
17+
org.label-schema.vcs-ref=$VCS_REF \
18+
org.label-schema.vcs-url="https://github.com/foundry-rs/foundry.git" \
19+
org.label-schema.vendor="Foundry-rs" \
20+
org.label-schema.version=$VERSION \
21+
org.label-schema.schema-version="1.0"

Makefile

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
# Cargo profile for builds.
77
PROFILE ?= dev
8+
# The docker image name
9+
DOCKER_IMAGE_NAME ?= ghcr.io/foundry-rs/foundry:latest
10+
BIN_DIR = dist/bin
11+
CARGO_TARGET_DIR ?= target
812

913
# List of features to use when building. Can be overridden via the environment.
1014
# No jemalloc on Windows
@@ -26,6 +30,49 @@ help: ## Display this help.
2630
build: ## Build the project.
2731
cargo build --features "$(FEATURES)" --profile "$(PROFILE)"
2832

33+
# The following commands use `cross` to build a cross-compile.
34+
#
35+
# These commands require that:
36+
#
37+
# - `cross` is installed (`cargo install cross`).
38+
# - Docker is running.
39+
# - The current user is in the `docker` group.
40+
#
41+
# The resulting binaries will be created in the `target/` directory.
42+
build-%:
43+
cross build --target $* --features "$(FEATURES)" --profile "$(PROFILE)"
44+
45+
.PHONY: docker-build-push
46+
docker-build-push: docker-build-prepare ## Build and push a cross-arch Docker image tagged with DOCKER_IMAGE_NAME.
47+
$(MAKE) build-x86_64-unknown-linux-gnu
48+
mkdir -p $(BIN_DIR)/amd64
49+
for bin in anvil cast chisel forge; do \
50+
cp $(CARGO_TARGET_DIR)/x86_64-unknown-linux-gnu/$(PROFILE)/$$bin $(BIN_DIR)/amd64/; \
51+
done
52+
53+
$(MAKE) build-aarch64-unknown-linux-gnu
54+
mkdir -p $(BIN_DIR)/arm64
55+
for bin in anvil cast chisel forge; do \
56+
cp $(CARGO_TARGET_DIR)/aarch64-unknown-linux-gnu/$(PROFILE)/$$bin $(BIN_DIR)/arm64/; \
57+
done
58+
59+
docker buildx build --file ./Dockerfile.cross . \
60+
--platform linux/amd64,linux/arm64 \
61+
$(foreach tag,$(shell echo $(DOCKER_IMAGE_NAME) | tr ',' ' '),--tag $(tag)) \
62+
--provenance=false \
63+
--push
64+
65+
.PHONY: docker-build-prepare
66+
docker-build-prepare: ## Prepare the Docker build environment.
67+
docker run --privileged --rm tonistiigi/binfmt --install amd64,arm64
68+
@if ! docker buildx inspect cross-builder &> /dev/null; then \
69+
echo "Creating a new buildx builder instance"; \
70+
docker buildx create --use --driver docker-container --name cross-builder; \
71+
else \
72+
echo "Using existing buildx builder instance"; \
73+
docker buildx use cross-builder; \
74+
fi
75+
2976
##@ Other
3077

3178
.PHONY: clean
@@ -69,4 +116,4 @@ test: ## Run all tests.
69116

70117
pr: ## Run all tests and linters in preparation for a PR.
71118
make lint && \
72-
make test
119+
make test

0 commit comments

Comments
 (0)