Releases: canonical/operator
3.7.0: ops.testing usability improvements
This release brings usability improvement in state transition testing: charmcraft extensions are now expanded, which means easier testing of 12-factor charms; breakpoint is supported; .get_relation can be called with a relation object; a single argument to Context can be used for metadata, actions and config declarations. Additionally, there are fixes for the run-time: secret expiration time zone, typing: StorageMeta.properties and state transition testing: mypy support, cleaner ownership for state data and a warning when unit test potentially relies on container data.
What's Changed
Features
- Enable interactive debugging via
breakpointin testing in #2363 - ops.testing autoload support for charmcraft extensions in #2367
- Allow testing.State.get_relation to accept relation objects in #2359
- Support charmcraft.yaml format as meta for testing.Context in #2296
Fixes
- Correct type annotation for StorageMeta.properties in #2348
- Move the testing.Container compatibility import so that mypy style checkers understand it in #2343
- Hold only copies of user provided meta/config/actions in testing.Context in #2349
- Deep-copy layer objects during testing.State plan rendering in #2380
- Return copies from testing.State secret_get and action_get in #2379
- Use timezone-aware datetimes in expiry calculation in #2378
- Warn before clearing non-empty container in testing in #2365
Documentation
- Replace links to juju.is by canonical.com/juju in #2368
- Refactor homepage to better put Ops in context in #2370
- Add pytest-operator migration guide from Jubilant docs in #2381
- Add a tip about AI help in the Jubilant migration guide in #2382
- Mention jhack scenario snapshot in #2351
- Update integration testing how-to guide in #2390
- Explain K8s charms briefly at the start of the tutorial in #2392
- Juju secrets identifier is now an opaque string in #2387
Tests
- Extend the type checking of the ops-scenario tests in #2230
CI
- Run ruff check --fix in tox -e format in #2369
- Check example charms with mypy in CI in #2360
- Update the list of published charms in the compatibility tests in #2384
- Adjust minimum Python version in broad charm compatibility tests in #2317
Full Changelog: 3.6.0...3.7.0
3.6.0: Use Juju 3.6.14 as the default version in ops.testing
In this release, the ops.testing Context sets the mock Juju version to 3.6.14 (you can customise this if needed).
If you're using Pebble's exec to run commands in containers, and the exec failed (with a timeout, for example), the exception would previously include the entire command that was attempted; it now only includes the first item, to protect against sensitive data leaking into exceptions. However, we strongly recommend against passing sensitive data in the command line - use other methods (such as environment variables) whenever possible.
If you'd like to use Pydantic's experimental MISSING sentinel, that will now work with Relation.save (ops will consider a value of MISSING to mean "delete from Juju").
What's Changed
Features
- Bump default Juju version in
ops.testing.Contextto 3.6.14 in #2316
Fixes
- Correct the
Model.get_binding()return type in #2329 - Only show executable in
ExecError.__str__, not full command line in #2336 - Support Pydantic
MISSINGsentinel inops.Relation.savein #2306
Documentation
- Add how-to subcategory for managing containers in #2309
- Remove 2.19 version in docs, tweak ops.testing title in #2332
- Use "true" and "false" consistently in the reference documentation in #2330
- Add CLI args as another place to not put sensitive data in #2334
- Fix remote unit kwarg in testing example in #2342
- Clarify that secret labels are not names in #2337
Tests
- Set
SCENARIO_BARE_CHARM_ERRORS=truein Ops tests that care in #2314
CI
- Fix releasing on branches with no
versions.mddoc in #2323
Full Changelog: 3.5.2...3.6.0
3.5.2: fixes for testing package build and more
This release is prompted by a fix to recent build failures for ops[testing]. The release also includes a couple of minor fixes for the testing framework itself: making the level argument of testing.CheckInfo type checking compatible with pebble.CheckInfo.level, and baking in the knowledge that credential-get is available on K8s in newer Juju versions.
What's Changed
Fixes
- Make testing.CheckInfo level arg type match pebble.CheckInfo.level in #2274
- Make testing consistency check aware that
credential-getis available on k8s in newer Juju in #2307 - Drop unused
setuptools_scmbuild dependency in #2310
Documentation
- Update Pebble version in Juju 3.6 in #2295
- Refresh K8s tutorial to use Concierge and uv-based Charmcraft profile in #2285
- Add missing "How to" in page titles in #2289
- Fix and improve observability part of K8s tutorial in #2305
Full Changelog: 3.5.1...3.5.2
2.23.2: fix testing package build
What's Changed
This release fixes a recent build failure for ops[testing].
Fixes
- Drop unused
setuptools_scmbuild dependency in #2318
Documentation
- For 2.23, update links and config for switch to documentation.ubuntu.com/ops in #1942
- For 2.x, fix site title and unstyled error pages in #1945
- For 2.x, remove .html extensions in #1954
- For 2.x, fix unstyled error pages in #1973
Full Changelog: 2.23.1...2.23.2
3.5.1: fixes and documentation improvements
This is a maintenance release that includes work on Ops internals and documentation.
What's Changed
Fixes
- Use
parse_rfc3339for datetime parsing to support Juju 4 in #2264 - Correct the value of
additional_propertiesin the action meta in Juju 4 in #2250 - Prevent
KeyErroronauth-typewhen creatingCloudCredentialobject in #2268 _checks_actionshould return empty list when there are no changes in #2270
Documentation
- Provide examples in unit testing how-to, and other small improvements in #2251
- Update the action how-to to explain the additionalProperties default flip in #2249
- For state-transition tests, clarify about immutability and reusing state in #2153
- Fix and clarify holistic example of handling storage in #2098
- Remove comments from K8s tutorial and clarify about persisting data in #2253
- Clarify handling of postgres relation data in K8s tutorial in #2256
- Improve unit tests of httpbin demo charm in #2254
- Add version information for tools in the charming ecosystem in #2231
- Avoid emojis that render differently across platforms in #2273
- Secrets over CMR comment added in #2271
- Fix charm name in httpbin deploy command in #2276
- Updated security@ubuntu.com PGP key in #2286
Tests
- Remove unnecessary test module in #2247
CI
- Replace git reference injection with wheel artifacts in charm test workflows in #2252
- Explicitly provide the charmcraft repo location in CI in #2277
- Remove outdated custom signature generation in #2280
Full Changelog: 3.5.0...3.5.1
3.5.0: env var to control extension wrapping in testing
This is a small release with some user-facing changes to ops.testing.
We've added an environment variable to disable the use of UncaughtCharmError in testing. By default, exceptions raised from charm code are wrapped in an UncaughtCharmError in state-transition tests. This makes debugging harder and adds extra steps to making assertions about expected errors in tests. Set SCENARIO_BARE_CHARM_ERRORS=true to have exceptions be propagated to your test code as-is instead. This may become the default behaviour in a future major ops release. You can lock in the current default behaviour explicitly by setting SCENARIO_BARE_CHARM_ERRORS=false in your test runners.
Additionally, the ops.testing.Context.charm_spec attribute is now deprecated -- this is intended for internal use only, and was not widely used, so the warning should steer new users in the right direction.
What's Changed
Features
- Env var to control exception wrapping in tests in #2142
- Deprecate testing.Context.charm_spec in #2219
Documentation
- Fix charmcraft init command in #2210
- Update CI examples to use uv and tox-uv in #2213
- Update and clarify info about environment prep in #2217
- Match Charmcraft profiles in tox.ini example for integration testing in #2221
- Use base 24.04 for httpbin-demo charm in #2222
- Clarify parts of the machine charm tutorial in #2223
- Match Charmcraft profiles in "Write and structure charm code" in #2220
- Use cosl binary in K8s tutorial charm to work around error in #2232
- Fix URL issues by updating doc starter pack in #2238
Tests
- Don't skip tests if ops[testing] isn't installed in #2215
- Switch the integration test charms to use the uv plugin in #2218
CI
- Avoid jitter in the best practice doc PRs in #2193
- Ignore PERF401 (manual list comprehension) across the repo in #2201
- The git commands need to be run in the operator directory as well in #2197
- Have cycle in the sbomber manifests use the default value in #2209
- Add pytest.warns to note an expected warning in #2092
- Update release script to handle non-final versions in #2199
- Add ops-tracing as a dependency for the observability tests in #2239
- Add scheduled workflow for packing and integration testing example charms in #2233
Full Changelog: 3.4.0...3.5.0
3.4.0: a low-level API for the Juju hook commands
The main feature in this release is the introduction of ops.hookcmds, which provides an API to the Juju hook commands. The API is low-level, complete (other than deprecated commands), and generally a 1-1 mapping to the hook commands, but providing a Pythonic interface.
Additionally, the length of the defer queue is now logged; more arguments can be passed as paths to ops.Container and ops.PebbleClient methods; and state transition testing Context has gained optional availability zone and principal unit arguments.
What's Changed
Breaking Changes
There are breaking changes in this release. Please review them carefully:
- Fix: Change
JujuContext.machine_idfrominttostrin #2108- Note that this fix was already included in Ops 3.3.1
- If you use this field, you may need to adjust type hints in your code
- Fix: Ensure that the testing context manager is exited when an exception occurs in #2117
- If you use
ops.testing.Contextas a context manager and expect the charm to raise an exception, you need to adjust the expected exception type.
- If you use
Features
- Add a low-level API for the Juju hook commands in #2019
- Make PebbleClient file methods also accept pathlib.PurePath in #2097
- Log the total number of deferred events in #2161
- Allow setting the Juju availability zone and principal unit in the testing Context in #2187
Fixes
- Allow actions without params or descriptions in ops[testing] in #2090
- Ensure
ops.Pebble.pullcleans up temporary files if it errors in #2087 - Make secret info description visible to the charm in ops[testing] in #2115
- Raise ActionFailed when using Context as a context manager in #2121
- Detect categories with an explanation mark indicating breaking changes in #2132
- Normalise Secret.owner to 'app' for ops[testing] output state in #2127
- Don't cache secret metadata in Ops in #2143
- Secret-info-get cannot be provided with both an ID and a label in #2170
- Minor hookcmds fixes in #2175
Documentation
- Update referenced examples for managing interfaces in #2068
- Tidy up spelling and formatting in several places in #2060
- Add missing assignment to state_out in unit tests how-to in #2075
- Update the holistic/delta explanation with the reconciler pattern in #2029
- Fix broken setup/teardown links in README in #2094
- Update info about release docs, mark testing changelog as not maintained in #2074
- Switch to makefile for building the docs in #2073
- Document how to extract the charm instance from the testing context in #2084
- Add a how-to guide for migrating away from Harness in #2062
- Rename hook tools to hook commands in #2114
- Remove legacy how-to guide for Harness in #2122
- Update the Juju release the metrics functionality is removed from 4.0 to 3.6.11 in #2126
- Clarify that Context is the testing context not only the Juju context in #2123
- Explain the Charmhub public listing process and add a reference list of best practices in #1989
- Expand next steps for K8s tutorial in #2034
- Remove mention of the
simpleCharmcraft profile in #2138 - Expand landing pages with summaries of pages in #2140
- Update environment setup for integration tests and K8s tutorial in #2124
- Replace machine charm tutorial by an improved tutorial in #2119
- Change HACKING.md instructions for maintaining Charmcraft profiles in #2151
- In integration tests, use consistent approach to logging and packing in #2150
- In integration testing how-to, clarify that Juju model is destroyed after module all tests in the module complete in #2154
- Remove Charmcraft channel specifier from machine charm tutorial in #2148
- Add AI contribution note and style guideline for type annotation of return values in #2168
- Add ops[testing] to the ops.testing docstring in #2171
- Add links to the Juju hook from each event class in #2176
- Add a short umask note in #2184
Tests
- Re-enable testing consistency checks after disabling them in #2141
- Expand secrets integration and state transition tests in #2130
Refactoring
- Use ops.hookcmds in _ModelBackend in #2116
- Don't get the storage details from --help in #2172
- Drop 3.8 and 3.9 compatibility code in #2173
- Use json.dumps to produce the YAML in relation-set and state-set in #2174
- Rely on type annotations instead of casts in hookcmds in #2179
CI
- Add integration and state transition tests for the secrets API in #2078
- Temporarily disable tracing integration tests in #2102
- Add secrets tests follow-up in #2105
- Support monorepos in ops charm compatibility testing in #2100
- Test both Charmcraft 3 and Charmcraft 4 profiles in #2103
- Add automated doc checks (and related starter pack updates) in #2099
- Clean up accidental workflow trigger in #2144
- Test if package versions match dependency versions before publishing in #2139
- Update spelling in #2167
- Test against 4.0/stable in #2186
- Store charmcraft logs if smoke tests fail in #2192
- Use Juju channel 4/stable in Ops smoke tests in #2190
Full Changelog: 3.3.0...3.4.0
3.4.0b3 Fix dependency version in testing extra
3.4.0b2 was not released to PyPI, as there was an error in the testing optional extra. This release is otherwise identical to 3.4.0b2.
3.4.0b2 Small hookcmds fixes
This second beta for the 3.4.0 release fixes one significant bug with the new ops.hookcmds usage in the model backend, where getting secret info when the secret object had both ID and label set would fail.
In addition, we now include the size of the defer queue in the (debug-level) log message when processing deferrals.
What's Changed
Features
- Log the total number of deferred events in #2161
Fixes
- Normalise
Secret.ownerto 'app' for ops[testing] output state in #2127 - Don't cache secret metadata in Ops in #2143
secret-info-getcannot be provided with both an ID and a label in #2170- Minor hookcmds fixes in #2175
Documentation
- Explain the Charmhub public listing process and add a reference list of best practices in #1989
- Expand next steps for K8s tutorial in #2034
- Remove mention of the
simpleCharmcraft profile in #2138 - Expand landing pages with summaries of pages in #2140
- Update environment setup for integration tests and K8s tutorial in #2124
- Replace machine charm tutorial by an improved tutorial in #2119
- Change HACKING.md instructions for maintaining Charmcraft profiles in #2151
- In integration tests, use consistent approach to logging and packing in #2150
- In integration testing how-to, clarify that Juju model is destroyed after module in #2154
- Remove Charmcraft channel specifier from machine charm tutorial in #2148
- Add AI contribution note and style guideline for type annotation of return values in #2168
- Add ops[testing] to the ops.testing docstring in #2171
- Add links to the Juju hook from each event class in #2176
Tests
- Re-enable ops[testing] consistency checks after disabling them in #2141
- Expand secrets integration and state transition tests in #2130
Refactoring
- Don't get the storage details from
--helpin #2172 - Drop Python 3.8 and 3.9 compatibility code in #2173
CI
- Clean up accidental workflow trigger in #2144
- Test if package versions match dependency versions before publishing in #2139
- Update spelling in #2167
Full Changelog: 3.4.0b1...3.4.0b2
3.4.0b1: ops.hookcmds - a low-level API for the Juju hook commands
The main feature in this release is the introduction of ops.hookcmds, which provides an API to the Juju hook commands. The API is low-level, complete (other than deprecated commands), and generally a 1-1 mapping to the hook commands, but providing a Pythonic interface.
The intention is that this makes it easier to build experimental charm APIs or frameworks (in particular, having the Juju knowledge encapsulated in Ops) rather than for charms to use the ops.hookcmds package directly. This new API is also used by the Ops model, which is the primary reason we are doing a beta release. We're confident that there will be no charm-visible differences, but this is at the heart of the framework, so we would really appreciate you trying it out and letting us know if there are any issues. We expect to release a 3.4.0 final in mid November 2025.
There is also a breaking change to ops.testing as part of a bug fix in this release. Previously, if using testing.Context() as a context manager, cleanup was not properly run. This meant that exceptions did not get wrapped in UncaughtCharmError as with a regular run(), ActionFailed wasn't raised if the action failed, the environment wasn't properly cleaned up, and so on. If you have tests that are using testing.Context() in this way, and are doing a pytest.raises with the actual exception, you'll need to update those to expect UncaughtCharmError.
There are also the usual set of bug fixes, documentation improvements, and also one small feature: if you're using ops.pebble.Client directly (most of you probably use ops.Container), you can now pass in pathlib.Path objects rather than just str.
What's Changed
Breaking Changes
- Fix: Ensure that the testing context manager is exited when an exception occurs in #2117
Features
- Add a low-level API for the Juju hook commands in #2019
- Make Pebble
Clientfile methods also acceptpathlib.PurePathin #2097
Fixes
- Allow actions without params or descriptions in
ops[testing]in #2090 - Ensure
ops.Pebble.pullcleans up temporary files if it errors in #2087 - Make secret info description visible to the charm in
ops[testing]in #2115 - Raise
ActionFailedwhen usingContextas a context manager in #2121
Documentation
- Update referenced examples for managing interfaces in #2068
- Tidy up spelling and formatting in several places in #2060
- Add missing assignment to
state_outin unit tests how-to in #2075 - Update the holistic/delta explanation with the reconciler pattern in #2029
- Fix broken setup/teardown links in README in #2094
- Switch to Makefile for building the docs in #2073
- Document how to extract the charm instance from the testing context in #2084
- Add a how-to guide for migrating away from Harness in #2062
- Rename hook tools to hook commands in #2114
- Remove legacy how-to guide for Harness in #2122
- Update the Juju release in which the metrics functionality is removed from 4.0 to 3.6.11 in #2126
- Clarify that
Contextis the testing context not only the Juju context in #2123
Refactoring
- Use
ops.hookcmdsin_ModelBackendin #2116
CI
- Add integration and state transition tests for the secrets API in #2078
- Temporarily disable tracing integration tests in #2102
- Add secrets tests follow-up in #2105
- Support monorepos in Ops charm compatibility testing in #2100
- Test both Charmcraft 3 and Charmcraft 4 profiles in #2103
- Add automated doc checks (and related starter pack updates) in #2099
Full Changelog: 3.3.0...3.4.0b1