{"id":41590312,"url":"https://github.com/fabien-marty/github-next-semantic-version","last_synced_at":"2026-01-24T09:13:15.259Z","repository":{"id":245801995,"uuid":"819274795","full_name":"fabien-marty/github-next-semantic-version","owner":"fabien-marty","description":"Little CLI binary (written in golang) to guess the next semantic version only from existing git tags and recently merged pull-requests labels.  We don't use any \"commit message parsing\" here (only configurable PR labels).","archived":false,"fork":false,"pushed_at":"2026-01-16T01:31:25.000Z","size":7124,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-16T12:15:59.887Z","etag":null,"topics":["cli","git","github","golang","semantic-version","semantic-versioning","semantic-versions"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabien-marty.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-24T07:26:24.000Z","updated_at":"2025-05-06T14:29:12.000Z","dependencies_parsed_at":"2024-06-24T08:49:49.284Z","dependency_job_id":"aee3d64c-7fb6-435f-bcfd-bc007d92943c","html_url":"https://github.com/fabien-marty/github-next-semantic-version","commit_stats":null,"previous_names":["fabien-marty/github-next-semantic-version"],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/fabien-marty/github-next-semantic-version","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabien-marty%2Fgithub-next-semantic-version","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabien-marty%2Fgithub-next-semantic-version/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabien-marty%2Fgithub-next-semantic-version/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabien-marty%2Fgithub-next-semantic-version/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabien-marty","download_url":"https://codeload.github.com/fabien-marty/github-next-semantic-version/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabien-marty%2Fgithub-next-semantic-version/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28722371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T08:27:05.734Z","status":"ssl_error","status_checked_at":"2026-01-24T08:27:01.197Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","git","github","golang","semantic-version","semantic-versioning","semantic-versions"],"created_at":"2026-01-24T09:13:15.199Z","updated_at":"2026-01-24T09:13:15.252Z","avatar_url":"https://github.com/fabien-marty.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# github-next-semantic-version\n\n[![](https://img.shields.io/badge/go%20report-A+-brightgreen.svg?style=flat)](https://goreportcard.com/report/github.com/fabien-marty/github-next-semantic-version)\n[![Mergify Badge](https://raw.githubusercontent.com/fabien-marty/common/refs/heads/main/badges/mergify.svg)](https://mergify.com/)\n[![Renovate Badge](https://raw.githubusercontent.com/fabien-marty/common/refs/heads/main/badges/renovate.svg)](https://docs.renovatebot.com/)\n[![MIT Licensed](https://raw.githubusercontent.com/fabien-marty/common/refs/heads/main/badges/mit.svg)](https://en.wikipedia.org/wiki/MIT_License)\n\n## What is it?\n\n`github-next-semantic-version` is a little CLI binary (written in golang) to\n**guess the next [semantic version](https://semver.org/)** from:\n\n- existing **git tags** *(read from a locally cloned git repository)*\n- and recently merged **pull-requests labels** *(read from the GitHub API)*\n\nUnlinke plenty of \"similar\" tools, we don't use any \"commit message parsing\" here but only \n**configurable PR labels**.\n\nExample *(with a repo cloned in the current directory)*:\n\n```console\n$ github-next-semantic-version .\nv1.10.0 =\u003e v1.10.1\n$ # v1.10.0 is the latest version\n$ # v1.10.1 is the next version\n```\n\n\u003e [!TIP]\n\u003e **How do we determine the next version? How do we determine if the next version is a patch/minor/major version?**\n\u003e\n\u003e - we list PRs merged since the latest tag\n\u003e - we examine corresponding PR labels:\n\u003e     - if we find at least one `breaking` or `Type: Major` label =\u003e this is a major release *(so we increment the major version number)*\n\u003e     - if we find at least one `feature` or `Type: Feature` label =\u003e this is a minor release *(so we increment the minor version number)*\n\u003e     - else this is a patch release\n\u003e\n\u003e *(of course, you can define your own labels to configure the logic)*\n\n\u003e [!NOTE]\n\u003e We also provide:\n\u003e\n\u003e - a dedicated GitHub Action in [this dedicated repository](https://github.com/fabien-marty/github-next-semantic-version-action) *if you want to use this tool inside a GHA workflow*\n\u003e - another CLI binary: `github-create-next-semantic-release` *(in this current repository)* to use the previous rules to automatically create a GitHub release with the guessed version and the corresponding release notes *(made from merged PRs and a configurable template)*\n\u003e - another GitHub Action in [this other repository](https://github.com/fabien-marty/github-create-next-semantic-release-action) *if you want to use this alternate tool: `github-create-next-semantic-release` inside a GHA workflow*\n\u003e - a full changelog generator CLI: `github-generate-changelog` (configurable by a [golang text/template](https://pkg.go.dev/text/template))\n\n## Features\n\n- support full semver specification (basic `1.2.3` but also `1.0.0-beta.2`, `0.1.9-post.24_a5256f1`...)\n- can filter tags with regex (see `--tag-regex` option)\n- support prefixed tags (example: `v1.2.3` but also `foo/bar/v1.2.3`...) when parsing the semantic version\n- configure your own PR labels for major and minor increments\n- ... (see \"CLI reference\" in this document)\n- addon binary to automatically create GitHub releases with the guessed version and corresponding release notes\n- addon binary to generate full changelog\n\n## Non-features\n\n- \"commit message parsing\": there are plenty of tools to do that, here, we want to rely only on merged PR labels\n- \"other providers support\": we support only \"GitHub\" *(feel free to fork if you want to add other providers support)*\n\n## Installation / Quickstart\n\nWe provide compiled binaries for various architecture in the [release page](https://github.com/fabien-marty/github-next-semantic-version/releases).\n\n- download the corresponding file\n- set the \"executable bit\"\n- clone a public repository locally (with all tags)\n- execute `./github-next-semantic-version .`\n\n*(same for `github-create-next-semantic-release` binary)*\n\n\u003e [!NOTE]\n\u003e Of course it also works with private repositories but you will need a GitHub token\n\u003e set to `GITHUB_TOKEN` env var (for example).\n\n## CLI reference\n\n\u003cdetails open\u003e\n\n\u003csummary\u003eCLI reference of github-next-semantic-version\u003c/summary\u003e\n\n```console\n$ github-next-semantic-version --help\n\nNAME:\n   github-next-semantic-version - Compute the next semantic version with merged PRs and corresponding labels\n\nUSAGE:\n   github-next-semantic-version [global options] command [command options] LOCAL_GIT_REPO_PATH\n\nCOMMANDS:\n   help, h  Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --log-level value                 log level (DEBUG, INFO, WARN, ERROR) (default: \"INFO\") [$LOG_LEVEL]\n   --log-format value                log format (text-human, text, json, json-gcp) (default: \"text-human\") [$LOG_FORMAT]\n   --github-token value              github token [$GITHUB_TOKEN]\n   --repo-owner value                repository owner (organization); if not set, we are going to try to guess [$GNSV_REPO_OWNER]\n   --repo-name value                 repository name (without owner/organization part); if not set, we are going to try to guess [$GNSV_REPO_NAME]\n   --branches value, --branch value  Coma separated list of branch names to filter on for getting tags and prs (if not set, the default branch is guessed/used) [$GNSV_BRANCH_NAME]\n   --consider-also-non-merged-prs    Consider also non-merged PRs (default: false) [$GNSV_CONSIDER_ALSO_NON_MERGED_PRS]\n   --tag-regex value                 Regex to match tags (if empty string (default) =\u003e no filtering) [$GNSV_TAG_REGEX]\n   --ignore-labels value             Coma separated list of PR labels to consider as ignored PRs (OR condition) (default: \"Type: Hidden\") [$GNSV_HIDDEN_LABELS]\n   --must-have-labels value          Coma separated list of PR labels that PRs must have to be considered (OR condition, empty =\u003e no filtering) [$GNSV_MUST_HAVE_LABELS]\n   --minimal-delay-in-seconds value  Minimal delay in seconds between a PR and a tag (if less, we consider that the tag is always AFTER the PR) (default: 5)\n   --cache                           Cache pull-requests read (default: false) [$GNSV_CACHE]\n   --cache-lifetime value            Lifetime (in seconds) of the pull-requests cache (default: 3600) [$GNSV_CACHE_LIFETIME]\n   --cache-location value            Cache Location (directory that must exist) (default: \".\") [$GNSV_CACHE_LOCATION]\n   --cache-dont-try-to-update        If set, don't try to update the cache (use it only if you know what you are doing) (default: false) [$GNSV_CACHE_DONT_TRY_TO_UPDATE]\n   --major-labels value              Coma separated list of PR labels to consider as major (OR condition) (default: \"major,breaking,Type: Major,Type: Breaking\") [$GNSV_MAJOR_LABELS]\n   --minor-labels value              Coma separated list of PR labels to consider as minor (OR condition) (default: \"feature,Type: Feature,Type: Minor,Type: Added\") [$GNSV_MINOR_LABELS]\n   --dont-increment-if-no-pr         Don't increment the version if no PR is found (or if only ignored PRs found) (default: false) [$GNSV_DONT_INCREMENT_IF_NO_PR]\n   --next-version-only               If set, output only the next version (without the old one) (default: false) [$GNSV_NEXT_VERSION_ONLY]\n   --help, -h                        show help\n\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eCLI reference of github-create-next-semantic-release\u003c/summary\u003e\n\n```console\n$ github-create-next-semantic-release --help\n\nNAME:\n   github-create-next-semantic-release - Create the next semantice release on GitHub (depending on the PRs merged since the last release)\n\nUSAGE:\n   github-create-next-semantic-release [global options] command [command options] LOCAL_GIT_REPO_PATH\n\nCOMMANDS:\n   help, h  Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --log-level value                   log level (DEBUG, INFO, WARN, ERROR) (default: \"INFO\") [$LOG_LEVEL]\n   --log-format value                  log format (text-human, text, json, json-gcp) (default: \"text-human\") [$LOG_FORMAT]\n   --github-token value                github token [$GITHUB_TOKEN]\n   --repo-owner value                  repository owner (organization); if not set, we are going to try to guess [$GNSV_REPO_OWNER]\n   --repo-name value                   repository name (without owner/organization part); if not set, we are going to try to guess [$GNSV_REPO_NAME]\n   --branches value, --branch value    Coma separated list of branch names to filter on for getting tags and prs (if not set, the default branch is guessed/used) [$GNSV_BRANCH_NAME]\n   --consider-also-non-merged-prs      Consider also non-merged PRs (default: false) [$GNSV_CONSIDER_ALSO_NON_MERGED_PRS]\n   --tag-regex value                   Regex to match tags (if empty string (default) =\u003e no filtering) [$GNSV_TAG_REGEX]\n   --ignore-labels value               Coma separated list of PR labels to consider as ignored PRs (OR condition) (default: \"Type: Hidden\") [$GNSV_HIDDEN_LABELS]\n   --must-have-labels value            Coma separated list of PR labels that PRs must have to be considered (OR condition, empty =\u003e no filtering) [$GNSV_MUST_HAVE_LABELS]\n   --minimal-delay-in-seconds value    Minimal delay in seconds between a PR and a tag (if less, we consider that the tag is always AFTER the PR) (default: 5)\n   --cache                             Cache pull-requests read (default: false) [$GNSV_CACHE]\n   --cache-lifetime value              Lifetime (in seconds) of the pull-requests cache (default: 3600) [$GNSV_CACHE_LIFETIME]\n   --cache-location value              Cache Location (directory that must exist) (default: \".\") [$GNSV_CACHE_LOCATION]\n   --cache-dont-try-to-update          If set, don't try to update the cache (use it only if you know what you are doing) (default: false) [$GNSV_CACHE_DONT_TRY_TO_UPDATE]\n   --major-labels value                Coma separated list of PR labels to consider as major (OR condition) (default: \"major,breaking,Type: Major,Type: Breaking\") [$GNSV_MAJOR_LABELS]\n   --minor-labels value                Coma separated list of PR labels to consider as minor (OR condition) (default: \"feature,Type: Feature,Type: Minor,Type: Added\") [$GNSV_MINOR_LABELS]\n   --release-draft                     if set, the release is created in draft mode (default: false) [$GNSV_RELEASE_DRAFT]\n   --release-body-template value       golang template to generate the release body (default: \"{{ range . }}- {{.Title}} (#{{.Number}})\\n{{ end }}\") [$GNSV_RELEASE_BODY_TEMPLATE]\n   --release-body-template-path value  golang template path to generate the release body (if set, release-body-template option is ignored) [$GNSV_RELEASE_BODY_TEMPLATE_PATH]\n   --release-force                     if set, force the version bump and the creation of a release (even if there is no PR) (default: false) [$GNSV_RELEASE_FORCE]\n   --help, -h                          show help\n\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eCLI reference of github-generate-changelog\u003c/summary\u003e\n\n```console\n$ github-generate-changelog --help\n\nNAME:\n   github-generate-changelog - Make a changelog from local git tags and GitHub merged PRs\n\nUSAGE:\n   github-generate-changelog [global options] command [command options] LOCAL_GIT_REPO_PATH\n\nCOMMANDS:\n   help, h  Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --log-level value                 log level (DEBUG, INFO, WARN, ERROR) (default: \"INFO\") [$LOG_LEVEL]\n   --log-format value                log format (text-human, text, json, json-gcp) (default: \"text-human\") [$LOG_FORMAT]\n   --github-token value              github token [$GITHUB_TOKEN]\n   --repo-owner value                repository owner (organization); if not set, we are going to try to guess [$GNSV_REPO_OWNER]\n   --repo-name value                 repository name (without owner/organization part); if not set, we are going to try to guess [$GNSV_REPO_NAME]\n   --branches value, --branch value  Coma separated list of branch names to filter on for getting tags and prs (if not set, the default branch is guessed/used) [$GNSV_BRANCH_NAME]\n   --consider-also-non-merged-prs    Consider also non-merged PRs (default: false) [$GNSV_CONSIDER_ALSO_NON_MERGED_PRS]\n   --tag-regex value                 Regex to match tags (if empty string (default) =\u003e no filtering) [$GNSV_TAG_REGEX]\n   --ignore-labels value             Coma separated list of PR labels to consider as ignored PRs (OR condition) (default: \"Type: Hidden\") [$GNSV_HIDDEN_LABELS]\n   --must-have-labels value          Coma separated list of PR labels that PRs must have to be considered (OR condition, empty =\u003e no filtering) [$GNSV_MUST_HAVE_LABELS]\n   --minimal-delay-in-seconds value  Minimal delay in seconds between a PR and a tag (if less, we consider that the tag is always AFTER the PR) (default: 5)\n   --cache                           Cache pull-requests read (default: false) [$GNSV_CACHE]\n   --cache-lifetime value            Lifetime (in seconds) of the pull-requests cache (default: 3600) [$GNSV_CACHE_LIFETIME]\n   --cache-location value            Cache Location (directory that must exist) (default: \".\") [$GNSV_CACHE_LOCATION]\n   --cache-dont-try-to-update        If set, don't try to update the cache (use it only if you know what you are doing) (default: false) [$GNSV_CACHE_DONT_TRY_TO_UPDATE]\n   --future                          if set, include a future section (default: false) [$GNSV_CHANGELOG_FUTURE]\n   --template-path value             if set, define the path to the changelog template [$GNSV_CHANGELOG_TEMPLATE_PATH]\n   --starting-tag value              if set, defining a starting tag (excluded) for changelog generation, the special value 'LATEST' (combined with --future) will use the latest semantic tag to get only the future section [$GNSV_CHANGELOG_STARTING_TAG]\n   --help, -h                        show help\n\n```\n\n\u003c/details\u003e\n\n## DEV\n\nThis tool is fully developped in Golang 1.23+ with following libraries:\n\n- [github.com/Masterminds/semver V3](https://github.com/Masterminds/semver/): for semver parsing\n- [github.com/google/go-github V70](https://github.com/google/go-github/): for GitHub API \n- [github.com/urfave/cli V2](https://github.com/urfave/cli/): for CLI\n\nWe follow [golang-standards/project-layout](https://github.com/golang-standards/project-layout) directories structure\nand we use \"hexagonal architecture\" with:\n- domain/use-cases code in the `app` subdir\n- IO adapters in the `infra/adapters` subdir\n- CLI controller in the `infra/controllers` subdir\n\nDev commands are implemented inside a `Makefile` with following targets:\n\n```console\n$ make help\nbuild                          Build Go binaries\nclean                          Clean the repo\ndoc                            Generate documentation\nlint                           Lint the code (also fix the code if FIX=1, default)\nno-dirty                       Check if the repo is dirty\ntest-integration               Run integration tests\ntest-unit                      Execute all unit tests\ntest                           Execute all tests \n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabien-marty%2Fgithub-next-semantic-version","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabien-marty%2Fgithub-next-semantic-version","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabien-marty%2Fgithub-next-semantic-version/lists"}