Releases: canonical/operator
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
3.3.1: fix loading the Juju machine ID
This is a bug-fix release to fix an issue introduced in Ops 3.3.0 (in production) and Ops 3.2.0 (in testing), where loading the Juju machine ID would fail if the ID was not an integer.
The type of the machine ID (both in ops.JujuContext and testing.Context) is changed from int to str, so some code or tests may need to be adjusted to use the correct type.
What's Changed
Fixes
- Change JujuContext.machine_id from int to str (#2108)
Full Changelog: 3.3.0...3.3.1
3.3.0: fixes and documentation improvements
This is a small maintenance release that includes work on ops and testing internals and documentation.
What's Changed
Features
- Expose the Juju hook context in ops.JujuContext in #1996
Fixes
- In testing, separate relation data cache from mock Juju backend in #2052
Documentation
- Use uv for testing and packing the httpbin charm in #2011
- Improve intro to ops.testing reference in #2023
- In httpbin charm integration tests, add env var for charm file to deploy in #2018
- Update get_cloud_spec doc now that credential-get works on K8s in #2031
- Note that arbitrary_types_allowed is required when ops.Secret is used in a Pydantic class in #2038
- Clean up Resources.fetch docstring, add ModelError exception in #2039
- Note that the peer databag isn't usable during the install event in #2051
- Fix testing code in actions how-to guide in #2054
CI
- Nicer logging output in the release script using rich in #2017
- Clean up PYTHONPATH in tox.ini in #2058
Full Changelog: 3.2.0...3.3.0
3.2.0: ops will log security events
With this release, Ops will send security event logs to Juju's log; for example, when there is a permission error getting relation or secret data. This is logged at TRACE level, so should not be noticeable in most cases, and is intended to be used in later work rather than by charms themselves.
A typing-only change has been made to support Pebble's new opentelemetry log target.
On the testing front, scenario now supports setting the JUJU_MACHINE_ID variable in the mocked environment.
Over the last month, we refreshed the Ops docs landing page, moved to documentation.ubuntu.com/ops, and removed the .html suffix from pages. We expect that this will be the last big renaming for the docs for a while now.
What's Changed
Features
- Add security event logging in #1905
- Surface JUJU_MACHINE_ID envvar in testing env in #1961
- Add a new log target type opentelemetry in #1937
Documentation
- Update links and config for switch to documentation.ubuntu.com/ops in #1940
- Update the required Python version and note the 2.x documentation site in #1946
- Be consistent with recommending self.config in #1947
- Use latest styles from starter pack and remove .html extensions in #1951
- Remove .html extensions from hardcoded links in #1955
- Fix broken URLs in sitemap in #1956
- Add related doc links to homepage in #1959
- Use classes from ops instead of ops. in #1968
- Fix unstyled error pages in #1969
- Add Google Analyics integration and cookie consent banner in #1971
- Refresh docs homepage with more context about Ops in #1964
- Update link to Charmlibs docs in #1985
- Remove unnecessary pages from sitemap in #1979
- Update the httpbin charm to jubilant in #1987
- Update zero to hero to jubilant in #1988
- Add model-config best practice note in #1990
- Change some best practices to tips in #2001
- Add integration test for invalid config in httpbin charm in #2002
- Make a
Layerinstead of aLayerDictin the httpbin charm in #2003 - Update how-to to feature Jubilant (1/2) in #2000
- Use Charmcraft-style format and lint for example charms, not Ops-style in #2008
- Update broken link to HookVars source code in #2006
- Update how-to to feature Jubilant (2/2) in #2004
CI
- Fixes for the sbom and secscan workflow, and trigger it on publishing in #1916
- Store the charmcraft logs if packing fails in #1936
- Install release dependencies for the TIOBE analysis in #1930
- Add Juju 4/beta to the smoke test matrix in #1963
- Adjust permissions block in publish workflow in #1984
- Update actions/checkout to v5 in #1993
- Enable doctests in #1991
- Ignore juju/4 timeouts in #1998
- Remove the token for SBOM and secscan on publish in #2009
- Speed up integration test in #1978
Full Changelog: 3.1.0...3.2.0
3.1.0: app_name and unit_id available from testing.Context
This release exposes the app name and unit ID in the testing Context. In addition, a number of bugs are fixed, particularly ones introduced with the recent change to exposing the relation data of departed units.
What's Changed
Features
Fixes
- If an event ends with
_Abort(0)tests should behave as if it ended successfully in #1887 - If
self.appis not actually set avoid a new crash location in #1897 - Only add the remote unit for departed and broken relation events, fix ordering in #1918
- Add the remote unit to
Relation.databut notRelation.unitsin #1925
Documentation
- Use
load_configin the httpbin example charm in #1852 - Update
HACKING.mdwith how to bump ops version in Charmcraft profiles in #1872 - Change title of docs site in #1890
- Use config and action classes in the Kubernetes tutorial in #1891
- Reference example charms from K8s tutorial and fix consistency in #1898
- Update style guide in #1720
- Fix issues in how-to guide for stored state in #1901
- Link out to the 12-factor tutorials from the tutorial index page in #1902
- Replace broken link in testing explanation in #1913
- Expand the storage how-to with content from juju docs scheduled for removal in #1915
- Ops tracing how to in #1853
- Add a security explanation doc in #1904
Tests
- Replace Python version to 3.10 for observability charm tests in #1914
CI
- Use httpbin demo charm for the
charmcraft packtest in #1895 - Move TIOBE workflow to self-hosted runners in #1912
- Add SBOM generation and secscan workflow in #1906
- Build and publish in one step in #1857
- Update the name and email when updating the charm pins in #1924
- Drop smoke test against 20.04 in #1923
Full Changelog: 3.0.0...3.1.0
2.23.1: Add the remote unit to Relation.data, but not Relation.units
This is a small bug-fix release for the 2.x series that addresses issues with the recent feature making relation data available in relation-departed events. Rather than inserting the remote unit into Relation.units, the data is available from Relation.data, without changing Relation.units.
What's Changed
Fixes
- Add the remote unit to
Relation.databut notRelation.unitsin #1928
Documentation
- Be consistent with recommending
self.appandself.unitin #1856 - Add notice about ops 2 and ops 3 in #1867
- Update title and edit links for ops 2.23 docs in #1885
CI
- Hotfix, publish job for ops-tracing in #1865
Full Changelog: 2.23.0...2.23.1