diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4088f5d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: Lint and type-check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + - name: Install dependencies + run: uv sync --group dev + - name: Lint + run: uv run ruff check src/ tests/ + - name: Type-check + run: uv run mypy src/ + + test: + name: Test (Python ${{ matrix.python-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.12', '3.13'] + steps: + - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + - name: Run tests (including doctests) + run: uv run --python ${{ matrix.python-version }} --group dev pytest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..cd6bbc0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,45 @@ +name: Release + +on: + release: + types: [published] + +jobs: + test: + name: Test, lint, type-check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v5 + - name: Install dependencies + run: uv sync --group dev + - name: Run tests (including doctests) + run: uv run pytest + - name: Lint + run: uv run ruff check src/ tests/ + - name: Type-check + run: uv run mypy src/ + + publish: + name: Build and publish to PyPI + needs: test + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/project/framesmith/ + permissions: + id-token: write # required for PyPI Trusted Publishing (OIDC); no token needed + steps: + - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v5 + - name: Build sdist and wheel + run: uv build + - name: Smoke-test the built wheel + run: | + python3 -m venv /tmp/smoke + /tmp/smoke/bin/pip install --quiet dist/*.whl + /tmp/smoke/bin/python -c "import framesmith; assert hasattr(framesmith, 'compose_column'); print('wheel imports OK')" + - name: Publish to PyPI (Trusted Publishing) + run: uv publish --trusted-publishing always diff --git a/README.md b/README.md index 200728f..a4db3f0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # framesmith +[![CI](https://github.com/andrewjordan3/framesmith/actions/workflows/ci.yml/badge.svg)](https://github.com/andrewjordan3/framesmith/actions/workflows/ci.yml) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Python](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/) [![Polars](https://img.shields.io/badge/polars-1.0%2B-CD792C.svg)](https://pola.rs) @@ -62,7 +63,11 @@ df_snake = raw.with_columns( ## Installation -`framesmith` is not yet on PyPI — install from source: +```bash +pip install framesmith +``` + +Or install from source: ```bash git clone https://github.com/andrewjordan3/framesmith.git