A convenient way to get a version identifier from a set of ordered sources (ENV, Git, File, NPM Package, default value...)
Features:
version
in NPM Packages
package.json
package-lock.json
npm-shrinkwrap.json
Documentation best viewed on https://foxxmd.github.io/get-version
You have a project that can be distributed, or run, in multiple ways. You want to output the version of the project so users know what they are running or for debugging purposes.
The problem you have is you have:
and there's no one way to make sure all of these instances display an accurate version unless you want to manually add/commit a Source of Truth value somewhere every time you make a change.
@foxxmd/get-version solves this problem. It parses multiple sources, in an order you define, to glean a "version identifier" that is most accurate to display based on how and from what source your app is deployed from.
We will look for a version from sources in this order=: ENV, Git, NPM, Fallback
First look for ENV...
APP_VERSION
parsed from release tag with GH ActionsAPP_VERSION
for one-offsENV not found then with Git...
{branch}-{commit}
Git not found then with NPM...
package-lock.json
in project folder and uses version
set by you for releaseNPM not found...
fallback
value set in project so you know user is using an uncommon setup (or something is wrong!)npm install @foxxmd/get-version
import { getVersion } from "@foxxmd/get-version";
// defaults to ENV => Git => Files => NPM => Fallback
const version = await getVersion();
console.log(version); // 1.0.0
Pass an object implementing VersionOpts
to getVersion
import { getVersion, VersionOpts } from "@foxxmd/get-version";
import path from 'node:path';
const opts: VersionOpts = {
priority: ['file', 'env', 'git'],
env: {
names: ['CUSTOM_VERSION','APP_VERSION']
},
file: {
npmPackage: false,
additionalFiles: [path.join(process.cwd(), 'version.txt')],
},
git: {
gitTemplate: 'GIT-{branch}-{hash}'
},
fallback: 'unknown'
}
const version = await getVersion(opts);
console.log(version); // 1.0.0
get-version
looks for APP_VERSION
env by default. Set APP_VERSION
using docker build arg in Dockerfile
:
#FROM ....
# then in your last build stage...
ARG APP_BUILD_VERSION
ENV APP_VERSION=$APP_BUILD_VERSION
#ENTRYPOINT ...
APP_VERSION
based on Github Actions triggerIf you build and publish images using Github Actions the version can be configured to use release tag, github info (without including git repo in image), or other arbitrary info.
In your workflow when using build-push-action:
# steps:
# ....
- name: Build and push Docker image
env:
APP_VERSION: myCustomAppVersionInfo
uses: docker/build-push-action@v5
with:
context: .
build-args: |
APP_BUILD_VERSION=${{env.APP_VERSION}}
# ...
on:
push:
branches:
- 'master'
- 'develop'
tags:
- '*.*.*'
jobs:
publish:
name: Build and Publish Image
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
-
- name: Check out the repo
uses: actions/checkout@v4
- name: Set short git commit SHA
id: vars
# https://dev.to/hectorleiva/github-actions-and-creating-a-short-sha-hash-8b7
# short sha available under env.COMMIT_SHORT_SHA
run: |
calculatedSha=$(git rev-parse --short HEAD)
branchName=$(git rev-parse --abbrev-ref HEAD)
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
echo "COMMIT_BRANCH=$branchName" >> $GITHUB_ENV
# do whatever else you need to do...
- name: Build and push Docker image
env:
# if action triggers on release, version uses tag
# if action triggers on push to an included branch version is {branch}-{shortSHA}
APP_VERSION: ${{ contains(github.ref, 'refs/tags/') && github.ref_name || format('{0}-{1}', env.COMMIT_BRANCH, env.COMMIT_SHORT_SHA ) }}
uses: docker/build-push-action@v5
with:
context: .
build-args: |
APP_BUILD_VERSION=${{env.APP_VERSION}}
# ...
WARNING: Do not use pull_request_target
trigger without some security measures in place to prevent malicious PRs.
name: PR Workflow
on:
pull_request_target:
types:
- labeled
- synchronize
- reopened
- opened
# only run if PR targets 'develop' branch for merging
branches:
- 'develop'
jobs:
release-snapshot:
name: Release snapshot
runs-on: ubuntu-latest
# don't run job unless PR has been marked safe after manual review of changes!
if: contains(github.event.pull_request.labels.*.name, 'safe to test')
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
# ...
- name: Build and push
id: docker_build
uses: docker/build-push-action@v5
env:
# produces version like pr152-11ec1c7c
APP_VERSION: ${{ format('pr{0}-{1}', github.event.number, github.event.pull_request.head.sha ) }}
with:
context: .
build-args: |
APP_BUILD_VERSION=${{env.APP_VERSION}}
# ...