versifyr is a specialized CLI tool designed to synchronize project versions across multiple files. It supports various formats (Go, YAML, XML, Java, JSON, etc.) by using powerful Go templates and Sprig functions to ensure consistency across your entire codebase.
Whether you need to update a Helm chart, a Maven pom.xml, or a Go constant, versifyr automates the process through a single command.
- Format Agnostic: Works with any text-based file format.
- Template Driven: Uses standard Go
text/templatesyntax. - Extensible: Includes Sprig functions for complex string manipulations.
- Flexible Configuration: Define templates directly in source comments or in a central YAML configuration.
- Context Aware: Automatically provides values like
latesttag,actualdate, andactualtimestamp.
go install github.com/zukrin/versifyr/cmd/versifyr@latestRun the following command to create a default .versifyr/configuration.yaml in your project root:
versifyr initYou can define what needs to be updated in two ways:
Add a comment directly above the line you want to manage. The tool will replace the immediately following line with the result of your template.
Go Example:
// $versifyr:template=const Version = "{{ .version }}"$
const Version = "v0.0.0"Maven Example (XML):
<!--$versifyr:template=<version>{{ .version }}</version>$-->
<version>1.0.0-SNAPSHOT</version>If you cannot add comments to a file, define the target row and template in .versifyr/configuration.yaml:
files:
- name: version.go
type: go
path: internal/versifyr/version.go
templates:
- row: 3
template: 'const Version = "{{ .version }}"'Update your files by passing key-value pairs:
versifyr set version="v1.2.3"The following variables are always available in your templates:
version: The primary value usually passed via CLI.latesttag: The most recent Git tag (e.g.,v0.1.0).actualdate: Current date (YYYY-MM-DD).actualtime: Current time (HH:MM:SS).actualtimestamp: Current date and time.
You can use any Sprig function for transformations. For example, to generate a snake_case version for a constant:
// $versifyr:template=const BUILD_ID = "{{ .version | replace "." "_" }}"$
const BUILD_ID = "v0_1_0"For formats like JSON where quotes must be escaped, use the unescape flag in your configuration:
files:
- name: package.json
path: package.json
type: json
unescape: true| Command | Alias | Description |
|---|---|---|
init |
i |
Creates the initial .versifyr/configuration.yaml. |
show |
s |
Displays the current configuration and managed file content. |
set |
Executes template replacements based on provided arguments. |
Global Options:
--debug,-d: Enable verbose logging.--nochange,-n: Run in simulation mode (dry-run).
versifyr uses Taskfile for a streamlined development experience.
- Lint:
task lint- Runsgolangci-lintexactly as it runs in CI. - Test:
task test- Runs the full test suite with coverage reporting. - Check Coverage:
task test-coverage- Verifies coverage against defined thresholds. - Advance Version:
task advance-version [VERSION=vX.Y.Z]- Increments the patch version from the latest Git tag.
Every push and pull request to main triggers a comprehensive pipeline:
- Linting: Static analysis with
golangci-lint. - Testing: Unit and integration tests with coverage enforcement.
- Release: Automated multi-arch builds and GitHub Release creation (triggered on version tags).
(c) 2023-2026 Stefano Zuccaro. All rights reserved.