Skip to content

feat: add Python library API for programmatic use #107

feat: add Python library API for programmatic use

feat: add Python library API for programmatic use #107

Workflow file for this run

name: CI
on:
push:
branches: [main]
# Skip CI for docs-only and metadata changes on push to main
paths-ignore:
- '**.md'
- 'docs/**'
- 'examples/**'
- '.github/**'
- '!.github/workflows/**'
- '.gitignore'
pull_request:
branches: [main]
# Always run on PRs (for review), but individual jobs can skip if needed
# Cancel in-progress runs when a new workflow with the same group name starts
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
# Set read-only permissions by default
permissions:
contents: read
jobs:
# Separate lint job - runs once instead of on every matrix combination
lint:
name: Lint and format check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6
with:
python-version: "3.14"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install uv
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
- name: Install dependencies
run: uv sync --extra dev
- name: Run ruff check
run: uv run ruff check peakbagger tests
- name: Run ruff format check
run: uv run ruff format --check peakbagger tests
- name: Run ty
run: uvx ty check peakbagger
continue-on-error: true
test:
name: Test on ${{ matrix.os }} - Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.12", "3.13", "3.14"]
include:
# Smoke tests on macOS and Windows with latest Python
- os: macos-latest
python-version: "3.14"
- os: windows-latest
python-version: "3.14"
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml
- name: Install uv
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
- name: Install dependencies
run: uv sync --extra dev
- name: Run tests with coverage
run: uv run pytest --cov=peakbagger --cov-report=xml --cov-report=term
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14'
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
fail_ci_if_error: false
validate-pr-title:
name: Validate PR title
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Validate PR title follows conventional commit format
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
style
refactor
perf
test
chore
ci
build
requireScope: false
subjectPattern: ^.+$
subjectPatternError: |
The subject "{subject}" found in the PR title "{title}"
must not be empty.
validateSingleCommit: false
ignoreLabels: |
bot
dependencies
# Sentinel job that always runs - use this as the required status check
required-checks:
name: Required Checks
runs-on: ubuntu-latest
needs: [lint, test, validate-pr-title]
if: always()
steps:
- name: Check results
run: |
lint_result="${{ needs.lint.result }}"
test_result="${{ needs.test.result }}"
pr_title_result="${{ needs.validate-pr-title.result }}"
echo "Lint result: $lint_result"
echo "Test result: $test_result"
echo "PR title validation result: $pr_title_result"
# Lint must always pass
if [[ "$lint_result" == "failure" ]]; then
echo "❌ Lint failed"
exit 1
elif [[ "$lint_result" == "cancelled" ]]; then
echo "❌ Lint was cancelled"
exit 1
fi
# Tests must always pass
if [[ "$test_result" == "failure" ]]; then
echo "❌ Tests failed"
exit 1
elif [[ "$test_result" == "cancelled" ]]; then
echo "❌ Tests were cancelled"
exit 1
fi
# PR title validation must pass (if it ran)
if [[ "$pr_title_result" == "failure" ]]; then
echo "❌ PR title validation failed"
exit 1
elif [[ "$pr_title_result" == "cancelled" ]]; then
echo "❌ PR title validation was cancelled"
exit 1
fi
echo "✅ All required checks passed"