Skip to content

Commit eb35af4

Browse files
committed
Add first implementation
Support multiarch and python 3.7 to 3.11.
1 parent e876df2 commit eb35af4

File tree

6 files changed

+228
-0
lines changed

6 files changed

+228
-0
lines changed

.gitlab-ci.yml

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
image: docker:latest
2+
3+
include:
4+
- project: divio/infra/gitlab-pipelines
5+
ref: master
6+
file: base/.gitlab-ci.yml
7+
8+
variables:
9+
BUILDX_VERSION: v0.11.2
10+
BUILDX_ARCH: linux-amd64
11+
PLATFORMS: linux/arm64/v8,linux/amd64
12+
PUBLIC_REPOSITORY: divio/multi-python
13+
BUILDX_URL: https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.${BUILDX_ARCH}
14+
LINT_FILE_DOCKER: Dockerfile
15+
16+
linting:
17+
allow_failure: true
18+
19+
.build:
20+
stage: build
21+
needs: []
22+
before_script:
23+
# Install buildx
24+
- mkdir -p /usr/libexec/docker/cli-plugins
25+
- wget -q -O /usr/libexec/docker/cli-plugins/docker-buildx ${BUILDX_URL}
26+
- chmod +x /usr/libexec/docker/cli-plugins/docker-buildx
27+
- docker buildx version
28+
- docker buildx create --use
29+
# Login to the Gitlab registry
30+
- docker login -u ${CI_REGISTRY_USER} -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
31+
# Update the QEMU version on the host
32+
- docker run --rm --privileged linuxkit/binfmt:af88a591f9cc896a52ce596b9cf7ca26a061ef97
33+
script:
34+
# This allows to also push the tag "latest" when running on the main branch
35+
- if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then
36+
extra_tag="--tag ${CI_REGISTRY_IMAGE}:latest";
37+
fi
38+
- echo "Using extra_tag=${extra_tag:-}"
39+
- >
40+
docker buildx build
41+
--platform ${PLATFORMS}
42+
--tag ${IMAGE_NAME}
43+
${extra_tag:-}
44+
--push
45+
.
46+
47+
build-dev:
48+
extends: .build
49+
variables:
50+
IMAGE_NAME: ${CI_REGISTRY_IMAGE}/build:${CI_PIPELINE_IID}
51+
except:
52+
- tags
53+
54+
test:
55+
stage: qa
56+
needs: [build-dev]
57+
image: ${CI_REGISTRY_IMAGE}/build:${CI_PIPELINE_IID}
58+
except:
59+
- tags
60+
script:
61+
- cd test && tox
62+
63+
build-prod:
64+
extends: .build
65+
variables:
66+
IMAGE_NAME: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}
67+
only:
68+
- tags
69+
70+
push:
71+
stage: release
72+
needs:
73+
- build-prod
74+
image:
75+
name: ananace/skopeo
76+
entrypoint: [""]
77+
variables:
78+
GIT_STRATEGY: none
79+
SRC_REGISTRY_CREDS: ${CI_REGISTRY_USER}:${CI_JOB_TOKEN}
80+
DST_REGISTRY_CREDS: ${DOCKER_HUB_USER}:${DOCKER_HUB_TOKEN}
81+
script:
82+
- >
83+
/skopeo
84+
copy
85+
--multi-arch all
86+
--src-creds=${SRC_REGISTRY_CREDS}
87+
--dest-creds=${DST_REGISTRY_CREDS}
88+
docker://${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}
89+
docker://${PUBLIC_REPOSITORY}:latest
90+
- >
91+
/skopeo
92+
copy
93+
--multi-arch all
94+
--src-creds=${SRC_REGISTRY_CREDS}
95+
--dest-creds=${DST_REGISTRY_CREDS}
96+
docker://${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}
97+
docker://${PUBLIC_REPOSITORY}:${CI_COMMIT_TAG}
98+
only:
99+
- tags

Dockerfile

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
FROM ubuntu:22.04
2+
3+
## Main python version to install + use for tox
4+
ARG PYTHON_MAIN_VERSION=3.11
5+
## Other python versions to install
6+
# Must be available either in the deadsnakes PPA or in
7+
# the official Ubuntu repositories
8+
ARG PYTHON_OTHER_VERSIONS="3.7 3.8 3.9 3.10"
9+
## PyPy version to install
10+
# for versions see https://www.pypy.org/download.html
11+
ARG PYTHON_PYPY_VERSION=3.9-v7.3.12
12+
## GPG key for the deadsnakes PPA
13+
# See https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa
14+
ARG DEADSNAKES_GPG_KEY=F23C5A6CF475977595C89F51BA6932366A755776
15+
16+
ARG TARGETARCH
17+
ENV DEBIAN_FRONTEND=noninteractive
18+
19+
# Install common build dependencies, add deadsnakes PPA and cleanup.
20+
# (see https://github.com/deadsnakes)
21+
# hadolint ignore=DL3008,SC2086
22+
RUN set -eux \
23+
; apt-get update \
24+
; apt-get install -y --no-install-recommends \
25+
ca-certificates \
26+
g++ \
27+
gcc \
28+
git \
29+
curl \
30+
bzip2 \
31+
make \
32+
; savedAptMark="$(apt-mark showmanual)" \
33+
\
34+
; apt-get install -y --no-install-recommends \
35+
dirmngr \
36+
gnupg \
37+
\
38+
; tmp_home="$(mktemp -d)"; export GNUPGHOME="$tmp_home" \
39+
; gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys "$DEADSNAKES_GPG_KEY" \
40+
; gpg -o /usr/share/keyrings/deadsnakes.gpg --export "$DEADSNAKES_GPG_KEY" \
41+
; echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/deadsnakes.gpg] https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy main" >> /etc/apt/sources.list \
42+
\
43+
; apt-mark auto '.*' > /dev/null \
44+
; apt-mark manual $savedAptMark \
45+
; apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
46+
; rm -rf /var/lib/apt/lists/*
47+
48+
# Install pip3, all python versions and tox in the main python version
49+
# hadolint ignore=DL3008,SC2086
50+
RUN set -eux \
51+
; apt-get update \
52+
; apt-get install -y --no-install-recommends python3-pip \
53+
; for version in ${PYTHON_OTHER_VERSIONS} ${PYTHON_MAIN_VERSION} \
54+
; do \
55+
apt-get install -y --no-install-recommends \
56+
python${version} \
57+
python${version}-dev \
58+
python${version}-venv \
59+
python${version}-distutils \
60+
; python${version} -m pip install --upgrade pip \
61+
; done \
62+
; python${PYTHON_MAIN_VERSION} -m pip install --no-cache tox \
63+
; rm -rf /var/lib/apt/lists/*;
64+
65+
# Install PyPy
66+
RUN set -eux \
67+
; if [ "$TARGETARCH" = "arm64" ] ; then curl -L --show-error --retry 5 -o /pypy.tar.bz2 https://downloads.python.org/pypy/pypy${PYTHON_PYPY_VERSION}-aarch64.tar.bz2 \
68+
; else curl -L --show-error --retry 5 -o /pypy.tar.bz2 https://downloads.python.org/pypy/pypy${PYTHON_PYPY_VERSION}-linux64.tar.bz2 \
69+
; fi \
70+
; mkdir /pypy && tar -xf /pypy.tar.bz2 -C /pypy --strip-components=1
71+
72+
ENV PATH="/pypy/bin:$PATH"
73+
74+
# Create user and app directory
75+
RUN set -eux \
76+
; groupadd -r tox --gid=1000 \
77+
; useradd --no-log-init -r -g tox -m --uid=1000 tox \
78+
; mkdir /app \
79+
; chown tox:tox /app
80+
81+
WORKDIR /app
82+
VOLUME /app
83+
USER tox
84+
85+
# Add safe.directory to git to avoid setuptools_scm "unable to detect version"
86+
# This can't be limited to /app since gitlab-ci mounts the workspace somewhere else
87+
# (see https://github.com/pypa/setuptools_scm/issues/797)
88+
# This needs to run as user tox
89+
RUN git config --global --add safe.directory '*'

Makefile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
IMAGE_NAME = registry.gitlab.com/divio/incubator/multi-python
2+
TARGET ?= amd64
3+
4+
lint:
5+
docker run --rm -e LINT_FILE_DOCKER=Dockerfile -v $(CURDIR):/app divio/lint /bin/lint ${ARGS}
6+
7+
build:
8+
docker build -t ${IMAGE_NAME} --platform linux/${TARGET} .

README.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Multi-Python Image
2+
3+
This repository defines a Python image based on Ubuntu with multiple Python versions installed,
4+
along with the `tox` executable. It is meant to use in CI for test purposes.
5+
6+
It supports both ARM and AMD architectures.
7+
8+
## Python versions
9+
10+
The list of Python versions to install is passed as arguments (see `Dockerfile`).
11+
One Python version must be selected as "main" - it will be used to install `tox`.
12+
Along with "regular" Python versions, one pypy version will also be installed.
13+
14+
**IMPORTANT**: Python versions must be available either in the official Ubuntu repositories or in
15+
the [deadsnakes PPA](https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa). The PyPy version should
16+
be available at https://www.pypy.org/download.html.
17+
18+
## Usage
19+
20+
Run the following from a terminal at the root of your Python project:
21+
```bash
22+
docker run --rm -it -v $(PWD):/app registry.gitlab.com/divio/incubator/multi-Python:latest tox
23+
```
24+
25+
## Development
26+
27+
After updating the Python versions in the `Dockerfile`, ensure you also update `test/tox.ini` to
28+
reflect the change.

test/test_foo.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
assert True

test/tox.ini

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[tox]
2+
envlist = py37,py38,py39,py3.10,py3.11,pypy3
3+
skip_missing_interpreters = false

0 commit comments

Comments
 (0)