Skip to content

Instantly share code, notes, and snippets.

@robotamer
Forked from jiroshimaya/README-update-version-sh.ja.md
Last active January 25, 2026 12:39
Show Gist options
  • Select an option

  • Save robotamer/35ef24fdd326626b7f5d8e9571e133c5 to your computer and use it in GitHub Desktop.

Select an option

Save robotamer/35ef24fdd326626b7f5d8e9571e133c5 to your computer and use it in GitHub Desktop.
A script to git add, git tag, git commit, and git push. Including auto incrementing tags with semantic versioning. Optionaly creates a meta data file
#!/bin/bash
help() {
echo "
NAME
commit - git add, tag, commit & push
SYNOPSIS
commit OPTION...
DESCRIPTION
A script to git add, git tag, git commit, and git push.
Including auto incrementing tags with semantic versioning.
Optionaly creates a meta data file
OPTIONS
-m, --message (optional only in dry run mode)
Specify a commit message
-i, --increment [major, minor, patch] (optional patch is the default)
Specify the type of version increment, alternatives: -v or -r
-v, --version (optional) (default: -i patch)
Specify a version. Use semantic versioning (v0.2.3).
-r, --recreate (optional)
Recreate the last tag, if it already exists, by deleting and retagging
-n, --nopush ( optional) (default for -i patch)
Do not push the tag to the remote even if it is created.
-d, --dryrun (optional)
Perform a dry run; no commit, tag, push ...
-t, --metadata (optional)
Create metadata.toml file
-p, --print (optional)
Print git info
EXAMPLES
commit.sh -v v2.0.0 -m 'code for freedom'
commit.sh -i patch -n -m '-i patch is the default you don't need to provide it'
commit.sh -r -d
REPO
https://gist.github.com/robotamer/35ef24fdd326626b7f5d8e9571e133c5
LICENSE
MIT ( http://blog.tamer.pw/license )
"
exit 0
}
set -eu
# Initialize variables
help=false
arg_message=''
arg_version=''
arg_inc=''
arg_toml=false
arg_dry_run=false
arg_retag=false
arg_no_push=false
arg_print_info=false
# variables to get from git
git_branch=''
git_hash=''
git_remote=''
git_origin=''
git_version=''
has_remote=false
new_version=''
if [[ "$#" -eq 0 ]]; then help; fi
if ! test -d ".git"
then
git init
git commit --allow-empty -m "init"
git tag v0.0.0
fi
if git stash show >/dev/null 2>&1
then
echo you have a stash, exiting!
git stash show
exit 1
fi
if git log -n 1 >/dev/null 2>&1
then
git_hash=$(git log --pretty=format:'%h' -n 1)
git_branch=$(git branch --show-current)
git_version=$(git describe --tags --always --abbrev=0 --match='v[0-9]*.[0-9]*.[0-9]*')
fi
if git remote -v | grep -q "push"
then
has_remote=true
git_origin=$(git remote -v | head -1 | cut -f1)
git_remote=$(git remote -v | head -1 | cut -f2 | cut -d' ' -f1)
fi
gittag() {
if $arg_retag
then
new_version=$git_version
if git rev-parse "$git_version" >/dev/null 2>&1
then
git tag -d "$git_version"
if $has_remote
then
if git ls-remote --tags "$git_origin" | grep -q "refs/tags/$git_version"
then
git push --delete "$git_origin" "$git_version"
fi
fi
fi
fi
git tag "$new_version"
}
gitcommit() {
git add .
git commit -am "$arg_message"
}
gitpush() {
if [[ "$arg_inc" && "$arg_inc" == "major" || "$arg_inc" == "minor" ]]
then
if $has_remote
then
echo pushing to remote "$git_origin"
git push
git push "$git_origin" $new_version
else
echo no remote server set
fi
fi
}
# create metadata.toml file
metadata() {
if test -f "go.mod"
then
PACKAGE=$(head -n 1 go.mod | cut -d' ' -f2)
fi
if test -f "env.sh"
then
. env.sh
else
echo "NAME='sendmail'" >> env.sh
echo "TITLE='Sendmail to Ntfy'" >> env.sh
echo "DESCRIPTION='Sendmail ntfy is a replacement of the sendmail linux command. This sendmail command sends mail to ntfy servers.'" >> env.sh
echo "KEYWORDS=('open' 'source')" >> env.sh
echo "LICENSE='MIT'" >> env.sh
echo edit env.sh file then re-run
exit 1
fi
## Converting bash array to toml
length=${#KEYWORDS[@]}
length=$length-1
tags='['
for (( i=$length; i >= 0; i-- ))
do
tags+="\"${KEYWORDS[$i]}\""
if [[ $i -ne 0 ]]
then
tags+=','
fi
done
tags+=']'
echo '# Do not edit this file here, see env.sh' > metadata.toml
echo "Name = '${NAME}'" >> metadata.toml
echo "Title = '${TITLE}'" >> metadata.toml
echo "Description = '${DESCRIPTION}'" >> metadata.toml
echo "Tags = ${tags}" >> metadata.toml
echo "License = '$LICENSE'" >> metadata.toml
echo "Version = '$git_version'" >> metadata.toml
echo "GitHash = '$git_hash'" >> metadata.toml
echo "GitBranch = '$git_branch'" >> metadata.toml
echo "GitRepo = '$git_remote'" >> metadata.toml
if [[ ! -z $PACKAGE ]]
then
echo "Package = '${PACKAGE}'" >> metadata.toml
echo "Homepage = 'http://${PACKAGE}'" >> metadata.toml
echo "Documentation = 'https://pkg.go.dev/${PACKAGE}'" >> metadata.toml
fi
}
# Parse arguments
while [[ "$#" -gt 0 ]]
do
case $1 in
-v|--version) arg_version=$2; shift ;;
-i|--increment) arg_inc="$2"; shift ;;
-h|--help) help ;;
-d|--dryrun) arg_dry_run=true ;;
-r|--recreate) arg_retag=true ;;
-n|--nopush) arg_no_push=true ;;
-t|--metadata) arg_toml=true ;;
-p|--print) arg_print_info=true ;;
-m|--message) arg_message="$2"; shift ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
# Validate increment
if [[ "$arg_inc" && "$arg_inc" != "major" && "$arg_inc" != "minor" && "$arg_inc" != "patch" ]]
then
echo "Invalid version increment: $arg_inc"
exit 1
fi
# The new arg_version
if [ -n "$arg_version" ] && [ ${arg_version:0:1} = 'v' ]
then
new_version=$arg_version
else
# Remove the leading 'v' then Split the version number in to parts
IFS='.' read -r -a version_parts <<< "${git_version#v}"
#echo version parts: ${version_parts[*]}
# Update the version based on the increment
case "$arg_inc" in
major)
((version_parts[0]=version_parts[0]+1))
version_parts[1]=0
version_parts[2]=0
;;
minor)
((version_parts[1]=version_parts[1]+1))
version_parts[2]=0
;;
*)
((version_parts[2]=version_parts[2]+1))
;;
esac
# Adding the leading 'v' back, and combining the parts
new_version="v${version_parts[0]}.${version_parts[1]}.${version_parts[2]}"
fi
if git status | grep -q "working tree clean"
then
echo current version: $git_version
echo Nothing to commit, working tree clean
exit 0
fi
if [[ ! -z $arg_message ]] && $arg_dry_run
then
echo current version: $git_version
echo Message is not optional, please provide one.
exit 1
fi
git status
read -e -p "Do you want to commit? " choice
if [[ "$choice" != [Yy]* ]]
then
exit 0
fi
if $arg_dry_run
then
echo "Dry run enabled, skipping everything."
else
if $arg_toml; then metadata; fi
gitcommit
gittag
if ! $arg_no_push; then gitpush; fi
fi
if $arg_print_info
then
echo Message: $arg_message
echo git origin: $git_origin
echo git branch: $git_branch
echo git hash: $git_hash
if $has_remote; then echo git remote: $git_remote; fi
echo git version old: $git_version
echo git version new: $new_version
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment