├── .github └── workflows │ └── build-and-push.yml ├── .gitignore ├── .gitmodules ├── Dockerfile ├── LICENSE.txt ├── README.md └── run_tests.sh /.github/workflows/build-and-push.yml: -------------------------------------------------------------------------------- 1 | name: Build, test and push container images 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | pull_request: 8 | branches: 9 | - 'master' 10 | schedule: 11 | - cron: '48 23 * * 6' 12 | workflow_dispatch: 13 | 14 | env: 15 | FEDORA_VERSION: 41 16 | 17 | jobs: 18 | build-and-push: 19 | name: Build, test and push 20 | runs-on: ubuntu-latest 21 | strategy: 22 | matrix: 23 | include: 24 | - arch: amd64 25 | toxenv: py36,py38,py39,py310,py311,py312,py313,py314,pypy,pypy39,pypy310,pypy311 26 | - arch: arm64 27 | toxenv: py312 28 | - arch: ppc64le 29 | toxenv: py38,py311 30 | - arch: s390x 31 | toxenv: py39,py310,py312 32 | steps: 33 | - name: Checkout 34 | uses: actions/checkout@v2 35 | with: 36 | submodules: true 37 | - name: Set up QEMU 38 | uses: docker/setup-qemu-action@v1 39 | - name: Build 40 | uses: docker/build-push-action@v2 41 | with: 42 | context: . 43 | platforms: linux/${{ matrix.arch }} 44 | load: true 45 | tags: | 46 | fedorapython/fedora-python-tox:${{ matrix.arch }} 47 | fedorapython/fedora-python-tox:${{ matrix.arch }}-f${{ env.FEDORA_VERSION }} 48 | - name: Test local project 49 | env: 50 | TOXENV: ${{ matrix.toxenv }} 51 | run: | 52 | docker run --rm --platform linux/${{ matrix.arch }} -v $PWD/example_project:/src -w /src -e TOXENV fedorapython/fedora-python-tox:${{ matrix.arch }} 53 | - name: Test remote project 54 | env: 55 | TOXENV: ${{ matrix.toxenv }} 56 | run: | 57 | docker run --rm --platform linux/${{ matrix.arch }} -e TOXENV -e GIT_URL=https://github.com/frenzymadness/python-tox-example.git fedorapython/fedora-python-tox:${{ matrix.arch }} 58 | - name: Test parallel run 59 | env: 60 | TOXENV: ${{ matrix.toxenv }} 61 | run: | 62 | docker run --rm --platform linux/${{ matrix.arch }} -v $PWD/example_project:/src -w /src -e TOXENV -e TOX_PARAMS="-p auto" fedorapython/fedora-python-tox:${{ matrix.arch }} 63 | - name: Test dnf install and wheel build 64 | env: 65 | TOXENV: ${{ matrix.toxenv }} 66 | run: | 67 | docker run --rm --platform linux/${{ matrix.arch }} -e DNF_INSTALL="libffi-devel 'pkgconfig(libgit2) >= 1.9' /usr/bin/cowsay" fedorapython/fedora-python-tox:${{ matrix.arch }} sh -c "/run_tests.sh; pip install -I --no-deps --compile --no-binary :all: cffi pygit2~=1.17.0 && cowsay DONE" 68 | - name: Test external project with WORKDIR 69 | run: | 70 | docker run --rm --platform linux/${{ matrix.arch }} -e TOXENV=py3 -e GIT_URL=https://github.com/frenzymadness/nflxprofile.git -e WORKDIR=python fedorapython/fedora-python-tox:${{ matrix.arch }} 71 | - name: Login to DockerHub 72 | uses: docker/login-action@v1 73 | if: github.event_name == 'push' || github.event_name == 'schedule' 74 | with: 75 | username: ${{ secrets.DOCKERHUB_USERNAME }} 76 | password: ${{ secrets.DOCKERHUB_TOKEN }} 77 | - name: Push to Dockerhub 78 | uses: docker/build-push-action@v2 79 | if: github.event_name == 'push' || github.event_name == 'schedule' 80 | with: 81 | context: . 82 | platforms: linux/${{ matrix.arch }} 83 | push: true 84 | tags: | 85 | fedorapython/fedora-python-tox:${{ matrix.arch }} 86 | fedorapython/fedora-python-tox:${{ matrix.arch }}-f${{ env.FEDORA_VERSION }} 87 | 88 | description_update: 89 | name: 'Update Dockerhub description' 90 | if: github.event_name == 'push' 91 | needs: build-and-push 92 | runs-on: ubuntu-latest 93 | steps: 94 | - name: Checkout 95 | uses: actions/checkout@v4 96 | - name: 'Update Dockerhub description' 97 | uses: peter-evans/dockerhub-description@v4 98 | with: 99 | username: ${{ secrets.DOCKERHUB_USERNAME }} 100 | password: ${{ secrets.DOCKERHUB_TOKEN }} 101 | repository: fedorapython/fedora-python-tox 102 | 103 | release: 104 | name: 'Update and test manifests' 105 | if: github.event_name == 'push' || github.event_name == 'schedule' 106 | needs: build-and-push 107 | runs-on: ubuntu-latest 108 | steps: 109 | - name: Login to DockerHub 110 | uses: docker/login-action@v1 111 | with: 112 | username: ${{ secrets.DOCKERHUB_USERNAME }} 113 | password: ${{ secrets.DOCKERHUB_TOKEN }} 114 | - name: Pull all images 115 | run: > 116 | for arch in amd64 arm64 ppc64le s390x; do 117 | docker pull fedorapython/fedora-python-tox:$arch; 118 | docker pull fedorapython/fedora-python-tox:${arch}-f${{ env.FEDORA_VERSION }}; 119 | done 120 | - name: Create and push manifest for the :latest tag 121 | env: 122 | DOCKER_CLI_EXPERIMENTAL: enabled 123 | run: > 124 | docker manifest create fedorapython/fedora-python-tox:latest 125 | fedorapython/fedora-python-tox:amd64 126 | fedorapython/fedora-python-tox:arm64 127 | fedorapython/fedora-python-tox:ppc64le 128 | fedorapython/fedora-python-tox:s390x; 129 | docker manifest push fedorapython/fedora-python-tox:latest; 130 | - name: Test the latest manifest 131 | run: | 132 | docker manifest inspect fedorapython/fedora-python-tox:latest | grep '"architecture":' | grep -Ez '(.*(amd64|arm64|ppc64le|s390x).*){4}' 133 | - name: Create and push manifest for the versioned tag 134 | env: 135 | DOCKER_CLI_EXPERIMENTAL: enabled 136 | run: > 137 | docker manifest create fedorapython/fedora-python-tox:f${{ env.FEDORA_VERSION }} 138 | fedorapython/fedora-python-tox:amd64-f${{ env.FEDORA_VERSION }} 139 | fedorapython/fedora-python-tox:arm64-f${{ env.FEDORA_VERSION }} 140 | fedorapython/fedora-python-tox:ppc64le-f${{ env.FEDORA_VERSION }} 141 | fedorapython/fedora-python-tox:s390x-f${{ env.FEDORA_VERSION }}; 142 | docker manifest push fedorapython/fedora-python-tox:f${{ env.FEDORA_VERSION }}; 143 | - name: Test the versioned manifest 144 | run: | 145 | docker manifest inspect fedorapython/fedora-python-tox:f${{ env.FEDORA_VERSION }} | grep '"architecture":' | grep -Ez '(.*(amd64|arm64|ppc64le|s390x).*){4}' 146 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | example_project/.tox 2 | example_project/__pycache__ 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "example_project"] 2 | path = example_project 3 | url = https://github.com/frenzymadness/python-tox-example.git 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.fedoraproject.org/fedora:41 2 | 3 | LABEL maintainer="Lumír 'Frenzy' Balhar " 4 | 5 | RUN dnf update -y \ 6 | && dnf install -y \ 7 | --setopt=tsflags=nodocs \ 8 | --setopt=deltarpm=false \ 9 | findutils \ 10 | pypy2-devel \ 11 | pypy3.9-devel \ 12 | pypy3.10-devel \ 13 | pypy3.11-devel \ 14 | python3.6 \ 15 | python3.8 \ 16 | python3.9 \ 17 | python3.10-devel \ 18 | python3.10-tkinter \ 19 | python3.11-devel \ 20 | python3.11-tkinter \ 21 | python3.12-devel \ 22 | python3.12-tkinter \ 23 | python3.13-devel \ 24 | python3.13-tkinter \ 25 | python3.14-devel \ 26 | python3.14-tkinter \ 27 | python3-pip \ 28 | /usr/bin/tox \ 29 | /usr/bin/virtualenv \ 30 | gcc \ 31 | gcc-c++ \ 32 | git-core \ 33 | make \ 34 | && dnf clean all 35 | 36 | ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 37 | 38 | ADD run_tests.sh / 39 | 40 | CMD ["/run_tests.sh"] 41 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Lumír Balhar 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fedora + Pythons + Tox in docker image 2 | 3 | ![CI/CD status](https://github.com/fedora-python/fedora-python-tox/actions/workflows/build-and-push.yml/badge.svg) 4 | 5 | This repository contains source code for Docker image designed to help you 6 | run your Tox tests with all available Python versions in Docker container. 7 | 8 | [Docker image is hosted on Docker Hub](https://hub.docker.com/r/fedorapython/fedora-python-tox/) and build automatically after every push to master branch. 9 | 10 | # Fedora base image version 11 | 12 | We usually add the newest Pythons to all supported Fedora releases. We also have to remove the oldest ones 13 | from time to time. These are the reasons why we move this container image from Fedora N to N+1 when 14 | N goes EOL. 15 | 16 | # Installed packages 17 | 18 | On top of stable Fedora, this Docker image contains: 19 | - Python 3.6, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 20 | - Pypy2, Pypy3.9, Pypy3.10 and Pypy3.11 21 | - python3-pip 22 | - gcc, gcc-c++, git-core and make 23 | - tox 24 | - virtualenv 25 | 26 | # Docker and Podman 27 | 28 | The image works very well with both [Docker](https://www.docker.com/) and [Podman](https://podman.io/) so you can use containers management tool you prefer. 29 | 30 | # Example usage with local source code 31 | 32 | If you want to use this Docker image as environmet for your test, use this command: 33 | 34 | ``` 35 | cd example_project 36 | docker run --rm -it -v $PWD:/src -w /src fedorapython/fedora-python-tox 37 | 38 | py27 create: /src/.tox/py27 39 | py27 installdeps: pytest < 3.3 40 | py27 installed: py==1.5.3,pytest==3.2.5 41 | py27 runtests: PYTHONHASHSEED='85819776' 42 | py27 runtests: commands[0] | pytest 43 | ==== test session starts ==== 44 | platform linux2 -- Python 2.7.18, pytest-3.2.5, py-1.5.3, pluggy-0.4.0 45 | rootdir: /src, inifile: 46 | collected 10 items 47 | 48 | test_fac.py .......... 49 | 50 | ==== 10 passed in 0.02 seconds ==== 51 | 52 | py35 create: /src/.tox/py35 53 | py35 installdeps: pytest < 3.3 54 | py35 installed: py==1.5.3,pytest==3.2.5 55 | py35 runtests: PYTHONHASHSEED='1223497559' 56 | py35 runtests: commands[0] | pytest 57 | ==== test session starts ==== 58 | platform linux -- Python 3.5.10, pytest-3.2.5, py-1.5.3, pluggy-0.4.0 59 | rootdir: /src, inifile: 60 | collected 10 items 61 | 62 | test_fac.py .......... 63 | 64 | ==== 10 passed in 0.04 seconds ==== 65 | ... etc ... 66 | ``` 67 | 68 | This command will download an image from Docker hub for you 69 | 70 | ``` 71 | Unable to find image 'fedorapython/fedora-python-tox:latest' locally 72 | Trying to pull repository docker.io/fedorapython/fedora-python-tox ... 73 | sha256:d4b51931dd86a33552b6a08f39575db336b606f4ccebbc48f390d7f728367a6f: Pulling from docker.io/fedorapython/fedora-python-tox 74 | 75 | ``` 76 | 77 | Command and argument description: 78 | 79 | - `docker run` - run docker image 80 | - `--rm` - automatically remove the container when it exits 81 | - `-i` - keep STDIN open even if not attached 82 | - `-t` - allocate a pseudo-TTY 83 | - `-v $PWD:/src` - mount your current working directory to /src inside container 84 | - `-w` - use /src (mountpoint) as working directory inside container 85 | - `fedorapython/fedora-python-tox` - name of Docker image 86 | 87 | Tox is run automatically with this container. How cool! 88 | 89 | You also can limit Tox tests by passing environment variable to Docker. For example: 90 | 91 | ``` 92 | cd example_project 93 | docker run --rm -it -v $PWD:/src -w /src -e TOXENV=pypy3 fedorapython/fedora-python-tox 94 | pypy3 create: /src/.tox/pypy3 95 | pypy3 installdeps: pytest 96 | pypy3 installed: cffi==1.10.1,greenlet==0.4.12,py==1.4.34,pytest==3.2.2,readline==6.2.4.1 97 | pypy3 runtests: PYTHONHASHSEED='68938415' 98 | pypy3 runtests: commands[0] | pytest 99 | ==== test session starts ==== 100 | platform linux -- Python 3.5.3[pypy-5.8.0-beta], pytest-3.2.2, py-1.4.34, pluggy-0.4.0 101 | rootdir: /src, inifile: 102 | collected 10 items 103 | 104 | test_fac.py .......... 105 | 106 | ==== passed in 0.24 seconds ==== 107 | 108 | pypy3: commands succeeded 109 | congratulations :) 110 | ``` 111 | 112 | ## Parallel run and other tox features 113 | 114 | You can adjust the behavior of tox by setting TOX_PARAMS variable with any combination of CLI parameters. It's useful for example for parallel run of your tests. 115 | 116 | ``` 117 | docker run --rm -it -v $PWD:/src -w /src -e TOX_PARAMS="-p auto" fedorapython/fedora-python-tox 118 | ✔ OK py37 in 1.664 seconds 119 | ✔ OK py35 in 1.893 seconds 120 | ✔ OK py27 in 1.902 seconds 121 | ✔ OK py38 in 1.913 seconds 122 | ✔ OK py36 in 1.987 seconds 123 | ✔ OK pypy in 2.904 seconds 124 | ✔ OK pypy3 in 3.688 seconds 125 | __________________________________________ summary ___________________________________________ 126 | py27: commands succeeded 127 | py35: commands succeeded 128 | py36: commands succeeded 129 | py37: commands succeeded 130 | py38: commands succeeded 131 | pypy: commands succeeded 132 | pypy3: commands succeeded 133 | congratulations :) 134 | ``` 135 | 136 | # Example usage with GIT URL 137 | 138 | Instead of mounting local folder with source code into container, you can 139 | provide HTTPS URL of your GIT repository and it will be cloned automatically. 140 | 141 | For example: 142 | ``` 143 | docker run --rm -it -e GIT_URL=https://github.com/fedora-python/pyp2rpm.git fedorapython/fedora-python-tox 144 | Cloning into 'temp_project_dir'... 145 | remote: Counting objects: 3075, done. 146 | remote: Compressing objects: 100% (5/5), done. 147 | remote: Total 3075 (delta 1), reused 3 (delta 1), pack-reused 3069 148 | Receiving objects: 100% (3075/3075), 2.97 MiB | 2.57 MiB/s, done. 149 | Resolving deltas: 100% (2188/2188), done. 150 | GLOB sdist-make: /temp_project_dir/setup.py 151 | py27 create: /temp_project_dir/.tox/py27 152 | 153 | ... etc ... 154 | ``` 155 | 156 | # Installing RPM packages from Fedora 157 | 158 | Sometimes, your tests need some system packages (such as C libraries). 159 | You can install them via `dnf` by setting the `$DNF_INSTALL` environment variable: 160 | 161 | ``` 162 | docker run --rm -it -v $PWD:/src -w /src -e DNF_INSTALL="libyaml-devel libgit2-devel" fedorapython/fedora-python-tox 163 | ... 164 | Installed: 165 | http-parser-2.9.3-2.fc32.x86_64 libgit2-1.0.1-2.fc32.x86_64 166 | libgit2-devel-1.0.1-2.fc32.x86_64 libssh2-1.9.0-5.fc32.x86_64 167 | libyaml-devel-0.2.2-3.fc32.x86_64 openssl-devel-1:1.1.1g-1.fc32.x86_64 168 | pcre2-devel-10.35-4.fc32.x86_64 pcre2-utf16-10.35-4.fc32.x86_64 169 | pcre2-utf32-10.35-4.fc32.x86_64 zlib-devel-1.2.11-21.fc32.x86_64 170 | 171 | Complete! 172 | py27 create: /src/.tox/py27 173 | ... 174 | ``` 175 | 176 | You can install packages by any RPM *Provides*, for example: 177 | 178 | * Fedora package names, e.g. `libgit2-devel`, 179 | * pkgconfig names, e.g. `pkgconfig(libgit2)`, or 180 | * commands, e.g. `/usr/bin/cowsay`. 181 | 182 | Complex specifications including spaces have to be enclosed in single quotes 183 | inside the double quotes. For example: `-e DNF_INSTALL="libyaml-devel 'pytest > 7'"` 184 | 185 | # WORKDIR 186 | 187 | If your `tox.ini` file is not in the root directory of your project, set `WORKDIR` to the path you want to cd to before the tests are executed. 188 | 189 | ``` 190 | docker run --rm -it -e TOXENV=py310-minimal -e GIT_URL=https://github.com/trezor/trezor-firmware.git -e WORKDIR=python fedora-python-tox 191 | ``` 192 | 193 | # License 194 | 195 | MIT 196 | -------------------------------------------------------------------------------- /run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # This script will clone project from $GIT_URL (if defined) 4 | # and run tox in project directory 5 | 6 | TEMP_DIR=temp_project_dir 7 | 8 | if [ ! -z $GIT_URL ]; then 9 | git clone $GIT_URL $TEMP_DIR && cd $TEMP_DIR 10 | fi 11 | 12 | if [ ! -z "$DNF_INSTALL" ]; then 13 | echo $DNF_INSTALL | xargs dnf -y --setopt=tsflags=nodocs --setopt=deltarpm=false install 14 | fi 15 | 16 | # Mark the current directory as safe for Git: 17 | git --git-dir=~ config --system --add safe.directory $PWD 18 | 19 | if [ ! -z $WORKDIR ]; then 20 | echo "Changing directory to $WORKDIR" 21 | cd $WORKDIR 22 | fi 23 | 24 | /usr/bin/tox $TOX_PARAMS 25 | --------------------------------------------------------------------------------