Skip to content

Commit 2fb7363

Browse files
authored
Merge pull request #2 from caiyunapp/feat/docker
fix: pylong
2 parents 6a6be8a + f3fb4d7 commit 2fb7363

18 files changed

Lines changed: 1663 additions & 911 deletions

.github/workflows/docker-build.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Build Docker Image
2+
3+
on:
4+
push:
5+
branches: [ main, master, develop ]
6+
pull_request:
7+
branches: [ main, master, develop ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: read
15+
packages: write
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v6
20+
with:
21+
submodules: recursive
22+
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v3
25+
26+
- name: Build Docker image
27+
uses: docker/build-push-action@v6
28+
with:
29+
context: .
30+
file: ./Dockerfile
31+
push: false
32+
tags: python-mapnik:latest
33+
cache-from: type=gha,scope=buildkit-python-mapnik
34+
cache-to: type=gha,mode=max,scope=buildkit-python-mapnik
35+
load: true
36+
37+
- name: Cache uv virtual environment (for container tests)
38+
uses: actions/cache@v5
39+
with:
40+
path: .venv
41+
key: venv-docker-${{ runner.os }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}
42+
restore-keys: |
43+
venv-docker-${{ runner.os }}-
44+
45+
- name: Run tests in Docker container
46+
run: |
47+
docker run --rm \
48+
-v ${{ github.workspace }}:/workspace \
49+
-w /workspace/test/python_tests \
50+
python-mapnik:latest \
51+
sh -c "uv sync --extra test && uv run pytest . -v"

.github/workflows/release.yml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
workflow_dispatch:
8+
inputs:
9+
tag:
10+
description: 'Tag to release (e.g., v4.2.0)'
11+
required: true
12+
type: string
13+
14+
jobs:
15+
test:
16+
uses: ./.github/workflows/test.yml
17+
18+
build:
19+
needs: test
20+
runs-on: ubuntu-latest
21+
container:
22+
image: python:3.12-bookworm
23+
env:
24+
UV_LINK_MODE: copy
25+
UV_CACHE_DIR: /github/home/.cache/uv
26+
permissions:
27+
actions: write
28+
contents: write
29+
30+
steps:
31+
- name: Checkout code
32+
uses: actions/checkout@v6
33+
with:
34+
submodules: recursive
35+
36+
- name: Cache uv downloads
37+
uses: actions/cache@v5
38+
with:
39+
path: /github/home/.cache/uv
40+
key: uvcache-${{ runner.os }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
41+
restore-keys: |
42+
uvcache-${{ runner.os }}-
43+
44+
- name: Extract version from tag
45+
id: version
46+
run: |
47+
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
48+
VERSION=${{ inputs.tag }}
49+
else
50+
VERSION=${GITHUB_REF#refs/tags/}
51+
fi
52+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
53+
echo "version_number=${VERSION#v}" >> $GITHUB_OUTPUT
54+
55+
- name: Add Debian sid repository
56+
run: |
57+
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
58+
echo 'Package: *\nPin: release a=sid\nPin-Priority: 100' > /etc/apt/preferences.d/sid
59+
60+
- name: Install system dependencies
61+
run: |
62+
apt-get update
63+
# Ensure /etc/os-release exists (required by some actions' OS detection).
64+
apt-get install -y base-files
65+
apt-get install -y build-essential pkg-config libbz2-dev
66+
apt-get install -y -t sid libmapnik-dev
67+
68+
- name: Install uv
69+
uses: astral-sh/setup-uv@v7
70+
with:
71+
enable-cache: false
72+
73+
- name: Build wheel and sdist
74+
run: |
75+
uv build --wheel --sdist
76+
77+
- name: Upload build artifacts
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: dist
81+
path: dist/
82+
retention-days: 7
83+
84+
- name: Create GitHub Release
85+
uses: softprops/action-gh-release@v2
86+
if: github.event_name == 'push'
87+
with:
88+
tag_name: ${{ steps.version.outputs.version }}
89+
name: Release ${{ steps.version.outputs.version }}
90+
body: |
91+
## Python Mapnik ${{ steps.version.outputs.version_number }}
92+
93+
### Installation
94+
95+
Download the wheel file below and install:
96+
```bash
97+
pip install mapnik-${{ steps.version.outputs.version_number }}-*.whl
98+
```
99+
100+
Or install directly from GitHub:
101+
```bash
102+
pip install https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/mapnik-${{ steps.version.outputs.version_number }}-cp312-cp312-linux_x86_64.whl
103+
```
104+
105+
Or install from source:
106+
```bash
107+
pip install git+https://github.com/${{ github.repository }}.git@${{ steps.version.outputs.version }}
108+
```
109+
110+
### Requirements
111+
112+
- Python >= 3.8
113+
- Mapnik >= 4.0.0
114+
115+
### Changes
116+
117+
See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ steps.version.outputs.version }}/CHANGELOG.md) for details.
118+
files: |
119+
dist/*.whl
120+
dist/*.tar.gz
121+
draft: false
122+
prerelease: false
123+
env:
124+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
125+
126+
- name: Summary
127+
run: |
128+
echo "## Release Summary" >> $GITHUB_STEP_SUMMARY
129+
echo "" >> $GITHUB_STEP_SUMMARY
130+
echo "✅ Released version: **${{ steps.version.outputs.version }}**" >> $GITHUB_STEP_SUMMARY
131+
echo "" >> $GITHUB_STEP_SUMMARY
132+
echo "### Artifacts Built:" >> $GITHUB_STEP_SUMMARY
133+
ls -lh dist/ >> $GITHUB_STEP_SUMMARY
134+
echo "" >> $GITHUB_STEP_SUMMARY
135+
echo "### Distribution:" >> $GITHUB_STEP_SUMMARY
136+
echo "- GitHub Release: ✅" >> $GITHUB_STEP_SUMMARY

.github/workflows/test.yml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [ main, master, develop ]
6+
pull_request:
7+
branches: [ main, master, develop ]
8+
workflow_dispatch:
9+
workflow_call:
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
container:
15+
image: python:3.12-bookworm
16+
env:
17+
UV_LINK_MODE: copy
18+
UV_CACHE_DIR: /github/home/.cache/uv
19+
permissions:
20+
actions: write
21+
contents: read
22+
checks: write
23+
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v6
27+
with:
28+
submodules: recursive
29+
30+
- name: Cache uv downloads
31+
uses: actions/cache@v5
32+
with:
33+
path: /github/home/.cache/uv
34+
key: uvcache-${{ runner.os }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
35+
restore-keys: |
36+
uvcache-${{ runner.os }}-
37+
38+
- name: Cache uv virtual environment and build artifacts
39+
uses: actions/cache@v5
40+
with:
41+
path: .venv
42+
key: venv-${{ runner.os }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}-${{ hashFiles('src/**/*.cpp', 'src/**/*.hpp', 'packaging/**/*.py') }}
43+
restore-keys: |
44+
venv-${{ runner.os }}-${{ hashFiles('uv.lock', 'pyproject.toml', 'setup.py') }}-
45+
venv-${{ runner.os }}-
46+
47+
- name: Add Debian sid repository
48+
run: |
49+
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list
50+
echo 'Package: *\nPin: release a=sid\nPin-Priority: 100' > /etc/apt/preferences.d/sid
51+
52+
- name: Install system dependencies
53+
run: |
54+
apt-get update
55+
# Ensure /etc/os-release exists (required by some actions' OS detection).
56+
apt-get install -y base-files
57+
apt-get install -y build-essential pkg-config libbz2-dev
58+
apt-get install -y -t sid libmapnik-dev fonts-noto-cjk
59+
60+
- name: Install uv
61+
uses: astral-sh/setup-uv@v7
62+
with:
63+
# Work around container-job failures determining Linux distribution during
64+
# setup-uv's built-in caching path; we cache UV_CACHE_DIR ourselves above.
65+
enable-cache: false
66+
67+
- name: Install Python dependencies and build package
68+
run: |
69+
# Use lockfile when present; avoid doing two full syncs (which can rebuild twice).
70+
if [ -f uv.lock ]; then
71+
uv sync --extra test --frozen --verbose
72+
else
73+
uv sync --extra test --verbose
74+
fi
75+
76+
- name: Run tests with coverage
77+
run: |
78+
uv run pytest test/python_tests -v \
79+
--cov=mapnik \
80+
--cov-report=term \
81+
--cov-report=xml:coverage.xml \
82+
--cov-report=html:htmlcov \
83+
--junitxml=junit.xml
84+
85+
- name: Upload coverage reports
86+
uses: actions/upload-artifact@v4
87+
if: always()
88+
with:
89+
name: coverage-reports
90+
path: |
91+
coverage.xml
92+
htmlcov/
93+
junit.xml
94+
retention-days: 30
95+
96+
- name: Publish test results
97+
uses: EnricoMi/publish-unit-test-result-action@v2
98+
if: always()
99+
with:
100+
files: junit.xml
101+
check_name: Test Results
102+
comment_mode: off
103+
104+
- name: Upload coverage to Codecov
105+
uses: codecov/codecov-action@v5
106+
if: always()
107+
with:
108+
files: ./coverage.xml
109+
flags: unittests
110+
name: python-mapnik-coverage
111+
fail_ci_if_error: false

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*.dylib
1313
build/
1414
dist/
15-
mapnik/paths.py
15+
packaging/mapnik/paths.py
1616
*.egg-info/
1717
.eggs/
1818
.mason/

Dockerfile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
FROM python:3.14-rc-bookworm
2+
3+
# Build-time proxy support (affects apt/uv/etc. during docker build)
4+
ARG http_proxy
5+
ARG https_proxy
6+
ARG no_proxy
7+
ENV http_proxy=${http_proxy} \
8+
https_proxy=${https_proxy} \
9+
no_proxy=${no_proxy} \
10+
HTTP_PROXY=${http_proxy} \
11+
HTTPS_PROXY=${https_proxy} \
12+
NO_PROXY=${no_proxy}
13+
14+
# 添加 Debian sid 仓库以获取 Mapnik 4.2
15+
RUN echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list.d/sid.list && \
16+
echo 'Package: *\nPin: release a=sid\nPin-Priority: 100' > /etc/apt/preferences.d/sid
17+
18+
# 安装必要的工具
19+
RUN apt-get update && \
20+
apt-get install -y \
21+
build-essential \
22+
pkg-config
23+
24+
# 安装 Mapnik 4.2 和必要的开发工具
25+
RUN apt-get install -y -t sid \
26+
libmapnik-dev \
27+
fonts-noto-cjk
28+
29+
# 需要额外的依赖写在这里,避免缓存失效。上面的依赖安装起来时间很长
30+
RUN apt-get install -y \
31+
libbz2-dev \
32+
&& rm -rf /var/lib/apt/lists/*
33+
34+
# 安装 uv
35+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
36+
37+
# 复制依赖文件
38+
COPY pyproject.toml .
39+
COPY uv.lock* ./
40+
41+
# 复制源代码文件(构建本地包所需)
42+
COPY src/ src/
43+
COPY setup.py .
44+
COPY build.py .
45+
COPY packaging/ packaging/
46+
47+
# 安装 Python 依赖(包括构建本地 python-mapnik)
48+
# 使用 --verbose 显示详细的编译日志
49+
RUN uv sync --frozen --no-dev --verbose || uv sync --no-dev --verbose

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ Once you have installed you can test the package by running:
2020
pytest test/python_tests/
2121
```
2222

23+
## UV Sync via Docker
2324

24-
25-
25+
```
26+
docker run --rm -it \
27+
-e http_proxy -e https_proxy -e no_proxy \
28+
-v "$(pwd):/workspace" \
29+
-w /workspace \
30+
python-mapnik:local \
31+
uv sync --verbose
32+
```

0 commit comments

Comments
 (0)