Skip to content
Open
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
5 changes: 3 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ python -m pymarkdown -c .pymarkdown.json scan **/*.md
Install the linter via the dev dependencies:

```bash
python -m pip install -r dev-requirements.txt
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group lint
```

## Building and Testing
Expand Down Expand Up @@ -203,7 +204,7 @@ activate or modify the per-app `.venv` directories created by Nox.
- `azure-functions-durable/` — Azure Durable Functions provider source
- `examples/` — example orchestrations (see `examples/README.md`)
- `tests/` — test suite
- `dev-requirements.txt` — development dependencies
- `pyproject.toml` `[dependency-groups]` — development and CI tooling dependencies

## External Dependencies

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/durabletask-azurefunctions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
python-version: 3.13
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox
- name: Run lint checks
run: nox -s lint

Expand All @@ -47,8 +47,8 @@ jobs:

- name: Install Nox
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox

- name: Run unit tests
run: nox -s functions_unit-${{ matrix.python-version }}
Expand Down Expand Up @@ -89,8 +89,8 @@ jobs:

- name: Install nox
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox

- name: Run end-to-end tests
# nox provisions each sample app's in-app virtual environment (a link to
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/durabletask-azuremanaged.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
python-version: "3.15"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox
- name: Run lint checks
run: nox -s lint

Expand All @@ -47,8 +47,8 @@ jobs:

- name: Install Nox
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox

- name: Run the tests
run: nox -s azuremanaged_tests-${{ matrix.python-version }}
8 changes: 4 additions & 4 deletions .github/workflows/durabletask.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
python-version: "3.15"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox
- name: Run lint checks
run: nox -s lint

Expand Down Expand Up @@ -61,8 +61,8 @@ jobs:

- name: Install Nox
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox

- name: Pytest unit tests
run: nox -s core_tests-${{ matrix.python-version }}
8 changes: 4 additions & 4 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ jobs:

- name: Install packages and dependencies
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox

- name: Run pyright (strict, Python 3.11)
run: nox -s typecheck_core
Expand All @@ -48,8 +48,8 @@ jobs:

- name: Install packages and dependencies
run: |
python -m pip install --upgrade pip
pip install nox
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox

- name: Run pyright (strict, Python 3.13)
run: nox -s typecheck_functions
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
init:
pip3 install -r requirements.txt
python3 -m pip install --upgrade "pip>=25.1"
python3 -m pip install --group dev -e ".[azure-blob-payloads,opentelemetry]" -e ./durabletask-azuremanaged

test:
pytest --verbose
Expand Down
4 changes: 0 additions & 4 deletions dev-requirements.txt

This file was deleted.

34 changes: 32 additions & 2 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,39 @@ The following is more information about how to develop this project.
Use Nox to run the representative local correctness checks:

```sh
python -m pip install -r dev-requirements.txt
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group nox
nox -s ci
```

Development dependencies are defined once in the root `pyproject.toml` under
`[dependency-groups]` (PEP 735). Installing groups directly with pip requires
pip 25.1 or later. Nox uses its built-in group resolver to install each session's
tools without upgrading pip inside the session. The official build uses the
same `build`, `lint`, and `test` groups. Add test-only dependencies to `test`
so local and official test environments stay in sync. Keep runtime dependencies
and public extras in each package's `[project]` metadata, not in tooling groups:
the official build resolves them through built wheels to catch missing
declarations.

For development without Nox, install all tools with `--group dev` and install
the local packages separately. Use Python 3.13 or later for Azure Functions:

```bash
python -m pip install --group dev \
-e ".[azure-blob-payloads,opentelemetry]" \
-e ./durabletask-azuremanaged -e ./azure-functions-durable
```

```powershell
python -m pip install --group dev `
-e ".[azure-blob-payloads,opentelemetry]" `
-e .\durabletask-azuremanaged -e .\azure-functions-durable
```

Sample and Function app `requirements.txt` files remain deployment inputs, not
the source of repository development dependencies.

The `ci` session runs linting, strict type checks, core SDK and Azure Managed
tests on Python 3.11, Azure Functions unit tests on Python 3.13, and Azure
Functions end-to-end tests on Python 3.13. It intentionally runs one
Expand Down Expand Up @@ -70,7 +99,8 @@ These commands require `make`. If you're using Windows, you can install `make`
using [Chocolatey](https://chocolatey.org/) or use WSL.

```sh
pip3 install -r dev-requirements.txt
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group protobuf
make gen-proto
```

Expand Down
6 changes: 3 additions & 3 deletions eng/templates/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ jobs:
# that a wheel which accidentally drops a declared dependency surfaces
# the missing dep instead of being silently masked.
- script: |
python -m pip install --upgrade pip
python -m pip install build flake8 pytest pytest-asyncio
python -m pip install --upgrade "pip>=25.1"
python -m pip install --group build --group lint --group test
displayName: "Install build tooling"

# Lint core SDK
Expand Down Expand Up @@ -78,7 +78,7 @@ jobs:
# intentional: if a wheel ever accidentally drops a declared
# dependency, this step will surface the missing dependency at install
# or test time instead of being masked by a preinstalled
# requirements.txt. Test-only tools (pytest, pytest-asyncio) are
# development environment. Test-only tools from the shared test group are
# already installed in the "Install build tooling" step above.
#
# >>> MAINTENANCE NOTE <<<
Expand Down
43 changes: 20 additions & 23 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
DEFAULT_CI_PYTHON = "3.11"


def _install_groups(session: nox.Session, *groups: str) -> None:
"""Install shared tooling without preinstalling SDK runtime dependencies."""
pyproject = nox.project.load_toml(REPO_ROOT / "pyproject.toml")
session.install(*nox.project.dependency_groups(pyproject, *groups))


def _install_packages(session: nox.Session, editable: bool = False) -> None:
"""Install durabletask and the azure-functions-durable provider.

Expand Down Expand Up @@ -281,7 +287,7 @@ def _stop_dts_emulator(container_name: str) -> None:
@nox.session
def lint(session: nox.Session) -> None:
"""Run the Flake8 checks required by the GitHub Actions workflows."""
session.install("flake8")
_install_groups(session, "lint")
targets = session.posargs or (
"durabletask",
"durabletask-azuremanaged",
Expand All @@ -297,27 +303,19 @@ def lint(session: nox.Session) -> None:
@nox.session(python=["3.11"])
def typecheck_core(session: nox.Session) -> None:
"""Run strict pyright checks for the core and Azure Managed packages."""
session.install("-r", "requirements.txt")
session.install("-r", "examples/requirements.txt")
for requirements in sorted((REPO_ROOT / "examples").glob("*/requirements.txt")):
session.install("-r", str(requirements))
_install_groups(session, "test", "typecheck", "examples")
session.install(
"--force-reinstall",
"--no-deps",
str(REPO_ROOT),
f"{REPO_ROOT}[azure-blob-payloads,opentelemetry]",
str(AZUREMANAGED),
)
session.install(f"{REPO_ROOT}[azure-blob-payloads,opentelemetry]")
session.install("pyright")
session.run("pyright", *session.posargs)


@nox.session(python=["3.13"])
def typecheck_functions(session: nox.Session) -> None:
"""Run strict pyright checks for azure-functions-durable."""
session.install("-r", "requirements.txt")
_install_groups(session, "test", "typecheck")
_install_packages(session, editable=True)
session.install("pyright")
session.run(
"pyright",
"-p",
Expand All @@ -329,7 +327,7 @@ def typecheck_functions(session: nox.Session) -> None:
@nox.session(python=["3.13"])
def typecheck_functions_package(session: nox.Session) -> None:
"""Check the installed Functions and core wheels with strict Pyright."""
session.install("build", "pyright")
_install_groups(session, "build", "typecheck")
temp_dir = Path(session.create_tmp())
artifact_dir = temp_dir / "functions-dist"
core_artifact_dir = temp_dir / "core-dist"
Expand Down Expand Up @@ -389,7 +387,9 @@ def typecheck_functions_package(session: nox.Session) -> None:
"-c",
"import sys; print(sys.executable)",
silent=True,
).strip()
)
assert python_path is not None
python_path = python_path.strip()
session.run(
"pyright",
"--pythonpath",
Expand All @@ -408,8 +408,8 @@ def core_tests(session: nox.Session) -> None:
arguments=("--silent", "--blobPort", "10000"),
)
try:
session.install("-r", "requirements.txt")
session.install("-e", f"{REPO_ROOT}[azure-blob-payloads]", "aiohttp")
_install_groups(session, "test")
session.install("-e", f"{REPO_ROOT}[azure-blob-payloads,opentelemetry]")
arguments = _pytest_arguments("tests/durabletask", session.posargs)
session.run(
"pytest",
Expand All @@ -429,8 +429,7 @@ def azuremanaged_tests(session: nox.Session) -> None:
try:
session.env["TASKHUB"] = "default"
session.env["ENDPOINT"] = endpoint
session.install("-r", "requirements.txt")
session.install("-r", "examples/requirements.txt")
_install_groups(session, "test")
session.install(
"-e",
str(REPO_ROOT),
Expand All @@ -449,9 +448,8 @@ def azuremanaged_tests(session: nox.Session) -> None:
@nox.session(python=["3.13", "3.14", "3.15"])
def functions_unit(session: nox.Session) -> None:
"""Run the azure-functions-durable unit tests (no func/azurite required)."""
session.install("-r", "requirements.txt")
_install_groups(session, "test")
_install_packages(session, editable=True)
session.install("pytest")
arguments = _pytest_arguments("tests/azure-functions-durable", session.posargs)
session.run(
"pytest", *arguments,
Expand Down Expand Up @@ -497,10 +495,9 @@ def functions_e2e(session: nox.Session) -> None:
"AzureFunctionsJobHost__extensions__durableTask__hubName"
] = _new_test_namespace("nox")
session.env["E2E_PAYLOAD_CONTAINER"] = _new_test_namespace("payloads")
session.install("-r", "requirements.txt")
_install_groups(session, "functions-e2e")
_install_packages(session, editable=True)
session.install("-e", f"{REPO_ROOT}[azure-blob-payloads]", "aiohttp")
session.install("pytest", "opentelemetry-exporter-otlp-proto-grpc")
session.install("-e", f"{REPO_ROOT}[azure-blob-payloads]")
for app in E2E_APPS:
_link_app_venv(session, E2E_APPS_DIR / app)
arguments = _pytest_arguments(
Expand Down
42 changes: 42 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,48 @@ history-export-azure = [
repository = "https://github.com/microsoft/durabletask-python"
changelog = "https://github.com/microsoft/durabletask-python/blob/main/CHANGELOG.md"

# Development tools only: runtime dependencies belong in each package's metadata.
[dependency-groups]
test = [
"pytest",
"pytest-asyncio",
"pytest-cov",
]
lint = [
"autopep8",
"flake8",
"pymarkdownlnt",
]
typecheck = [
"pyright",
]
build = [
"build",
]
protobuf = [
"grpcio-tools",
]
nox = [
"nox>=2025.2.9",
]
examples = [
"pydantic>=2",
"opentelemetry-exporter-otlp-proto-grpc",
]
functions-e2e = [
{include-group = "test"},
"opentelemetry-exporter-otlp-proto-grpc",
]
dev = [
{include-group = "test"},
{include-group = "lint"},
{include-group = "typecheck"},
{include-group = "build"},
{include-group = "protobuf"},
{include-group = "nox"},
{include-group = "examples"},
]

[tool.setuptools.packages.find]
include = ["durabletask", "durabletask.*"]

Expand Down
12 changes: 0 additions & 12 deletions requirements.txt

This file was deleted.

Loading