Repository navigation
oakum 0.8.0
Added
oakum ci post-comment DIR posts the comment ci pr-status --emit-comment DIR wrote, from a job that holds the write token and has no checkout. It updates oakum's plan comment, or removes it when the emitting run had none, under the same ownership rule pr-status uses. The pull request comes from that job's own event (pull_request, or a same-repository workflow_run), never from the artifact. The body must start with oakum's marker, end with the closing line --emit-comment writes, and fit GitHub's 65,536-character limit; one that does not start with the marker or is over the limit is refused (exit 1).
--emit-comment now always leaves exactly one file, written whole: oakum-pr-comment.md, or oakum-pr-comment.none when the run has no comment. A run that stops first leaves neither. post-comment refuses as unverified (exit 2) when the artifact cannot be trusted whole (neither file or both, a body cut short, an entry that is not a regular file) or the token cannot write, so a lost artifact never reads as nothing to post and an earlier run's comment is never reposted.
With commits-only intent, each commit's summary now reaches only the changelogs of the packages that commit names. Before, every package releasing from a range listed every commit in the range, prefixed with the package it belonged to, so alpha's changelog carried - beta: ... lines. Each commit now lands in its own section by its own level: a fix under ### Fixed, a feat under ### Added, where before all of a package's commits shared the section of its highest level.
A changelog template's file field for a commit-derived change now holds the commit's hash, where it read commits.
A Cargo crate and an npm package with the same name in one directory now both release from an unscoped commit that touches it, as coverage already counted. Before, commits-only planning refused with "commit-derived package <name> matches more than one workspace package".
oakum migrate from knope names each package's scopes list among the remaining steps, saying it was not carried over and that oakum attributes a commit whose scope names no package by the files it changes. The lists used to be dropped without a word.
oakum ci pr-status --emit-comment DIR with pr-status = "none" no longer refuses. It writes no comment or job summary, leaves the oakum-pr-comment.none marker in DIR, and exits 0 without calling GitHub, so the trusted job posting the emitted comment removes the old one after switching to none.
With conventional commits, a commit that asks for a release (feat, fix or breaking) and changes no package's files, under a scope that names no workspace package such as fix(gamma) or fix(alpha,beta), is now reported instead of dropped without a word. A merge under such a scope is reported too, since its paths are not read. A commit with no scope, or a non-conventional message, is not reported. status and ci pr-status list it under "Released by a commit but reaching no package", status --json and the title and commit-message templates carry it as unresolved_scopes (commit, scope), and check, version and generate name it on stderr. Exit codes do not change, --strict included. A commit that releases nothing is not reported, and its ambiguous scope (a Cargo crate and an npm package sharing the name) now falls back to its paths instead of refusing the run.
oakum status and the ci pr-status job summary say what to do next. An empty plan with no bump file pending says so and names oakum add, and oakum generate when conventional commits are on. An uncovered package is followed by the command that covers it, oakum add --packages <package>:<level>, plus oakum generate --from <base> where check would offer it (or a conventional commit naming it, in a commits-only repository), and the pull request comment carries the same line.
The version pull request body from oakum ci version-pr now quotes each package's changelog entry under Release notes, one collapsible block per package, so a reader on the Conversation tab or in email sees what ships, not only what bumps. The entry is read back from the changelog the branch writes. An entry that would take the body past GitHub's 65,536-character limit, or that holds raw HTML which could break the page, is named with its CHANGELOG.md path instead of being cut, and a body still over the limit stops the run before anything is pushed.
Changed
Running oakum with no command prints its help on stderr and exits 2, the usage-error code, where it printed oakum and exited 0. The help lists commands in the order a new user meets them (init, add, generate, status, check, then version, release and ci) and ends with the typical flow and a link to the guides.
check --strict coverage counts only a branch's own intent. A bump file already pending on the base branch no longer covers a pull request that changes the package it names; the branch needs its own bump file (oakum add), or an edit to the pending one. Under conventional commits only, only the branch's commits cover it, not unreleased commits on the base branch. status, status --json (uncovered) and the ci pr-status comment report coverage the same way. A base sharing no history with HEAD leaves coverage unverified (exit 2).
A package's CHANGELOG.md that is a symlink whose target does not exist no longer reads as absent. check reports it under "changelog(s) oakum version would refuse to append to" (exit 2), naming the link and the fix, and migrate lists it among the remaining steps; version already refused to write through it.
A manifest version set by hand above its highest tag, with no changelog section for that version, is now treated like an untagged hand-set version: version and ci version-pr refuse to bump past it (exit 1), and check names it as set by hand with the tag to cut, instead of stacking the next release on it. A version above its tag that has its section, as version writes, is still stacked on. A 0.0.0 or 0.1.0 manifest is checked against tags only when its changelog has a section for an older version, so a new package versions as before, while one whose changelog has one now needs full history: in a shallow clone version exits 2 rather than bump unchecked.
Help text states the --from default from one source: the merge-base with origin/main, else main, else master, with commit-derived intent starting at the highest reachable tag of each package oakum tags. version and ci version-pr say they read --from only for commit-derived intent. Options no longer cite ADR numbers, check --strict names both looks it gates (coverage and notes), and version describes itself in one line.
A manifest below its highest tag, such as 0.1.0 after v0.2.0 shipped, no longer plans a version already released or below one. check fails naming both versions and the fix ("N package(s) below their highest tag"), version and ci version-pr refuse before any write (exit 1), and status, status --json (hand_set) and the ci pr-status comment show the plan as blocked. To tell, these read tags whenever the plan bumps a package oakum tags, tagged yet or not, so in a shallow clone they now exit 2 (unverified) and ask for full history; a fresh 0.0.0 or 0.1.0 package with no earlier changelog section still versions there.
oakum migrate from knope compares plans when nothing is pending. knope's dry run prints nothing and exits 0 then, which migrate read as the tool being unavailable, ending unverified (exit 2) on the usual time to migrate, right after a release. When the workflow it ran has a PrepareRelease step (or knope.toml declares none, so knope's own defaults run), that silence is now an empty before-plan: nothing pending on either side is reported as such and exits 0, and a bump file oakum plans that knope does not is a finding (exit 1). Silence from a workflow with no PrepareRelease step, which knope gives whether or not anything is pending, stays unverified and says why, as does output oakum does not recognise.
check's staging look now sweeps the directory of every file version writes, including a nested workspace's Cargo.toml, Cargo.lock, pnpm-lock.yaml and catalog when they are regular files. A stray oakum staging file beside one of them (rust/.Cargo.lock.oakum-write.…) is reported as unverified (exit 2) instead of passing.
With conventional commits and change files off, the plan (status, version, check, ci pr-status, ci version-pr) now reads each package's commits since its own highest reachable tag, instead of merge-base(origin/main, HEAD)..HEAD. On the default branch that range was empty, so a commits-only repository planned nothing there unless every run passed --from; version now releases on main. A package never tagged reads all of its history. A package version released and no tag records yet (its manifest is above its tag and its changelog has the section) reads no commits until oakum release tags it, so the version pull request job running beside release does not plan the same release twice, wherever the release was cut; check --strict still reads the branch's commits for it, so a branch's own fix covers its change. status lists it under "Released, awaiting its tag", and status --json and the templates as awaiting_tag. A package oakum does not tag keeps the merge-base range. A shallow clone, a --no-tags remote, tags oakum cannot attribute, or one version tagged on two commits now make these commands unverified (exit 2) in commits-only mode, where the plan read no tags before. With a tag to read from, status no longer needs git merge-base for the plan, so a merge-base it cannot get now leaves only its coverage look unchecked (exit 0, "Coverage was not checked") rather than failing the run. --from still reads one range for every package, generate keeps the merge-base range, and check --strict still asks what changed since the merge-base, now against intent pending since each tag.
Conventional commits now release only for feat (minor), fix (patch) and a breaking change (! or a BREAKING CHANGE footer, any type: major), as knope and release-please read the convention. Every other type (docs, chore, ci, refactor, test, …) planned a patch and now releases nothing: it covers the packages it names, as a name: none bump file does, so check --strict does not report them as changed with no covering intent.
This applies to commits-only intent (status, check, version) and to generate, which writes a name: none entry for a package only such commits touched, and leaves their summaries out of a note that releases something. A non-releasing commit to a package the config does not version is not reported as "named by a commit but not version-managed". A message that is not conventional still releases a patch for the packages its files touch.
In a CHANGELOG.md that more than one managed package writes, such as a crate and an npm package in one directory, only a ## <name>@<version> heading is a package's section, and version writes that heading there. A bare ## 0.3.0 no longer makes a hand-set sibling at 0.3.0 read as released by version, and each release body is its own entry rather than the first match. A bare heading for a package's version in a shared changelog, as earlier releases wrote, now stops version, commits-only planning and release (exit 1) with the heading to write, and check reports the version as set by hand. A template whose heading would read as any package's is refused there.
A version heading inside an HTML comment or a <details> block no longer counts as a section, and a bump-file note or template entry that leaves either open is refused like an open code fence. A changelog that leaves one open, which hides every heading after it, is named with its line by check, and version, commits-only planning and release refuse it (exit 1) until it is closed.
status, status --json and the ci pr-status comment now show when the plan bumps a version set by hand, which version refuses until it is tagged. The render names it under "Blocked by a version set by hand" with the fix version prints, and the PR comment lists it before the packages that would release. status --json and the templates carry it as hand_set, one entry per package with name, ecosystem, version and fix. status still exits 0 on a block. When it cannot read the tags or a planned package's changelog it needs to tell, such as in a shallow clone, it now exits 2 (unverified) rather than show the plan as unblocked, naming any version set by hand it did find; a plan with no version that could have been set by hand reads no tags, as before.
oakum ci version-pr exits 0 and writes nothing when a newer push has moved the default branch past the run's checkout: GitHub's compare shows the branch tip descending from HEAD, and stdout names both commits. Back-to-back merges no longer leave a failed version-pr job behind the run that rebuilt the pull request. A tip that is behind or has diverged from HEAD, or a compare GitHub answers with 404, still exits 1, now naming which; a compare that could not be read exits 2.
oakum release tags the commit that set each package's pending version, not HEAD: it walks back along HEAD's first parents to where the manifest (or, for version.workspace = true, [workspace.package]) began declaring the version. A commit that lands between the version commit and a delayed release now stays after the tag and is planned in the next release, rather than shipping inside a tag no plan covered. A version a merge brought in is tagged at the merge, and a package created at its version is tagged where its manifest appeared.
release now refuses as unverified (exit 2) where it used to tag HEAD: when the walk reaches a manifest that names no version oakum can read before it finds where the version was set, when the newest commit to change the manifest declares another version, or when the commit that set the version lacks the changelog section HEAD has for it, as when a version was bumped by hand before adopting oakum. Tag the release by hand and run release again to publish it. A working tree holding changes is refused before the walk. The skip-ci refusal now says that a later commit does not move the tag: tag a clean commit by hand, or start the downstream workflow by hand.
The release body follows a symlinked changelog in the tagged commit rather than falling back to the title, and a +build release takes its body from a bare ## <version> heading, as check already matches it. A link git will not follow (one that loops, is absolute, or leaves the repository) still falls back to the title, and the notice now names which.
oakum ci version-pr no longer opens a version pull request whose only change is deleting bump files that release nothing, such as a none-only bump file from a tests-only change. It prints nothing to version, naming how many pending bump files release nothing, and leaves them for the next real release to consume. A version pull request an earlier plan opened is still refreshed to match, so it stops offering a release whose intent left the default branch; a plan that also bumps a package opens the pull request as before.
Fixed
In a repository using git's reftable ref format, git loads the ref store whole: one table or tables.list it cannot read, in the shared store or a linked worktree's own, makes git list no tags at exit 0. Every command that reads tags now checks each table first, read by path as git reads it, and reports one that cannot be opened, is not a regular file, or does not start like a reftable table as unverified (exit 2), naming the file. Before, the run stayed unverified only because git refs verify crashed on that store, and the message told you to run that same crashing command.
Install oakum 0.8.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/oakoss/oakum/releases/download/v0.8.0/oakum-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/oakoss/oakum/releases/download/v0.8.0/oakum-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install oakoss/tap/oakumInstall prebuilt binaries into your npm project
npm install @oakoss/oakum@0.8.0Download oakum 0.8.0
| File | Platform | Checksum |
|---|---|---|
| oakum-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| oakum-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| oakum-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| oakum-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| oakum-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
| oakum-x86_64-unknown-linux-musl.tar.xz | x64 MUSL Linux | checksum |
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo oakoss/oakumYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>