Skip to content

Releases: sasmaq/incrmit

v0.3.6

Choose a tag to compare

@github-actions github-actions released this 28 Sep 05:23

[0.3.6] - 2026-09-28

Security

  • A state file can no longer point undo at a file outside the project. It was
    the one way incrmit wrote to a path no trusted input named: the config is
    trusted like a Makefile, but a repository can commit .incrmit.state.toml,
    and its recorded absolute paths sent undo to any file you can write that
    held the recorded version. undo now writes only to files the config lists
    and to that config. An absolute or ../ path is still undone when the config
    lists it.

Changed

  • undo works on the project whose config it is given, not the directory the
    bump ran in. The state file recorded every file's absolute path and the
    config's, and undo acted on those, so undo in a copy of a project reverted
    the original, reported the change as though it were local, and popped the
    copy's entry, and undo in a moved project failed looking for the config where
    it used to be. Entries now record each path as incrmit.toml lists it,
    resolved against the config undo is given. Older state files still load,
    with the absolute paths ignored.
  • undo reverts only files the config lists at the version the bump wrote, and
    otherwise refuses, naming the file, with nothing written. This also stops an
    undo after the config was edited since the bump, which used to revert the
    files and leave the edited config entries as they were.

Removed

  • Releases no longer publish checksums.txt and checksums-macos.txt. GitHub
    records a SHA-256 digest for every release asset and shows it on the release
    page, so the files duplicated what is already there. The checksums and
    pkg-checksums make targets are gone with them.

v0.3.5

Choose a tag to compare

@github-actions github-actions released this 27 Sep 17:21

[0.3.5] - 2026-09-27

Security

  • The config and the state file are no longer opened when they are not ordinary
    files. incrmit.toml, the --output that discover reads an ignore list
    from, and .incrmit.state.toml skipped the check that bump targets get, so a
    named pipe at any of them hung the command with no output. That included
    preview and discover --dry-run, the commands meant for a tree you do not
    own. A repository can also commit incrmit.toml -> /dev/zero, which was read
    without end. Each is now reported as not a regular file with exit 1 before
    anything is written. A link to an ordinary file is still followed.
  • The config and the state file are capped at 16 MiB. The state file drops its
    oldest entries rather than grow past the cap, so a project with thousands of
    files keeps fewer than 20 bumps to undo instead of failing to read its own
    history.

Fixed

  • A bump whose state file cannot be read now fails before writing anything. The
    state file used to be read last, so a bump could rewrite every target and the
    config and then fail, leaving no entry for undo to find. --dry-run reads
    it too and reports the same failure.

v0.3.4

Choose a tag to compare

@github-actions github-actions released this 25 Sep 22:42

[0.3.4] - 2026-09-26

Security

  • The project lock no longer writes through a symbolic link. .incrmit.lock
    was opened following links and truncated to hold the lock's note, so a
    repository that committed it as a link to a file outside the tree had that
    file's contents replaced with two lines of lock text by the first discover,
    bump, or undo in the clone, and a dangling link created the file it named.
    The lock file is now opened without following links. A link, a directory, or
    a named pipe at that path is left as it is, named in a warning, and the run
    continues unlocked. A regular file already there is used as the lock but
    never rewritten: the note goes only into a lock file that is empty.

Fixed

  • The warning for an unavailable project lock names the lock file once, rather
    than repeating its path inside the OS error.

v0.3.3

Choose a tag to compare

@github-actions github-actions released this 25 Sep 02:24

[0.3.3] - 2026-09-25

Security

  • Names and file contents no longer reach the terminal raw. A file in a scanned
    tree could carry escape sequences in its name or on its version line, and
    discover --dry-run — the command meant for trees you do not own — printed
    them as they were, letting the file clear the screen, retitle the window,
    plant a hyperlink, or write to the clipboard on terminals that allow it. All
    output now passes through an escaping layer: a name with a control character,
    a bidirectional override, or a byte that is not UTF-8 is shown Go-quoted
    ("invoice\u202efdp.exe"), and such characters in a context line appear as
    escapes (\x1b[2J). Ordinary names and text print unchanged, and files are
    still read, written, and recorded under their real names.

Fixed

  • incrmit discover on Linux no longer writes a config that cannot be loaded
    when a file name is not valid UTF-8. TOML cannot hold such a name, so the file
    is now skipped with a warning.

  • A filesystem error names the file once, rather than repeating its raw path
    after the name (reading X: stat X: file name too long).

  • incrmit discover no longer slows to a crawl on minified files. Each
    occurrence kept a copy of its whole line and recounted lines from the top of
    the file, so a 620 KB one-line bundle holding twenty thousand versions took
    seconds and allocated about 12 GB. The scan is now a single pass, and the
    --dry-run context for a long line is clipped to 80 bytes on each side of the
    version, with ... marking each cut.

  • discover --dry-run numbers lines correctly in files with classic-Mac (\r)
    line endings. Such a file was reported as one line, and its carriage returns
    were printed to the terminal, which overprinted the output. A lone \r now
    ends a line, as it does in an editor, and a UTF-8 byte-order mark is left out
    of the first line's context.

  • A file that grows past the discovery size cap while it is being read is
    skipped, as a file over the cap already was, rather than scanned up to the
    cap. A cut falling mid-token could record 1.2.34 as 1.2.3.

Documented

  • What a bump keeps and what it gives up: line endings, a byte-order mark, and a
    missing final newline are preserved exactly; UTF-16 files are not supported
    and report no version; and because the new contents are renamed into place,
    permission bits survive (a read-only file is still bumped) while setuid,
    setgid, and sticky bits, hard links, ownership, and extended attributes do
    not. See "What a bump keeps" in README.md.
  • ignore patterns match a metacharacter literally when it is bracketed
    (v[*].txt); a config path and --file are always literal names.

v0.3.2

Choose a tag to compare

@github-actions github-actions released this 21 Sep 23:04

[0.3.2] - 2026-09-22

Fixed

  • A version with a leading zero in one of its numeric components (1.02.3) no
    longer reports a successful bump while leaving the file untouched. The token
    parsed as 1.2.3, so the rewriter went looking for the text 1.2.3, found
    nothing, and wrote the file back unchanged — incrmit --patch printed
    1.2.3 -> 1.2.4 over a file that still said 1.02.3. Leading zeros are
    rejected now, as semver requires, so the file reports "no semantic version
    found" and says which file it is.
  • A version token ending in a hyphen (1.2.3+0-) is rejected for the same
    reason: semver permits it, but the scanner stops at the word boundary and
    reads it back out of a file as 1.2.3+0, so a config could pin a token no
    bump could ever locate.
  • --max-file-size now accepts the 1234 bytes spelling that incrmit itself
    prints for a limit that is not a whole number of KiB/MiB/GiB. The flag showed
    a default the flag would not take back.

Added

  • Fuzz targets over the version parser, the token scanner, the file rewriter,
    the size parser, and config loading, with make fuzz to run them locally and
    a CI job that runs a bounded pass on every push. See doc/DEVELOPMENT.md
    §12.1 for what each one proves; the three fixes above are what the first pass
    found.

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 19 Sep 00:21
Add lock

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 19 Sep 00:00

[0.3.0] - 2026-09-19

Fixed

  • Broadened test coverage over paths that had none, so the behavior they
    describe cannot regress unnoticed: reading a version from a file, splitting a
    version token across the config's keys, semver precedence for prerelease
    numbers too large for a 64-bit integer, drift detection following the version
    most files hold rather than the first one listed, ignore patterns that trim to
    nothing or outrun the path, an unreadable file being skipped by discover
    instead of failing the scan, and undo refusing a journal whose recorded
    version does not parse. Coverage rose from 92.9% to 95.8%.

Changed

  • The build and release pipeline runs on current GitHub Actions: checkout
    v7.0.1, setup-go v7.0.0, and action-gh-release v3.0.3, each still pinned
    to a commit SHA. The previous pins ran on the deprecated Node 20 runtime,
    which GitHub had begun forcing onto Node 24 anyway.
  • Building incrmit now requires Go 1.27 or later, up from Go 1.26. The go
    directive in go.mod and the requirement documented in README.md were
    raised together; CI already built with whatever stable resolves to, which is
    Go 1.27.
  • CI lints with golangci-lint v2.13.2, up from v2.12.2. A released
    golangci-lint can only typecheck the standard library of the Go it was built
    with or older, so Go 1.27 becoming stable made the older pin fail on Go's
    own internal/poll rather than on anything in this repository.

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 18 Aug 20:46

[0.2.1] - 2026-08-18

Added

  • An incrmit preview command shows, for every file in the config, the version
    it holds today alongside what a --patch, --minor, and --major bump
    would write — all three outcomes in one aligned table, without a --dry-run
    per component. It is read-only: no target file, config, or bump history is
    written. The v prefix is carried into every projection, a prerelease or
    build section is dropped exactly as a real bump would drop it, and a file
    listed once per version it contains gets one row per version.
    • Rows whose version differs from the one most entries hold are marked *
      and explained under the table, so a file left behind by a partial bump is
      visible at a glance. Only semver precedence counts as a difference, so
      v1.2.3, 1.2.3, and 1.2.3+build.7 are never marked against each other.
    • --file / -f previews a single target without a config, and
      --max-file-size / -s applies as it does to a bump.

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 14 Aug 14:53

[0.2.0] - 2026-08-14

Added

  • Semver prerelease and build metadata are now first-class:
    1.2.3-rc.1, 1.2.3+build.7, and v2.0.0-beta.1+exp.sha.5114f85 are parsed,
    recorded by incrmit discover, and rewritten as whole tokens. A version
    pinned in incrmit.toml matches the full token, so a prerelease and the
    release it names are never mistaken for each other, even in the same file.
    A version welded into a longer hyphen-joined word keeps only its numbers, so
    release filenames and download URLs still bump as expected
    (incrmit-1.2.3-linux-amd64.tar.gz -> incrmit-1.2.4-linux-amd64.tar.gz)
    rather than having the filename read as a prerelease and rewritten away.
  • incrmit.toml records a running prerelease in its own prerelease key (and
    build metadata in build) beside the numeric version. --pre writes the
    key, --release and any component bump remove it, so the config reads as the
    project's actual state. Because the config now says which suffix belongs to
    the version, a prerelease is tracked correctly even where it sits inside a
    release filename: --release turns app-1.2.3-rc.1.zip into
    app-1.2.3.zip, and a prerelease written into a download URL is found again
    on the next step instead of being stranded at -rc.1. Configs that spell the
    whole token in version (version = "1.2.3-rc.1") keep working and are
    migrated to the split form on the next write.
  • A --release / -r flag promotes a prerelease to the release it names
    (1.2.3-rc.1 -> 1.2.3) without touching the numbers. Using it on a version
    that has no prerelease, or alongside --pre or a component flag, is a usage
    error (exit 2).
  • A --pre <id> / -e <id> flag starts or advances a prerelease:
    1.2.3 -> 1.2.4-rc.1, then 1.2.4-rc.1 -> 1.2.4-rc.2. Naming a component
    alongside it opens a new release line instead (--minor --pre rc gives
    1.3.0-rc.1).

Fixed

  • A bump no longer mangles a prerelease or build version. The token matcher
    stopped at the numeric core, so 1.2.3-rc.1 bumped to 1.2.4-rc.1 and
    1.2.3+build.7 to 1.2.4+build.7 — both wrong under semver, and both leaving
    a suffix attached to a version it no longer described. A --major, --minor,
    or --patch bump now drops both sections (1.2.3-rc.1 -> 1.2.4), matching
    every other bump tool; use --release or --pre to work within a prerelease.

v0.1.15

Choose a tag to compare

@github-actions github-actions released this 02 Aug 21:25

[0.1.15] - 2026-08-03

Added

  • A --max-file-size / -s flag sets the largest file incrmit will read.
    Values are written as a byte count (1048576) or with a unit suffix (512KB,
    32MiB, 2G), and 0 means no limit.
    • incrmit discover --max-file-size adjusts the 32 MiB cap that decides which
      files a scan reads: lower it to keep a scan light on a tree full of large
      generated files, or set 0 to scan everything.
    • incrmit --max-file-size puts a cap on the files a bump reads. There is
      still no cap by default, since targets are listed by hand; when one is set,
      a target over the limit is reported (naming the file and the limit) and the
      bump writes nothing at all.

Security

  • incrmit discover no longer follows symlinks. Previously a link inside the
    scanned tree pointing at a file elsewhere was read, its matched line shown in
    --dry-run output, and — once recorded in the config — its contents copied into
    the tree by the next bump. Scanning a checkout you did not author can no longer
    reach outside the directory you pointed at.
  • incrmit discover now reads only regular files. A named pipe in the tree used
    to hang the scan indefinitely (a read waits for a writer), and a link to an
    endless device such as /dev/zero read without limit until memory ran out.
  • A bump target that is not an ordinary file is now reported instead of hanging.
    Naming a pipe in incrmit.toml or passing one to --file used to leave
    incrmit waiting forever with no output. A config entry is rejected up front
    as config: target <path> is not a regular file, alongside the existing check
    for a target that is a directory; a --file target is reported as
    reading <path>: not a regular file.
  • incrmit discover now skips files larger than 32 MiB, so one very large file
    in a tree can no longer drive the scan's memory use without bound. Version
    strings live in small text files, and files listed in the config by hand are
    unaffected.
  • Every published artifact now has a SHA-256 hash. The macOS .pkg installers
    previously shipped with none, even though README.md documented verifying them;
    their hashes are now published as checksums-macos.txt alongside the existing
    checksums.txt.
  • Release binaries are built with -trimpath, so they no longer embed absolute
    paths from the machine that built them and the same source produces the same
    bytes anywhere.
  • GitHub Actions in both workflows are pinned to commit SHAs instead of movable
    tags, workflow permissions default to read-only with write granted only to the
    jobs that publish, and govulncheck now gates both CI and the release. Steps
    that install a Go tool set GOPROXY and GOSUMDB explicitly, so the
    checksum verification that makes a pinned version immutable cannot be lost
    to a change in the runner's defaults.

Fixed

  • Documented that incrmit.toml is trusted input: a target path may be
    absolute or reach outside the config's directory with ../, so review a config
    before running incrmit in a checkout you do not control.
  • Documented that a target which is a symlink is replaced by a regular file rather
    than written through, leaving whatever it pointed at untouched.