Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d84b43c
Add stepped frame-range parsing and %x formatting support
rsgalloway Jul 20, 2026
688e7fc
Adds small stepped on-disk fixture in tests/files
rsgalloway Jul 21, 2026
98cf952
Add coarse regression performance test
rsgalloway Jul 21, 2026
08aeeeb
Add performance module with three coarse regression tests
rsgalloway Jul 21, 2026
1c248e9
Adds benchmarks workflow and scripts
rsgalloway Jul 21, 2026
be5a899
Add benchmark tooling and GitHub Pages docs publishing workflow
rsgalloway Jul 21, 2026
f0dd177
Add compact %x formatting and negative frame filename support
rsgalloway Jul 21, 2026
99f2ba6
Add extended syntax support with negative-frame CLI coverage and rele…
rsgalloway Jul 21, 2026
71410b6
Address PR comments
rsgalloway Jul 21, 2026
e1ef7aa
Consolidate benchmarks into a single runner and run smoke benchmarks …
rsgalloway Jul 21, 2026
969ded6
Make negative frame support opt-in and improve benchmark provenance
rsgalloway Jul 24, 2026
e18035b
Fixed the benchmark comparison edge case
rsgalloway Jul 24, 2026
a8c812e
Add PR benchmark regression checks with mixed synthetic datasets
rsgalloway Jul 24, 2026
ea80a50
Fix PR benchmark workflow baseline checkout and failure handling
rsgalloway Jul 24, 2026
4769219
Create baseline scripts dir before copying benchmark runner
rsgalloway Jul 24, 2026
1a1fda4
Use percentage and absolute thresholds for PR benchmark regressions
rsgalloway Jul 24, 2026
fa8793d
Limit PR benchmark runs to pyseq and benchmark workflow changes
rsgalloway Jul 24, 2026
dbde8ec
Limit unit test runs to code, tests, and packaging changes
rsgalloway Jul 24, 2026
514dcd0
Defer unused sequence format calculations in lss output path
rsgalloway Jul 24, 2026
135084d
Tighten benchmark regression gates and defer non-lss import overhead
rsgalloway Jul 24, 2026
ce3e5b6
Limit negative-frame test env usage and remove unused util import
rsgalloway Jul 24, 2026
47c6003
Refresh seq docstrings and update library copyright headers
rsgalloway Jul 24, 2026
26427a9
Add black, flake8, isort, and mccabe quality checks with optional pre…
rsgalloway Jul 24, 2026
c4ea4e5
Pin code quality tool versions for consistent local and CI checks
rsgalloway Jul 24, 2026
3c55282
Fix negative-frame test state and harden benchmark regression gating
rsgalloway Jul 24, 2026
8a69cef
Adds lazy import explanatory comment
rsgalloway Jul 24, 2026
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
18 changes: 18 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[flake8]
max-line-length = 100
max-complexity = 35
exclude =
.git,
__pycache__,
.venv,
venv,
build,
dist,
baseline
extend-ignore =
E203,
E501,
W503
per-file-ignores =
lib/pyseq/__init__.py:F401,F403
tests/test_pyseq.py:E402
244 changes: 244 additions & 0 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
name: benchmarks

on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
- converted_to_draft
paths:
- "lib/pyseq/**"
- "scripts/benchmark.py"
- ".github/workflows/benchmarks.yml"
workflow_dispatch:
inputs:
profile:
description: Benchmark profile to run
required: false
default: smoke
type: choice
options:
- smoke
- full
schedule:
- cron: "0 9 * * 1"

permissions:
contents: read
pull-requests: write

jobs:
benchmark-pr:
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04

steps:
- name: Check out candidate branch
uses: actions/checkout@v4
with:
fetch-depth: 0

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

- name: Install package dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"

- name: Check out baseline branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.sha }}
path: baseline

- name: Run baseline benchmarks
working-directory: baseline
run: |
mkdir -p scripts
cp "$GITHUB_WORKSPACE/scripts/benchmark.py" scripts/benchmark.py
python scripts/benchmark.py --scenarios contiguous,mixed --json baseline-benchmark.json > baseline-benchmark.md

- name: Run candidate benchmarks
run: |
python scripts/benchmark.py --scenarios contiguous,mixed --json candidate-benchmark.json > candidate-benchmark.md

- name: Compare benchmark runs
id: compare
if: success() || hashFiles('baseline/baseline-benchmark.json', 'candidate-benchmark.json') != ''
run: |
set +e
python scripts/benchmark.py \
--compare baseline/baseline-benchmark.json candidate-benchmark.json \
--json benchmark-compare.json \
--fail-on-regression-pct 3 \
--fail-on-regression-s 0.005 > benchmark-compare.md
status=$?
echo "exit_code=$status" >> "$GITHUB_OUTPUT"
if [ "$status" -eq 0 ]; then
echo "threshold_exceeded=false" >> "$GITHUB_OUTPUT"
else
echo "threshold_exceeded=true" >> "$GITHUB_OUTPUT"
fi
exit 0

- name: Write benchmark summaries
if: always()
shell: bash
run: |
{
if [ -f candidate-benchmark.md ]; then
echo "## Candidate benchmark"
cat candidate-benchmark.md
echo
fi
if [ -f baseline/baseline-benchmark.md ]; then
echo "## Baseline benchmark"
cat baseline/baseline-benchmark.md
echo
fi
if [ -f benchmark-compare.md ]; then
echo "## Comparison"
cat benchmark-compare.md
else
echo "## Comparison"
echo "Benchmark comparison did not run to completion."
fi
} >> "$GITHUB_STEP_SUMMARY"

- name: Post pull request benchmark comment
if: always() && hashFiles('benchmark-compare.md') != ''
uses: actions/github-script@v7
env:
BENCHMARK_COMPARE_PATH: benchmark-compare.md
BENCHMARK_THRESHOLD_EXCEEDED: ${{ steps.compare.outputs.threshold_exceeded }}
with:
script: |
const fs = require("fs");
const marker = "<!-- pyseq-benchmark-comment -->";
const compare = fs.readFileSync(process.env.BENCHMARK_COMPARE_PATH, "utf8");
const failed = process.env.BENCHMARK_THRESHOLD_EXCEEDED === "true";
const header = failed
? "## Benchmark Regression Alert"
: "## Benchmark Comparison";
const status = failed
? "_Regression guard exceeded the +3.00% and +0.005s thresholds._"
: "_No benchmark exceeded the +3.00% and +0.005s regression thresholds._";
const body = `${marker}\n${header}\n\n${status}\n\n${compare}`;

const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number,
per_page: 100,
});

const existing = comments.find((comment) => comment.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body,
});
}

- name: Upload benchmark artifacts
if: always()
shell: bash
run: |
mkdir -p benchmark-artifacts/baseline
if [ -f baseline/baseline-benchmark.json ]; then
cp baseline/baseline-benchmark.json benchmark-artifacts/baseline/
fi
if [ -f baseline/baseline-benchmark.md ]; then
cp baseline/baseline-benchmark.md benchmark-artifacts/baseline/
fi
if [ -d baseline/tmp/benchmarks/profiles ]; then
mkdir -p benchmark-artifacts/baseline/tmp/benchmarks
cp -R baseline/tmp/benchmarks/profiles benchmark-artifacts/baseline/tmp/benchmarks/
fi

- name: Publish benchmark artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-results-pr-${{ github.event.pull_request.number }}
path: |
candidate-benchmark.json
candidate-benchmark.md
benchmark-compare.json
benchmark-compare.md
tmp/benchmarks/profiles
benchmark-artifacts/baseline
if-no-files-found: warn

- name: Enforce regression threshold
if: always() && steps.compare.outputs.threshold_exceeded == 'true'
run: |
echo "Benchmark regression exceeded the +3.00% and +0.005s thresholds."
exit 1

benchmark-branch:
if: github.event_name != 'pull_request'
runs-on: ubuntu-24.04

steps:
- name: Check out repository
uses: actions/checkout@v4

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

- name: Install package
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"

- name: Select profile
id: profile
shell: bash
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "value=${{ inputs.profile }}" >> "$GITHUB_OUTPUT"
elif [ "${{ github.event_name }}" = "schedule" ]; then
echo "value=full" >> "$GITHUB_OUTPUT"
else
echo "value=smoke" >> "$GITHUB_OUTPUT"
fi

- name: Run benchmarks
run: |
if [ "${{ steps.profile.outputs.value }}" = "full" ]; then
python scripts/benchmark.py --full --json benchmark.json > benchmark.md
else
python scripts/benchmark.py --json benchmark.json > benchmark.md
fi

- name: Write benchmark summary
run: |
cat benchmark.md >> "$GITHUB_STEP_SUMMARY"

- name: Upload benchmark artifacts
uses: actions/upload-artifact@v4
with:
name: benchmark-results-${{ steps.profile.outputs.value }}
path: |
benchmark.json
benchmark.md
tmp/benchmarks/profiles
72 changes: 72 additions & 0 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: publish-docs

on:
push:
branches:
- master
- main
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-24.04

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Configure Pages
uses: actions/configure-pages@v5

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

- name: Install package
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"

- name: Generate benchmark report
run: |
python scripts/benchmark.py --json benchmark.json > benchmark.md

- name: Build Jekyll source tree
run: |
python scripts/build_pages_site.py \
--output _site_src \
--benchmark-summary benchmark.md \
--benchmark-json benchmark.json

- name: Build site with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: _site_src
destination: _site

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: _site

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-24.04
needs: build

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
40 changes: 40 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,50 @@ on:
push:
branches:
- main
paths:
- "lib/pyseq/**"
- "tests/**"
- "scripts/**"
- "pyproject.toml"
- ".flake8"
- ".github/workflows/tests.yml"
pull_request:
paths:
- "lib/pyseq/**"
- "tests/**"
- "scripts/**"
- "pyproject.toml"
- ".flake8"
- ".github/workflows/tests.yml"
workflow_dispatch:

jobs:
quality:
runs-on: ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v4

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

- name: Install package and quality dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"

- name: Check import ordering
run: python -m isort --check-only --diff lib/pyseq tests scripts

- name: Check black formatting
run: python -m black --check lib/pyseq tests scripts

- name: Run flake8 and mccabe checks
run: python -m flake8 lib/pyseq tests scripts

test:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ tmp/
venv*/
.vscode/
pyseq.egg-info/
default.env
default.env
.codex
.agents/
.pytest_cache/
Loading
Loading