-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathtest-in-docker.sh
More file actions
executable file
·206 lines (175 loc) · 5.42 KB
/
Copy pathtest-in-docker.sh
File metadata and controls
executable file
·206 lines (175 loc) · 5.42 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env bash
set -euo pipefail
IMAGE_PREFIX=${IMAGE_PREFIX:-transloadit-python-sdk-dev}
CACHE_ROOT=${CACHE_ROOT:-.docker-cache}
POETRY_CACHE_DIR="$CACHE_ROOT/pypoetry"
PIP_CACHE_DIR="$CACHE_ROOT/pip"
NPM_CACHE_DIR="$CACHE_ROOT/npm"
HOME_DIR="$CACHE_ROOT/home"
DEFAULT_MATRIX=("3.9" "3.10" "3.11" "3.12" "3.13")
declare -a PYTHON_MATRIX=()
declare -a CUSTOM_COMMAND=()
usage() {
cat <<'EOF'
Usage: scripts/test-in-docker.sh [options] [-- command ...]
Options:
-p, --python VERSION Only run for the given Python version (repeatable)
-h, --help Show this help
Environment:
PYTHON_VERSIONS Space-separated Python versions to run (default CI matrix)
SKIP_POETRY_RUN Set to 1 to run the custom command without "poetry run"
IMAGE_NAME Override the Docker image name prefix
CACHE_ROOT Override the cache directory (default: .docker-cache)
Examples:
scripts/test-in-docker.sh
scripts/test-in-docker.sh --python 3.12
scripts/test-in-docker.sh -- pytest tests/test_client.py
SKIP_POETRY_RUN=1 scripts/test-in-docker.sh -- python -m pytest -k smartcdn
EOF
}
ensure_docker() {
if ! command -v docker >/dev/null 2>&1; then
echo "Docker is required to run this script." >&2
exit 1
fi
if ! docker info >/dev/null 2>&1; then
if [[ -z "${DOCKER_HOST:-}" && -S "$HOME/.colima/default/docker.sock" ]]; then
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
fi
fi
if ! docker info >/dev/null 2>&1; then
echo "Docker daemon is not reachable. Start Docker (or Colima) and retry." >&2
exit 1
fi
}
configure_platform() {
if [[ -z "${DOCKER_PLATFORM:-}" ]]; then
local arch
arch=$(uname -m)
if [[ "$arch" == "arm64" || "$arch" == "aarch64" ]]; then
DOCKER_PLATFORM=linux/amd64
fi
fi
}
parse_python_versions() {
local -a cli_versions=()
local -a custom_cmd=()
while [[ $# -gt 0 ]]; do
case "$1" in
-p|--python)
if [[ $# -lt 2 ]]; then
echo "Missing value for $1" >&2
exit 1
fi
cli_versions+=("$2")
shift 2
;;
--python=*)
cli_versions+=("${1#*=}")
shift
;;
-h|--help)
usage
exit 0
;;
--)
shift
custom_cmd=("$@")
break
;;
*)
custom_cmd+=("$1")
shift
;;
esac
done
if [[ ${#cli_versions[@]} -gt 0 ]]; then
PYTHON_MATRIX=("${cli_versions[@]}")
elif [[ -n "${PYTHON_VERSIONS:-}" ]]; then
read -r -a PYTHON_MATRIX <<< "$PYTHON_VERSIONS"
else
PYTHON_MATRIX=("${DEFAULT_MATRIX[@]}")
fi
if [[ ${#PYTHON_MATRIX[@]} -eq 0 ]]; then
PYTHON_MATRIX=("${DEFAULT_MATRIX[@]}")
fi
CUSTOM_COMMAND=("${custom_cmd[@]}")
}
build_image_for_version() {
local version=$1
local image_name=$2
local -a build_args=()
if [[ -n "${DOCKER_PLATFORM:-}" ]]; then
build_args+=(--platform "$DOCKER_PLATFORM")
fi
build_args+=(-t "$image_name" --build-arg "PYTHON_VERSION=$version" -f Dockerfile .)
echo "==> Building image $image_name (Python $version)"
docker build "${build_args[@]}"
}
run_for_version() {
local version=$1
local image_name=$2
local -a docker_args=(
--rm
--user "$(id -u):$(id -g)"
-v "$PWD":/workspace
-w /workspace
)
if [[ -n "${DOCKER_PLATFORM:-}" ]]; then
docker_args+=(--platform "$DOCKER_PLATFORM")
fi
mkdir -p "$POETRY_CACHE_DIR" "$PIP_CACHE_DIR" "$NPM_CACHE_DIR" "$HOME_DIR"
local container_home="/workspace/$HOME_DIR"
docker_args+=(
-e "HOME=$container_home"
-e "PIP_CACHE_DIR=/workspace/$PIP_CACHE_DIR"
-e "POETRY_CACHE_DIR=/workspace/$POETRY_CACHE_DIR"
-e "NPM_CONFIG_CACHE=/workspace/$NPM_CACHE_DIR"
-e "PYTHON_VERSION_UNDER_TEST=$version"
-v "$PWD/$POETRY_CACHE_DIR":/workspace/"$POETRY_CACHE_DIR"
-v "$PWD/$PIP_CACHE_DIR":/workspace/"$PIP_CACHE_DIR"
-v "$PWD/$NPM_CACHE_DIR":/workspace/"$NPM_CACHE_DIR"
-v "$PWD/$HOME_DIR":/workspace/"$HOME_DIR"
)
if [[ -f .env ]]; then
docker_args+=(--env-file "$PWD/.env")
fi
local -a passthrough_envs=(TRANSLOADIT_KEY TRANSLOADIT_SECRET TRANSLOADIT_TEMPLATE_ID PYTHON_SDK_E2E)
for var in "${passthrough_envs[@]}"; do
if [[ -n "${!var:-}" ]]; then
docker_args+=(-e "$var=${!var}")
fi
done
if [[ "$version" == "3.12" && ${#CUSTOM_COMMAND[@]} -eq 0 ]]; then
docker_args+=(-e TEST_NODE_PARITY=1)
fi
local run_cmd
if [[ ${#CUSTOM_COMMAND[@]} -gt 0 ]]; then
printf -v user_cmd '%q ' "${CUSTOM_COMMAND[@]}"
if [[ "${SKIP_POETRY_RUN:-0}" == "1" ]]; then
run_cmd="set -euo pipefail; poetry install; ${user_cmd}"
else
run_cmd="set -euo pipefail; poetry install; poetry run ${user_cmd}"
fi
else
if [[ "$version" == "3.12" ]]; then
run_cmd='set -euo pipefail; poetry install; poetry run pytest --cov=transloadit --cov-report=xml --cov-report=json --cov-report=html --cov-report=term-missing --cov-fail-under=65 tests'
else
run_cmd='set -euo pipefail; poetry install; poetry run pytest tests'
fi
fi
echo "==> Running Python $version: $run_cmd"
docker run "${docker_args[@]}" "$image_name" bash -lc "$run_cmd"
}
main() {
parse_python_versions "$@"
ensure_docker
configure_platform
mkdir -p "$CACHE_ROOT"
for version in "${PYTHON_MATRIX[@]}"; do
image_name="${IMAGE_NAME:-$IMAGE_PREFIX}-${version//./}"
build_image_for_version "$version" "$image_name"
run_for_version "$version" "$image_name"
done
}
main "$@"