rapsqlite 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rapsqlite-0.0.1/.github/workflows/CI.yml +109 -0
- rapsqlite-0.0.1/.github/workflows/publish-existing-rebuild-sdist.yml +120 -0
- rapsqlite-0.0.1/.github/workflows/publish-existing.yml +122 -0
- rapsqlite-0.0.1/.github/workflows/publish.yml +333 -0
- rapsqlite-0.0.1/.github/workflows/security.yml +90 -0
- rapsqlite-0.0.1/.gitignore +47 -0
- rapsqlite-0.0.1/Cargo.lock +2136 -0
- rapsqlite-0.0.1/Cargo.toml +24 -0
- rapsqlite-0.0.1/LICENSE +22 -0
- rapsqlite-0.0.1/PKG-INFO +235 -0
- rapsqlite-0.0.1/README.md +215 -0
- rapsqlite-0.0.1/ROADMAP.md +353 -0
- rapsqlite-0.0.1/pyproject.toml +33 -0
- rapsqlite-0.0.1/rapsqlite/__init__.py +13 -0
- rapsqlite-0.0.1/src/lib.rs +80 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test on ${{ matrix.os }}
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install Rust
|
|
27
|
+
uses: actions-rs/toolchain@v1
|
|
28
|
+
with:
|
|
29
|
+
toolchain: stable
|
|
30
|
+
override: true
|
|
31
|
+
|
|
32
|
+
- name: Install maturin
|
|
33
|
+
run: pip install maturin
|
|
34
|
+
|
|
35
|
+
- name: Build package (Linux)
|
|
36
|
+
if: runner.os == 'Linux'
|
|
37
|
+
run: python -m maturin build --release --skip-auditwheel
|
|
38
|
+
|
|
39
|
+
- name: Build package (macOS/Windows)
|
|
40
|
+
if: runner.os != 'Linux'
|
|
41
|
+
run: python -m maturin build --release
|
|
42
|
+
|
|
43
|
+
- name: Install package
|
|
44
|
+
shell: bash
|
|
45
|
+
run: pip install target/wheels/rapsqlite-*.whl --force-reinstall
|
|
46
|
+
|
|
47
|
+
- name: Test package import
|
|
48
|
+
shell: bash
|
|
49
|
+
run: |
|
|
50
|
+
python -c "import rapsqlite; print('Version:', rapsqlite.__version__)"
|
|
51
|
+
|
|
52
|
+
lint:
|
|
53
|
+
name: Lint
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Set up Rust
|
|
59
|
+
uses: actions-rs/toolchain@v1
|
|
60
|
+
with:
|
|
61
|
+
toolchain: stable
|
|
62
|
+
components: clippy, rustfmt
|
|
63
|
+
override: true
|
|
64
|
+
|
|
65
|
+
- name: Run clippy
|
|
66
|
+
run: cargo clippy --lib -- -D clippy::all -A deprecated
|
|
67
|
+
|
|
68
|
+
- name: Check formatting
|
|
69
|
+
run: cargo fmt -- --check
|
|
70
|
+
|
|
71
|
+
build-wheels:
|
|
72
|
+
name: Build wheels on ${{ matrix.os }}
|
|
73
|
+
runs-on: ${{ matrix.os }}
|
|
74
|
+
strategy:
|
|
75
|
+
matrix:
|
|
76
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
77
|
+
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
|
|
81
|
+
- name: Set up Python
|
|
82
|
+
uses: actions/setup-python@v5
|
|
83
|
+
with:
|
|
84
|
+
python-version: '3.12'
|
|
85
|
+
|
|
86
|
+
- name: Install Rust
|
|
87
|
+
uses: actions-rs/toolchain@v1
|
|
88
|
+
with:
|
|
89
|
+
toolchain: stable
|
|
90
|
+
override: true
|
|
91
|
+
|
|
92
|
+
- name: Install maturin
|
|
93
|
+
run: pip install maturin
|
|
94
|
+
|
|
95
|
+
- name: Build wheels (Linux with manylinux)
|
|
96
|
+
if: matrix.os == 'ubuntu-latest'
|
|
97
|
+
run: |
|
|
98
|
+
docker run --rm -v "${{ github.workspace }}":/io -w /io ghcr.io/pyo3/maturin:main build --release --out dist --manylinux manylinux_2_24
|
|
99
|
+
|
|
100
|
+
- name: Build wheels (macOS/Windows)
|
|
101
|
+
if: matrix.os != 'ubuntu-latest'
|
|
102
|
+
run: maturin build --release --out dist
|
|
103
|
+
|
|
104
|
+
- name: Upload wheels
|
|
105
|
+
uses: actions/upload-artifact@v4
|
|
106
|
+
with:
|
|
107
|
+
name: wheels-${{ matrix.os }}
|
|
108
|
+
path: dist
|
|
109
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
name: Publish Existing Wheels + Rebuild Sdist
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
run_id:
|
|
7
|
+
description: 'GitHub Actions Run ID containing the wheel artifacts to use'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
MATURIN_PROFILE: release
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
publish-existing-rebuild-sdist:
|
|
16
|
+
name: Publish Existing Wheels + Rebuild Sdist
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
actions: read
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout repository
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.12"
|
|
29
|
+
|
|
30
|
+
- name: Set up Rust
|
|
31
|
+
uses: dtolnay/rust-toolchain@stable
|
|
32
|
+
|
|
33
|
+
- name: Install build tooling
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
pip install maturin
|
|
37
|
+
|
|
38
|
+
- name: Build sdist (with fixed metadata)
|
|
39
|
+
run: maturin sdist --out dist
|
|
40
|
+
|
|
41
|
+
- name: Download all wheel artifacts from existing run
|
|
42
|
+
uses: actions/download-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
run-id: ${{ inputs.run_id }}
|
|
45
|
+
pattern: wheel-*
|
|
46
|
+
merge-multiple: true
|
|
47
|
+
path: artifacts/wheels
|
|
48
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
49
|
+
|
|
50
|
+
- name: Combine artifacts
|
|
51
|
+
shell: bash
|
|
52
|
+
run: |
|
|
53
|
+
set -e
|
|
54
|
+
|
|
55
|
+
# Copy wheels from artifacts directory
|
|
56
|
+
echo "=== Copying wheels ==="
|
|
57
|
+
find artifacts -name "*.whl" -type f -exec cp -v {} dist/ \; || true
|
|
58
|
+
|
|
59
|
+
# Verify we have files
|
|
60
|
+
echo ""
|
|
61
|
+
echo "=== Final dist contents ==="
|
|
62
|
+
ls -lah dist/ || echo "dist/ is empty or doesn't exist"
|
|
63
|
+
echo ""
|
|
64
|
+
echo "=== Distribution files ==="
|
|
65
|
+
find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) 2>/dev/null | sort || echo "No files found"
|
|
66
|
+
echo ""
|
|
67
|
+
|
|
68
|
+
# Count files
|
|
69
|
+
WHEEL_COUNT=$(find dist -name "*.whl" -type f 2>/dev/null | wc -l || echo "0")
|
|
70
|
+
SDIST_COUNT=$(find dist -name "*.tar.gz" -type f 2>/dev/null | wc -l || echo "0")
|
|
71
|
+
echo "Wheels: $WHEEL_COUNT"
|
|
72
|
+
echo "Source distributions: $SDIST_COUNT"
|
|
73
|
+
|
|
74
|
+
if [ "$WHEEL_COUNT" -eq 0 ] || [ "$SDIST_COUNT" -eq 0 ]; then
|
|
75
|
+
echo "ERROR: Missing distribution files!"
|
|
76
|
+
echo "Wheels found: $WHEEL_COUNT"
|
|
77
|
+
echo "Source distributions found: $SDIST_COUNT"
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
echo "✅ Successfully prepared $((WHEEL_COUNT + SDIST_COUNT)) distribution files"
|
|
82
|
+
|
|
83
|
+
- name: Publish to PyPI
|
|
84
|
+
env:
|
|
85
|
+
TWINE_USERNAME: __token__
|
|
86
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
87
|
+
run: |
|
|
88
|
+
set -e
|
|
89
|
+
pip install twine
|
|
90
|
+
|
|
91
|
+
# Check if we have files to upload
|
|
92
|
+
echo "=== Files to upload ==="
|
|
93
|
+
ls -lah dist/
|
|
94
|
+
echo ""
|
|
95
|
+
|
|
96
|
+
# Verify token is set (without exposing it)
|
|
97
|
+
if [ -z "$TWINE_PASSWORD" ]; then
|
|
98
|
+
echo "ERROR: PYPI_API_TOKEN secret is not set!"
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
echo "✅ PyPI token is configured"
|
|
103
|
+
echo ""
|
|
104
|
+
|
|
105
|
+
# Upload with verbose output for debugging
|
|
106
|
+
echo "=== Uploading to PyPI ==="
|
|
107
|
+
twine upload dist/* --verbose || {
|
|
108
|
+
echo ""
|
|
109
|
+
echo "❌ Upload failed. Common issues:"
|
|
110
|
+
echo " 1. Package version already exists on PyPI"
|
|
111
|
+
echo " 2. Invalid or expired PyPI API token"
|
|
112
|
+
echo " 3. Network/authentication error"
|
|
113
|
+
echo ""
|
|
114
|
+
echo "Check PyPI: https://pypi.org/project/rapsqlite/"
|
|
115
|
+
exit 1
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
echo ""
|
|
119
|
+
echo "✅ Successfully published to PyPI!"
|
|
120
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
name: Publish Existing Artifacts to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
run_id:
|
|
7
|
+
description: 'GitHub Actions Run ID containing the artifacts to publish'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
MATURIN_PROFILE: release
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
publish-existing:
|
|
16
|
+
name: Publish Existing Artifacts to PyPI
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
actions: read
|
|
21
|
+
steps:
|
|
22
|
+
- name: Download all wheel artifacts from run
|
|
23
|
+
uses: actions/download-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
run-id: ${{ inputs.run_id }}
|
|
26
|
+
pattern: wheel-*
|
|
27
|
+
merge-multiple: true
|
|
28
|
+
path: artifacts/wheels
|
|
29
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
+
|
|
31
|
+
- name: Download sdist artifact from run
|
|
32
|
+
uses: actions/download-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
run-id: ${{ inputs.run_id }}
|
|
35
|
+
pattern: sdist
|
|
36
|
+
merge-multiple: true
|
|
37
|
+
path: artifacts/sdist
|
|
38
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
|
|
40
|
+
- name: Combine artifacts
|
|
41
|
+
shell: bash
|
|
42
|
+
run: |
|
|
43
|
+
set -e
|
|
44
|
+
|
|
45
|
+
# Debug: Show what we downloaded
|
|
46
|
+
echo "=== Artifacts structure ==="
|
|
47
|
+
find artifacts -type f -o -type d 2>/dev/null | sort || true
|
|
48
|
+
echo ""
|
|
49
|
+
|
|
50
|
+
# Create clean dist directory
|
|
51
|
+
mkdir -p dist
|
|
52
|
+
|
|
53
|
+
# Copy wheels from artifacts directory (handle all possible structures)
|
|
54
|
+
echo "=== Copying wheels ==="
|
|
55
|
+
find artifacts -name "*.whl" -type f -exec cp -v {} dist/ \; || true
|
|
56
|
+
|
|
57
|
+
# Copy sdist from artifacts directory (handle all possible structures)
|
|
58
|
+
echo "=== Copying sdist ==="
|
|
59
|
+
find artifacts -name "*.tar.gz" -type f -exec cp -v {} dist/ \; || true
|
|
60
|
+
|
|
61
|
+
# Verify we have files
|
|
62
|
+
echo ""
|
|
63
|
+
echo "=== Final dist contents ==="
|
|
64
|
+
ls -lah dist/ || echo "dist/ is empty or doesn't exist"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "=== Distribution files ==="
|
|
67
|
+
find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) 2>/dev/null | sort || echo "No files found"
|
|
68
|
+
echo ""
|
|
69
|
+
|
|
70
|
+
# Count files
|
|
71
|
+
WHEEL_COUNT=$(find dist -name "*.whl" -type f 2>/dev/null | wc -l || echo "0")
|
|
72
|
+
SDIST_COUNT=$(find dist -name "*.tar.gz" -type f 2>/dev/null | wc -l || echo "0")
|
|
73
|
+
echo "Wheels: $WHEEL_COUNT"
|
|
74
|
+
echo "Source distributions: $SDIST_COUNT"
|
|
75
|
+
|
|
76
|
+
if [ "$WHEEL_COUNT" -eq 0 ] && [ "$SDIST_COUNT" -eq 0 ]; then
|
|
77
|
+
echo "ERROR: No distribution files found in dist/!"
|
|
78
|
+
echo "Checking artifacts directory:"
|
|
79
|
+
find artifacts -type f 2>/dev/null || true
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
echo "✅ Successfully prepared $((WHEEL_COUNT + SDIST_COUNT)) distribution files"
|
|
84
|
+
|
|
85
|
+
- name: Publish to PyPI
|
|
86
|
+
env:
|
|
87
|
+
TWINE_USERNAME: __token__
|
|
88
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
89
|
+
run: |
|
|
90
|
+
set -e
|
|
91
|
+
pip install twine
|
|
92
|
+
|
|
93
|
+
# Check if we have files to upload
|
|
94
|
+
echo "=== Files to upload ==="
|
|
95
|
+
ls -lah dist/
|
|
96
|
+
echo ""
|
|
97
|
+
|
|
98
|
+
# Verify token is set (without exposing it)
|
|
99
|
+
if [ -z "$TWINE_PASSWORD" ]; then
|
|
100
|
+
echo "ERROR: PYPI_API_TOKEN secret is not set!"
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
echo "✅ PyPI token is configured"
|
|
105
|
+
echo ""
|
|
106
|
+
|
|
107
|
+
# Upload with verbose output for debugging
|
|
108
|
+
echo "=== Uploading to PyPI ==="
|
|
109
|
+
twine upload dist/* --verbose || {
|
|
110
|
+
echo ""
|
|
111
|
+
echo "❌ Upload failed. Common issues:"
|
|
112
|
+
echo " 1. Package version already exists on PyPI"
|
|
113
|
+
echo " 2. Invalid or expired PyPI API token"
|
|
114
|
+
echo " 3. Network/authentication error"
|
|
115
|
+
echo ""
|
|
116
|
+
echo "Check PyPI: https://pypi.org/project/rapsqlite/"
|
|
117
|
+
exit 1
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
echo ""
|
|
121
|
+
echo "✅ Successfully published to PyPI!"
|
|
122
|
+
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*' # Triggers on version tags like v0.1.0, v1.0.0, etc.
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
MATURIN_PROFILE: release
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-wheels:
|
|
13
|
+
name: Build wheels (${{ matrix.os }} / ${{ matrix.architecture }} / py${{ matrix.python }})
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
include:
|
|
21
|
+
# Ubuntu x86-64
|
|
22
|
+
- os: ubuntu-latest
|
|
23
|
+
python: "3.8"
|
|
24
|
+
architecture: x86-64
|
|
25
|
+
- os: ubuntu-latest
|
|
26
|
+
python: "3.9"
|
|
27
|
+
architecture: x86-64
|
|
28
|
+
- os: ubuntu-latest
|
|
29
|
+
python: "3.10"
|
|
30
|
+
architecture: x86-64
|
|
31
|
+
- os: ubuntu-latest
|
|
32
|
+
python: "3.11"
|
|
33
|
+
architecture: x86-64
|
|
34
|
+
- os: ubuntu-latest
|
|
35
|
+
python: "3.12"
|
|
36
|
+
architecture: x86-64
|
|
37
|
+
- os: ubuntu-latest
|
|
38
|
+
python: "3.13"
|
|
39
|
+
architecture: x86-64
|
|
40
|
+
# Ubuntu ARM64 (aarch64)
|
|
41
|
+
- os: ubuntu-latest
|
|
42
|
+
python: "3.8"
|
|
43
|
+
architecture: aarch64
|
|
44
|
+
- os: ubuntu-latest
|
|
45
|
+
python: "3.9"
|
|
46
|
+
architecture: aarch64
|
|
47
|
+
- os: ubuntu-latest
|
|
48
|
+
python: "3.10"
|
|
49
|
+
architecture: aarch64
|
|
50
|
+
- os: ubuntu-latest
|
|
51
|
+
python: "3.11"
|
|
52
|
+
architecture: aarch64
|
|
53
|
+
- os: ubuntu-latest
|
|
54
|
+
python: "3.12"
|
|
55
|
+
architecture: aarch64
|
|
56
|
+
- os: ubuntu-latest
|
|
57
|
+
python: "3.13"
|
|
58
|
+
architecture: aarch64
|
|
59
|
+
# macOS latest (typically arm64/Apple Silicon)
|
|
60
|
+
- os: macos-latest
|
|
61
|
+
python: "3.8"
|
|
62
|
+
architecture: aarch64
|
|
63
|
+
- os: macos-latest
|
|
64
|
+
python: "3.9"
|
|
65
|
+
architecture: aarch64
|
|
66
|
+
- os: macos-latest
|
|
67
|
+
python: "3.10"
|
|
68
|
+
architecture: aarch64
|
|
69
|
+
- os: macos-latest
|
|
70
|
+
python: "3.11"
|
|
71
|
+
architecture: aarch64
|
|
72
|
+
- os: macos-latest
|
|
73
|
+
python: "3.12"
|
|
74
|
+
architecture: aarch64
|
|
75
|
+
- os: macos-latest
|
|
76
|
+
python: "3.13"
|
|
77
|
+
architecture: aarch64
|
|
78
|
+
# Windows x86-64
|
|
79
|
+
- os: windows-latest
|
|
80
|
+
python: "3.8"
|
|
81
|
+
architecture: x86-64
|
|
82
|
+
- os: windows-latest
|
|
83
|
+
python: "3.9"
|
|
84
|
+
architecture: x86-64
|
|
85
|
+
- os: windows-latest
|
|
86
|
+
python: "3.10"
|
|
87
|
+
architecture: x86-64
|
|
88
|
+
- os: windows-latest
|
|
89
|
+
python: "3.11"
|
|
90
|
+
architecture: x86-64
|
|
91
|
+
- os: windows-latest
|
|
92
|
+
python: "3.12"
|
|
93
|
+
architecture: x86-64
|
|
94
|
+
- os: windows-latest
|
|
95
|
+
python: "3.13"
|
|
96
|
+
architecture: x86-64
|
|
97
|
+
# macOS 15 Intel (x86-64)
|
|
98
|
+
- os: macos-15-intel
|
|
99
|
+
python: "3.8"
|
|
100
|
+
architecture: x86-64
|
|
101
|
+
- os: macos-15-intel
|
|
102
|
+
python: "3.9"
|
|
103
|
+
architecture: x86-64
|
|
104
|
+
- os: macos-15-intel
|
|
105
|
+
python: "3.10"
|
|
106
|
+
architecture: x86-64
|
|
107
|
+
- os: macos-15-intel
|
|
108
|
+
python: "3.11"
|
|
109
|
+
architecture: x86-64
|
|
110
|
+
- os: macos-15-intel
|
|
111
|
+
python: "3.12"
|
|
112
|
+
architecture: x86-64
|
|
113
|
+
- os: macos-15-intel
|
|
114
|
+
python: "3.13"
|
|
115
|
+
architecture: x86-64
|
|
116
|
+
# Windows 11 ARM (aarch64)
|
|
117
|
+
- os: windows-11-arm
|
|
118
|
+
python: "3.11"
|
|
119
|
+
architecture: aarch64
|
|
120
|
+
- os: windows-11-arm
|
|
121
|
+
python: "3.12"
|
|
122
|
+
architecture: aarch64
|
|
123
|
+
- os: windows-11-arm
|
|
124
|
+
python: "3.13"
|
|
125
|
+
architecture: aarch64
|
|
126
|
+
steps:
|
|
127
|
+
- name: Checkout repository
|
|
128
|
+
uses: actions/checkout@v4
|
|
129
|
+
|
|
130
|
+
- name: Set up QEMU
|
|
131
|
+
if: matrix.os == 'ubuntu-latest' && matrix.architecture == 'aarch64'
|
|
132
|
+
uses: docker/setup-qemu-action@v3
|
|
133
|
+
with:
|
|
134
|
+
platforms: arm64
|
|
135
|
+
|
|
136
|
+
- name: Build wheel (Linux - manylinux)
|
|
137
|
+
if: matrix.os == 'ubuntu-latest'
|
|
138
|
+
env:
|
|
139
|
+
PYO3_USE_ABI3_FORWARD_COMPATIBILITY: ${{ (matrix.python == '3.13') && '1' || '' }}
|
|
140
|
+
run: |
|
|
141
|
+
PYTHON_VER="${{ matrix.python }}"
|
|
142
|
+
PYTHON_TAG="cp${PYTHON_VER//./}"
|
|
143
|
+
if [ "${{ matrix.architecture }}" = "aarch64" ]; then
|
|
144
|
+
DOCKER_IMAGE="quay.io/pypa/manylinux_2_28_aarch64:latest"
|
|
145
|
+
else
|
|
146
|
+
DOCKER_IMAGE="quay.io/pypa/manylinux_2_28_x86_64:latest"
|
|
147
|
+
fi
|
|
148
|
+
docker run --rm \
|
|
149
|
+
--platform linux/${{ matrix.architecture }} \
|
|
150
|
+
-v "$PWD:/io" \
|
|
151
|
+
-e PYO3_USE_ABI3_FORWARD_COMPATIBILITY="${{ (matrix.python == '3.13') && '1' || '' }}" \
|
|
152
|
+
-e PYTHON_TAG="${PYTHON_TAG}" \
|
|
153
|
+
-w /io \
|
|
154
|
+
${DOCKER_IMAGE} \
|
|
155
|
+
/bin/bash -c "
|
|
156
|
+
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --profile minimal
|
|
157
|
+
source \$HOME/.cargo/env
|
|
158
|
+
/opt/python/\${PYTHON_TAG}-\${PYTHON_TAG}/bin/pip install maturin
|
|
159
|
+
/opt/python/\${PYTHON_TAG}-\${PYTHON_TAG}/bin/python -m maturin build \
|
|
160
|
+
--out dist \
|
|
161
|
+
--strip \
|
|
162
|
+
--release \
|
|
163
|
+
--manylinux 2_28 \
|
|
164
|
+
--interpreter /opt/python/\${PYTHON_TAG}-\${PYTHON_TAG}/bin/python
|
|
165
|
+
"
|
|
166
|
+
|
|
167
|
+
- name: Set up Python ${{ matrix.python }} (macOS/Windows)
|
|
168
|
+
if: matrix.os != 'ubuntu-latest'
|
|
169
|
+
uses: actions/setup-python@v5
|
|
170
|
+
with:
|
|
171
|
+
python-version: ${{ matrix.python }}
|
|
172
|
+
|
|
173
|
+
- name: Set up Rust (macOS/Windows)
|
|
174
|
+
if: matrix.os != 'ubuntu-latest'
|
|
175
|
+
uses: dtolnay/rust-toolchain@stable
|
|
176
|
+
|
|
177
|
+
- name: Install build tooling (macOS/Windows)
|
|
178
|
+
if: matrix.os != 'ubuntu-latest'
|
|
179
|
+
run: |
|
|
180
|
+
python -m pip install --upgrade pip
|
|
181
|
+
pip install maturin
|
|
182
|
+
|
|
183
|
+
- name: Build wheel (macOS/Windows)
|
|
184
|
+
if: matrix.os != 'ubuntu-latest'
|
|
185
|
+
env:
|
|
186
|
+
PYO3_USE_ABI3_FORWARD_COMPATIBILITY: ${{ (matrix.python == '3.13') && '1' || '' }}
|
|
187
|
+
run: maturin build --out dist --strip --release
|
|
188
|
+
|
|
189
|
+
- name: Upload wheel artifact
|
|
190
|
+
uses: actions/upload-artifact@v4
|
|
191
|
+
with:
|
|
192
|
+
name: wheel-${{ matrix.os }}-${{ matrix.architecture }}-py${{ matrix.python }}
|
|
193
|
+
path: dist/*.whl
|
|
194
|
+
if-no-files-found: error
|
|
195
|
+
retention-days: 7
|
|
196
|
+
|
|
197
|
+
build-sdist:
|
|
198
|
+
name: Build source distribution
|
|
199
|
+
runs-on: ubuntu-latest
|
|
200
|
+
permissions:
|
|
201
|
+
contents: read
|
|
202
|
+
steps:
|
|
203
|
+
- name: Checkout repository
|
|
204
|
+
uses: actions/checkout@v4
|
|
205
|
+
|
|
206
|
+
- name: Set up Python
|
|
207
|
+
uses: actions/setup-python@v5
|
|
208
|
+
with:
|
|
209
|
+
python-version: "3.12"
|
|
210
|
+
|
|
211
|
+
- name: Set up Rust
|
|
212
|
+
uses: dtolnay/rust-toolchain@stable
|
|
213
|
+
|
|
214
|
+
- name: Install build tooling
|
|
215
|
+
run: |
|
|
216
|
+
python -m pip install --upgrade pip
|
|
217
|
+
pip install maturin
|
|
218
|
+
|
|
219
|
+
- name: Build sdist
|
|
220
|
+
run: maturin sdist --out dist
|
|
221
|
+
|
|
222
|
+
- name: Upload sdist artifact
|
|
223
|
+
uses: actions/upload-artifact@v4
|
|
224
|
+
with:
|
|
225
|
+
name: sdist
|
|
226
|
+
path: dist/*.tar.gz
|
|
227
|
+
if-no-files-found: error
|
|
228
|
+
retention-days: 7
|
|
229
|
+
|
|
230
|
+
publish:
|
|
231
|
+
name: Publish to PyPI
|
|
232
|
+
needs: [build-wheels, build-sdist]
|
|
233
|
+
runs-on: ubuntu-latest
|
|
234
|
+
permissions:
|
|
235
|
+
contents: read
|
|
236
|
+
steps:
|
|
237
|
+
- name: Download all artifacts
|
|
238
|
+
uses: actions/download-artifact@v4
|
|
239
|
+
with:
|
|
240
|
+
pattern: wheel-*
|
|
241
|
+
merge-multiple: true
|
|
242
|
+
path: artifacts/wheels
|
|
243
|
+
|
|
244
|
+
- name: Download sdist
|
|
245
|
+
uses: actions/download-artifact@v4
|
|
246
|
+
with:
|
|
247
|
+
pattern: sdist
|
|
248
|
+
merge-multiple: true
|
|
249
|
+
path: artifacts/sdist
|
|
250
|
+
|
|
251
|
+
- name: Combine artifacts
|
|
252
|
+
shell: bash
|
|
253
|
+
run: |
|
|
254
|
+
set -e
|
|
255
|
+
|
|
256
|
+
# Debug: Show what we downloaded
|
|
257
|
+
echo "=== Artifacts structure ==="
|
|
258
|
+
find artifacts -type f -o -type d 2>/dev/null | sort || true
|
|
259
|
+
echo ""
|
|
260
|
+
|
|
261
|
+
# Create clean dist directory
|
|
262
|
+
mkdir -p dist
|
|
263
|
+
|
|
264
|
+
# Copy wheels from artifacts directory (handle all possible structures)
|
|
265
|
+
echo "=== Copying wheels ==="
|
|
266
|
+
find artifacts -name "*.whl" -type f -exec cp -v {} dist/ \; || true
|
|
267
|
+
|
|
268
|
+
# Copy sdist from artifacts directory (handle all possible structures)
|
|
269
|
+
echo "=== Copying sdist ==="
|
|
270
|
+
find artifacts -name "*.tar.gz" -type f -exec cp -v {} dist/ \; || true
|
|
271
|
+
|
|
272
|
+
# Verify we have files
|
|
273
|
+
echo ""
|
|
274
|
+
echo "=== Final dist contents ==="
|
|
275
|
+
ls -lah dist/ || echo "dist/ is empty or doesn't exist"
|
|
276
|
+
echo ""
|
|
277
|
+
echo "=== Distribution files ==="
|
|
278
|
+
find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) 2>/dev/null | sort || echo "No files found"
|
|
279
|
+
echo ""
|
|
280
|
+
|
|
281
|
+
# Count files
|
|
282
|
+
WHEEL_COUNT=$(find dist -name "*.whl" -type f 2>/dev/null | wc -l || echo "0")
|
|
283
|
+
SDIST_COUNT=$(find dist -name "*.tar.gz" -type f 2>/dev/null | wc -l || echo "0")
|
|
284
|
+
echo "Wheels: $WHEEL_COUNT"
|
|
285
|
+
echo "Source distributions: $SDIST_COUNT"
|
|
286
|
+
|
|
287
|
+
if [ "$WHEEL_COUNT" -eq 0 ] && [ "$SDIST_COUNT" -eq 0 ]; then
|
|
288
|
+
echo "ERROR: No distribution files found in dist/!"
|
|
289
|
+
echo "Checking artifacts directory:"
|
|
290
|
+
find artifacts -type f 2>/dev/null || true
|
|
291
|
+
exit 1
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
echo "✅ Successfully prepared $((WHEEL_COUNT + SDIST_COUNT)) distribution files"
|
|
295
|
+
|
|
296
|
+
- name: Publish to PyPI
|
|
297
|
+
env:
|
|
298
|
+
TWINE_USERNAME: __token__
|
|
299
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
300
|
+
run: |
|
|
301
|
+
set -e
|
|
302
|
+
pip install twine
|
|
303
|
+
|
|
304
|
+
# Check if we have files to upload
|
|
305
|
+
echo "=== Files to upload ==="
|
|
306
|
+
ls -lah dist/
|
|
307
|
+
echo ""
|
|
308
|
+
|
|
309
|
+
# Verify token is set (without exposing it)
|
|
310
|
+
if [ -z "$TWINE_PASSWORD" ]; then
|
|
311
|
+
echo "ERROR: PYPI_API_TOKEN secret is not set!"
|
|
312
|
+
exit 1
|
|
313
|
+
fi
|
|
314
|
+
|
|
315
|
+
echo "✅ PyPI token is configured"
|
|
316
|
+
echo ""
|
|
317
|
+
|
|
318
|
+
# Upload with verbose output for debugging
|
|
319
|
+
echo "=== Uploading to PyPI ==="
|
|
320
|
+
twine upload dist/* --verbose || {
|
|
321
|
+
echo ""
|
|
322
|
+
echo "❌ Upload failed. Common issues:"
|
|
323
|
+
echo " 1. Package version already exists on PyPI"
|
|
324
|
+
echo " 2. Invalid or expired PyPI API token"
|
|
325
|
+
echo " 3. Network/authentication error"
|
|
326
|
+
echo ""
|
|
327
|
+
echo "Check PyPI: https://pypi.org/project/rapsqlite/"
|
|
328
|
+
exit 1
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
echo ""
|
|
332
|
+
echo "✅ Successfully published to PyPI!"
|
|
333
|
+
|