verctl 0.0.1

Stack-agnostic version PRs from Changesets-format fragments
Documentation

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.

mise run ver -- status
mise run ver -- check
mise run ver -- prepare
mise run ver -- prepare --pr
mise run ver -- publish

Setup

min_version = "2026.7.7"

[settings]
experimental = true
lockfile = true

[task_config]
includes = [
  "git::https://github.com/victor-software-house/verctl.git//tasks/ver?ref=<tag>",
]
mise run ver -- status
mise run ver -- check
mise run ver -- publish --dry-run

Until a GitHub Release exists, build from this repo:

cargo run -- status

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.

[drivers.cargo]
format = "toml"
keys = ["workspace.package.version", "package.version"]
# after is optional. If omitted, verctl looks at lockfiles /
# packageManager (bun, pnpm, yarn, npm) and Cargo.lock.

[drivers.npm]
format = "json"
keys = ["version"]
# after = "mise run install"          # overrides detection

[[packages]]
name = "verctl"
path = "Cargo.toml"
# driver = "cargo"   # inferred from the file name

[[packages]]
name = "other"
path = "VERSION"
read = "ver-read-version"          # mise run ver-read-version
write = ["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.