Skip to content

Instantly share code, notes, and snippets.

@izikeros
Last active April 5, 2024 04:05
Show Gist options
  • Save izikeros/4aaa9010837a85afc5ea5146b38bd848 to your computer and use it in GitHub Desktop.
Save izikeros/4aaa9010837a85afc5ea5146b38bd848 to your computer and use it in GitHub Desktop.
[gitversion GitHub Action] GitHub action that support versioning for mono repo #github #action
on:
pull_request:
branches:
- develop
- main
push:
branches:
- develop
- main
- 'release/**'
- 'hotfix/**'
env:
GITVERSION: 'gittools/gitversion:5.10.0-alpine.3.14-6.0'
MAIN_BRANCHES: ("develop" "main")
GITVERSION_TAG_PROPERTY_PULL_REQUESTS: .SemVer
GITVERSION_TAG_PROPERTY_DEFAULT: .SemVer
GITVERSION_TAG_PROPERTY_DEVELOP: .MajorMinorPatch,.PreReleaseLabelWithDash
GITVERSION_TAG_PROPERTY_RELEASE: .MajorMinorPatch,.PreReleaseLabelWithDash
GITVERSION_TAG_PROPERTY_HOTFIX: .MajorMinorPatch,.PreReleaseLabelWithDash
GITVERSION_TAG_PROPERTY_MAIN: .MajorMinorPatch
jobs:
gitversion:
name: gitversion
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Fetch all history for all tags and branches
run: git fetch --unshallow && git checkout develop && git checkout main
#- name: Check base ref
# run: echo "baseref='$GITHUB_BASE_REF' ref='$GITHUB_REF' headref='$GITHUB_HEAD_REF' refname='$GITHUB_REF_NAME' eventname='$GITHUB_EVENT_NAME'"
- name: Checkout to branch
run: |
if [ "${GITHUB_EVENT_NAME}" = 'push' ]; then
DIFF_DEST="${GITHUB_REF_NAME}"
else
DIFF_DEST="${GITHUB_HEAD_REF}"
fi
git checkout ${DIFF_DEST}
- name: Calculate changed services
id: calculate_changed_services
run: |
if [ "${GITHUB_EVENT_NAME}" = 'push' ]; then
DIFF_DEST="${GITHUB_REF_NAME}"
DIFF_SOURCE=$(git rev-parse "${DIFF_DEST}"^1)
else
DIFF_DEST="${GITHUB_HEAD_REF}"
DIFF_SOURCE="${GITHUB_BASE_REF}"
fi
# use main as source if current branch is a release branch
if [ "$(echo "${DIFF_DEST}" | grep -o '^release/')" = "release/" ]; then
DIFF_SOURCE="main"
fi
# use main as source if current branch is a hotfix branch
if [ "$(echo "${DIFF_DEST}" | grep -o '^hotfix/')" = "hotfix/" ]; then
DIFF_SOURCE="main"
fi
# service change calculation with diff - ideally use something like 'plz' or 'bazel'
if [ "$(git diff "${DIFF_SOURCE}" "${DIFF_DEST}" --name-only | grep -o '^common/' > /dev/null && echo 'common changed')" = 'common changed' ]; then
changed_services=`ls -1 apps | xargs -n 1 printf 'apps/%s\n'`
else
changed_services=`git diff "${DIFF_SOURCE}" "${DIFF_DEST}" --name-only | grep -o '^apps/[a-zA-Z-]*' | sort | uniq`
fi
changed_services=$(printf '%s' "$changed_services" | jq --raw-input --slurp '.')
echo "::set-output name=changed_services::$changed_services"
echo "::set-output name=diff_source::$DIFF_SOURCE"
echo "::set-output name=diff_dest::$DIFF_DEST"
echo "DIFF_SOURCE='$DIFF_SOURCE'"
echo "DIFF_DEST='$DIFF_DEST'"
echo "changed_services='$(echo "$changed_services" | sed 'N;s/\n/, /g')'"
- name: Calculate service versions
id: calculate_service_versions
run: |
changed_services=( ${{ fromJSON(steps.calculate_changed_services.outputs.changed_services) }} )
if [ "${#changed_services[@]}" = "0" ]; then
service_versions_txt='## impact surface\nNo services changed\n'
else
service_versions_txt="## impact surface\n"
for svc in "${changed_services[@]}"; do
echo "calculation for ${svc}"
docker run --rm -v "$(pwd):/repo" ${GITVERSION} /repo /config "/repo/${svc}/.gitversion.yml"
gitversion_calc=$(docker run --rm -v "$(pwd):/repo" ${GITVERSION} /repo /config "/repo/${svc}/.gitversion.yml")
GITVERSION_TAG_PROPERTY_NAME="GITVERSION_TAG_PROPERTY_PULL_REQUESTS"
GITVERSION_TAG_PROPERTY=${!GITVERSION_TAG_PROPERTY_NAME}
service_version=$(echo "${gitversion_calc}" | jq -r "[${GITVERSION_TAG_PROPERTY}] | join(\"\")")
service_versions_txt+="- ${svc} - v${service_version}\n"
done
fi
# fix multiline variables
# from: https://github.com/actions/create-release/issues/64#issuecomment-638695206
PR_BODY="${service_versions_txt}"
PR_BODY=$(printf '%s' "$PR_BODY" | jq --raw-input --slurp '.')
echo "${PR_BODY}"
echo "::set-output name=PR_BODY::$PR_BODY"
- name: Update PR description
if: ${{ github.event_name == 'pull_request' }}
run: |
PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
# from https://github.com/actions/checkout/issues/58#issuecomment-614041550
jq -nc '{"body": "${{ fromJSON(steps.calculate_service_versions.outputs.PR_BODY) }}" }' | \
curl -sL -X PATCH -d @- \
-H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER"
- name: Tag build
if: ${{ github.event_name == 'push' && (startsWith(steps.calculate_changed_services.outputs.diff_dest, 'release') || startsWith(steps.calculate_changed_services.outputs.diff_dest, 'hotfix') || contains(env.MAIN_BRANCHES, steps.calculate_changed_services.outputs.diff_dest)) }}
run: |
# https://github.com/orgs/community/discussions/26560
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions"
changed_services=( ${{ fromJSON(steps.calculate_changed_services.outputs.changed_services) }} )
for svc in "${changed_services[@]}"; do
echo "calculation for ${svc}"
docker run --rm -v "$(pwd):/repo" ${GITVERSION} /repo /config "/repo/${svc}/.gitversion.yml"
gitversion_calc=$(docker run --rm -v "$(pwd):/repo" ${GITVERSION} /repo /config "/repo/${svc}/.gitversion.yml")
GITVERSION_TAG_PROPERTY_NAME="GITVERSION_TAG_PROPERTY_$(echo '${{ steps.calculate_changed_services.outputs.diff_dest }}' | sed 's|/.*$||' | tr '[[:lower:]]' '[[:upper:]]')"
GITVERSION_TAG_PROPERTY=${!GITVERSION_TAG_PROPERTY_NAME}
svc_without_prefix=$(echo "${svc}" | sed "s|^apps/||")
service_version=$(echo "${gitversion_calc}" | jq -r "[${GITVERSION_TAG_PROPERTY}] | join(\"\")")
if [ "${GITVERSION_TAG_PROPERTY}" != ".MajorMinorPatch" ]; then
echo tag_filter "^${svc_without_prefix}/v$(echo "${gitversion_calc}" | jq -r ".MajorMinorPatch")-$(echo "${gitversion_calc}" | jq -r ".PreReleaseLabel")"
echo tags with tag_filter "$(git tag -l | grep "^${svc_without_prefix}/v$(echo "${gitversion_calc}" | jq -r ".MajorMinorPatch")-$(echo "${gitversion_calc}" | jq -r ".PreReleaseLabel")")"
echo tags grepped on commit count "$(git tag -l | grep "^${svc_without_prefix}/v$(echo "${gitversion_calc}" | jq -r ".MajorMinorPatch")-$(echo "${gitversion_calc}" | jq -r ".PreReleaseLabel")" | grep -o -E '\.[0-9]+$')"
echo tags grepped on commit count and period removed "$(git tag -l | grep "^${svc_without_prefix}/v$(echo "${gitversion_calc}" | jq -r ".MajorMinorPatch")-$(echo "${gitversion_calc}" | jq -r ".PreReleaseLabel")" | grep -o -E '\.[0-9]+$' | grep -o -E '[0-9]+$')"
previous_commit_count=$(git tag -l | grep "^${svc_without_prefix}/v$(echo "${gitversion_calc}" | jq -r ".MajorMinorPatch")-$(echo "${gitversion_calc}" | jq -r ".PreReleaseLabel")" | grep -o -E '\.[0-9]+$' | grep -o -E '[0-9]+$' | sort -nr | head -1)
echo previous_commit_count $previous_commit_count
next_commit_count=$((previous_commit_count+1))
echo next_commit_count $next_commit_count
full_service_version="${service_version}.${next_commit_count}"
else
full_service_version="${service_version}"
fi
git tag -a "${svc_without_prefix}/v${full_service_version}" -m "${svc_without_prefix}/v${full_service_version}"
git push origin "${svc_without_prefix}/v${full_service_version}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment