Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .bandit
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Bandit configuration for py-pglite testing library
# These subprocess calls are necessary for managing npm/node processes
# and use fixed command arguments, not user input

skips:
- B603 # subprocess_without_shell_equals_true (safe with fixed args)
- B607 # start_process_with_partial_path (safe with npm/node)

exclude_dirs:
- examples
- tests
- node_modules
- dist
- build
- .git
- .pytest_cache
- .mypy_cache
- .ruff_cache

# We keep these checks:
# B404 - subprocess import (necessary for process management)
# B608 - SQL string formatting (using database metadata, not user input)
127 changes: 127 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# GitHub Actions Workflows

This directory contains the CI/CD workflows for py-pglite.

## 🔄 CI Workflow (`.github/workflows/ci.yml`)

**Triggers**: Push to `main`/`develop` branches and all pull requests

**Jobs**:

### 1. **Test Matrix**

- **Python versions**: 3.10, 3.11, 3.12, 3.13
- **Node.js versions**: 22
- **OS**: Ubuntu Latest

**Steps**:

- ✅ Code quality checks (Ruff linting & formatting)
- ✅ Type checking (MyPy)
- ✅ Test suite with coverage reporting
- ✅ Package build verification
- ✅ Coverage upload to Codecov

### 2. **Package Installation Test**

- Tests actual package installation from built wheel
- Verifies imports work correctly after installation

### 3. **Security Scanning**

- **Safety**: Scans dependencies for known vulnerabilities
- **Bandit**: Static security analysis of Python code

## 🚀 Release Workflow (`.github/workflows/release.yml`)

**Triggers**:

- Version tags (`v*`, e.g., `v0.2.0`)
- GitHub releases

**Jobs**:

### 1. **Pre-release Testing**

- Complete test suite
- Code quality verification
- Package build and installation test

### 2. **PyPI Release**

- **Trusted Publishing**: Secure, automated PyPI publishing
- **Environment**: Protected `pypi` environment
- **Permissions**: `id-token: write` for OIDC authentication

### 3. **GitHub Release Creation**

- Automatic GitHub release with built packages
- Release notes generation
- Pre-release detection (alpha/beta/rc versions)

## 🔧 Setup Requirements

### For Repository Maintainers

1. **PyPI Trusted Publishing Setup**:
- Go to [PyPI project settings](https://pypi.org/manage/project/py-pglite/settings/)
- Add GitHub as trusted publisher:
- Owner: `wey-gu`
- Repository: `py-pglite`
- Workflow: `release.yml`

2. **GitHub Environment Configuration**:
- Create `pypi` environment in repository settings
- Configure protection rules (optional)

3. **Codecov Integration**:
- Repository automatically uploads coverage
- No additional setup required for public repos

## 📋 Coverage Configuration

Coverage settings are in `pyproject.toml`:

```toml
[tool.coverage.run]
source = ["py_pglite"]
omit = ["*/tests/*", "*/test_*", "examples/*"]

[tool.coverage.report]
show_missing = true
precision = 2
```

## 🏃‍♂️ Local Development

Run the same checks locally:

```bash
# Full CI pipeline
ruff check py_pglite/
ruff format --check py_pglite/
mypy py_pglite/
pytest examples/ --cov=py_pglite --cov-report=term-missing -v

# Package build test
python -m build
twine check dist/*
```

## 🔖 Making a Release

1. Update version in `py_pglite/__init__.py`
2. Commit and push to main
3. Create and push version tag:

```bash
git tag v0.2.0
git push origin v0.2.0
```

4. GitHub Actions automatically handles the rest!

## 📊 Workflow Status

- [![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)
- [![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)
118 changes: 118 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: CI

on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
node-version: ["22"]
fail-fast: false

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
pip install coverage[toml] pytest-cov

- name: Install type stubs
run: |
pip install types-psutil

- name: Lint with Ruff
run: |
ruff check py_pglite/
ruff format --check py_pglite/

- name: Type check with MyPy
run: |
mypy py_pglite/

- name: Test package build
run: |
pip install build
python -m build

- name: Run tests with coverage
run: |
pytest examples/ --cov=py_pglite --cov-report=xml --cov-report=term-missing -v

- uses: codecov/codecov-action@v5
with:
fail_ci_if_error: true
files: ./coverage.xml
name: codecov-umbrella
verbose: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

test-package:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Test package installation
run: |
python -m pip install --upgrade pip build
python -m build
pip install dist/*.whl

- name: Test installed package
run: |
python -c "import py_pglite; print(f'Successfully imported py-pglite {py_pglite.__version__}')"
python -c "from py_pglite import PGliteManager, PGliteConfig; print('All imports working')"

security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install safety bandit[toml]

- name: Security scan with Safety
run: |
pip freeze | safety check --stdin

- name: Security scan with Bandit
run: |
bandit -r py_pglite/ -c .bandit -f json -o bandit-report.json || true
bandit -r py_pglite/ -c .bandit
Loading