Skip to content

Commit 2591655

Browse files
committed
added compatibility matrix
1 parent 4c242d1 commit 2591655

File tree

7 files changed

+281
-0
lines changed

7 files changed

+281
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Compatibility Check Workflow
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
branch:
7+
description: 'Branch to run the workflow on'
8+
required: true
9+
default: 'main'
10+
schedule:
11+
# Schedule to run at 00:00 on the 1st of every month
12+
- cron: '0 0 1 * *'
13+
14+
jobs:
15+
compatibility-check:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
ref: ${{ github.event.inputs.branch }}
22+
23+
- name: Install jq
24+
run: sudo apt-get update && sudo apt-get install jq -y
25+
26+
- name: Run Compatibility Matrix Script
27+
run: sudo bash compatibility_matrix.sh 3
28+
29+
- name: Commit and Push if not on main branch
30+
if: github.ref_name != 'main'
31+
run: |
32+
git config --global user.email "[email protected]"
33+
git config --global user.name "GitHub Actions"
34+
git add .
35+
git commit -m "Update compatibility matrix and badges"
36+
git push
37+
env:
38+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Dockerfile.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM python:3.10-slim
2+
3+
# Set the working directory in the container
4+
WORKDIR /app
5+
6+
# Copy the current directory contents into the container at /app
7+
COPY . /app
8+
9+
# Install any needed packages specified in requirements.txt
10+
ARG DJANGO_VERSION=5.0.3
11+
RUN pip install --no-cache-dir -r requirements-test.txt Django==${DJANGO_VERSION}
12+
13+
# Make port 8000 available to the world outside this container
14+
EXPOSE 8000
15+
16+
CMD ["python", "manage.py", "test"]

compatibility_matrix.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Compatibility Matrix
2+
3+
| Django \ Python | 3.6 | 3.7 | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |
4+
|------------------|-----|-----|-----|-----|------|------|------|
5+
| 3.2 | PASS | PASS | PASS | PASS | PASS | - | - |
6+
| 4.0 | - | - | PASS | PASS | PASS | - | - |
7+
| 4.1 | - | - | PASS | PASS | PASS | PASS | - |
8+
| 4.2 | - | - | PASS | PASS | PASS | PASS | FAIL |
9+
| 5.0 | - | - | - | - | PASS | PASS | PASS |
10+
11+
## Test Results Explanation
12+
13+
The compatibility matrix above demonstrates which combinations of Django and Python versions are compatible based on the conducted tests. A 'PASS' indicates a successful compatibility test, whereas a 'FAIL' denotes an incompatibility or an issue encountered during testing. Versions marked with '-' were not tested due to known incompatibilities or other constraints.
14+
15+
16+
It's important to ensure that your environment matches these compatible combinations to avoid potential issues. If a specific combination you're interested in is marked as 'FAIL', it's recommended to check the corresponding test logs for details and consider alternative versions or addressing the identified issues.

compatibility_matrix.sh

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#!/bin/bash
2+
# How to use:
3+
# sudo bash compatibility_matrix.sh 3
4+
# The above command will run the compatibility tests with a maximum of 3 parallel jobs.
5+
6+
# Check for command-line argument; default to 1 if not provided
7+
max_parallel_jobs=${1:-1}
8+
9+
10+
# Ensure jq is installed
11+
if ! command -v jq &> /dev/null; then
12+
echo "jq could not be found. Please install jq to run this script."
13+
exit 1
14+
fi
15+
16+
echo "Running compatibility tests with a maximum of $max_parallel_jobs parallel jobs..."
17+
18+
# Tests and store results in JSON
19+
run_tests() {
20+
local dj_ver_key=$1
21+
local dj_ver="${dj_ver_key//d_/}" # Convert key to version
22+
dj_ver="${dj_ver//_/.}"
23+
shift
24+
local python_versions=("$@")
25+
26+
# Define a counter for running jobs
27+
local -i jobs=0
28+
29+
for py_ver in "${python_versions[@]}"; do
30+
(
31+
echo "Testing with Python ${py_ver} and Django ${dj_ver}"
32+
local individual_result_file="${result_dir}/${dj_ver}_${py_ver}.json"
33+
# Replace this with your actual Docker-based test command
34+
if docker build -f Dockerfile.test --build-arg PYTHON_VERSION="${py_ver}" --build-arg DJANGO_VERSION="${dj_ver}" -t django_appointment_test:"${py_ver}_${dj_ver}" . && \
35+
docker run --rm django_appointment_test:"${py_ver}_${dj_ver}"; then
36+
echo "{\"result\": \"PASS\"}" > "$individual_result_file"
37+
echo "Test passed for Python ${py_ver} and Django ${dj_ver}"
38+
else
39+
echo "{\"result\": \"FAIL\"}" > "$individual_result_file"
40+
echo "Test failed for Python ${py_ver} and Django ${dj_ver}"
41+
fi
42+
) &
43+
44+
# Increment the job counter
45+
((jobs++))
46+
47+
# If we've reached the max parallel jobs, wait for one to finish
48+
if ((jobs >= max_parallel_jobs)); then
49+
wait -n # Wait for any job to finish
50+
((jobs--)) # Decrement the job counter
51+
fi
52+
done
53+
54+
wait # Wait for the remaining jobs to finish
55+
}
56+
57+
# Generate Markdown table from JSON results
58+
generate_markdown_table() {
59+
# Initialize Markdown file with the compatibility matrix header
60+
echo "# Compatibility Matrix" > compatibility_matrix.md
61+
# shellcheck disable=SC2129
62+
echo "" >> compatibility_matrix.md
63+
echo "| Django \\ Python | 3.6 | 3.7 | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |" >> compatibility_matrix.md
64+
echo "|------------------|-----|-----|-----|-----|------|------|------|" >> compatibility_matrix.md
65+
66+
for dj_ver_key in "${DJANGO_VERSIONS[@]}"; do
67+
local dj_ver="${dj_ver_key//d_/}" # Convert from d_x_y to x.y format
68+
dj_ver="${dj_ver//_/.}"
69+
echo -n "| $dj_ver " >> compatibility_matrix.md
70+
71+
for py_ver in "${PYTHON_VERSIONS[@]}"; do
72+
local combined_key="${dj_ver}_${py_ver}"
73+
# shellcheck disable=SC2155
74+
local result=$(jq -r --arg key "$combined_key" '.[$key]' "$result_file")
75+
[[ "$result" == "null" ]] && result="-"
76+
echo -n "| $result " >> compatibility_matrix.md
77+
done
78+
echo "|" >> compatibility_matrix.md
79+
done
80+
81+
# shellcheck disable=SC2129
82+
echo "" >> compatibility_matrix.md
83+
echo "## Test Results Explanation" >> compatibility_matrix.md
84+
echo "" >> compatibility_matrix.md
85+
echo "The compatibility matrix above demonstrates which combinations of Django and Python versions are compatible based on the conducted tests. A 'PASS' indicates a successful compatibility test, whereas a 'FAIL' denotes an incompatibility or an issue encountered during testing. Versions marked with '-' were not tested due to known incompatibilities or other constraints." >> compatibility_matrix.md
86+
echo "" >> compatibility_matrix.md
87+
echo "See [django's official documentation about supported python versions](https://docs.djangoproject.com/en/5.0/faq/install/#what-python-version-can-i-use-with-django) for more details."
88+
echo "" >> compatibility_matrix.md
89+
echo "It's important to ensure that your environment matches these compatible combinations to avoid potential issues. If a specific combination you're interested in is marked as 'FAIL', it's recommended to check the corresponding test logs for details and consider alternative versions or addressing the identified issues." >> compatibility_matrix.md
90+
}
91+
92+
generate_badge_json() {
93+
local python_compatible=()
94+
local django_compatible=()
95+
96+
for py_ver in "${PYTHON_VERSIONS[@]}"; do
97+
for dj_ver_key in "${DJANGO_VERSIONS[@]}"; do
98+
local dj_ver="${dj_ver_key//d_/}"
99+
dj_ver="${dj_ver//_/.}"
100+
local combined_key="${dj_ver}_${py_ver}"
101+
# shellcheck disable=SC2155
102+
local result=$(jq -r --arg key "$combined_key" '.[$key]' "$result_file")
103+
echo "Checking result for $combined_key: $result"
104+
if [[ "$result" == "PASS" ]]; then
105+
python_compatible+=("$py_ver")
106+
django_compatible+=("$dj_ver")
107+
fi
108+
done
109+
done
110+
111+
echo "Python compatible versions: ${python_compatible[*]}"
112+
echo "Django compatible versions: ${django_compatible[*]}"
113+
114+
echo "{
115+
\"schemaVersion\": 1,
116+
\"label\": \"python\",
117+
\"message\": \"$(IFS=, ; echo "${python_compatible[*]}")\",
118+
\"color\": \"blue\"
119+
}" > "python_compatible.json"
120+
121+
echo "{
122+
\"schemaVersion\": 1,
123+
\"label\": \"django\",
124+
\"message\": \"$(IFS=, ; echo "${django_compatible[*]}")\",
125+
\"color\": \"blue\"
126+
}" > "django_compatible.json"
127+
}
128+
129+
post_cleanup() {
130+
echo "Cleaning up temporary files..."
131+
rm -rf "$result_dir"
132+
133+
echo "Removing docker images..."
134+
# shellcheck disable=SC2155
135+
# local dangling_images=$(docker images -q --filter "dangling=true")
136+
# if [ -n "$dangling_images" ]; then
137+
# docker rmi "$dangling_images"
138+
# fi
139+
140+
echo "Cleanup complete."
141+
}
142+
143+
# Define directories and files
144+
result_dir="test_results"
145+
post_cleanup # Clean up any previous test results
146+
result_file="${result_dir}/results.json"
147+
148+
# Compatible Python versions for each Django version with prefixed keys
149+
declare -A DJANGO_COMPATIBILITY=(
150+
["d_3_2"]="3.6 3.7 3.8 3.9 3.10"
151+
["d_4_0"]="3.8 3.9 3.10"
152+
["d_4_1"]="3.8 3.9 3.10 3.11"
153+
["d_4_2"]="3.8 3.9 3.10 3.11 3.12"
154+
["d_5_0"]="3.10 3.11 3.12"
155+
)
156+
157+
# Django and Python versions
158+
DJANGO_VERSIONS=("d_3_2" "d_4_0" "d_4_1" "d_4_2" "d_5_0")
159+
PYTHON_VERSIONS=("3.6" "3.7" "3.8" "3.9" "3.10" "3.11" "3.12")
160+
161+
162+
# Setup
163+
mkdir -p "$result_dir"
164+
echo "{}" > "$result_file"
165+
166+
# Run tests for each Django/Python version combination
167+
for dj_ver_key in "${DJANGO_VERSIONS[@]}"; do
168+
IFS=' ' read -r -a python_versions <<< "${DJANGO_COMPATIBILITY[$dj_ver_key]}"
169+
run_tests "$dj_ver_key" "${python_versions[@]}"
170+
done
171+
172+
wait # Wait for all tests to complete
173+
174+
# Aggregate individual results into the final JSON file
175+
echo "{}" > "$result_file" # Reinitialize to ensure it's empty
176+
for file in "${result_dir}"/*.json; do
177+
dj_ver_py=$(basename "$file" .json)
178+
result=$(jq -r '.result' "$file")
179+
jq --arg dj_ver_py "$dj_ver_py" --arg result "$result" \
180+
'.[$dj_ver_py] = $result' "$result_file" > "${result_file}.tmp" && mv "${result_file}.tmp" "$result_file"
181+
done
182+
183+
# Generate the Markdown table after all tests are run
184+
generate_markdown_table
185+
186+
echo "Compatibility matrix has been generated: compatibility_matrix.md"
187+
echo "Generating compatibility badges..."
188+
generate_badge_json
189+
echo "Cleaning up..."
190+
post_cleanup

django_compatible.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"schemaVersion": 1,
3+
"label": "django",
4+
"message": "3.2,3.2,3.2,4.0,4.1,4.2,3.2,4.0,4.1,4.2,3.2,4.0,4.1,4.2,5.0,4.1,4.2,5.0,5.0",
5+
"color": "blue"
6+
}

python_compatible.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"schemaVersion": 1,
3+
"label": "python",
4+
"message": "3.6,3.7,3.8,3.8,3.8,3.8,3.9,3.9,3.9,3.9,3.10,3.10,3.10,3.10,3.10,3.11,3.11,3.11,3.12",
5+
"color": "blue"
6+
}

requirements-test.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Pillow==10.2.0
2+
phonenumbers==8.13.32
3+
django-phonenumber-field==7.3.0
4+
babel==2.14.0
5+
setuptools==69.2.0
6+
pytz~=2024.1
7+
requests~=2.31.0
8+
django-q2==1.6.2
9+
python-dotenv==1.0.1

0 commit comments

Comments
 (0)