Semantic versioning tool based on GitLab commit history and Conventional Commits
Semantic versioning tool based on GitLab commit history and Conventional Commits.
- 🚀 Calculate semantic versions from commit history
- 🔄 Follows Conventional Commits specification
- 🌿 Supports multi-branch workflows with prerelease versions
- 🌐 Pure API-based: all data fetched from GitLab API
- 🦊 Supports self-hosted GitLab instances
- 📦 Works perfectly with shallow clones in CI/CD
- 🎯 Zero configuration required
``bash`
npm install -g @sharedutils/glsemver
`bash`
npx @sharedutils/glsemver current
npx @sharedutils/glsemver next
Get the latest semantic version tag from your repository:
`bash`
glsemver currentOutput: 1.0.0
Calculate the next version based on commit history:
`bash`
glsemver nextOutput: 1.1.0
Use --log flag to see detailed information:
`bash`
glsemver next --logOutput:
Repository: mygroup/myproject
Host: https://gitlab.com
Current branch: main
Main branch: main
Base version: 1.0.0
HEAD SHA: abc1234
Tag SHA: def5678
Analyzing 3 commit(s)
Release type: minor
1.1.0
#### current command
Get the current version (latest semantic version tag).
`bash`
glsemver current [options]
Options:
- -r, --repo - Repository path (owner/repo or group/subgroup/repo)-H, --host
- - GitLab host URL (default: from git remote or gitlab.com)-b, --branch
- - Current branch name-m, --main-branch
- - Main branch name (default: from API)--sha
- - Current commit SHA--log
- - Enable verbose logging
#### next command
Calculate the next version based on commits.
`bash`
glsemver next [options]
Options:
- -r, --repo - Repository path (owner/repo or group/subgroup/repo)-H, --host
- - GitLab host URL (default: from git remote or gitlab.com)-b, --branch
- - Current branch name-m, --main-branch
- - Main branch name (default: from API)--sha
- - Current commit SHA-s, --suffix
- - Prerelease suffix for non-main branches--log
- - Enable verbose logging
This tool uses a pure API approach:
| Data | Source |
|------|--------|
| Repository info | CLI --repo > local git remote |--host
| GitLab host | CLI > local git remote > GITLAB_HOST env > gitlab.com |--branch
| Current branch | CLI > CI_COMMIT_BRANCH env > local git |--sha
| Current SHA | CLI > CI_COMMIT_SHA env > local git > API |--main-branch
| Main branch | CLI > GitLab API |
| Tags & Commits | GitLab API (always) |
This approach is:
- 📦 Shallow clone friendly: Works perfectly with git clone --depth 1
- 🎯 Consistent: Always reflects the remote repository state
- 🔧 Flexible: Can run without a git repository if all options provided
This tool follows Conventional Commits specification:
Incremented when commits contain breaking changes:
- BREAKING CHANGE: or BREAKING-CHANGE: in commit message body!
- after commit type: feat!:, fix!:
`
feat!: redesign authentication system
BREAKING CHANGE: removed old authentication API
`
Result: 1.0.0 → 2.0.0
Incremented for new features:
- Commit type: feat or feature
``
feat: add user export functionality
Result: 1.0.0 → 1.1.0
Incremented for bug fixes and performance improvements:
- Commit type: fixperf
- Commit type:
``
fix: resolve login page styling issue
perf: optimize database queries
Result: 1.0.0 → 1.0.1
On non-main branches, versions include a prerelease identifier:
Format: {version}-{suffix}.{number}
`bashOn develop branch
glsemver nextOutput: 1.1.0-develop.1
$3
When commits don't match Conventional Commits patterns or only contain non-versioning types:
-
chore:, docs:, style:, refactor:, test:, build:, ci:`bash
glsemver next
Output: (empty string)
`Environment Variables
$3
Set
GITLAB_TOKEN to authenticate with GitLab API:`bash
export GITLAB_TOKEN=your_gitlab_token_here
`Get a token at: https://gitlab.com/-/profile/personal_access_tokens
In GitLab CI/CD,
CI_JOB_TOKEN is automatically available and will be used if GITLAB_TOKEN is not set.$3
For self-hosted GitLab instances, set the host URL:
`bash
export GITLAB_HOST=https://gitlab.example.com
`In GitLab CI/CD,
CI_SERVER_URL is automatically used if GITLAB_HOST is not set.$3
The tool automatically uses these CI variables when available:
-
CI_COMMIT_BRANCH / CI_COMMIT_REF_NAME - Current branch
- CI_COMMIT_SHA - Current commit SHA
- CI_JOB_TOKEN - API authentication
- CI_SERVER_URL - GitLab instance URLExamples
$3
`bash
Get current version
glsemver current
Output: 1.0.0
Calculate next version
glsemver next
Output: 1.1.0
`$3
`bash
Specify repository explicitly
glsemver next --repo mygroup/myproject --branch main --sha abc1234With self-hosted GitLab
glsemver next --repo mygroup/myproject --host https://gitlab.example.com --branch main
`$3
`yaml
.gitlab-ci.yml
stages:
- version
- releasecalculate-version:
stage: version
image: node:20
script:
- npm install -g @sharedutils/glsemver
- VERSION=$(glsemver next --log)
- |
if [ -z "$VERSION" ]; then
echo "No version bump needed"
exit 0
fi
- echo "VERSION=$VERSION" >> version.env
artifacts:
reports:
dotenv: version.env
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
create-release:
stage: release
image: node:20
needs:
- job: calculate-version
artifacts: true
script:
- |
if [ -z "$VERSION" ]; then
echo "No version to release"
exit 0
fi
- git config user.email "ci@gitlab.com"
- git config user.name "GitLab CI"
- git tag "v$VERSION"
- git push origin "v$VERSION"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
`$3
`json
{
"scripts": {
"version:current": "glsemver current",
"version:next": "glsemver next",
"version:check": "glsemver next || echo 'No version bump needed'"
}
}
`$3
`bash
#!/bin/bash
VERSION=$(glsemver next)if [ -z "$VERSION" ]; then
echo "No version bump required"
exit 0
fi
echo "Bumping version to $VERSION"
npm version $VERSION --no-git-tag-version
git add package.json
git commit -m "chore: bump version to $VERSION"
git tag "v$VERSION"
git push --follow-tags
`Tag Format
- ✅ Valid:
v1.0.0, v2.3.4, v10.20.30, v1.0.0-beta.1
- ❌ Invalid: 1.0.0, v1.0, release-v1.0.0The tool only recognizes tags starting with
v followed by semantic version (X.Y.Z).Output versions do not include the
v` prefix.- Node.js >= 18.0.0
- GitLab API access (token required for private repositories)
- Git (optional, only needed if not providing --repo option)
ISC
Issues and merge requests are welcome!
Inspired by semantic-release but designed to be:
- Lighter weight
- Zero configuration
- Focused on version calculation only
- Pure API-based for better CI/CD compatibility