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

Cache final images instead of build layers #161

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/actions/run-interop-ping-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ runs:

- name: Build images
working-directory: ${{ steps.find-workdir.outputs.WORK_DIR }}
run: make
run: make -j 2
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to still use make here? We could as well just use typescript for this step.

Going even further, we could make it a "proper" action that is published to the GitHub marketplace. That would allow us to move away from a composite one to either Docker (and allow us to write it in go or Rust) or JavaScript.

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'm not opposed to it. Make gives us a lot of stuff out of the box, like this
-j flag for paralleization. I might punt on that for now though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To add another point, this is the root directory of these tests. Make here does nothing but call make in the implementation folders. I wouldn't want to remove this make. It's a good interface point such that implementations know they have to provide a Makefile that generates a image.json. The rest can be done however they want.

shell: bash

- name: Run the test
working-directory: ${{ steps.find-workdir.outputs.WORK_DIR }}
run: WORKER_COUNT=2 npm run test -- --extra-version=${{ inputs.extra-versions }} --name-filter=${{ inputs.test-filter }}
run: WORKER_COUNT=4 npm run test -- --extra-version=${{ inputs.extra-versions }} --name-filter=${{ inputs.test-filter }}
shell: bash

- name: Print the results
Expand Down
1 change: 0 additions & 1 deletion multidim-interop/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ $(RUST_SUBDIRS):
$(NIM_SUBDIRS):
$(MAKE) -C $@


.PHONY: $(GO_SUBDIRS) $(JS_SUBDIRS) $(RUST_SUBDIRS) $(NIM_SUBDIRS) all
13 changes: 0 additions & 13 deletions multidim-interop/dockerBuildWrapper.sh

This file was deleted.

5 changes: 4 additions & 1 deletion multidim-interop/go/v0.22/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1

FROM golang:1.19-alpine
FROM golang:1.19-alpine AS builder

WORKDIR /app

Expand All @@ -12,4 +12,7 @@ COPY *.go ./

RUN go build -o /testplan

FROM alpine:3.17
COPY --from=builder /testplan /testplan

ENTRYPOINT [ "/testplan"]
24 changes: 20 additions & 4 deletions multidim-interop/go/v0.22/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
image_name := go-v0.22
SHELL := /usr/bin/env bash
imageName := go-v0.22

cacheKey=${shell git ls-files | tr "\n" " " | xargs ../../helpers/hashFiles.sh}
shouldUseCache := ${shell IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/shouldUseCache.sh}

all: image.json

ifneq (${shouldUseCache},)
# We have a cached image, let's use it
image.json:
CACHE_KEY=${cacheKey} IMAGE_NAME=${imageName} ../../helpers/tryLoadCache.sh
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
else
image.json: Dockerfile main.go go.mod go.sum
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh .
docker image inspect ${image_name} -f "{{.Id}}" | \
docker build -t ${imageName} .
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
# If we're in CI, save the cache
if [[ -n "$${CI:-}" ]]; then IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/saveCache.sh; fi
endif

.PHONY: clean

clean:
rm image.json
rm image.json
7 changes: 5 additions & 2 deletions multidim-interop/go/v0.23/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1

FROM golang:1.19-alpine
FROM golang:1.19-alpine AS builder

WORKDIR /app

Expand All @@ -12,4 +12,7 @@ COPY *.go ./

RUN go build -o /testplan

ENTRYPOINT [ "/testplan"]
FROM alpine:3.17
COPY --from=builder /testplan /testplan

ENTRYPOINT [ "/testplan"]
24 changes: 20 additions & 4 deletions multidim-interop/go/v0.23/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
image_name := go-v0.23
SHELL := /usr/bin/env bash
imageName := go-v0.23

cacheKey=${shell git ls-files | tr "\n" " " | xargs ../../helpers/hashFiles.sh}
shouldUseCache := ${shell IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/shouldUseCache.sh}

all: image.json

ifneq (${shouldUseCache},)
# We have a cached image, let's use it
image.json:
CACHE_KEY=${cacheKey} IMAGE_NAME=${imageName} ../../helpers/tryLoadCache.sh
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
else
image.json: Dockerfile main.go go.mod go.sum
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh .
docker image inspect ${image_name} -f "{{.Id}}" | \
docker build -t ${imageName} .
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
# If we're in CI, save the cache
if [[ -n "$${CI:-}" ]]; then IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/saveCache.sh; fi
endif

.PHONY: clean

clean:
rm image.json
rm image.json
5 changes: 4 additions & 1 deletion multidim-interop/go/v0.24/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1

FROM golang:1.19-alpine
FROM golang:1.19-alpine AS builder

WORKDIR /app

Expand All @@ -12,4 +12,7 @@ COPY *.go ./

RUN go build -o /testplan

FROM alpine:3.17
COPY --from=builder /testplan /testplan

ENTRYPOINT [ "/testplan"]
24 changes: 20 additions & 4 deletions multidim-interop/go/v0.24/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
image_name := go-v0.24
SHELL := /usr/bin/env bash
imageName := go-v0.24

cacheKey=${shell git ls-files | tr "\n" " " | xargs ../../helpers/hashFiles.sh}
shouldUseCache := ${shell IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/shouldUseCache.sh}

all: image.json

ifneq (${shouldUseCache},)
# We have a cached image, let's use it
image.json:
CACHE_KEY=${cacheKey} IMAGE_NAME=${imageName} ../../helpers/tryLoadCache.sh
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
else
image.json: Dockerfile main.go go.mod go.sum
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh .
docker image inspect ${image_name} -f "{{.Id}}" | \
docker build -t ${imageName} .
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
# If we're in CI, save the cache
if [[ -n "$${CI:-}" ]]; then IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/saveCache.sh; fi
endif

.PHONY: clean

clean:
rm image.json
rm image.json
21 changes: 17 additions & 4 deletions multidim-interop/go/v0.25/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
image_name := go-v0.25
SHELL := /usr/bin/env bash
imageName := go-v0.25
commitSha := 5741b6c9bbcc1185bdf94d816dca966b37ce61ff
cacheKey := ${commitSha}
shouldUseCache := ${shell IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/shouldUseCache.sh}

all: image.json

ifneq (${shouldUseCache},)
# We have a cached image, let's use it
image.json:
CACHE_KEY=${cacheKey} IMAGE_NAME=${imageName} ../../helpers/tryLoadCache.sh
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
else
image.json: go-libp2p-${commitSha}
cd go-libp2p-${commitSha} && IMAGE_NAME=${image_name} ../../../dockerBuildWrapper.sh -f test-plans/PingDockerfile .
docker image inspect ${image_name} -f "{{.Id}}" | \
cd go-libp2p-${commitSha} && docker build -t ${imageName} -f test-plans/PingDockerfile .
# If we're in CI, save the cache
if [[ -n "$${CI:-}" ]]; then IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/saveCache.sh; fi
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
endif

go-libp2p-${commitSha}: go-libp2p-${commitSha}.zip
unzip -o go-libp2p-${commitSha}.zip
Expand All @@ -17,4 +30,4 @@ go-libp2p-${commitSha}.zip:
clean:
rm image.json
rm go-libp2p-*.zip
rm -rf go-libp2p-*
rm -rf go-libp2p-*
22 changes: 18 additions & 4 deletions multidim-interop/go/v0.26/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
image_name := go-v0.26
SHELL := /usr/bin/env bash
imageName := go-v0.26
commitSha := 59a14cf3194d5d057c45cb1dbc7b1af3a116bc7a
cacheKey := ${commitSha}
shouldUseCache := ${shell IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/shouldUseCache.sh}

all: image.json

ifneq (${shouldUseCache},)
# We have a cached image, let's use it
image.json:
echo "Using cached image ${shouldUseCache} f"
CACHE_KEY=${cacheKey} IMAGE_NAME=${imageName} ../../helpers/tryLoadCache.sh
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
else
image.json: go-libp2p-${commitSha}
cd go-libp2p-${commitSha} && IMAGE_NAME=${image_name} ../../../dockerBuildWrapper.sh -f test-plans/PingDockerfile .
docker image inspect ${image_name} -f "{{.Id}}" | \
cd go-libp2p-${commitSha} && docker build -t ${imageName} -f test-plans/PingDockerfile .
# If we're in CI, save the cache
if [[ -n "$${CI:-}" ]]; then IMAGE_NAME=${imageName} CACHE_KEY=${cacheKey} ../../helpers/saveCache.sh; fi
docker image inspect ${imageName} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
endif

go-libp2p-${commitSha}: go-libp2p-${commitSha}.zip
unzip -o go-libp2p-${commitSha}.zip
Expand All @@ -17,4 +31,4 @@ go-libp2p-${commitSha}.zip:
clean:
rm image.json
rm go-libp2p-*.zip
rm -rf go-libp2p-*
rm -rf go-libp2p-*
13 changes: 13 additions & 0 deletions multidim-interop/helpers/buildCacheKey.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env /bin/bash
set -eou pipefail
set -x

# Assert that IMAGE_NAME is not empty
if [ -z "$IMAGE_NAME" ]; then
echo "IMAGE_NAME is not set"
exit 1
fi

ARCH=$(docker info -f "{{.Architecture}}")
BUILD_CACHE_KEY="$IMAGE_NAME-$CACHE_KEY-$ARCH"
echo $BUILD_CACHE_KEY
5 changes: 5 additions & 0 deletions multidim-interop/helpers/hashFiles.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env /bin/bash
set -eou pipefail

# sort all the files passed in by name, then hash them
echo "$@" | xargs -n1 | sort | xargs sha256sum | sha256sum | sed 's/.$//' | xargs
9 changes: 9 additions & 0 deletions multidim-interop/helpers/saveCache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env /bin/bash
set -eou pipefail
set -x

script_dir=$(dirname "$0")
BUILD_CACHE_KEY=$($script_dir/buildCacheKey.sh)
AWS_BUCKET=${AWS_BUCKET:-libp2p-by-tf-aws-bootstrap}

docker image save $IMAGE_NAME | gzip | aws s3 cp - s3://$AWS_BUCKET/imageCache/$BUILD_CACHE_KEY.tar.gz
20 changes: 20 additions & 0 deletions multidim-interop/helpers/shouldUseCache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env /bin/bash
set -eou pipefail
set -x

# shouldUseCache.sh - Returns exit code 0 if we don't have the image locally and we have a cache hit.

AWS_BUCKET=${AWS_BUCKET:-libp2p-by-tf-aws-bootstrap}

script_dir=$(dirname "$0")
BUILD_CACHE_KEY=$($script_dir/buildCacheKey.sh)

# If we already have this image name in docker, lets not use the cache, since a
# small change will probaby be faster than refetch the cache
if docker image inspect $IMAGE_NAME -f "{{.Id}}" &> /dev/null; then
exit 1;
fi

curl --fail --head https://s3.amazonaws.com/$AWS_BUCKET/imageCache/$BUILD_CACHE_KEY.tar.gz &> /dev/null
# We need to echo something so that Make sees this as a target
echo $BUILD_CACHE_KEY
13 changes: 13 additions & 0 deletions multidim-interop/helpers/tryLoadCache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env /bin/bash
set -eou pipefail
set -x

script_dir=$(dirname "$0")
BUILD_CACHE_KEY=$($script_dir/buildCacheKey.sh)
AWS_BUCKET=${AWS_BUCKET:-libp2p-by-tf-aws-bootstrap}


curl https://s3.amazonaws.com/$AWS_BUCKET/imageCache/$BUILD_CACHE_KEY.tar.gz \
| docker image load && \
exit 0 \
|| exit 1
1 change: 1 addition & 0 deletions multidim-interop/js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*-image.json
22 changes: 3 additions & 19 deletions multidim-interop/js/v0.41/ChromiumDockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
# syntax=docker/dockerfile:1

FROM mcr.microsoft.com/playwright
ARG BASE_IMAGE
FROM $BASE_IMAGE

WORKDIR /app


COPY package*.json .

RUN npm ci

# Install browsers
RUN ./node_modules/.bin/playwright install

COPY tsconfig.json .
COPY .aegir.js .
COPY test ./test
COPY src ./src

RUN npm run build

ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "browser" ]
ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "browser" ]
10 changes: 7 additions & 3 deletions multidim-interop/js/v0.41/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# syntax=docker/dockerfile:1
FROM node:18
# Using playwright so that we have the same base across NodeJS + Browser tests
FROM mcr.microsoft.com/playwright

WORKDIR /app

COPY package*.json .
COPY package*.json ./

RUN npm ci

# Install browsers, Needed for the browser tests, but we do it here so we have the same base
RUN ./node_modules/.bin/playwright install

COPY tsconfig.json .
COPY .aegir.js .
COPY test ./test
COPY src ./src

RUN npm run build

ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "node" ]
ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "node" ]
Loading