Skip to content

Developing ado

Project Setup

To start developing ado, you need to set up a Python environment. We use uv for project and dependency management.

Installing uv

To install uv, refer to the official installation documentation and choose your preferred method.

Creating a development virtual environment

Create a development virtual environment by executing the following commands in the top-level of the ado repository:

uv sync
source .venv/bin/activate

Note

This installs ado in editable mode.

Note

In line with uv's defaults, the uv sync command creates a .venv in the top-level of the project's repository. Note that environments created by uv sync are intended only to be used when developing a specific project and should not be shared across projects.

Caution

uv sync ensures a reproducible development environment is created by using a lock-file, uv.lock. Only packages in the lockfile are installed, and other packages found in the virtual environment will be deleted. See Making changes to dependencies for how to add packages to the lockfile.

If you want to create your development virtual environment at an alternate location, $PATH, then

uv venv $PATH
source $PATH/bin/activate
uv sync --active

Caution

If you create a development in a different location you must direct uv sync explicitly to use it with --active If you do not it will default to using .venv in the project top-level directory.

Code style

Note

See the Automating checks with pre-commit section to automate this.

This repository follows the black style for formatting.

You can format your code by:

Linting with ruff

Note

See the Automating checks with pre-commit section to automate this.

This repository uses ruff to enforce linting rules. Install it using one of the methods described in the official ruff documentation. To run linting checks, execute:

ruff check --exclude website

Secret scanning

Note

See the Automating checks with pre-commit section to automate this.

This repository uses IBM's detect-secrets to scan for secrets before the code is pushed to GitHub. Follow installation instructions in their repository: https://github.com/ibm/detect-secrets?tab=readme-ov-file#example-usage

To update the secrets database manually, run:

detect-secrets scan --update .secrets.baseline

To audit detected secrets, use:

detect-secrets audit .secrets.baseline

Commit style

We require commit messages to use the conventional commit style.

Conventional Commit messages follow the following pattern (NOTE: the scope is optional):

type(scope): subject

extended body

Where type is one of: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test.

We require copyright and SPDX license headers to be added to the source code. This can be automated by using Hashicorp's Copywrite tool: https://github.com/hashicorp/copywrite

Once installed, run

copywrite headers

Automating checks with pre-commit

To automate the checks for code style, linting, and security, you can utilize the provided pre-commit hooks.

Installing the hooks

After having synced the dependencies, install the hooks with:

pre-commit install

This command will configure pre-commit to run automatically before each commit, highlighting any issues and preventing the commit if problems are found.

Handling pre-commit failures

  1. Black code formatting failures: try committing again, black might have reformatted your code in-place.
  2. Ruff linter failures: run ruff as specified in Linting with ruff and fix the code that is causing the failures.
    • In case of false positives, you might need to add #noqa annotations.
    • If your local ruff installation does not detect any failure you may be using an old version that needs updating.
  3. Detect secrets failures: include .secrets.baseline in your commit, it was updated by the pre-commit hook.
  4. Commit style failures: change your commit message to match conventional commits. See Commit style for more in-depth information.
  5. Misspellings detected by codespell: fix the misspellings reported or add an inline ignore comment.
  6. uv export failures: commit the updated requirements.txt file. It has been updated following changes to the lock file.

Making changes to dependencies

As mentioned in Project Setup, we use uv to manage dependencies. This means that all changes to dependencies must be done via uv, and not by manually editing pyproject.toml.

The relevant documentation on uv's website is available here, but at a glance:

Adding base dependencies

If you are adding (or updating) base dependencies for ado, you should use the uv add command:

Note

You can optionally add specific version selectors. By default, uv will add >=CURRENT_VERSION.

uv add pydantic

Adding optional dependencies

Dependencies may be optional, making them available only when using extras, such as ado-core[my-extra]. To add these kind of dependencies, use the uv add --optional command:

uv add --optional validation pydantic

Adding dependency groups

Sometimes we might want to include dependencies that have a specific purpose, like testing the code, linting it, or building the documentation. This is a perfect use case for dependency groups, sets of dependencies that do not get published to indices like PyPI and are not installed with ado. A noteworthy dependency group is the dev group, which uv installs by default when syncing dependencies.

Users are highly encouraged to read the documentation available both on uv's and Python's website:

With uv you can add dependencies to groups using uv add --group NAME:

Note

For the dev group there is the shorthand --dev that replaces --group dev.

uv add --group dev pytest