Skip to content

Commit 1176b57

Browse files
committed
Test every supported Python version in containers
actions/setup-python can't install 2.7 or 3.4-3.7 on current runners, so each version's suite now runs inside the matching python:<version> image via run_tests_containers.sh (podman locally, Docker in CI). Signed-off-by: Thomas Calmant <thomas.calmant@gmail.com>
1 parent 398b30e commit 1176b57

6 files changed

Lines changed: 387 additions & 57 deletions

File tree

‎.coveragerc‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@ source = javaobj/
33

44
[report]
55
include = javaobj/*
6+
7+
[paths]
8+
# The test suite is run in a container for each supported Python version (see
9+
# run_tests_containers.sh), where the tree is unpacked in /work. The data
10+
# files are then combined outside of the containers: this maps the
11+
# in-container paths back to the local checkout, so a single report covers
12+
# every version.
13+
source =
14+
javaobj/
15+
/work/javaobj/

‎.github/workflows/build-24.04.yml‎

Lines changed: 0 additions & 57 deletions
This file was deleted.

‎.github/workflows/ci-build.yml‎

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Lints the code, runs the tests on every supported Python version, and
2+
# reports coverage.
3+
#
4+
# The tests run inside the matching official ``python:<version>`` container
5+
# via ./run_tests_containers.sh. This is what lets CI cover Python 2.7 and
6+
# 3.4-3.7 too -- actions/setup-python cannot provide those on a current
7+
# runner. javaobj.v3 requires Python 3.12+ and is skipped below that by
8+
# run_tests.sh.
9+
10+
name: CI Build
11+
12+
on:
13+
push:
14+
branches: ["main", "master"]
15+
tags: "**"
16+
pull_request:
17+
branches: ["main", "master"]
18+
19+
jobs:
20+
lint:
21+
timeout-minutes: 10
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- uses: actions/checkout@v7
26+
- name: Set up Python
27+
uses: actions/setup-python@v7
28+
with:
29+
python-version: "3.14"
30+
- name: Install dependencies
31+
run: |
32+
python -m pip install --upgrade pip
33+
python -m pip install flake8
34+
- name: Lint with flake8
35+
run: |
36+
# stop the build if there are Python syntax errors or undefined names
37+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
38+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
39+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
40+
41+
test:
42+
needs: lint
43+
timeout-minutes: 20
44+
runs-on: ubuntu-latest
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
# Every version declared as supported (pyproject.toml classifiers).
49+
# Each runs in its matching python:<version> container, which is the
50+
# only way to cover 2.7 and 3.4-3.7 on a modern runner.
51+
python-version:
52+
[
53+
"2.7",
54+
"3.4",
55+
"3.5",
56+
"3.6",
57+
"3.7",
58+
"3.8",
59+
"3.9",
60+
"3.10",
61+
"3.11",
62+
"3.12",
63+
"3.13",
64+
"3.14",
65+
]
66+
67+
steps:
68+
- uses: actions/checkout@v7
69+
- name: Set up Java
70+
uses: actions/setup-java@v5
71+
with:
72+
distribution: temurin
73+
java-version: "17"
74+
- name: Build the Java test fixtures
75+
# tests/java/pom.xml targets -source/-target 7, which javac has
76+
# refused since JDK 20: Temurin 17 keeps this working. The generated
77+
# .ser fixtures are then streamed into every container below, so none
78+
# of them need a JDK themselves.
79+
working-directory: tests/java
80+
run: mvn -B test
81+
- name: Run the suite in a Python ${{ matrix.python-version }} container
82+
# run_tests_containers.sh streams a clean copy of the tree into the
83+
# container and runs run_tests.sh there. The engine is pinned to
84+
# Docker (the runner ships both Docker and Podman, and the script
85+
# prefers Podman otherwise). JAVAOBJ_NO_MAVEN skips the redundant
86+
# in-container Maven call, since the fixtures were just built above.
87+
# COVERAGE_OUTPUT_DIR makes it copy the coverage data of this version
88+
# out of the container, so the coverage job below can combine them.
89+
env:
90+
CONTAINER_ENGINE: docker
91+
COVERAGE_OUTPUT_DIR: coverage-data
92+
ENGINE_RUN_ARGS: "-e JAVAOBJ_NO_MAVEN=1"
93+
run: ./run_tests_containers.sh ${{ matrix.python-version }}
94+
- name: Keep the coverage data of Python ${{ matrix.python-version }}
95+
uses: actions/upload-artifact@v7
96+
with:
97+
name: coverage-data-${{ matrix.python-version }}
98+
path: coverage-data/*.dat
99+
if-no-files-found: error
100+
retention-days: 1
101+
102+
coverage:
103+
# Every version of the matrix contributes: the report describes the whole
104+
# supported range, not just the one version a runner can install natively.
105+
needs: test
106+
timeout-minutes: 10
107+
runs-on: ubuntu-latest
108+
109+
steps:
110+
- uses: actions/checkout@v7
111+
- name: Set up Python
112+
uses: actions/setup-python@v7
113+
with:
114+
python-version: "3.14"
115+
- name: Get the coverage data of every version
116+
uses: actions/download-artifact@v8
117+
with:
118+
pattern: coverage-data-*
119+
merge-multiple: true
120+
path: coverage-data
121+
- name: Combine the coverage data
122+
# The data files come from containers, where the tree lives in /work:
123+
# .coveragerc maps that path back to this checkout.
124+
run: |
125+
python -m pip install --upgrade pip
126+
python -m pip install coverage
127+
coverage combine coverage-data/*.dat
128+
coverage report
129+
- name: Coveralls
130+
env:
131+
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
132+
run: |
133+
pip install coveralls
134+
coveralls

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ nosetests.xml
5050
# uv
5151
.venv
5252
uv.lock
53+
54+
# Local container test runs (see run_tests_containers.sh)
55+
work/

‎run_tests.sh‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
#
3+
# Runs the python-javaobj test suite for the current Python interpreter.
4+
#
5+
# Used both inside the per-version containers driven by
6+
# run_tests_containers.sh, and directly in CI on the runner. javaobj.v3
7+
# requires Python 3.12+, so it (and its tests) are skipped below that version,
8+
# matching the compatibility table in README.md.
9+
#
10+
11+
set -uo pipefail
12+
13+
echo "Installing dependencies..."
14+
python -m pip install --upgrade pip
15+
pip install pytest coverage || exit 1
16+
if [ -f requirements.txt ]; then
17+
pip install -r requirements.txt || exit 1
18+
fi
19+
20+
python_supports_v3() {
21+
python -c 'import sys; sys.exit(0 if sys.version_info >= (3, 12) else 1)'
22+
}
23+
24+
if python_supports_v3
25+
then
26+
echo "Python 3.12+: running the full suite (v1, v2, v3)..."
27+
coverage run -m pytest
28+
rc=$?
29+
else
30+
echo "Python < 3.12: javaobj.v3 is unsupported, skipping it and its tests..."
31+
coverage run --omit='javaobj/v3/*,tests/test_v3.py' -m pytest --ignore=tests/test_v3.py
32+
rc=$?
33+
fi
34+
35+
coverage report
36+
37+
exit "$rc"

0 commit comments

Comments
 (0)