Skip to main content

Module version

Module version 

Source
Expand description

Hybrid Git-based SemVer.

DevFlow derives the version entirely from git history (D-11) — the version file (Cargo.toml, pyproject.toml, or package.json) is no longer an input to compute_version, only an output write_version produces:

  • Baseline — the highest semver tag reachable from HEAD (reachable_semver_baseline, D-07). If the highest semver tag in the repository overall is NOT reachable from HEAD, compute_version refuses rather than silently falling back to a smaller reachable tag (D-10).
  • Bump — classified from the conventional-commit intent of the commits added since that baseline was released (classify_range_bump, D-08), over a range anchored by release_range_start to survive this repository’s squash-merge + sync-back release topology.

Structs§

SelfPin
One [workspace.dependencies] self-pin discovered by read_workspace_self_pins — a local-path dependency’s name and its pinned version sub-value.
Version
A semantic version, whether read from disk or computed from git history.

Enums§

Bump
The classified conventional-commit bump for a range of commits (D-08). Declaration order is the precedence order (lowest to highest), so Iterator::max()/Ord::max over a range’s individual classifications yields the highest-precedence result directly.
ChangelogHeading
Keep-a-Changelog heading a changelog bullet is grouped under (D-12). Declaration order is the render order render_changelog_body emits sections in: breaking changes first, then what’s new, then what’s fixed, then everything else.
VersionError
Errors produced by version operations.

Constants§

CHANGELOG_SUBJECT_MAX_CHARS
Maximum length, in characters, of a sanitized changelog bullet (sanitize_changelog_subject).

Functions§

changelog_sections
Group --no-merges commits in range_start..HEAD by ChangelogHeading (D-12). Walks the identical range and git log --no-merges <range> --format=%H%x1f%B%x1e argv as classify_range_bump (same record separators, same git_conventional::Commit::parse call) — but, unlike classify_range_bump (which folds every commit down to a single aggregate Bump value; see RESEARCH.md Pitfall 1), collects each commit’s subject into its group instead of discarding it. classify_range_bump’s returned Bump is never used as changelog content; this is sibling code, not a wrapper around it.
classify_range_bump
Classify the highest-precedence conventional-commit bump over --no-merges commits in range_start..HEAD. range_start may be the empty string, meaning “no baseline tag exists” — the whole history reachable from HEAD is classified instead (git log --no-merges HEAD, no exclusion).
commits_since_last_minor_tagDeprecated
Count commits since the most recent tag. If there are no tags yet, counts all commits reachable from HEAD.
compute_version
Compute the full version: the baseline resolved from the highest reachable semver tag (D-07), bumped by the conventional-commit classification of the commits added since that baseline was released (D-08). The version file is NOT read here (D-11) — write_version is the only writer, and read_version is the only reader of what’s on disk.
count_git_tagsDeprecated
Count all git tags.
detect_version_file
Detect the project’s version file, checking Cargo.toml, then pyproject.toml, then package.json. Returns the first that exists.
highest_semver_tag
Enumerate every tag in the repository (no reachability restriction), keep only values that parse as vMAJOR.MINOR.PATCH semver (a leading v is stripped first — the semver crate’s grammar is bare MAJOR.MINOR.PATCH), and return the maximum by semver ordering (D-07). A stray non-semver tag (e.g. this repository’s archive-planning-docs-2026-07-24) is silently excluded via filter_map(...ok()) rather than erroring — a malformed tag can never crash this path (T-25-02).
reachable_semver_baseline
As highest_semver_tag, but restricted to tags reachable from HEAD via git tag --merged HEAD — one spawn instead of an O(n) per-tag merge-base --is-ancestor loop, mirroring GitFlow::cleanup_merged’s existing branch --merged precedent in git.rs. This is compute_version’s baseline (D-07).
read_major_version
Read the MAJOR version component from a version file.
read_version
Read the full Version (major/minor/patch) out of whatever version file detect_version_file resolves, mirroring write_version’s format handling (including [workspace.package]).
read_workspace_self_pins
Extract [workspace.package] version and every local-path [workspace.dependencies] self-pin (crate name + pinned version) from a workspace Cargo.toml’s contents.
release_range_start
Resolve the commit range start for D-08’s conventional-commit classifier, given the baseline tag name (e.g. "v2.0.0").
render_changelog_body
Render sections (from changelog_sections) as Keep-a-Changelog markdown: each section’s heading line, a blank line, then one - {subject} line per bullet, with a blank line between sections. Returns an empty string when sections is empty — the “nothing changed” fallback text is crate::ship::prepend_changelog’s responsibility, not this function’s.
sanitize_changelog_subject
Neutralize and bound a commit-derived changelog bullet before it reaches CHANGELOG.md or a tracing line (D-12, ASVS V7, T-26-05). Commit subjects are contributor-authored text — the same attacker-influenced class T-17-13/T-25-52 already redact — so every char::is_control character is mapped to a single space, then, if the result exceeds CHANGELOG_SUBJECT_MAX_CHARS characters, it is truncated so the returned string is exactly CHANGELOG_SUBJECT_MAX_CHARS characters including the trailing … [truncated] marker. Mirrors render_gate_context’s properties (pipeline_outcomes.rs:323) — a sibling, not a shared function, since that one is pub(crate) inside devflow-cli and not importable from devflow-core.
write_version
Write version into the project’s auto-detected version file.