Skip to content

ci: make the broad compatibility tests install the ops wheels - #2773

Draft
tonyandrewmeyer wants to merge 8 commits into
canonical:mainfrom
tonyandrewmeyer:fix-broad-false-passes
Draft

tonyandrewmeyer wants to merge 8 commits into
canonical:mainfrom
tonyandrewmeyer:fix-broad-false-passes

Conversation

@tonyandrewmeyer

@tonyandrewmeyer tonyandrewmeyer commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

Makes the broad charm compatibility tests actually run each charm's tests against the ops wheels. At the moment a lot of the jobs pass without ever doing that: in the September run, 20 of the 89 charm jobs installed the wheels with the system pip (tox-uv environments have no pip of their own, so pip install went to the runner's user site-packages), and others put the charm's locked ops back afterwards with poetry install or ran the tests through uv run, which uses the project's own environment.

  • The wheels are installed with uv pip install, which goes into the tox environment via VIRTUAL_ENV, and with dependencies, since a charm locked to ops 2 doesn't have everything ops 3 needs (opentelemetry, for example).
  • They're installed again after each poetry install or uv sync in the tox commands, not just the last one, since some charms run their unit tests between two installs.
  • The ops-tracing wheel is only installed where the charm already has ops-tracing. Installing it everywhere would add the OpenTelemetry SDK to charms that don't use tracing, and leaving an older ops-tracing in place means it requires the old ops. This needs a small sh -c wrapper in the tox commands, so sh is added to allowlist_externals.
  • For uv charms, ops, ops-scenario, and ops-tracing are overridden in pyproject.toml and the charm relocked, so anything installing from uv.lock gets the wheels. The override keeps the extras from the lock, including ones that only a charm library asks for.
  • A new step fails the job if any environment the tests created has a different ops, ops-scenario, or ops-tracing version than the matching wheel, or if there's no ops installed at all, so any other way around the wheels shows up as a failure rather than a pass.
  • The patch script has tests now (test/test_patch_charm_deps.py), since its only feedback so far has been the monthly run, and it went a long time not doing what it said without anyone noticing. This adds tomli-w to the unit dependency group, and the tests skip on Python 3.10, which doesn't have tomllib.

A run on my fork with an earlier version of this change (https://github.com/tonyandrewmeyer/operator/actions/runs/36358609881) has 11 jobs that passed in September now failing, all of them charms that weren't getting the wheels before: parca-k8s, zookeeper and zookeeper-k8s, temporal-k8s and temporal-ui, kafka-k8s, the tempo coordinator, both mysql-router charms (whose tests use the Scenario 6 API), and grafana-agent's static check. k8s-operator's static check now passes. That run predates the ops-tracing and install-after-each changes, so the list will probably shift a bit. I haven't gone through each of those yet to see which are real ops regressions and which are charms that need to update their tests, so the next scheduled run will be noticeably redder, and I'll work through them after this is merged.

In that run the new check only caught one charm, kafka-operator, which runs poetry run pip install -U ./common after the wheels are installed and so tests with ops 3.8.2. That one was already failing, and I've left it failing rather than special-casing it.

I found this while trialling canonical/hyrum as a replacement for this workflow, which relocks rather than reinstalling and so had been reporting failures here that this workflow wasn't.

tonyandrewmeyer and others added 2 commits September 28, 2026 12:16
Many of the broad charm compatibility jobs passed without ever running the
charm's tests against the ops wheels:

* The wheels were installed with a bare `pip` in commands_pre, but tox-uv
  environments have no pip of their own, so the system pip installed them
  into the user site-packages instead (20 of 89 jobs in the September run).
* A `poetry install` in the tox commands put the locked ops back after the
  wheels were installed.
* `uv run` uses the project's own environment, built from uv.lock, rather
  than the tox environment.

Install the wheels with `uv pip install` (which uses the tox environment via
VIRTUAL_ENV), with their dependencies, since a charm locked to ops 2 lacks
some that ops 3 needs. Install them again after any `poetry install` or
`uv sync` in the tox commands. For uv charms, also override ops and its
companions in pyproject.toml and relock, so that anything installing from
uv.lock gets the wheels, and pass the ops-tracing wheel for that.

Add a step that fails the job if any environment the tests created has a
different ops version from the wheel, so that another way of bypassing the
wheels shows up as a failure rather than a pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An override replaces the extras on every requirement it matches, so taking
the extras from the charm's pyproject.toml dropped ones that only a
dependency asked for, such as a charm library that requires ops[tracing].
Take them from uv.lock instead, which records every requirement on ops.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tonyandrewmeyer
tonyandrewmeyer marked this pull request as draft September 28, 2026 03:08
@tonyandrewmeyer

Copy link
Copy Markdown
Collaborator Author

I'm not sure it's worth doing this, given that I really want to propose the other change, using hyrum. It would make for a better comparison, but I'm not sure that's worth bothering with.

tonyandrewmeyer and others added 6 commits October 9, 2026 10:04
The check only failed on a mismatched version, so when no environment was
created it found nothing and passed. Count the matches and fail on zero, and
skip the check when neither the unit nor the static environment ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the uv path put the ops-tracing wheel in place, so a poetry or
requirements charm on ops[tracing] kept its old ops-tracing next to the new
ops, and the check only looked at ops. The tox install now reinstalls
ops-tracing from the wheel where the charm already has it, without adding it
where it doesn't, and the check compares ops-scenario and ops-tracing with
their wheels wherever they're installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…last

Commands that run the unit tests between two locked installs, such as
'poetry install --only unit' before the tests and another install before the
static checks, ran the tests against the charm's own ops. The check didn't
notice, because by the time it runs the last install has put the wheel back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The script's only feedback was a monthly scheduled run, and it went months
without testing the wheels unnoticed. Test the pure parts: the wheel install
commands, inserting them after each locked install, the tox allowlist and
commands for INI and TOML, and the uv override and its extras.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The workflow already treats the wheel as required, so make the script agree:
a missing wheel now fails with argparse's message rather than a bare ls
error. Also note in _override_uv_lock that pyproject.toml is rewritten whole.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant