Skip to content
Draft
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
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ jobs:
- if: matrix.config == 'pytest-benchmark-5'
name: Install pytest-benchmark 5.0.0
run: uv pip install pytest-benchmark~=5.0.0
- name: Run tests
run: uv run --no-sync pytest -vs
- name: Run pytest-codspeed tests
run: uv run --no-sync pytest pytest-codspeed/tests/ --ignore=pytest-codspeed/tests/benchmarks --ignore=pytest-codspeed/tests/examples -vs
- name: Run asv-codspeed tests
run: uv run --no-sync pytest asv-codspeed/tests/ -vs

all-checks:
runs-on: ubuntu-latest
Expand Down
37 changes: 33 additions & 4 deletions .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ env:
SHARDS: 4

jobs:
benchmarks:
pytest-benchmarks:
strategy:
matrix:
shard: [1, 2, 3, 4]
mode: ["instrumentation", "walltime"]

name: "Run ${{ matrix.mode }} benchmarks (Shard #${{ matrix.shard }})"
name: "pytest ${{ matrix.mode }} benchmarks (Shard #${{ matrix.shard }})"
runs-on: ${{ matrix.mode == 'instrumentation' && 'ubuntu-24.04' || 'codspeed-macro' }}
steps:
- uses: actions/checkout@v5
Expand All @@ -37,12 +37,41 @@ jobs:
uses: CodSpeedHQ/action@main
with:
mode: ${{ matrix.mode }}
run: uv run pytest tests/benchmarks/ --codspeed --test-group=${{ matrix.shard }} --test-group-count=${{ env.SHARDS }}
run: uv run pytest pytest-codspeed/tests/benchmarks/ --codspeed --ignore=pytest-codspeed/tests/benchmarks/TheAlgorithms --test-group=${{ matrix.shard }} --test-group-count=${{ env.SHARDS }}
token: ${{ secrets.CODSPEED_TOKEN }}

asv-benchmarks:
strategy:
matrix:
mode: ["instrumentation", "walltime"]

name: "asv ${{ matrix.mode }} benchmarks"
runs-on: ${{ matrix.mode == 'instrumentation' && 'ubuntu-24.04' || 'codspeed-macro' }}
steps:
- uses: actions/checkout@v5
with:
submodules: "recursive"
- uses: astral-sh/setup-uv@v7
- uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install valgrind -y
uv sync --dev
sudo apt-get remove valgrind -y
- name: Run ASV benchmarks
uses: CodSpeedHQ/action@main
with:
mode: ${{ matrix.mode }}
run: uv run asv-codspeed run asv-codspeed/tests/sample_benchmarks
token: ${{ secrets.CODSPEED_TOKEN }}

all-checks:
runs-on: ubuntu-latest
steps:
- run: echo "All CI checks passed."
needs:
- benchmarks
- pytest-benchmarks
- asv-benchmarks
52 changes: 37 additions & 15 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ permissions:
contents: write

jobs:
build-wheels:
build-codspeed-wheels:
strategy:
matrix:
platform:
Expand All @@ -25,19 +25,20 @@ jobs:
- uses: actions/checkout@v5
with:
submodules: true
- name: Build wheels
- name: Build codspeed wheels
uses: pypa/cibuildwheel@v3.2.1
env:
CIBW_ARCHS: ${{ matrix.platform.arch }}
with:
package-dir: codspeed
output-dir: wheelhouse

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform.arch }}
name: codspeed-wheels-${{ matrix.platform.arch }}
path: wheelhouse/*.whl

build-py3-none-any:
build-codspeed-py3-none-any:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
Expand All @@ -47,17 +48,17 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Build py3-none-any wheel
- name: Build codspeed py3-none-any wheel
env:
PYTEST_CODSPEED_SKIP_EXTENSION_BUILD: "1"
run: uv build --wheel --out-dir dist/
CODSPEED_SKIP_EXTENSION_BUILD: "1"
run: uv build --wheel --out-dir dist/ --package codspeed

- uses: actions/upload-artifact@v4
with:
name: wheels-py3-none-any
name: codspeed-wheels-py3-none-any
path: dist/*.whl

build-sdist:
build-pytest-codspeed:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
Expand All @@ -67,19 +68,40 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Build the source dist
run: uv build --sdist --out-dir dist/
- name: Build pytest-codspeed wheel
run: uv build --wheel --out-dir dist/ --package pytest-codspeed
- name: Build pytest-codspeed sdist
run: uv build --sdist --out-dir dist/ --package pytest-codspeed

- uses: actions/upload-artifact@v4
with:
name: sdist
name: pytest-codspeed-dist
path: dist/*

build-codspeed-sdist:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
with:
submodules: true
- uses: astral-sh/setup-uv@v7
- uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Build the codspeed source dist
run: uv build --sdist --out-dir dist/ --package codspeed

- uses: actions/upload-artifact@v4
with:
name: codspeed-sdist
path: dist/*.tar.gz

publish:
needs:
- build-wheels
- build-py3-none-any
- build-sdist
- build-codspeed-wheels
- build-codspeed-py3-none-any
- build-codspeed-sdist
- build-pytest-codspeed

runs-on: ubuntu-24.04
steps:
Expand Down
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "tests/benchmarks/TheAlgorithms"]
path = tests/benchmarks/TheAlgorithms
path = pytest-codspeed/tests/benchmarks/TheAlgorithms
url = git@github.com:TheAlgorithms/Python.git
[submodule "src/pytest_codspeed/instruments/hooks/instrument-hooks"]
path = src/pytest_codspeed/instruments/hooks/instrument-hooks
path = codspeed/src/codspeed/instruments/hooks/instrument-hooks
url = https://github.com/CodSpeedHQ/instrument-hooks
29 changes: 29 additions & 0 deletions asv-codspeed/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[project]
name = "asv-codspeed"
version = "0.1.0"
description = "Run ASV (airspeed velocity) benchmarks with CodSpeed instrumentation"
license = "MIT"
requires-python = ">=3.9"
authors = [{ name = "Arthur Pastel", email = "arthur@codspeed.io" }]
keywords = ["codspeed", "benchmark", "performance", "asv", "airspeed-velocity"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Topic :: Software Development :: Testing",
"Topic :: System :: Benchmark",
]
dependencies = [
"codspeed>=0.1.0",
"rich>=13.8.1",
]

[project.scripts]
asv-codspeed = "asv_codspeed.__main__:main"

[build-system]
requires = ["setuptools >= 61"]
build-backend = "setuptools.build_meta"

[tool.setuptools.packages.find]
where = ["src"]
2 changes: 2 additions & 0 deletions asv-codspeed/src/asv_codspeed/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__version__ = "0.1.0"
__semver_version__ = "0.1.0"
97 changes: 97 additions & 0 deletions asv-codspeed/src/asv_codspeed/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from __future__ import annotations

import argparse
import sys
from pathlib import Path

from asv_codspeed import __version__
from asv_codspeed.runner import run_benchmarks
from codspeed.instruments import MeasurementMode


def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
prog="asv-codspeed",
description="Run ASV benchmarks with CodSpeed instrumentation",
)
parser.add_argument(
"--version",
action="version",
version=f"asv-codspeed {__version__}",
)

subparsers = parser.add_subparsers(dest="command", required=True)

# 'run' subcommand
run_parser = subparsers.add_parser("run", help="Run ASV benchmarks")
run_parser.add_argument(
"benchmark_dir",
type=Path,
nargs="?",
default=Path("benchmarks"),
help="Path to benchmark directory (default: benchmarks/)",
)
run_parser.add_argument(
"--mode",
choices=[m.value for m in MeasurementMode],
default=None,
help="Measurement mode (default: walltime locally, simulation in CI)",
)
run_parser.add_argument(
"--warmup-time",
type=float,
default=None,
help="Warmup time in seconds (walltime mode only)",
)
run_parser.add_argument(
"--max-time",
type=float,
default=None,
help="Maximum benchmark time in seconds",
)
run_parser.add_argument(
"--max-rounds",
type=int,
default=None,
help="Maximum number of benchmark rounds",
)
run_parser.add_argument(
"--bench",
type=str,
default=None,
help="Regex pattern to filter benchmarks",
)

args = parser.parse_args(argv)

if args.command == "run":
import os

# Determine mode
if args.mode:
mode = MeasurementMode(args.mode)
elif os.environ.get("CODSPEED_ENV") is not None:
if os.environ.get("CODSPEED_RUNNER_MODE") == "walltime":
mode = MeasurementMode.WallTime
else:
mode = MeasurementMode.Simulation
else:
mode = MeasurementMode.WallTime

profile_folder = os.environ.get("CODSPEED_PROFILE_FOLDER")

return run_benchmarks(
benchmark_dir=args.benchmark_dir,
mode=mode,
warmup_time=args.warmup_time,
max_time=args.max_time,
max_rounds=args.max_rounds,
bench_filter=args.bench,
profile_folder=Path(profile_folder) if profile_folder else None,
)

return 1


if __name__ == "__main__":
sys.exit(main())
Loading
Loading