A lightweight GitHub Action and CLI tool that extracts version strings from diverse software project types and files using configurable YAML patterns. Features dynamic versioning detection with fallback to Git tags.
This tool automatically detects and extracts version information from popular project file formats including JavaScript/Node.js, Python, Java, C#/.NET, Go, PHP, Ruby, Rust, Swift, Dart/Flutter, and others. It supports both directory scanning and specific file analysis, with intelligent detection of dynamic versioning patterns and automatic Git tag fallback. Can output as either plain text or JSON, with pretty and minimised JSON formatting options.
steps:
- name: "Extract Project Version"
id: version-extract
uses: lfreleng-actions/version-extract-action@main
with:
path: "."
format: "json"
json_format: "pretty"
fail-on-error: true# Extract from current directory
./version-extract --path .
# Extract from specific file
./version-extract --path package.json --format json
# Pretty formatted JSON output
./version-extract --path . --format json --json-format pretty
# Minimised JSON output
./version-extract --path . --format json --json-format minimised
# List supported project types
./version-extract list --format json| Name | Required | Default | Description |
|---|---|---|---|
| path | false | "." | Path to search for project files or path to a specific file |
| config | false | "" | Path to custom configuration file |
| format | false | "text" | Output format (text or json) |
| verbose | false | "false" | Enable verbose output |
| fail-on-error. | false | "true" | Fail the action if version extraction fails |
| json_format | false | "pretty" | JSON output format: pretty, minimised |
| dynamic-fallback | false | "true" | Enable dynamic versioning fallback to Git tags |
| Name | Description |
|---|---|
| version | Extracted version string |
| project-type | Detected project type |
| file | File containing the extracted version |
| success | Whether version extraction was successful |
| version-source | Source of version: static or dynamic-git-tag |
| git-tag | Original Git tag when using dynamic fallback |
| Flag | Short | Default | Description |
|---|---|---|---|
| --path | -p | "." | Path to search for project files or path to a specific file |
| --config | -c | "" | Path to configuration file |
| --format | -f | "text" | Output format: text, json |
| --verbose | -v | false | Enable verbose output |
| --fail-on-error | true | Exit with error code if version extraction fails | |
| --json-format | "pretty" | JSON output format: pretty, minimised | |
| --dynamic-fallback | true | Enable dynamic versioning fallback to Git tags |
The tool supports extraction from the following project types (in priority order):
- JavaScript (npm) -
package.json - Python (Modern) -
pyproject.toml - Java (Maven) -
pom.xml - Java (Gradle) -
build.gradle,build.gradle.kts - C# (.NET) -
*.csproj - Go -
go.mod - PHP (Composer) -
composer.json - Ruby (Gemspec) -
*.gemspec - Python (Legacy) -
setup.py,setup.cfg,__init__.py - Rust (Cargo) -
Cargo.toml - Swift (Package Manager) -
Package.swift - Dart/Flutter -
pubspec.yaml - C/C++ (CMake) -
CMakeLists.txt - Elixir (Mix) -
mix.exs - Scala (SBT) -
build.sbt - Haskell (Cabal) -
*.cabal - Julia -
Project.toml,Manifest.toml - R -
DESCRIPTION - Perl -
*.pm,*.pl - Lua (LuaRocks) -
*.rockspec
- Helm Charts -
Chart.yaml - Docker -
Dockerfile - Terraform -
versions.tf - Ansible (Galaxy) -
galaxy.yml - Ansible (Role) -
meta/main.yml - Kubernetes -
*.yaml(with version annotations) - Docker Compose -
docker-compose.yml
- Snap Packages -
snapcraft.yaml - Homebrew Formulas -
*.rb - Flatpak -
*.flatpak.yml - AppImage -
*.desktop
- OpenAPI/Swagger -
openapi.yaml,swagger.yaml - VSCode Extensions -
package.json - Web Extensions -
manifest.json - GitHub Actions -
action.yml
- Gradle Properties -
gradle.properties - Meson -
meson.build - Makefile -
Makefile - Yarn Workspaces -
yarn.lock
The tool supports two modes of operation:
When path points to a directory, the tool searches through the
directory structure looking for supported project files in priority order.
with:
path: "." # Search current directoryWhen path points to a specific file, the tool validates that the file
is of a supported type and attempts version extraction directly.
with:
path: "package.json" # Extract from specific fileIf the specified file is not of a supported type, the action will fail unless
fail-on-error has a false value.
{
"success": true,
"version": "1.2.3",
"project_type": "JavaScript",
"subtype": "npm",
"file": "./package.json",
"matched_by": "\"version\":\\s*\"([^\"]+)\"",
"version_source": "static"
}{
"success": true,
"version": "2.1.0",
"project_type": "Python",
"subtype": "Modern (pyproject.toml)",
"file": "./pyproject.toml",
"matched_by": "dynamic-git-tag",
"version_source": "dynamic-git-tag",
"git_tag": "v2.1.0"
}{"success":true,"version":"1.2.3","project_type":"JavaScript","subtype":"npm","file":"./package.json","matched_by":"\"version\":\\s*\"([^\"]+)\"","version_source":"static"}The tool provides comprehensive error handling:
- File not found: Reports when specified files don't exist
- Unsupported file type: Reports when a specific file is not supported
- Invalid version format: Reports when extracted versions don't match expected patterns
- Configuration errors: Reports configuration file parsing issues
When fail-on-error is true (default), the action will fail on errors. When
set to false, errors become warnings and the action continues.
The tool intelligently detects projects using dynamic versioning and automatically falls back to extracting version information from Git tags.
- Python:
setuptools_scm,versioneer,dynamic = ["version"]in pyproject.toml - JavaScript:
semantic-release, development versions like0.0.0-development - Rust: Development versions
0.0.0,build.rsscripts - Java: Maven
${revision}variables,SNAPSHOTversions - Go: GitHub/GitLab hosted modules relying on Git tags
- C#: Dynamic versioning with build-time resolution
# Enable dynamic versioning (default)
with:
dynamic-fallback: "true"
# Disable dynamic versioning fallback
with:
dynamic-fallback: "false"When the tool finds dynamic versioning, it:
- Identifies dynamic version indicators in project files
- Attempts to extract the latest semantic version from Git tags
- Returns the Git tag version with
version_source: "dynamic-git-tag" - Includes the original Git tag in the
git_tagfield
The tool supports different Git tag formats:
- Semantic versioning:
v1.2.3,1.2.3 - Release prefixes:
release-1.2.3,rel-1.2.3 - Date-based:
2024.01.15 - Pre-release:
1.2.3-beta.1,1.2.3-rc.1
You can provide a custom configuration file to extend or change the supported project types:
with:
config: "path/to/custom-patterns.yaml"Configuration files use YAML format with project definitions including file patterns, regex patterns, dynamic versioning indicators, and metadata.
- Built with Go for fast, reliable performance
- Uses configurable regex patterns for version extraction
- Intelligent dynamic versioning detection with Git integration
- Supports semantic versioning and custom version formats
- Git tag extraction with fallback strategies
- Validates extracted versions against common patterns
- Provides detailed logging and error reporting
- Compatible with GitHub Actions and standalone CLI usage
- Backward compatible with existing static version extraction
For detailed development instructions, see docs/DEVELOPMENT.md.
# Install pre-commit hooks (runs Go fmt, vet, and other checks automatically)
pre-commit install
# Quick development cycle
make dev
# Full CI validation
make ciGit hooks run automatically before each commit, matching CI requirements:
- go fmt - Code formatting (
gofmt -l .) - go vet - Static analysis (
go vet ./...) - go mod verify - Dependency verification
- go mod tidy - Dependency cleanup
These hooks prevent CI failures by catching issues locally before pushing.
# Format code
make fmt
# Run tests
make test
# Run all linters
make lint-full
# Build binary
make buildSee docs/DEVELOPMENT.md for complete documentation.