docs: Initial release notes/migration guide support#3287
docs: Initial release notes/migration guide support#3287petejohanson wants to merge 1 commit intozmkfirmware:mainfrom
Conversation
| ::: | ||
|
|
||
| - Added a BLE function for getting profile addresses in [#2992](https://github.com/zmkfirmware/zmk/pull/2992) | ||
| - Add a source info to the battery event in [#2901](https://github.com/zmkfirmware/zmk/issues/2901) |
There was a problem hiding this comment.
Not sure it is worth it at this point, but the wired split PR's refactor moved a few headers around and renamed some functions: 4a2189d
There was a problem hiding this comment.
Fair. Added a bullet item.
| sidebar_label: v0.3 | ||
| --- | ||
|
|
||
| ## Change Summary |
There was a problem hiding this comment.
Added a description to the front matter.
|
|
||
| ZMK has moved to a formal release process that enables and encourages users to use an explicit released version of ZMK. This is a significant departure from the previous practice of builds tracking the latest code found in our `main` branch. | ||
|
|
||
| This is one of many important steps as ZMK works towards a more reliable, repeatable experience for users. Users are _strongly_ encouraged to adjust their builds to [pin](/blog/2025/06/20/pinned-zmk) to the [latest release](/docs/category/release-notes) to avoid disuption from development changes. |
There was a problem hiding this comment.
ZMK CLI has a zmk version <tag> command that will update both the manifest and actions workflow files. It looks like I forgot to document that on /docs/zmk-cli when I added it though. I think it would be good to document that as one way you can pin a specific version, alongside the steps for doing it manually.
There was a problem hiding this comment.
Just pushed a small addition in the v0.3 migration guide, if you could please verify it matches the expectation.
| (i) => | ||
| !( | ||
| args.docs.find((d) => d.id == i.id).frontMatter.unlisted ?? | ||
| false |
There was a problem hiding this comment.
!(thing ?? false) is equivalent to !thing, since !null == !undefined == true
If the intent is to fall back to false if args.docs doesn't include an item, then you need a ?. at the first thing that could be undefined
args.docs.find(...)?.frontMatter.unlisted ?? falsethough the fact that this isn't a problem right now tells me that args.docs is probably guaranteed to contain every item?
There was a problem hiding this comment.
We specifically need to handle the scenario we don't have a value for unlisted in the frontMatter. In that scenario, unlisted should be false. So we need to default to false only if the value isn't explicitly set/present in the frontMatter. Then we need to invert the value, for the expected filtering.
There was a problem hiding this comment.
If frontMatter doesn't have a value for unlisted, then frontMatter.unlisted is undefined. The only cases where ?? evaluates the right-hand side are when the left-hand side is null or undefined, and !null and !undefined are both true, so !(frontMatter.unlisted ?? false) is equivalent to !frontMatter.unlisted.
There was a problem hiding this comment.
Indeed. My tired brain somehow screwed up my testing of that last night. Changed.
| const sidebarItems = await defaultSidebarItemsGenerator(args); | ||
| const filtered = sidebarItems.filter( | ||
| (i) => | ||
| !( |
There was a problem hiding this comment.
Consider pulling part of this out into a helper function with a name that makes it clearer what the code is intended to do. Some ideas for that:
// Top-level helper function
function getFrontMatter(docs, item) {
return docs.find((d) => d.id === item.id);
}
...
const sidebarItems = ...
const filtered = sidebarItems.filter((item) => !getFrontMatter(args.docs, item).unlisted);// Lambda that captures args.docs so it doesn't need to be passed in as an argument
const getFrontMatter = (item) => args.docs.find((d) => d.id === item.id;
const sidebarItems = ...
const filtered = sidebarItems.filter((item) => !getFrontMatter(item).unlisted);// Pull the whole thing into a lambda
const isListed = (item) => !args.docs.find((d) => d.id === item.id).frontMatter.unlisted;
const sidebarItems = (await defaultSidebarItemsGenerator(args)).filter(isListed);There was a problem hiding this comment.
Tweaked a bit.
|
|
||
| ZMK v0.3 introduces initial support for [wired split](https://zmk.dev/docs/features/split-keyboards#full-duplex-wired-uart) devices as well as various bug fixes and minor improvements. For the complete changelog, see the [v0.3.0 release on GitHub](https://github.com/zmkfirmware/zmk/releases/tag/v0.3.0). | ||
|
|
||
| ## Breaking Changes |
There was a problem hiding this comment.
It feels like there's a lot of overlap between the release notes and migration guides pages for the same release. Both list breaking changes. One of them lists changes needed to user configs, while the other lists changes that might be needed to modules, which feels like something that belongs more in a migration guide?
IMO, we should either combine these into single pages for each release, or we should at the very least remove any duplicate info and make sure that every release notes page links to the matching migration guide page.
There was a problem hiding this comment.
So.... Yeah, I've been struggling with this. In particular, this v0.3 doesn't have a particularly significant set of release notes, so it feels a bit silly to have two docs. For larger releases, I think having this split will help bring clarity for folks who just need to go through the upgrade steps. I will move the module change not to the upgrade notes for more consistency, as a bare minimum here.
f761bb4 to
5bcee63
Compare
Add the initial infrastructure for formal release notes and migrations guides, with a retroactive v0.3 set of docs as a start.
5bcee63 to
88eb39d
Compare

Add the initial infrastructure for formal release notes and migrations guides, with a retroactive v0.3 set of docs as a start.
PR check-list