Skip to content

Commit e8f089d

Browse files
authored
Merge pull request #2 from wey-gu/dev
ci: build and release workflow
2 parents 8a1d55c + 2c4f1e7 commit e8f089d

File tree

11 files changed

+843
-39
lines changed

11 files changed

+843
-39
lines changed

.bandit

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Bandit configuration for py-pglite testing library
2+
# These subprocess calls are necessary for managing npm/node processes
3+
# and use fixed command arguments, not user input
4+
5+
skips:
6+
- B603 # subprocess_without_shell_equals_true (safe with fixed args)
7+
- B607 # start_process_with_partial_path (safe with npm/node)
8+
9+
exclude_dirs:
10+
- examples
11+
- tests
12+
- node_modules
13+
- dist
14+
- build
15+
- .git
16+
- .pytest_cache
17+
- .mypy_cache
18+
- .ruff_cache
19+
20+
# We keep these checks:
21+
# B404 - subprocess import (necessary for process management)
22+
# B608 - SQL string formatting (using database metadata, not user input)

.github/README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# GitHub Actions Workflows
2+
3+
This directory contains the CI/CD workflows for py-pglite.
4+
5+
## 🔄 CI Workflow (`.github/workflows/ci.yml`)
6+
7+
**Triggers**: Push to `main`/`develop` branches and all pull requests
8+
9+
**Jobs**:
10+
11+
### 1. **Test Matrix**
12+
13+
- **Python versions**: 3.10, 3.11, 3.12, 3.13
14+
- **Node.js versions**: 22
15+
- **OS**: Ubuntu Latest
16+
17+
**Steps**:
18+
19+
- ✅ Code quality checks (Ruff linting & formatting)
20+
- ✅ Type checking (MyPy)
21+
- ✅ Test suite with coverage reporting
22+
- ✅ Package build verification
23+
- ✅ Coverage upload to Codecov
24+
25+
### 2. **Package Installation Test**
26+
27+
- Tests actual package installation from built wheel
28+
- Verifies imports work correctly after installation
29+
30+
### 3. **Security Scanning**
31+
32+
- **Safety**: Scans dependencies for known vulnerabilities
33+
- **Bandit**: Static security analysis of Python code
34+
35+
## 🚀 Release Workflow (`.github/workflows/release.yml`)
36+
37+
**Triggers**:
38+
39+
- Version tags (`v*`, e.g., `v0.2.0`)
40+
- GitHub releases
41+
42+
**Jobs**:
43+
44+
### 1. **Pre-release Testing**
45+
46+
- Complete test suite
47+
- Code quality verification
48+
- Package build and installation test
49+
50+
### 2. **PyPI Release**
51+
52+
- **Trusted Publishing**: Secure, automated PyPI publishing
53+
- **Environment**: Protected `pypi` environment
54+
- **Permissions**: `id-token: write` for OIDC authentication
55+
56+
### 3. **GitHub Release Creation**
57+
58+
- Automatic GitHub release with built packages
59+
- Release notes generation
60+
- Pre-release detection (alpha/beta/rc versions)
61+
62+
## 🔧 Setup Requirements
63+
64+
### For Repository Maintainers
65+
66+
1. **PyPI Trusted Publishing Setup**:
67+
- Go to [PyPI project settings](https://pypi.org/manage/project/py-pglite/settings/)
68+
- Add GitHub as trusted publisher:
69+
- Owner: `wey-gu`
70+
- Repository: `py-pglite`
71+
- Workflow: `release.yml`
72+
73+
2. **GitHub Environment Configuration**:
74+
- Create `pypi` environment in repository settings
75+
- Configure protection rules (optional)
76+
77+
3. **Codecov Integration**:
78+
- Repository automatically uploads coverage
79+
- No additional setup required for public repos
80+
81+
## 📋 Coverage Configuration
82+
83+
Coverage settings are in `pyproject.toml`:
84+
85+
```toml
86+
[tool.coverage.run]
87+
source = ["py_pglite"]
88+
omit = ["*/tests/*", "*/test_*", "examples/*"]
89+
90+
[tool.coverage.report]
91+
show_missing = true
92+
precision = 2
93+
```
94+
95+
## 🏃‍♂️ Local Development
96+
97+
Run the same checks locally:
98+
99+
```bash
100+
# Full CI pipeline
101+
ruff check py_pglite/
102+
ruff format --check py_pglite/
103+
mypy py_pglite/
104+
pytest examples/ --cov=py_pglite --cov-report=term-missing -v
105+
106+
# Package build test
107+
python -m build
108+
twine check dist/*
109+
```
110+
111+
## 🔖 Making a Release
112+
113+
1. Update version in `py_pglite/__init__.py`
114+
2. Commit and push to main
115+
3. Create and push version tag:
116+
117+
```bash
118+
git tag v0.2.0
119+
git push origin v0.2.0
120+
```
121+
122+
4. GitHub Actions automatically handles the rest!
123+
124+
## 📊 Workflow Status
125+
126+
- [![CI](https://github.com/wey-gu/py-pglite/actions/workflows/ci.yml/badge.svg)](https://github.com/wey-gu/py-pglite/actions/workflows/ci.yml)
127+
- [![Release](https://github.com/wey-gu/py-pglite/actions/workflows/release.yml/badge.svg)](https://github.com/wey-gu/py-pglite/actions/workflows/release.yml)

.github/workflows/ci.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ main ]
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
python-version: ["3.10", "3.11", "3.12", "3.13"]
16+
node-version: ["22"]
17+
fail-fast: false
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Set up Python ${{ matrix.python-version }}
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: ${{ matrix.python-version }}
26+
27+
- name: Set up Node.js ${{ matrix.node-version }}
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: ${{ matrix.node-version }}
31+
32+
- name: Install Python dependencies
33+
run: |
34+
python -m pip install --upgrade pip
35+
pip install -e ".[dev]"
36+
pip install coverage[toml] pytest-cov
37+
38+
- name: Install type stubs
39+
run: |
40+
pip install types-psutil
41+
42+
- name: Lint with Ruff
43+
run: |
44+
ruff check py_pglite/
45+
ruff format --check py_pglite/
46+
47+
- name: Type check with MyPy
48+
run: |
49+
mypy py_pglite/
50+
51+
- name: Test package build
52+
run: |
53+
pip install build
54+
python -m build
55+
56+
- name: Run tests with coverage
57+
run: |
58+
pytest examples/ --cov=py_pglite --cov-report=xml --cov-report=term-missing -v
59+
60+
- uses: codecov/codecov-action@v5
61+
with:
62+
fail_ci_if_error: true
63+
files: ./coverage.xml
64+
name: codecov-umbrella
65+
verbose: true
66+
env:
67+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
68+
69+
test-package:
70+
runs-on: ubuntu-latest
71+
needs: test
72+
steps:
73+
- uses: actions/checkout@v4
74+
75+
- name: Set up Python
76+
uses: actions/setup-python@v5
77+
with:
78+
python-version: "3.11"
79+
80+
- name: Set up Node.js
81+
uses: actions/setup-node@v4
82+
with:
83+
node-version: "20"
84+
85+
- name: Test package installation
86+
run: |
87+
python -m pip install --upgrade pip build
88+
python -m build
89+
pip install dist/*.whl
90+
91+
- name: Test installed package
92+
run: |
93+
python -c "import py_pglite; print(f'Successfully imported py-pglite {py_pglite.__version__}')"
94+
python -c "from py_pglite import PGliteManager, PGliteConfig; print('All imports working')"
95+
96+
security:
97+
runs-on: ubuntu-latest
98+
steps:
99+
- uses: actions/checkout@v4
100+
101+
- name: Set up Python
102+
uses: actions/setup-python@v5
103+
with:
104+
python-version: "3.11"
105+
106+
- name: Install dependencies
107+
run: |
108+
python -m pip install --upgrade pip
109+
pip install safety bandit[toml]
110+
111+
- name: Security scan with Safety
112+
run: |
113+
pip freeze | safety check --stdin
114+
115+
- name: Security scan with Bandit
116+
run: |
117+
bandit -r py_pglite/ -c .bandit -f json -o bandit-report.json || true
118+
bandit -r py_pglite/ -c .bandit

0 commit comments

Comments
 (0)