verctl
It reads .changeset/*.md, bumps declared version files, writes
changelogs, and opens or updates one prepare-release PR.
It is not @changesets/cli, not Knope, and not a forkctl verb.
Setup
= "2026.7.7"
[]
= true
= true
[]
= [
"git::https://github.com/victor-software-house/verctl.git//tasks/ver?ref=<tag>",
]
Until a GitHub Release exists, build from this repo:
Fragments
Same file shape as Changesets. YAML fence. Quoted or unquoted keys.
forkctl: patch
"@scope/pkg": minor
Restore mise.toml when later patches unapply.
Allowed bumps: major, minor, patch, none.
Changelog
Rendered with minijinja 2.x from these defaults (override either path):
Default release line:
Internal + PR - Summary ([#12](https://github.com/org/repo/pull/12)).
External + PR - Summary ([#12](https://github.com/org/repo/pull/12) by [@ext](https://github.com/ext)).
Commit only - Summary ([`96fb0bc`](https://github.com/org/repo/commit/96fb0bc)).
No link - Summary.
No extra thanks line. If a PR exists, the SHA is omitted.
Author filtering is not a template if. Config internalAuthors is
matched against the GitHub login for the commit. Those logins get no
byline. Everyone else does.
Version files
verctl prepare applies fragment bumps through drivers.
Local writes are the default. prepare --pr is the Version PR
(Action happy path; the token is GITHUB_TOKEN, not the gh account).
prepare --dry-run / --preview prints the plan and writes nothing.
prepare --pr --preview also shows consumed fragments and open vs update.
Cargo and npm are stock drivers, not a separate code path.
[]
= "toml"
= ["workspace.package.version", "package.version"]
# after is optional. If omitted, verctl looks at lockfiles /
# packageManager (bun, pnpm, yarn, npm) and Cargo.lock.
[]
= "json"
= ["version"]
# after = "mise run install" # overrides detection
[[]]
= "verctl"
= "Cargo.toml"
# driver = "cargo" # inferred from the file name
[[]]
= "other"
= "VERSION"
= "ver-read-version" # mise run ver-read-version
= ["printenv", "VERCTL_VERSION"]
A string is a mise task. An array is execvp (no shell).
Stdin is the file. Write drivers also get VERCTL_VERSION.
Stdout is the version (read) or the new file (write).
after is printed, not run.
0.x rejects a major fragment.
Actions
These replace changesets/action. They are GitHub Actions, not a
GitHub App. The runner already has git and GITHUB_TOKEN. PRs are
opened with octocrab. Commits and push are git2 with that token,
not the git/gh CLIs. There is no local token setup.
| Action | Role |
|---|---|
actions/version-pr |
Open or update the Version PR |
actions/publish |
Run after that PR merges |
Example consumer workflow: examples/workflows/version-pr.yml.
Mise owns tools. Publish uses Actions OIDC, not a PAT.
License
MIT.