/
run-on-arch.sh
executable file
·146 lines (127 loc) · 4.33 KB
/
run-on-arch.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/bin/bash
set -euo pipefail
# Args
DOCKERFILE=$1
CONTAINER_NAME=$2
# Remainder of args get passed to docker
declare -a DOCKER_RUN_ARGS=${@:3:${#@}}
# Defaults
ACTION_DIR="$(cd "$(dirname "$0")"/.. >/dev/null 2>&1 ; pwd -P)"
LOWERCASE_REPOSITORY=$(printf "%s" "$GITHUB_REPOSITORY" | tr '[:upper:]' '[:lower:]')
PACKAGE_REGISTRY="ghcr.io/${LOWERCASE_REPOSITORY}/${CONTAINER_NAME}"
DEBIAN_FRONTEND=noninteractive
show_build_log_and_exit () {
# Show build-log.text output and exit if passed exit status != 0
status=$1
if [[ "$status" != 0 ]]
then
cat build-log.txt
exit $status
fi
}
quiet () {
# Hide the output of some command, unless it fails.
# If it fails, output is echoed and this script exits with the command's
# exit status code.
eval "$@" >> build-log.txt 2>&1 || show_build_log_and_exit $?
}
install_deps () {
# Install support for non-x86 emulation in Docker via QEMU.
# Platforms: linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x,
# linux/386, linux/arm/v7, linux/arm/v6
sudo apt-get update -q -y
sudo apt-get -qq install -y qemu qemu-user-static
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes
}
build_container () {
# Build the container image.
# If the GITHUB_TOKEN env var has a value, the container images will be
# cached between builds.
if [[ -z "${GITHUB_TOKEN:-}" ]]
then
docker build \
"${ACTION_DIR}/Dockerfiles" \
--file "$DOCKERFILE" \
--tag "${CONTAINER_NAME}:latest"
else
# Build optimization that uses GitHub package registry to cache docker
# images, based on Thai Pangsakulyanont's experiments.
# Read about it: https://dev.to/dtinth/caching-docker-builds-in-github-actions-which-approach-is-the-fastest-a-research-18ei
# Implementation is `build_with_gpr` here: https://github.com/dtinth/github-actions-docker-layer-caching-poc/blob/master/.github/workflows/dockerimage.yml
# About GitHub package registry: https://docs.github.com/en/packages/publishing-and-managing-packages/about-github-packages#support-for-package-registries
echo "GitHub token provided, caching to $PACKAGE_REGISTRY"
# Login without echoing token, just in case
BASH_FLAGS="$-"
set +x
echo "$GITHUB_TOKEN" | docker login ghcr.io \
-u "$GITHUB_ACTOR" \
--password-stdin
set "$BASH_FLAGS"
docker pull "$PACKAGE_REGISTRY:latest" || true
docker build \
"${ACTION_DIR}/Dockerfiles" \
--file "$DOCKERFILE" \
--tag "${CONTAINER_NAME}:latest" \
--cache-from="$PACKAGE_REGISTRY" \
--build-arg BUILDKIT_INLINE_CACHE=1
docker tag "${CONTAINER_NAME}:latest" "$PACKAGE_REGISTRY" \
&& docker push "$PACKAGE_REGISTRY" || true
fi
}
run_container () {
# Run the container.
# Run user-provided setup script, in same shell
source "${ACTION_DIR}/src/run-on-arch-setup.sh"
# Interpolate DOCKER_RUN_ARGS, to support evaluation of $VAR references
for i in "${!DOCKER_RUN_ARGS[@]}"
do
DOCKER_RUN_ARGS[$i]=$(eval echo "${DOCKER_RUN_ARGS[$i]}")
done
chmod +x "${ACTION_DIR}/src/run-on-arch-commands.sh"
# The location of the event.json file
EVENT_DIR=$(dirname "$GITHUB_EVENT_PATH")
docker run \
--workdir "${GITHUB_WORKSPACE}" \
--rm \
-e DEBIAN_FRONTEND=noninteractive \
-e CI \
-e GITHUB_ACTION \
-e GITHUB_ACTION_PATH \
-e GITHUB_ACTIONS \
-e GITHUB_ACTOR \
-e GITHUB_API_URL \
-e GITHUB_BASE_REF \
-e GITHUB_ENV \
-e GITHUB_EVENT_NAME \
-e GITHUB_EVENT_PATH \
-e GITHUB_GRAPHQL_URL \
-e GITHUB_HEAD_REF \
-e GITHUB_JOB \
-e GITHUB_REF \
-e GITHUB_REPOSITORY \
-e GITHUB_RUN_ID \
-e GITHUB_RUN_NUMBER \
-e GITHUB_SERVER_URL \
-e GITHUB_SHA \
-e GITHUB_WORKFLOW \
-e GITHUB_WORKSPACE \
-e RUNNER_OS \
-e RUNNER_TEMP \
-e RUNNER_TOOL_CACHE \
-e RUNNER_WORKSPACE \
-v "/var/run/docker.sock:/var/run/docker.sock" \
-v "${EVENT_DIR}:${EVENT_DIR}" \
-v "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}" \
-v "${ACTION_DIR}:${ACTION_DIR}" \
--tty \
${DOCKER_RUN_ARGS[@]} \
"${CONTAINER_NAME}:latest" \
"${ACTION_DIR}/src/run-on-arch-commands.sh"
}
# Installing deps produces a lot of log noise, so we do so quietly
quiet rm -f build-log.txt
quiet install_deps
echo "::group::Build container"
build_container
echo "::group::Run container"
run_container