
Security News
npm Adopts OIDC for Trusted Publishing in CI/CD Workflows
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.
Automatically ensures your software version metadata is consistent across key project files.
Automatically ensures your software version metadata is consistent across key project files.
same-version
checks that software version metadata is consistent across your project files. It can stop GitHub pull requests and local git commits/pushes of projects with inconsistent software version metadata.
Helps ensure:
β
Reproducibility
β
Correct citations
β
Consistent packaging metadata
β
Accurate DOIs (Zenodo)
β
Cross-language version consistency (Python / JS / metadata)
It can be used in three ways, each of which have different capabilities:
Runs in GitHub Actions
Can block:
Can report (but only after the tag/release has been created):
Note: GitHub Actions cannot block tags or releases after they have been created.
This workflow runs after the tag or release exists and can report problems, but cannot prevent them from appearing in GitHub UI.
same-version
manually from the command lineβ Ultra-conservative version normalization and strict equality comparison using Verple
β Compare software version metadata from:
CITATION.cff
pyproject.toml
(Python)setup.py
(Python, via static analysis only β no execution)setup.cfg
(Python)__version__
assignment (static parsing only β must be assigned directly to a string literal)codemeta.json
(General).zenodo.json
(General)package.json
(JS/TypeScript)composer.json
(PHP)Cargo.toml
(Rust)pom.xml
(Java).nuspec
(.NET/C#/NuGet)DESCRIPTION
(R)ro-crate-metadata.json
(RO-Crate)β Cross-language support (e.g., Python, R, JS/TypeScript, Java, Rust, PHP, C#)
β Cross-standard support for FAIR and Open Science metadata (e.g., CFF, CodeMeta, RO-Crate, Zenodo)
β Lightweight, pure Python β no third-party services
β Easy to configure via GitHub Action inputs
β Suitable for reproducible research and software citation best practices
β Blocks inconsistent GitHub pull requests (via GitHub Action)
β Reports inconsistent GitHub releases/tags (via GitHub Action)
β Blocks inconsistent commits and tags (via Pre-commit hook)
β Modular and extendable for additional software version metadata (via Python CLI)
same-version
automatically normalizes all detected versions using Verple, which provides a strict, ultra-conservative version model that fully supports PEP 440, SemVer, Calendar Versioning, and hybrid schemes across ecosystems.
1.0.0
vs 1.0.0+build123
are considered different).Many packaging standards (SemVer, PEP 440) have nuanced rules for equality and ordering:
However, for the purpose of cross-file version consistency checking (the core goal of same-version
), such leniency can mask subtle inconsistencies that may later cause confusion or deployment issues.
By using Verple's conservative model:
β
Any discrepancy between files will be surfaced explicitly.
β
No silent equivalence is assumed across ecosystems.
β
Comparison logic remains simple, transparent, and safe for reproducibility.
Verple's strict comparison is ideal for version consistency checks, where exact agreement across files is required:
Verpleβs ultra-conservative model may not be ideal for:
For those use cases, specialized dependency resolution libraries (e.g. packaging
, semver
, dephell
) may be more appropriate.
File | Original Version Format | Normalization |
---|---|---|
CITATION.cff | PEP 440 / free text | Verple |
pyproject.toml | PEP 440 | Verple |
setup.cfg | PEP 440 | Verple |
setup.py | PEP 440 | Verple |
package.json | SemVer | Verple |
codemeta.json | Free text | Verple |
.zenodo.json | Free text | Verple |
composer.json | PHP Composer (SemVer-like) | Verple |
Cargo.toml | Rust Cargo (SemVer-like) | Verple |
pom.xml | Maven (loosely SemVer) | Verple |
.nuspec | NuGet (SemVer-like) | Verple |
DESCRIPTION | Free text | Verple |
__version__ file | PEP 440 (usually) | Verple |
ro-crate-metadata.json | Free text | Verple |
β All formats are normalized automatically to Verple before comparison.
CLI Parameter | GitHub Action Input | Description | Required | Default |
---|---|---|---|---|
--base-version | base_version | Base version from which to compare all other versions | No | (empty) |
--check-github-event | check_github_event | Check GitHut events? (true or false ) | No | false |
--github-event-name | github_event_name | GitHub event name (push or release or pull_request ) | No | (empty) |
--github-event-ref | github_event_ref | GitHub ref (for push event) | No | (empty) |
--github-event-release-tag | github_event_release_tag | GitHub release tag name (for release event) | No | (empty) |
--fail-for-missing-file | fail_for_missing_file | Fail for any checked file that is missing | No | false |
--check-citation-cff | check_citation_cff | Check CITATION.cff ? (true/false ) | No | true |
--citation-cff-path | citation_cff_path | Path to CITATION.cff | No | CITATION.cff |
--check-pyproject-toml | check_pyproject_toml | Check pyproject.toml ? (true/false ) | No | true |
--pyproject-toml-path | pyproject_toml_path | Path to pyproject.toml | No | pyproject.toml |
--check-codemeta-json | check_codemeta_json | Check codemeta.json ? (true/false ) | No | true |
--codemeta-json-path | codemeta_json_path | Path to codemeta.json | No | codemeta.json |
--check-zenodo-json | check_zenodo_json | Check .zenodo.json ? (true/false ) | No | true |
--zenodo-json-path | zenodo_json_path | Path to .zenodo.json | No | .zenodo.json |
--check-package-json | check_package_json | Check package.json ? (true/false ) | No | true |
--package-json-path | package_json_path | Path to package.json | No | package.json |
--check-setup-py | check_setup_py | Check setup.py ? (true/false ) | No | true |
--setup-py-path | setup_py_path | Path to setup.py | No | setup.py |
--check-setup-cfg | check_setup_cfg | Check setup.cfg ? (true/false ) | No | true |
--setup-cfg-path | setup_cfg_path | Path to setup.cfg | No | setup.cfg |
--check-py-version-assignment | check_py_version_assignment | Check Python file with __version__ assignment? (true/false ) | No | false |
--py-version-assignment-path | py_version_assignment_path | Path to Python file with __version__ assignment | No | (empty) |
--check-composer-json | check_composer_json | Check composer.json ? (true/false ) | No | true |
--composer-json-path | composer_json_path | Path to composer.json | No | composer.json |
--check-ro-crate-metadata-json | check_ro_crate_metadata_json | Check ro-crate-metadata.json ? (true/false ) | No | false |
--ro-crate-metadata-json-path | ro_crate_metadata_json_path | Path to ro-crate-metadata.json | No | ro-crate-metadata.json |
--ro-crate-metadata-json-id | ro_crate_metadata_json_id | @id of resource in ro-crate-metadata.json | No | (empty) |
--check-cargo-toml | check_cargo_toml | Check Cargo.toml ? (true/false ) | No | true |
--cargo-toml-path | cargo_toml_path | Path to Cargo.toml | No | Cargo.toml |
--check-r-description | check_r_description | Check R DESCRIPTION file? (true/false ) | No | true |
--r-description-path | r_description_path | Path to R DESCRIPTION file | No | DESCRIPTION |
--check-pom-xml | check_pom_xml | Check pom.xml ? (true/false ) | No | true |
--pom-xml-path | pom_xml_path | Path to pom.xml | No | pom.xml |
--check-nuspec | check_nu_spec | Check .nuspec ? (true/false ) | No | true |
--nuspec-path | nuspec_path | Path to .nuspec | No | .nuspec |
workflow_dispatch
)pre-commit
hook)pre-push
hook)name: Check version consistency on pull requests for Python project using pyproject.toml
on:
pull_request:
jobs:
check-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: ">=3.10"
- name: Run same-version
uses: willynilly/same-version@v7.1.0
with:
fail_for_missing_file: false
check_github_event: true
github_event_name: ${{ github.event_name }}
github_event_ref: ${{ github.ref }}
github_event_release_tag: ${{ github.event.release.tag_name }}
check_pyproject_toml: true
check_citation_cff: true
check_codemeta_json: true
check_zenodo_json: true
check_setup_cfg: false
check_setup_py: false
check_r_description: false
check_cargo_toml: false
check_py_version_assignment: false
check_pom_xml: false
check_nuspec: false
check_composer_json: false
check_ro_crate_metadata_json: false
name: Check version consistency on tags/releases for Python project using pyproject.toml
on:
push:
tags:
- 'v*.*.*'
release:
types: [published]
jobs:
check-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: ">=3.10"
- name: Run same-version
uses: willynilly/same-version@v7.1.0
with:
fail_for_missing_file: false
check_github_event: true
github_event_name: ${{ github.event_name }}
github_event_ref: ${{ github.ref }}
github_event_release_tag: ${{ github.event.release.tag_name }}
check_pyproject_toml: true
check_citation_cff: true
check_codemeta_json: true
check_zenodo_json: true
check_setup_cfg: false
check_setup_py: false
check_r_description: false
check_cargo_toml: false
check_py_version_assignment: false
check_pom_xml: false
check_nuspec: false
check_composer_json: false
check_ro_crate_metadata_json: false
You can configure a pre-commit hook to block:
β
Commits with inconsistent version metadata (pre-commit
)
β
Tags with inconsistent version metadata (pre-push
)
Add to your .pre-commit-config.yaml
:
repos:
- repo: https://github.com/willynilly/same-version
rev: v7.1.0 # Use latest tag
hooks:
- id: same-version
stages: [pre-commit, pre-push]
# Install the pre-commit tool if you have not already installed it
pip install pre-commit
# Install for both pre-commit and pre-push
pre-commit install -t pre-commit -t pre-push
pre-commit run same-version --all-files
After installing the package:
pip install same-version # or pip install .
Run the CLI:
same-version
By default, it will scan all files, but not GitHub events. You can specify additiona parameters (see the action.yml
of this GitHub Action for a robust example).
By default, the tool will not fail if some of the files are missing. This inclusively checks as many file types as possible without additional configuration. However, you may want to be strict and fail if any files used during checking is missing. Here's an example of failing if any files are missing for a Python project that uses a CITATION.CFF file and pyproject.toml file, any of the other supported files that contain software version metatadata (e.g., codemeta.json, setup.py, package.json, etc.)
same-version --fail-for-missing-file "true" --check-package-json "false" --check-codemeta-json "false" --check-setup-py "false" --check-zenodo-json "false"
You can integrate this into:
β
Local release scripts
β
CI pipelines (non-GitHub)
β
Manual checks
Pull requests and contributions are welcome!
To set up your development environment:
git clone https://github.com/willynilly/same-version.git
cd same-version
pip install -e .[testing,dev]
pre-commit install -t pre-commit -t pre-push
pre-commit run --all-files
Tool / Action | Scope / Limitations |
---|---|
check-version | Compares one or two files (e.g. package.json or pyproject.toml ) against Git tag; no cross-file or multi-ecosystem checks |
validate-version-tag-action | Focused on NPM (package.json only); no support for Python, metadata standards, or multi-file consistency |
python-semantic-release | Automated release tool (version bumping, changelogs); not designed for cross-file or cross-language version consistency |
check-tag-version (various community actions) | Typically limited to checking one file type; lacks support for multiple ecosystems and scientific metadata standards |
β
same-version
is currently the only GitHub Action that provides:
pyproject.toml
, setup.py
, __version__
)package.json
)CITATION.cff
, codemeta.json
, .zenodo.json
, ro-crate-metadata.json
)composer.json
, Cargo.toml
, pom.xml
, .nuspec
, DESCRIPTION
)Apache License 2.0 β free to use, fork, extend π
Inspired by best practices for reproducible research and software citation!
FAQs
Automatically ensures your software version metadata is consistent across key project files.
We found that same-version demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.
Research
/Security News
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.