| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Language/content agnostic method of automatically determining the semantic version for a product based on branch merge history with MINIMAL discipline dependencies.
This is accomplished by counting the merges of branches matching the naming scheme into the [main|master] branch. Folks familiar with Scrum/SAFe or GitFlow/fooFlow strategies will recognize this scheme.
git checkout v1.2.3 git tag 1.2.3 git push --tags
npm version ${{ steps.gitops-autover.outputs.new-version }}
git checkout -b fix/not-a-feature git commit --allow-empty -m "This was a bug and not a feature after all..." git push --set-upstream origin fix/not-a-feature # THEN: Click the link to create a PR & merge it
Note: Only required for setting up mono-repo versioning.
Below is a valid workflow utilizing this action. If you wanted to extend it to do something like update a 'package.json' version, for example, you would simply create a step that runs: npm version $NEW_VERSION.
name: gitops-autover
on:
push:
branches:
- main
jobs:
use-action:
name: Verify GitOps AutoVer Action
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run GitOps Automatic Versioning Action
id: gitops-autover
uses: AlexAtkinson/github-action-gitops-autover@0.3.1
- name: Verify Outputs
run: |
NEW_VERSION=${{ steps.gitops-autover.outputs.new-version }}
echo "new-version: $NEW_VERSION"
PREVIOUS_VERSION=${{ steps.gitops-autover.outputs.previous-version }}
echo "previous-version: $PREVIOUS_VERSION"
To make use of the mono-repo support, simply add a block for the director you wish to version.
- name: Run GitOps Automatic Versioning Action
id: gitops-autover
uses: AlexAtkinson/github-action-gitops-autover@0.3.1
with:
mono-repo-product-name: bob
mono-repo-product-path: path/to/bob
This results in outputs like:
major:
patch:
minor:
Q: How did you execute 103 merges?
A: You can use the bump scripts in the scripts directory of this
repo, like: './scripts/bumpPatch.sh 42'. (Does not work with branch protection enabled)
Additionally, this repo uses its own action for versioning, so feel free to investigate that workflow for another example.
name: gitops-autover-example
on:
push:
branches:
- main
jobs:
init:
name: Initialize
runs-on: ubuntu-latest
outputs:
REPOSITORY: ${{ steps.init.outputs.REPOSITORY }}
PRODUCT: ${{ steps.init.outputs.PRODUCT_NAME }}
PRODUCT_NAME_LOWER: ${{ steps.init.outputs.PRODUCT_NAME_LOWER }}
NEW_VERSION: ${{ steps.gitops-autover.outputs.new-version }}
PREVIOUS_VERSION: ${{ steps.gitops-autover.outputs.previous-version }}
steps:
- name: Checkout Source
uses: actions/checkout@v3
with:
lfs: true
fetch-depth: 0
- name: Initialize
id: init
run: |
# Detect repo name.
REPOSITORY=${PWD##*/}
echo "REPOSITORY=$REPOSITORY" >> $GITHUB_OUTPUT
# Autodetect product name. Eg:
# A repo named cool-corp-awesome-docker will result in
# the image being pushed as: awesome-docker:x.x.x
[[ $(echo -n "$(cut -d- -f3- <<< ${REPOSITORY})" | wc -c) -gt 0 ]] && PRODUCT_NAME=$(cut -d- -f3- <<< ${REPOSITORY})
[[ $(echo -n "$(cut -d- -f3- <<< ${REPOSITORY})" | wc -c) -eq 0 ]] && PRODUCT_NAME=default
echo "PRODUCT_NAME=$PRODUCT_NAME" >> $GITHUB_OUTPUT
PRODUCT_NAME_LOWER=${PRODUCT_NAME,,}
echo "PRODUCT_NAME_LOWER=$PRODUCT_NAME_LOWER" >> $GITHUB_OUTPUT
- name: GitOps Automatic Versioning
id: gitops-autover
uses: AlexAtkinson/github-action-gitops-autover@0.3.1
build:
name: "Build"
runs-on: ubuntu-latest
needs: [init]
steps:
- name: "Build"
run: |
echo "SUCCESSFUL BUILD" > "${{ needs.init.outputs.PRODUCT_NAME_LOWER }}.${{ needs.init.outputs.NEW_VERSION }}.txt"
# Then bolt on extras such as slack notify or github release actions as needed.
This action depends only on the following branch naming scheme being observed.
| Branch Name | Increment | Description |
|---|---|---|
| feature/.* | Minor | Product features. |
| enhancement/.* | Minor | Product enhancements. |
| fix/.* | Patch | Product fixes |
| bugfix/.* | Patch | You should use fix. |
| hotfix/.* | Patch | Are you from the past? |
| ops/.* | Patch | Enables ops changes to trigger builds. |
For example, the name of the branch for a new awesome feature named Awesome Feature, might be: 'feature/awesome_feature'.
When a merged PR has one of the labels 'semver:patch', 'semver:minor', 'semver:major', or 'semver:breaking', that label takes precedence over the branch name for bump selection.
Label lookup support by platform:
If a label lookup is configured (credentials present) but cannot complete, the run fails with error 592 rather than silently falling back to branch-name classification.
Squash merges are supported where the PR/MR number can be recovered from the commit:
Since a squashed commit does not carry the source branch name, classification of squash merges relies on semver labels (or overrides). Unlabeled squash merges are ignored.
This action is most suitable for git projects with the following operational design:
This action is not suitable for projects requiring:
Versions are returned only in the following format: 'MAJOR.MINOR.PATCH'.
MAJOR version increments depend upon manual intervention to trigger as it is not practical to automatically detect either major refactoring or accepted/planned breaking changes to a product. Human input informs the tool of such MAJOR increment qualifying scenarios.
This increment can be accomplished in one of the following ways:
Push a commit message containing: '+semver: [major|breaking]'. For example:
git commit --allow-empty -m "+semver: major" git push
Push the MAJOR tag manually. That this is the less desirable option as it will require the merge of a qualifying branch to iterate the version number, making the first possible version that could be produced 'n.0.1'. Assuming successful build and testing.
git tag 1.0.0 git push --tags
In mono-repo mode, the MAJOR indicator must appear on a commit that touches the scoped directory, otherwise that product's history will not include it.
For those interested, here's some pseudo code:
lastMajor = Extract from previous git tag on the repo or scoped directory history
lastMinor = Extract from previous git tag
lastPatch = Extract from previous git tag
IF no previous git tag; THEN
MAJOR = 0
MINOR = 0
PATCH = 0
IF major increment indicator; THEN
MAJOR = lastMajor + 1
MINOR = 0
PATCH = 0
ELSEIF merged PR has a semver label; THEN
use that label's bump instead of the branch name
ELSEIF merged feature/.* or enhancement/.* branches; THEN
MAJOR = lastMajor
MINOR = lastMinor + count of merged branches
PATCH = 0
ELSEIF merged bugfix/.* or hotfix/.* branches; THEN
MAJOR = lastMajor
MINOR = lastMinor
PATCH = lastPatch + count of merged branches
If there are no merges of branches conforming to the above naming scheme, this action will fail with the following output:
ERROR: No feature, enhancement, fix, bugfix, hotfix, or ops branches detected!
If a PR/MR label lookup is configured but fails (network, auth, etc.), the action fails with:
ERROR: 592 - PR/MR label lookup failed!
This is intentional: a version must never be computed from incomplete label data.
Run the isolated test harness locally with:
bash scripts/tests.sh
The script creates a temporary git repository, exercises repo and directory versioning paths, validates PR label precedence, squash-merge classification, and parallel full-history re-evaluation, and removes the fixture repo on exit. The same suite runs in CI on every pull request.
Merged branches not conforming to the above naming scheme will simply be ignored.
The version output does not have a 'v' prefix.
If you would like a 'v' prefix to your versions, add it to your logic when using the output from this action. For example:
echo "The new version is v${{ steps.detect-version.outputs.new-version }}"
^ here
If both 'main' and 'master' branches exist remotely: FAIL
Squash merging must be disabled. This is required to populate the git log with the commit messages issued from the git provider.
PRs are welcome.
| Back | FazBrowse Home | New Git URL |