-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ci: adjust the release process to handle publishing ops and ops-scenario #1432
base: main
Are you sure you want to change the base?
Changes from 2 commits
0e52610
6efe054
0579a7c
c204005
8dab1f8
f044748
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -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 <major>.<minor>.<patch> & ops-scenario <major>.<minor>.<patch>` | ||||||||||
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 <major>.<minor>.<patch> and ops-scenario <major>.<minor>.<patch>` | ||||||||||
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 `<major>.<minor>.<patch>` | ||||||||||
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 `<major>.<minor>.<patch>` for | ||||||||||
`ops` and `scenario-<major>.<minor>.<patch>` 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-<major>.<minor>.<patch>`. | ||||||||||
|
||||||||||
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-<major>.<minor>.<patch>`. This is done by | ||||||||||
executing `git tag scenario-x.y.z`, then `git push upstream --tags` locally | ||||||||||
tonyandrewmeyer marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
(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-<major>.<minor>.<patch>` tag as | ||||||||||
part of the GitHub release process instead of the `<major>.<minor>.<patch>` 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. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sentence left me wondering what these different artefacts are specifically and what the implications are for someone doing a release. Aren't all our docs always tracking main, rather than specific releases? Are the release artifacts changing from just being zipped source code? Oh also today I learned that artifacts is US English, and artefacts is British English. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hmm, I maybe need to use a different term then. They are the things outlined in the subsequent sections: raw logs, changelogs, release notes, release post.
Yes, except for these documents that are specifically about the release.
The zipped and tar.gz repository dump (what GitHub calls "assets") stay the same: I don't think we can change those, and no-one should really be using them. The CI pipeline produces .tar.gz and wheels of the two packages (unchanged for Any suggestions for a better/clearer title here? Or clearer text? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I see now. I just immediately jumped to build artefacts. Probably just my unfamiliarity with terminology. Mentally substituting with "We produce several pieces of documentation for |
||||||||||
|
||||||||||
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth adding a note about choosing the previous release tag to compare to?
I think the rule is: find the previous release tag for each thing you're releasing, and if there is more than one (i.e. an ops only release and a scenario only release), use the older of the two.
Say you had an ops release, then a scenario release, and are now doing a joint release -- you'd want to choose the ops release to generate release notes.
But you'd need to filter out any scenario PRs from before the last scenario release, since they'd have been covered already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is another place where it gets messy, at least in theory. I think in practice it will be unusual to release only one of the packages, so it ends up being fairly simple. The rule is indeed to pick the oldest I think.
The instructions also don't cover what to do for a patch release, or when doing a normal release after a patch release. I'm leaving that for someone else to explain :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add it to the release instructions! "If you're the first one to do a patch release, update the release instructions with what you did and remove this directive."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarification: mostly joking. I'll hit approve now as I don't think any of this is worth blocking merging over (though you have two approvals anyway)