GitHub action that support versioning for mono repo
There is video explaining howto use it. GitHub action starts at 7min14
https://youtu.be/tTaIXej35rU?si=Cb_GRDeBteOAR-UQ&t=434
GitHub action that support versioning for mono repo
There is video explaining howto use it. GitHub action starts at 7min14
https://youtu.be/tTaIXej35rU?si=Cb_GRDeBteOAR-UQ&t=434
| 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 |