Skip to content

Commit 24b6422

Browse files
authored
Merge pull request #234 from BurnySc2/add-python-314-support
Add python 3.14
2 parents 2cfb87e + 340dd9a commit 24b6422

File tree

10 files changed

+717
-160
lines changed

10 files changed

+717
-160
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ env:
2424
# Docker image version, see https://hub.docker.com/r/burnysc2/python-sc2-docker/tags
2525
# This version should always lack behind one version behind the docker-ci.yml because it is possible that it doesn't exist
2626
VERSION_NUMBER: "1.0.4"
27-
# TODO Change to '3.13' when a new image has been pushed
28-
LATEST_PYTHON_VERSION: "3.12"
27+
# TODO Change to '3.14' when a new image has been pushed
28+
LATEST_PYTHON_VERSION: "3.13"
2929
LATEST_SC2_VERSION: "4.10"
3030

3131
jobs:
@@ -109,7 +109,7 @@ jobs:
109109
# Python 3.8 support has been dropped because numpy >=1.26.0 requires Python >=3.9 (this numpy version is required to run python 3.12)
110110
# Python 3.9 support has been dropped since numpy >=2.1.0 (this numpy version is required to run python 3.13)
111111
os: [macos-latest, windows-latest, ubuntu-latest]
112-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
112+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
113113

114114
steps:
115115
- uses: actions/checkout@v3

.github/workflows/docker-ci.yml

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,41 @@ on:
1414
- develop
1515

1616
env:
17-
VERSION_NUMBER: "1.0.6"
18-
LATEST_PYTHON_VERSION: "3.13"
17+
VERSION_NUMBER: "1.0.7"
18+
LATEST_PYTHON_VERSION: "3.14"
1919
LATEST_SC2_VERSION: "4.10"
20-
EXPERIMENTAL_PYTHON_VERSION: "3.14"
20+
EXPERIMENTAL_PYTHON_VERSION: "3.15"
2121

2222
jobs:
23+
download_sc2_maps:
24+
name: Download and cache sc2 maps
25+
runs-on: ${{ matrix.os }}
26+
timeout-minutes: 15
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
os: [ubuntu-latest]
31+
32+
steps:
33+
- uses: actions/checkout@v3
34+
35+
- name: Cache sc2 maps
36+
uses: actions/cache@v4
37+
id: cache-sc2-maps
38+
with:
39+
path: |
40+
dockerfiles/maps
41+
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
42+
restore-keys: |
43+
${{ runner.os }}-maps-
44+
45+
- name: Download sc2 maps
46+
run: sh dockerfiles/download_maps.sh
47+
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
48+
2349
run_test_docker_image:
2450
name: Run test_docker_image.sh
51+
needs: [download_sc2_maps]
2552
runs-on: ${{ matrix.os }}
2653
timeout-minutes: 30
2754
strategy:
@@ -32,10 +59,19 @@ jobs:
3259
steps:
3360
- uses: actions/checkout@v3
3461

35-
- name: Enable experimental docker features
36-
run: |
37-
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
38-
sudo systemctl restart docker.service
62+
- name: Cache sc2 maps
63+
uses: actions/cache@v4
64+
id: cache-sc2-maps
65+
with:
66+
path: |
67+
dockerfiles/maps
68+
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
69+
restore-keys: |
70+
${{ runner.os }}-maps-
71+
72+
- name: Download sc2 maps
73+
run: sh dockerfiles/download_maps.sh
74+
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
3975

4076
- name: Run shell script
4177
env:
@@ -46,6 +82,7 @@ jobs:
4682

4783
run_test_new_python_version:
4884
name: Run test_new_python_candidate.sh
85+
needs: [download_sc2_maps]
4986
runs-on: ${{ matrix.os }}
5087
timeout-minutes: 30
5188
strategy:
@@ -56,10 +93,19 @@ jobs:
5693
steps:
5794
- uses: actions/checkout@v3
5895

59-
- name: Enable experimental docker features
60-
run: |
61-
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
62-
sudo systemctl restart docker.service
96+
- name: Cache sc2 maps
97+
uses: actions/cache@v4
98+
id: cache-sc2-maps
99+
with:
100+
path: |
101+
dockerfiles/maps
102+
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
103+
restore-keys: |
104+
${{ runner.os }}-maps-
105+
106+
- name: Download sc2 maps
107+
run: sh dockerfiles/download_maps.sh
108+
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
63109

64110
- name: Run shell script
65111
continue-on-error: true
@@ -71,13 +117,14 @@ jobs:
71117

72118
docker_build:
73119
name: Build docker image
120+
needs: [download_sc2_maps]
74121
runs-on: ${{ matrix.os }}
75122
timeout-minutes: 30
76123
strategy:
77124
fail-fast: false
78125
matrix:
79126
os: [ubuntu-latest]
80-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
127+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
81128
sc2-version: ["4.10"]
82129
env:
83130
IMAGE_NAME: burnysc2/python-sc2-docker:py_${{ matrix.python-version }}-sc2_${{ matrix.sc2-version }}
@@ -86,26 +133,31 @@ jobs:
86133
steps:
87134
- uses: actions/checkout@v3
88135

89-
- name: Build docker image
90-
run: docker build -t $IMAGE_NAME-v$VERSION_NUMBER $BUILD_ARGS - < dockerfiles/Dockerfile
136+
- name: Cache sc2 maps
137+
uses: actions/cache@v4
138+
id: cache-sc2-maps
139+
with:
140+
path: |
141+
dockerfiles/maps
142+
key: ${{ runner.os }}-maps-${{ hashFiles('dockerfiles/maps/**') }}
143+
restore-keys: |
144+
${{ runner.os }}-maps-
91145
92-
- name: Enable experimental docker features
93-
run: |
94-
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
95-
sudo systemctl restart docker.service
146+
- name: Download sc2 maps
147+
run: sh dockerfiles/download_maps.sh
148+
if: steps.cache-sc2-maps.outputs.cache-hit != 'true'
96149

97-
- name: Build squashed image
98-
run: docker build -t $IMAGE_NAME-v$VERSION_NUMBER-squashed --squash $BUILD_ARGS - < dockerfiles/Dockerfile
150+
- name: Build docker image
151+
run: docker build -f dockerfiles/Dockerfile -t $IMAGE_NAME-v$VERSION_NUMBER $BUILD_ARGS .
99152

100-
- name: Run test bots on squashed image
101-
if: matrix.python-version != '3.7'
153+
- name: Run test bots on image
102154
run: |
103155
echo "Start container, override the default entrypoint"
104156
docker run -i -d \
105157
--name test_container \
106158
--env 'PYTHONPATH=/root/python-sc2/' \
107159
--entrypoint /bin/bash \
108-
$IMAGE_NAME-v$VERSION_NUMBER-squashed
160+
$IMAGE_NAME-v$VERSION_NUMBER
109161
echo "Install python-sc2"
110162
docker exec -i test_container mkdir -p /root/python-sc2
111163
docker cp pyproject.toml test_container:/root/python-sc2/
@@ -131,12 +183,8 @@ jobs:
131183
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
132184
run: docker push $IMAGE_NAME-v$VERSION_NUMBER
133185

134-
- name: Upload squashed docker image
135-
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
136-
run: docker push $IMAGE_NAME-v$VERSION_NUMBER-squashed
137-
138-
- name: Upload squashed docker image as latest tag
186+
- name: Upload docker image as latest tag
139187
if: github.ref == 'refs/heads/develop' && github.event_name == 'push' && matrix.python-version == env.LATEST_PYTHON_VERSION && matrix.sc2-version == env.LATEST_SC2_VERSION
140188
run: |
141-
docker tag $IMAGE_NAME-v$VERSION_NUMBER-squashed burnysc2/python-sc2-docker:latest
189+
docker tag $IMAGE_NAME-v$VERSION_NUMBER burnysc2/python-sc2-docker:latest
142190
docker push burnysc2/python-sc2-docker:latest

dockerfiles/Dockerfile

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
ARG PYTHON_VERSION=3.10
33

44
# https://docs.astral.sh/uv/guides/integration/docker/#available-images
5-
FROM ghcr.io/astral-sh/uv:python$PYTHON_VERSION-bookworm-slim
5+
FROM ghcr.io/astral-sh/uv:python$PYTHON_VERSION-bookworm-slim AS base
66

77
ARG SC2_VERSION=4.10
88

@@ -37,7 +37,7 @@ WORKDIR /root/
3737
# Download and uncompress StarCraftII from https://github.com/Blizzard/s2client-proto#linux-packages and remove zip file
3838
# If file is locally available, use this instead:
3939
#COPY SC2.4.10.zip /root/
40-
RUN curl --retry 3 --retry-delay 5 -C - http://blzdistsc2-a.akamaihd.net/Linux/SC2.$SC2_VERSION.zip -o "SC2.$SC2_VERSION.zip" \
40+
RUN curl --retry 5 --retry-delay 5 -C - http://blzdistsc2-a.akamaihd.net/Linux/SC2.$SC2_VERSION.zip -o "SC2.$SC2_VERSION.zip" \
4141
&& unzip -q -P iagreetotheeula "SC2.$SC2_VERSION.zip" \
4242
&& rm SC2.$SC2_VERSION.zip
4343

@@ -51,51 +51,13 @@ RUN ln -s /root/StarCraftII/Maps /root/StarCraftII/maps \
5151
# Remove the Maps that come with the SC2 client
5252
&& rm -rf /root/StarCraftII/maps/*
5353

54-
# Change to maps folder
55-
WORKDIR /root/StarCraftII/maps/
56-
57-
# Maps are available here https://github.com/Blizzard/s2client-proto#map-packs and here https://sc2ai.net/wiki/maps/
58-
# Download and uncompress StarCraftII Maps, remove zip file - using "maps" instead of "Maps" as target folder
59-
60-
# Get sc2ai.net ladder maps
61-
# -L param follows links https://stackoverflow.com/a/2663023/10882657
62-
RUN curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/9/ -o 1.zip \
63-
&& curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/14/ -o 2.zip \
64-
&& curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/21/ -o 3.zip \
65-
&& curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/35/ -o 4.zip \
66-
&& curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/36/ -o 5.zip \
67-
&& curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/38/ -o 6.zip \
68-
&& curl -L https://sc2ai.net/wiki/184/plugin/attachments/download/39/ -o 7.zip \
69-
&& unzip -q -o '*.zip' \
70-
&& rm *.zip
71-
72-
# Get official blizzard maps
73-
RUN curl --retry 3 --retry-delay 5 -C - http://blzdistsc2-a.akamaihd.net/MapPacks/Ladder2019Season3.zip -o 'Ladder2019Season3.zip' \
74-
&& unzip -q -P iagreetotheeula -o 'Ladder2019Season3.zip' \
75-
&& mv Ladder2019Season3/* . \
76-
&& rm Ladder2019Season3.zip \
77-
&& rm -r Ladder2019Season3
78-
79-
# Get v5.0.6 maps
80-
RUN curl -L https://github.com/shostyn/sc2patch/raw/4987d4915b47c801adbc05e297abaa9ca2988838/Maps/506.zip -o 506.zip \
81-
&& unzip -q -o '506.zip' \
82-
&& rm 506.zip
83-
84-
# Get flat and empty maps
85-
RUN curl --retry 3 --retry-delay 5 -C - http://blzdistsc2-a.akamaihd.net/MapPacks/Melee.zip -o Melee.zip \
86-
&& unzip -q -P iagreetotheeula -o 'Melee.zip' \
87-
&& mv Melee/* . \
88-
&& rm Melee.zip \
89-
&& rm -r Melee
90-
91-
# Remove LE suffix from file names
92-
RUN rename -v 's/LE.SC2Map/.SC2Map/' *.SC2Map
93-
94-
# List all map files
95-
RUN tree
54+
# See download_maps.sh
55+
COPY dockerfiles/maps/* /root/StarCraftII/maps/
9656

57+
# Squash image with trick https://stackoverflow.com/a/56118557/10882657
58+
FROM scratch
59+
COPY --from=base / /
9760
WORKDIR /root/
98-
9961
ENTRYPOINT [ "/bin/bash" ]
10062

10163
# To run a python-sc2 bot:

dockerfiles/download_maps.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
# Run via
3+
# sh dockerfiles/download_maps.sh
4+
set -e
5+
6+
# Create maps directory if it doesn't exist
7+
mkdir -p dockerfiles/maps
8+
cd dockerfiles/maps
9+
10+
# Download function with retries
11+
download_with_retry() {
12+
local url=$1
13+
local output=$2
14+
curl --retry 5 --retry-delay 5 -C - -L "$url" -o "$output"
15+
}
16+
17+
# Download and process sc2ai.net ladder maps
18+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/9/" "1.zip"
19+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/14/" "2.zip"
20+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/21/" "3.zip"
21+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/35/" "4.zip"
22+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/36/" "5.zip"
23+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/38/" "6.zip"
24+
download_with_retry "https://sc2ai.net/wiki/184/plugin/attachments/download/39/" "7.zip"
25+
unzip -q -o '*.zip'
26+
rm *.zip
27+
28+
# Download and process official blizzard maps
29+
download_with_retry "http://blzdistsc2-a.akamaihd.net/MapPacks/Ladder2019Season3.zip" "Ladder2019Season3.zip"
30+
unzip -q -P iagreetotheeula -o "Ladder2019Season3.zip"
31+
mv Ladder2019Season3/* .
32+
rm "Ladder2019Season3.zip"
33+
rmdir Ladder2019Season3
34+
35+
# Download and process v5.0.6 maps
36+
download_with_retry "https://github.com/shostyn/sc2patch/raw/4987d4915b47c801adbc05e297abaa9ca2988838/Maps/506.zip" "506.zip"
37+
unzip -q -o "506.zip"
38+
rm "506.zip"
39+
40+
# Download and process flat/empty maps
41+
download_with_retry "http://blzdistsc2-a.akamaihd.net/MapPacks/Melee.zip" "Melee.zip"
42+
unzip -q -P iagreetotheeula -o "Melee.zip"
43+
mv Melee/* .
44+
rm "Melee.zip"
45+
rmdir Melee
46+
47+
# Remove LE suffix from file names
48+
for f in *LE.SC2Map; do
49+
mv -- "$f" "${f%LE.SC2Map}.SC2Map";
50+
done

dockerfiles/test_docker_image.sh

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,16 @@ set -e
77

88
# Set which versions to use
99
export VERSION_NUMBER=${VERSION_NUMBER:-0.9.9}
10-
export PYTHON_VERSION=${PYTHON_VERSION:-3.12}
10+
export PYTHON_VERSION=${PYTHON_VERSION:-3.13}
1111
export SC2_VERSION=${SC2_VERSION:-4.10}
1212

1313
# For better readability, set local variables
1414
IMAGE_NAME=burnysc2/python-sc2-docker:py_$PYTHON_VERSION-sc2_$SC2_VERSION-v$VERSION_NUMBER
1515
BUILD_ARGS="--build-arg PYTHON_VERSION=$PYTHON_VERSION --build-arg SC2_VERSION=$SC2_VERSION"
1616

17-
# Allow image squashing by enabling experimental docker features
18-
# https://stackoverflow.com/a/21164441/10882657
19-
# https://github.com/actions/virtual-environments/issues/368#issuecomment-582387669
20-
# file=/etc/docker/daemon.json
21-
# if [ ! -e "$file" ]; then
22-
# echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
23-
# sudo systemctl restart docker.service
24-
# fi
25-
2617
# Build image without context
2718
# https://stackoverflow.com/a/54666214/10882657
28-
docker build -t $IMAGE_NAME $BUILD_ARGS - < dockerfiles/Dockerfile
29-
# Build squashed image where the layers are combined to one
30-
#docker build -t $IMAGE_NAME-squashed --squash $BUILD_ARGS - < dockerfiles/Dockerfile
19+
docker build -f dockerfiles/Dockerfile -t $IMAGE_NAME $BUILD_ARGS .
3120

3221
# Delete previous container if it exists
3322
docker rm -f test_container

dockerfiles/test_new_python_candidate.sh

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ set -e
88

99
# Set which versions to use
1010
export VERSION_NUMBER=${VERSION_NUMBER:-0.9.9}
11-
export PYTHON_VERSION=${PYTHON_VERSION:-3.13}
11+
export PYTHON_VERSION=${PYTHON_VERSION:-3.14}
1212
export SC2_VERSION=${SC2_VERSION:-4.10}
1313

1414
# For better readability, set local variables
1515
IMAGE_NAME=burnysc2/python-sc2-docker:py_$PYTHON_VERSION-sc2_$SC2_VERSION-v$VERSION_NUMBER
1616
BUILD_ARGS="--build-arg PYTHON_VERSION=$PYTHON_VERSION --build-arg SC2_VERSION=$SC2_VERSION"
1717

1818
# Build image
19-
docker build -t $IMAGE_NAME $BUILD_ARGS - < dockerfiles/Dockerfile
19+
docker build -f dockerfiles/Dockerfile -t $IMAGE_NAME $BUILD_ARGS .
2020

2121
# Delete previous container if it exists
2222
docker rm -f test_container
@@ -25,14 +25,22 @@ docker rm -f test_container
2525
# https://docs.docker.com/storage/bind-mounts/#use-a-read-only-bind-mount
2626
docker run -i -d \
2727
--name test_container \
28-
--volume ./:/root/python-sc2:ro \
28+
--env 'PYTHONPATH=/root/python-sc2' \
29+
--entrypoint /bin/bash \
2930
$IMAGE_NAME
3031

32+
# Install requirements
33+
docker exec -i test_container mkdir -p /root/python-sc2
34+
docker cp pyproject.toml test_container:/root/python-sc2/
35+
docker cp uv.lock test_container:/root/python-sc2/
36+
docker exec -i test_container bash -c "pip install uv && cd python-sc2 && uv sync --no-cache --no-install-project"
3137

32-
# Install python-sc2, via mount the python-sc2 folder will be available
33-
docker exec -i test_container bash -c "pip install uv \
34-
&& cd python-sc2 && uv sync --frozen --no-cache --no-install-project"
38+
docker cp sc2 test_container:/root/python-sc2/sc2
39+
docker cp s2clientprotocol test_container:/root/python-sc2/s2clientprotocol
40+
docker cp test test_container:/root/python-sc2/test
3541

3642
# Run various test bots
3743
docker exec -i test_container bash -c "cd python-sc2 && uv run python test/travis_test_script.py test/autotest_bot.py"
44+
45+
docker cp examples test_container:/root/python-sc2/examples
3846
docker exec -i test_container bash -c "cd python-sc2 && uv run python test/run_example_bots_vs_computer.py"

0 commit comments

Comments
 (0)