This GitHub Action validates whether a given version string follows the Semantic Versioning (semver) specification.
- ✅ Validates version strings against semver format
- 📊 Returns detailed parsing information for valid versions
- 🔍 Provides clear error messages for invalid versions
- 🚀 Fast execution using the trusted
semvernpm package
| INPUT | TYPE | REQUIRED | DEFAULT | DESCRIPTION |
|---|---|---|---|---|
| version | string | true | Version string to validate against semver format |
| OUTPUT | TYPE | DESCRIPTION |
|---|---|---|
| error_message | string | Error message if validation fails |
| is_valid | string | Whether the version is a valid semver (true/false) |
| parsed_version | string | Parsed version object with major, minor, patch, prerelease, and build metadata |
name: Validate Version
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Validate semver
id: semver
uses: loft-sh/github-actions/.github/actions/semver-validation@semver-validation/v1
with:
version: '1.2.3'
- name: Check result
run: |
echo "Is valid: ${{ steps.semver.outputs.is_valid }}"
echo "Parsed: ${{ steps.semver.outputs.parsed_version }}"name: Release Workflow
on:
push:
tags:
- 'v*'
jobs:
validate-and-release:
runs-on: ubuntu-latest
steps:
- name: Extract version from tag
id: version
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Validate version
id: semver
uses: loft-sh/github-actions/.github/actions/semver-validation@semver-validation/v1
with:
version: ${{ steps.version.outputs.version }}
- name: Proceed with release
if: steps.semver.outputs.is_valid == 'true'
run: echo "Releasing version ${{ steps.version.outputs.version }}"
- name: Fail on invalid version
if: steps.semver.outputs.is_valid == 'false'
run: |
echo "Error: ${{ steps.semver.outputs.error_message }}"
exit 1- name: Validate and parse version
id: semver
uses: loft-sh/github-actions/.github/actions/semver-validation@semver-validation/v1
with:
version: '2.1.0-alpha.1+build.123'
- name: Use parsed components
run: |
echo "Major: $(echo '${{ steps.semver.outputs.parsed_version }}' | jq -r '.major')"
echo "Minor: $(echo '${{ steps.semver.outputs.parsed_version }}' | jq -r '.minor')"
echo "Patch: $(echo '${{ steps.semver.outputs.parsed_version }}' | jq -r '.patch')"
echo "Prerelease: $(echo '${{ steps.semver.outputs.parsed_version }}' | jq -r '.prerelease')"1.0.01.2.310.20.301.1.2-prerelease+meta1.1.2+meta1.1.2+meta-valid1.0.0-alpha1.0.0-beta1.0.0-alpha.beta1.0.0-alpha.11.0.0-alpha0.valid1.0.0-alpha.0valid1.0.0-alpha-a.b-c-somethinglong+metadata+meta.meta.meta
11.21.2.3-01231.2.3-0123.01231.1.2+.123+invalid-invalid-invalid+invalidalpha1.2.3.DEV1.2-SNAPSHOT
For valid semver versions, the parsed_version output contains:
{
"major": 1,
"minor": 2,
"patch": 3,
"prerelease": "alpha.1",
"build": "build.123",
"raw": "1.2.3-alpha.1+build.123"
}major,minor,patch: Integer version numbersprerelease: String of prerelease identifiers (null if none)build: String of build metadata (null if none)raw: Original input version string
The action will:
- Set
is_validtofalsefor invalid versions - Provide descriptive error messages in
error_message - Log warnings for invalid versions
- Fail the action only on unexpected errors (not validation failures)
This action uses:
@actions/corefor GitHub Actions integrationsemverfor robust semver validation and parsing
This action uses @vercel/ncc to bundle all dependencies into a single file for GitHub Actions:
npm install
npm run buildThe bundled output is generated in dist/index.js and must be committed to the repository.
- Edit the source code in
index.js - Run
npm run buildto create the bundled version - Commit both the source and bundled files
- Create/update the action tag
You can test the action locally using environment variables:
# Test with valid semver
INPUT_VERSION="1.2.3" node dist/index.js
# Test with invalid semver
INPUT_VERSION="invalid" node dist/index.jsThe action includes comprehensive tests using Jest:
# Run all tests
npm test
# Run tests with coverage
npm test -- --coverageTests cover:
- Valid semver versions (basic, with prefixes, prerelease, build metadata)
- Invalid semver versions (incomplete, non-numeric, malformed)
- Edge cases (large numbers, the original failing case)
- Error handling