From 0e526104532d5eebb2c9de692091e6470f1df093 Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Fri, 11 Oct 2024 14:41:51 +1300 Subject: [PATCH 1/5] Adjust the publishing workflow and documentation to handle releasing both ops and ops-scenario. --- .github/workflows/build_scenario_wheels.yaml | 61 ------------- ...{publish.yml => publish-ops-scenario.yaml} | 11 +-- .github/workflows/publish-ops.yaml | 39 ++++++++ .github/workflows/smoke.yaml | 4 +- .../workflows/test-publish-ops-scenario.yaml | 35 ++++++++ ...test-publish.yml => test-publish-ops.yaml} | 2 +- .gitignore | 1 + HACKING.md | 89 ++++++++++++------- testing/CHANGES.md | 43 +++++++++ 9 files changed, 186 insertions(+), 99 deletions(-) delete mode 100644 .github/workflows/build_scenario_wheels.yaml rename .github/workflows/{publish.yml => publish-ops-scenario.yaml} (84%) create mode 100644 .github/workflows/publish-ops.yaml create mode 100644 .github/workflows/test-publish-ops-scenario.yaml rename .github/workflows/{test-publish.yml => test-publish-ops.yaml} (95%) create mode 100644 testing/CHANGES.md diff --git a/.github/workflows/build_scenario_wheels.yaml b/.github/workflows/build_scenario_wheels.yaml deleted file mode 100644 index 87833841a..000000000 --- a/.github/workflows/build_scenario_wheels.yaml +++ /dev/null @@ -1,61 +0,0 @@ -name: Build ops-scenario wheels - -# TODO: adjust this workflow to properly build ops-scenario from the operator repo -# and then this should be adjusted to run when appropriate (not on push to main -# any more, but as part of the releasing workflow we agree on). -on: - workflow_dispatch -# push: -# branches: -# - main - -jobs: - build_wheel: - name: Build wheel on ubuntu (where else???) - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - - - name: Install build - run: pip install build - - - name: Build wheel - run: python -m build - - - uses: actions/upload-artifact@v3 - with: - path: ./dist/*.whl - - - name: Get the version - id: get_version - run: echo "VERSION=$(sed -n 's/^ *version.*=.*"\([^"]*\)".*/\1/p' pyproject.toml)" >> $GITHUB_OUTPUT - - - name: release - uses: actions/create-release@v1 - id: create_release - with: - draft: false - prerelease: false - tag_name: ${{ steps.get_version.outputs.VERSION }} - release_name: ${{ steps.get_version.outputs.VERSION }} - - env: - GITHUB_TOKEN: ${{ github.token }} - - - name: upload wheel - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ github.token }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/ops_scenario-${{ steps.get_version.outputs.VERSION }}-py3-none-any.whl - asset_name: ops_scenario-${{ steps.get_version.outputs.VERSION }}-py3-none-any.whl - asset_content_type: application/wheel - - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish-ops-scenario.yaml similarity index 84% rename from .github/workflows/publish.yml rename to .github/workflows/publish-ops-scenario.yaml index 05c1527e8..15664910f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish-ops-scenario.yaml @@ -1,8 +1,8 @@ name: Publish on: - release: - types: - - published + push: + tags: + - 'scenario-7.*' jobs: framework-tests: @@ -12,7 +12,7 @@ jobs: hello-charm-tests: uses: ./.github/workflows/hello-charm-tests.yaml build-n-publish: - name: Build and Publish to PyPI + name: Build and Publish ops-scenario to PyPI runs-on: ubuntu-latest permissions: id-token: write @@ -27,9 +27,10 @@ jobs: run: pip install wheel build - name: Build run: python -m build + working-directory: ./testing - name: Attest build provenance uses: actions/attest-build-provenance@v1.4.3 with: - subject-path: 'dist/*' + subject-path: 'testing/dist/*' - name: Publish uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/publish-ops.yaml b/.github/workflows/publish-ops.yaml new file mode 100644 index 000000000..c391664a4 --- /dev/null +++ b/.github/workflows/publish-ops.yaml @@ -0,0 +1,39 @@ +name: Publish +on: + push: + tags: + # TODO: When we come to ops v3.x we will need to reconsider what to do + # here (we might want to start prefixing with 'v' for one thing), and we + # will likely be publishing at least three packages: ops, ops-scenario, + # and ops-harness. + - '2.*' + +jobs: + framework-tests: + uses: ./.github/workflows/framework-tests.yaml + observability-charm-tests: + uses: ./.github/workflows/observability-charm-tests.yaml + hello-charm-tests: + uses: ./.github/workflows/hello-charm-tests.yaml + build-n-publish: + name: Build and Publish ops to PyPI + runs-on: ubuntu-latest + permissions: + id-token: write + attestations: write + contents: read + needs: [framework-tests, observability-charm-tests, hello-charm-tests] + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + - name: Install build dependencies + run: pip install wheel build + - name: Build + run: python -m build + - name: Attest build provenance + uses: actions/attest-build-provenance@v1.4.3 + with: + subject-path: 'dist/*' + - name: Publish + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/smoke.yaml b/.github/workflows/smoke.yaml index 3f69d1e2f..b95940d17 100644 --- a/.github/workflows/smoke.yaml +++ b/.github/workflows/smoke.yaml @@ -2,8 +2,8 @@ name: ops Smoke Tests on: workflow_dispatch: - schedule: - - cron: '0 7 25 * *' + schedule: + - cron: '0 7 25 * *' jobs: test: diff --git a/.github/workflows/test-publish-ops-scenario.yaml b/.github/workflows/test-publish-ops-scenario.yaml new file mode 100644 index 000000000..398d5af1b --- /dev/null +++ b/.github/workflows/test-publish-ops-scenario.yaml @@ -0,0 +1,35 @@ +name: Test Publish +on: [workflow_dispatch, workflow_call] + +jobs: + framework-tests: + uses: ./.github/workflows/framework-tests.yaml + observability-charm-tests: + uses: ./.github/workflows/observability-charm-tests.yaml + hello-charm-tests: + uses: ./.github/workflows/hello-charm-tests.yaml + build-n-publish: + name: Build and Publish ops-scenario to Test PyPI + runs-on: ubuntu-latest + permissions: + id-token: write + attestations: write + contents: read + needs: [framework-tests, observability-charm-tests, hello-charm-tests] + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + - name: Install build dependencies + run: pip install wheel build + - name: Build + run: python -m build + working-directory: ./testing + - name: Attest build provenance + uses: actions/attest-build-provenance@v1.4.3 + with: + subject-path: 'testing/dist/*' + - name: Publish to test.pypi.org + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/test-publish.yml b/.github/workflows/test-publish-ops.yaml similarity index 95% rename from .github/workflows/test-publish.yml rename to .github/workflows/test-publish-ops.yaml index da6fb5567..dcfcb3b9d 100644 --- a/.github/workflows/test-publish.yml +++ b/.github/workflows/test-publish-ops.yaml @@ -9,7 +9,7 @@ jobs: hello-charm-tests: uses: ./.github/workflows/hello-charm-tests.yaml build-n-publish: - name: Build and Publish to Test PyPI + name: Build and Publish ops to Test PyPI runs-on: ubuntu-latest permissions: id-token: write diff --git a/.gitignore b/.gitignore index 97e7a9657..04395b2b8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ coverage.xml /build /docs/_build /testing/ops_scenario.egg-info/ +/testing/src/ops_scenario.egg-info/ /testing/build/ /testing/dist/ diff --git a/HACKING.md b/HACKING.md index 0ba4ffb55..d6d7e4a0b 100644 --- a/HACKING.md +++ b/HACKING.md @@ -179,14 +179,17 @@ Pull requests should have a short title that follows the * revert * test -If the PR is limited to changes in ops.testing (Harness), also include the scope -`(harness)` in the title. At present, we do not add a scope in any other cases. +At present, we only add a scope in these cases: + +* If the PR is limited to changes in ops/_private/harness.py, also include the scope `(harness)` +* If the PR is limited to changes in testing/, also include the scope `(testing)` For example: * feat: add the ability to observe change-updated events * fix!: correct the type hinting for config data * docs(harness): clarify the types of exceptions that Harness.add_user_secret may raise +* ci(testing): adjust the workflow that publishes ops-scenario Note that the commit messages to the PR's branch do not need to follow the conventional commit format, as these will be squashed into a single commit to `main` @@ -202,10 +205,10 @@ The copyright information in existing files does not need to be updated when tho In general, new functionality should always be accompanied by user-focused documentation that is posted to -https://juju.is/docs/sdk. The content for this site is written and hosted on -https://discourse.charmhub.io/c/doc. New documentation should get a new +https://juju.is/docs/sdk. The content for this site is written and hosted on +https://discourse.charmhub.io/c/doc. New documentation should get a new topic/post on this Discourse forum and then should be linked into the main -docs navigation page(s) as appropriate. The ops library's SDK page +docs navigation page(s) as appropriate. The ops library's SDK page content is pulled from [the corresponding Discourse topic](https://discourse.charmhub.io/t/the-charmed-operator-software-development-kit-sdk-docs/4449). Each page on [juju.is](https://juju.is/docs/sdk) has a link at the bottom that @@ -221,13 +224,21 @@ Currently we don't publish separate versions of documentation for separate relea next to the relevant content (e.g. headings, etc.). The ops library's API reference is automatically built and published to -[ops.readthedocs.io](https://ops.readthedocs.io/en/latest/). Please be complete with +[ops.readthedocs.io](https://ops.readthedocs.io/en/latest/). Please be complete with docstrings and keep them informative for _users_. The published docs are always for the in-development (main branch) of ops, and do not include any notes -indicating changes or additions across versions - we encourage all charmers to +indicating changes or additions across ops versions - we encourage all charmers to promptly upgrade to the latest version of ops, and to refer to the release notes and changelog for learning about changes. +We do note when features behave differently when using different Juju versions. +Use the `.. jujuadded:: x.y` directive to indicate that the feature is only +available when using version x.y (or higher) of Juju, `..jujuchanged:: x.y` +when the feature's behaviour _in ops_ changes, and `..jujuremoved:: x.y` when +the feature will be available in ops but not in that version (or later) of Juju. +Unmarked features are assumed to work and be available in the current LTS +version of Juju. + During the release process, changes also get a new entry in [CHANGES.md](CHANGES.md). These are grouped into the same groupings as [commit messages](https://www.conventionalcommits.org/en/) @@ -311,43 +322,61 @@ To make a release of the ops library, do the following: 1. Visit the [releases page on GitHub](https://github.com/canonical/operator/releases). 2. Click "Draft a new release" -3. The "Release Title" is simply the full version number, in the form `..` - and a brief summary of the main changes in the release - E.g. 2.3.12 Bug fixes for the Juju foobar feature when using Python 3.12 -4. Use the "Generate Release Notes" button to get a copy of the changes into the +3. The "Release Title" is the full version numbers of ops and ops-scenario, in + the form `ops .. & ops-scenario ..` + and a brief summary of the main changes in the releases. If the release only + includes one of `ops` and `ops-scenario`, leave out the other one. + For example: `ops 2.3.12 Bug fixes for the Juju foobar feature when using Python 3.12` +4. Have the release create a new tag, in the form `..` +5. Use the "Generate Release Notes" button to get a copy of the changes into the notes field. -5. Group the changes by the commit type (feat, fix, etc.) and use full names (e.g., "Features", - not "feat") for group headings. Strip the commit type prefix from the bullet point. Strip the - username (who did each commit) if the author is a member of the Charm Tech team. -6. Where appropriate, collapse multiple tightly related bullet points into a +6. Group the changes first by package (`ops` and `ops-scenario`) and then by + the commit type (feat, fix, etc.) and use full names (e.g., "Features", + not "feat") for group headings. Strip the commit type prefix from the bullet point, + and capitalise the first word. Strip the username (who did each commit) if the + author is a member of the Charm Tech team. + For example: the PR `docs: clarify where StoredState is stored` + becomes `* Clarify where StoredState is stored` in the "Documentation" section. +7. Where appropriate, collapse multiple tightly related bullet points into a single point that refers to multiple commits. -7. Create a new branch, and copy this text to the [CHANGES.md](CHANGES.md) file, +8. Create a new branch, and copy this text to the [CHANGES.md](CHANGES.md) file, stripping out links, who did each commit, the new contributor list, and the link to the full changelog. -8. Change [version.py](ops/version.py)'s `version` to the +9. Change [version.py](ops/version.py)'s `version` to the [appropriate string](https://semver.org/). -9. Check if there's a `chore: update charm pins` auto-generated PR in the queue. If it looks +10. Check if there's a `chore: update charm pins` auto-generated PR in the queue. If it looks good, merge it and check that tests still pass. If needed, you can re-trigger the `Update Charm Pins` workflow manually to ensure latest charms and ops get tested. -10. Add, commit, and push, and open a PR to get the changelog and version bump +11. Add, commit, and push, and open a PR to get the changelog and version bump into main (and get it merged). -11. Back in the GitHub releases page, tweak the release notes - for example, +12. Back in the GitHub releases page, tweak the release notes - for example, you might want to have a short paragraph at the intro on particularly noteworthy changes. -12. Have someone else in the Charm-Tech team proofread the release notes. -13. When you are ready, click "Publish". (If you are not ready, click "Save as Draft".) - -This will trigger an automatic build for the Python package and publish it to -[PyPI](https://pypi.org/project/ops/)) (authorisation is handled via a +13. Have someone else in the Charm-Tech team proofread the release notes. +14. When you are ready, click "Publish". (If you are not ready, click "Save as Draft".) +15. If the release includes an `ops-scenario` package, then create a new tag in + the form `scenario-..`. + +This will trigger automatic builds for the Python packages and publish them to +PyPI ([ops](https://pypi.org/project/ops/) and +[ops-scenario](https://pypi.org/project/ops-scenario)) (authorisation is handled via a [Trusted Publisher](https://docs.pypi.org/trusted-publishers/) relationship). -Note that it sometimes take a bit of time for the new release to show up. +Note that it sometimes take a bit of time for the new releases to show up. + +To do a release that does not include an `ops-scenario` package, skip the +step above where a `scenario-` tag is created. To do a release that does not +include an `ops` package, create the `scenario-..` tag as +part of the GitHub release process instead of the `..` one. -See [.github/workflows/publish.yml](.github/workflows/publish.yml) for details. (Note that the versions in publish.yml refer to versions of the GitHub actions, not the versions of the ops library.) +See [.github/workflows/publish-ops.yaml](.github/workflows/publish-ops.yaml) and +[.github/workflows/publish-ops-scenario.yaml](.github/workflows/publish-ops-scenario.yaml) for details. +(Note that the versions in the YAML refer to versions of the GitHub actions, not the versions of the ops library.) You can troubleshoot errors on the [Actions Tab](https://github.com/canonical/operator/actions). -13. Announce the release on [Discourse](https://discourse.charmhub.io/c/framework/42) and [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com) +16. Announce the release on [Discourse](https://discourse.charmhub.io/c/framework/42) and [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com). Mention both the `ops` and `ops-scenario` releases in the same posts, but avoid the word "Scenario", preferring "unit testing API" or "state transition testing". -14. Open a PR to change [version.py](ops/version.py)'s `version` to the expected +17. Open a PR to change [version.py](ops/version.py)'s `version` to the expected next version, with ".dev0" appended (for example, if 3.14.1 is the next expected version, use - `'3.14.1.dev0'`). + `'3.14.1.dev0'`) and [testing/pyproject.toml](testing/pyproject.toml)'s + `version` similarly. diff --git a/testing/CHANGES.md b/testing/CHANGES.md new file mode 100644 index 000000000..b60094e9a --- /dev/null +++ b/testing/CHANGES.md @@ -0,0 +1,43 @@ +# 7.0.5 - 20 Sep 2024 + +## Features + +* Use a slightly more strict type for `AnyJson` + +# 7.0.4 - 18 Sep 2024 + +## Chores + +* Add a `py.typed` file + +# 7.0.3 - 18 Sep 2024 + +## Fixes + +* `ops.Model.get_relation` should not raise when a relation with the specified ID does not exist + +# 7.0.2 - 13 Sep 2024 + +## Refactor + +* Adjustments to handle the upcoming release of ops 2.17 + +# 7.0.1 - 9 Sep 2024 + +## Fixes + +* Fix broken Python 3.8 compatibility. + +# 7.0.0 - 9 Sep 2024 + +## Features + +* Support for testing Pebble check events +* Container exec mocking can match against a command prefix +* Inspect a list of the commands that a charm has `exec`'d in a container +* Add consistency checks for `StoredState` +* Specifying your event is now done via `ctx.on` attributes +* The context manager is accessed via the `Context` object +* State collections are frozensets instead of lists +* Most classes now expect at least some arguments to be passed as keywords +* Secret tests are much simpler - particularly, revision numbers do not need to be managed From 6efe0541f1e8dd97af2de0d57870b8c5febc8da8 Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Tue, 15 Oct 2024 11:40:50 +1300 Subject: [PATCH 2/5] Add more details about the use of tags and the release documentation. --- HACKING.md | 189 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 138 insertions(+), 51 deletions(-) diff --git a/HACKING.md b/HACKING.md index d6d7e4a0b..9738fc43c 100644 --- a/HACKING.md +++ b/HACKING.md @@ -318,65 +318,152 @@ the build frontend is [build](https://pypi.org/project/build/). # Publishing a Release -To make a release of the ops library, do the following: - -1. Visit the [releases page on GitHub](https://github.com/canonical/operator/releases). -2. Click "Draft a new release" -3. The "Release Title" is the full version numbers of ops and ops-scenario, in - the form `ops .. & ops-scenario ..` - and a brief summary of the main changes in the releases. If the release only - includes one of `ops` and `ops-scenario`, leave out the other one. +To make a release of the `ops` and/or `ops-scenario` packages, do the following: + +1. Check if there's a `chore: update charm pins` auto-generated PR in the queue. + If it looks good, merge it and check that tests still pass. If needed, you + can re-trigger the `Update Charm Pins` workflow manually to ensure latest + charms and ops get tested. +2. Visit the [releases page on GitHub](https://github.com/canonical/operator/releases). +3. Click "Draft a new release" +4. The "Release Title" is the full version numbers of ops and/or ops-scenario, + in the form `ops .. and ops-scenario ..` + and a brief summary of the main changes in the release. For example: `ops 2.3.12 Bug fixes for the Juju foobar feature when using Python 3.12` -4. Have the release create a new tag, in the form `..` -5. Use the "Generate Release Notes" button to get a copy of the changes into the - notes field. -6. Group the changes first by package (`ops` and `ops-scenario`) and then by - the commit type (feat, fix, etc.) and use full names (e.g., "Features", - not "feat") for group headings. Strip the commit type prefix from the bullet point, - and capitalise the first word. Strip the username (who did each commit) if the - author is a member of the Charm Tech team. - For example: the PR `docs: clarify where StoredState is stored` - becomes `* Clarify where StoredState is stored` in the "Documentation" section. -7. Where appropriate, collapse multiple tightly related bullet points into a - single point that refers to multiple commits. -8. Create a new branch, and copy this text to the [CHANGES.md](CHANGES.md) file, - stripping out links, who did each commit, the new contributor list, and the - link to the full changelog. -9. Change [version.py](ops/version.py)'s `version` to the - [appropriate string](https://semver.org/). -10. Check if there's a `chore: update charm pins` auto-generated PR in the queue. If it looks - good, merge it and check that tests still pass. If needed, you can re-trigger the - `Update Charm Pins` workflow manually to ensure latest charms and ops get tested. -11. Add, commit, and push, and open a PR to get the changelog and version bump +5. Have the release create a new tag, in the form `..` for + `ops` and `scenario-..` for `ops-scenario`. If releasing + both packages, use the ops tag. +6. Use the "Generate Release Notes" button to get a copy of the changes into the + notes field. The 'Release Documentation' section below details the form that + the release notes and changelog should take. +7. For `ops`, change [version.py](ops/version.py)'s `version` to the + appropriate string. For `ops-scenario`, change the version in + [testing/pyproject.toml](testing/pyproject.toml). Both packages use + [semantic versioning]](https://semver.org/), and adjust independently + (that is: ops 2.18 doesn't imply ops-scenario 2.18, or any other number). +8. Add, commit, and push, and open a PR to get the changelogs and version bumps into main (and get it merged). -12. Back in the GitHub releases page, tweak the release notes - for example, - you might want to have a short paragraph at the intro on particularly - noteworthy changes. -13. Have someone else in the Charm-Tech team proofread the release notes. -14. When you are ready, click "Publish". (If you are not ready, click "Save as Draft".) -15. If the release includes an `ops-scenario` package, then create a new tag in - the form `scenario-..`. - -This will trigger automatic builds for the Python packages and publish them to -PyPI ([ops](https://pypi.org/project/ops/) and -[ops-scenario](https://pypi.org/project/ops-scenario)) (authorisation is handled via a -[Trusted Publisher](https://docs.pypi.org/trusted-publishers/) relationship). +9. Save the release notes as a draft, and have someone else in the Charm-Tech + team proofread the release notes. +10. If the release includes both `ops` and `ops-scenario` packages, then push a + new tag in the form `scenario-..`. This is done by + executing `git tag scenario-x.y.z`, then `git push upstream --tags` locally + (assuming you have configured `canonical/operator` as a remote named + `upstream`). +11. When you are ready, click "Publish". GitHub will create the additional tag. + +Pushing the tags will trigger automatic builds for the Python packages and +publish them to PyPI ([ops](https://pypi.org/project/ops/) and +[ops-scenario](https://pypi.org/project/ops-scenario)) (authorisation is handled +via a [Trusted Publisher](https://docs.pypi.org/trusted-publishers/) relationship). Note that it sometimes take a bit of time for the new releases to show up. -To do a release that does not include an `ops-scenario` package, skip the -step above where a `scenario-` tag is created. To do a release that does not -include an `ops` package, create the `scenario-..` tag as -part of the GitHub release process instead of the `..` one. - See [.github/workflows/publish-ops.yaml](.github/workflows/publish-ops.yaml) and [.github/workflows/publish-ops-scenario.yaml](.github/workflows/publish-ops-scenario.yaml) for details. (Note that the versions in the YAML refer to versions of the GitHub actions, not the versions of the ops library.) You can troubleshoot errors on the [Actions Tab](https://github.com/canonical/operator/actions). -16. Announce the release on [Discourse](https://discourse.charmhub.io/c/framework/42) and [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com). Mention both the `ops` and `ops-scenario` releases in the same posts, but avoid the word "Scenario", preferring "unit testing API" or "state transition testing". +12. Announce the release on [Discourse](https://discourse.charmhub.io/c/framework/42) and [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com). + +13. Open a PR to change the version strings to the expected + next version, with ".dev0" appended (for example, if 3.14.1 is the next + expected version, use `'3.14.1.dev0'`). + +## Release Documentation + +`ops` and `ops-scenario` releases have several documentation artifacts, each +serving a separate purpose and covering a different level. + +Avoid using the word "Scenario", preferring "unit testing API" or "state +transition testing". Users should install `ops-scenario` with +`pip install ops[testing]` rather than using the `ops-scenario` package name +directly. + +### `git log` + +`git log` is used to see every change since a previous release. Obviously, no +special work needs to be done so that this is available. A link to the GitHub +view of the log will be included at the end of the GitHub release notes when +the "Generate Release Notes" button is used, in the form: + +``` +**Full Changelog**: https://github.com/canonical/operator/compare/2.17.0...2.18.0 +``` + +These changes include both `ops` and `ops-scenario`. If someone needs to see +changes only for one of the packages, then the `/testing/` folder can be +filtered in/out. + +### CHANGES.md + +A changelog is kept in version control that simply lists the changes in each +release, other than chores like bumping version numbers. The changelog for `ops` +is at the top level, in [CHANGES.md](CHANGES.md), and the changelog for +`ops-scenario` is in the `/testing` folder, [CHANGES.md](testing/CHANGES.md). +There will be overlap between the two files, as many PRs will include changes to +common infrastructure, or will adjust both `ops` and also the testing API in +`ops-scenario`. + +Adding the changes is done in preparation for a release. Use the "Generate +Release Notes" button in the GitHub releases page, and copy the text to the +CHANGES.md files. + +* Group the changes by the commit type (feat, fix, and so on) and use full names + ("Features", not "feat", "Fixes", not "fix") for group headings. +* Remove any bullets that do not apply to the package (`ops` only changes for + `ops-scenario`, and `ops-scenario` only changes for `ops`). +* Strip the commit type prefix from the bullet point, and capitalise the first + word. +* Strip the username (who did each commit) if the author is a member of the + Charm Tech team. +* Replace the link to the pull request with the PR number in parentheses. +* Where appropriate, collapse multiple tightly related bullet points into a + single point that refers to multiple commits. + +For example: the PR + +``` +* docs: clarify where StoredState is stored by @benhoyt in https://github.com/canonical/operator/pull/2006 +``` + +is added to the "Documentation" section as: + +``` +* Clarify where StoredState is stored (#2006) +``` + +### GitHub Release Notes + +The GitHub release notes include the list of changes found in the changelogs, +but: + +* If both `ops` and `ops-scenario` packages are being released, include all the + changes in the same set of release notes. If only one package is being + released, remove any bullets that apply only to the other package. +* The links to the PRs are left in full. +* Add a section above the list of changes that briefly outlines any key changes + in the release. + +### Discourse Release Announcement + +Post to the [framework category](https://discourse.charmhub.io/c/framework/42) +with a subject matching the GitHub release title. + +The post should resemble this: + +``` +The Charm Tech team has just released version x.y.z of ops! + +It’s available from PyPI by using `pip install ops`, and `pip install ops[testing]`, +which will pick up the latest version. Upgrade by running `pip install --upgrade ops`. + +The main improvements in this release are ... + +Read more in the [full release notes on GitHub](link to the GitHub release). +``` -17. Open a PR to change [version.py](ops/version.py)'s `version` to the expected - next version, with ".dev0" appended (for example, if 3.14.1 is the next expected version, use - `'3.14.1.dev0'`) and [testing/pyproject.toml](testing/pyproject.toml)'s - `version` similarly. +In the post, outline the key improvements both in `ops` and `ops-scenario` - +the point here is to encourage people to check out the full notes and to upgrade +promptly, so ensure that you entice them with the best that the new versions +have to offer. From c204005521db0c00c9d9715fd7078d400f691d29 Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Tue, 15 Oct 2024 12:35:03 +1300 Subject: [PATCH 3/5] Update HACKING.md --- HACKING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index 9738fc43c..4bde9f2b9 100644 --- a/HACKING.md +++ b/HACKING.md @@ -347,7 +347,7 @@ To make a release of the `ops` and/or `ops-scenario` packages, do the following: team proofread the release notes. 10. If the release includes both `ops` and `ops-scenario` packages, then push a new tag in the form `scenario-..`. This is done by - executing `git tag scenario-x.y.z`, then `git push upstream --tags` locally + executing `git tag scenario-x.y.z`, then `git push upstream tag scenario-x.y.z` locally (assuming you have configured `canonical/operator` as a remote named `upstream`). 11. When you are ready, click "Publish". GitHub will create the additional tag. From 8dab1f87a95ac31fe309db64e89ec4e21d5af983 Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Tue, 15 Oct 2024 12:36:27 +1300 Subject: [PATCH 4/5] Update HACKING.md --- HACKING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index 4bde9f2b9..7afe69feb 100644 --- a/HACKING.md +++ b/HACKING.md @@ -372,7 +372,7 @@ You can troubleshoot errors on the [Actions Tab](https://github.com/canonical/op ## Release Documentation -`ops` and `ops-scenario` releases have several documentation artifacts, each +`ops` and `ops-scenario` releases have several documentation artefacts, each serving a separate purpose and covering a different level. Avoid using the word "Scenario", preferring "unit testing API" or "state From f044748969f08be361b6e2f800a8776f45a5185b Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Tue, 15 Oct 2024 13:29:18 +1300 Subject: [PATCH 5/5] Tweaks, per review. --- HACKING.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/HACKING.md b/HACKING.md index 7afe69feb..2873ede45 100644 --- a/HACKING.md +++ b/HACKING.md @@ -330,27 +330,30 @@ To make a release of the `ops` and/or `ops-scenario` packages, do the following: in the form `ops .. and ops-scenario ..` and a brief summary of the main changes in the release. For example: `ops 2.3.12 Bug fixes for the Juju foobar feature when using Python 3.12` -5. Have the release create a new tag, in the form `..` for +5. If the last release was for both `ops` and `ops-scenario`, leave the previous + tag choice on `auto`. If the last release was for only one package, change + the previous tag to be the last time the same package(s) were being released. +6. Have the release create a new tag, in the form `..` for `ops` and `scenario-..` for `ops-scenario`. If releasing both packages, use the ops tag. -6. Use the "Generate Release Notes" button to get a copy of the changes into the +7. Use the "Generate Release Notes" button to get a copy of the changes into the notes field. The 'Release Documentation' section below details the form that the release notes and changelog should take. -7. For `ops`, change [version.py](ops/version.py)'s `version` to the +8. For `ops`, change [version.py](ops/version.py)'s `version` to the appropriate string. For `ops-scenario`, change the version in [testing/pyproject.toml](testing/pyproject.toml). Both packages use [semantic versioning]](https://semver.org/), and adjust independently (that is: ops 2.18 doesn't imply ops-scenario 2.18, or any other number). -8. Add, commit, and push, and open a PR to get the changelogs and version bumps +9. Add, commit, and push, and open a PR to get the changelogs and version bumps into main (and get it merged). -9. Save the release notes as a draft, and have someone else in the Charm-Tech +10. Save the release notes as a draft, and have someone else in the Charm-Tech team proofread the release notes. -10. If the release includes both `ops` and `ops-scenario` packages, then push a +11. If the release includes both `ops` and `ops-scenario` packages, then push a new tag in the form `scenario-..`. This is done by executing `git tag scenario-x.y.z`, then `git push upstream tag scenario-x.y.z` locally (assuming you have configured `canonical/operator` as a remote named `upstream`). -11. When you are ready, click "Publish". GitHub will create the additional tag. +12. When you are ready, click "Publish". GitHub will create the additional tag. Pushing the tags will trigger automatic builds for the Python packages and publish them to PyPI ([ops](https://pypi.org/project/ops/) and @@ -364,16 +367,16 @@ See [.github/workflows/publish-ops.yaml](.github/workflows/publish-ops.yaml) and You can troubleshoot errors on the [Actions Tab](https://github.com/canonical/operator/actions). -12. Announce the release on [Discourse](https://discourse.charmhub.io/c/framework/42) and [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com). +13. Announce the release on [Discourse](https://discourse.charmhub.io/c/framework/42) and [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com). -13. Open a PR to change the version strings to the expected +14. Open a PR to change the version strings to the expected next version, with ".dev0" appended (for example, if 3.14.1 is the next expected version, use `'3.14.1.dev0'`). ## Release Documentation -`ops` and `ops-scenario` releases have several documentation artefacts, each -serving a separate purpose and covering a different level. +We produce several pieces of documentation for `ops` and `ops-scenario` +releases, each serving a separate purpose and covering a different level. Avoid using the word "Scenario", preferring "unit testing API" or "state transition testing". Users should install `ops-scenario` with