Skip to content

Release

Release #14

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
branch:
type: string
description: Branch name to release
required: true
default: main
section:
type: choice
description: Version section to increment
options:
- PATCH
- MINOR
- MAJOR
required: true
default: PATCH
version:
type: string
description: |
...or manually define version like 1.2.3, 1.2.3-suffix
required: false
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Setup bot token
uses: actions/create-github-app-token@v1
id: bot
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Configure bot git account
id: get-user-id
env:
GH_TOKEN: ${{ steps.bot.outputs.token }}
run: |
USER_ID="$(gh api "/users/${{ steps.bot.outputs.app-slug }}[bot]" --jq .id)"
USER_EMAIL="$USER_ID+${{ steps.bot.outputs.app-slug }}[bot]@users.noreply.github.com"
USER_NAME="${{ steps.bot.outputs.app-slug }}[bot]"
git config --global user.name "$USER_NAME"
git config --global user.email "$USER_EMAIL"
- name: Checkout
uses: actions/checkout@v4
with:
ref: "refs/heads/${{ inputs.branch }}"
token: ${{ steps.bot.outputs.token }}
# Required to deduce version from git tags
fetch-depth: 0
- name: Validate build succeeded
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if git tag --points-at HEAD | grep -Eq "^v[0-9]+.[0-9]+.[0-9]+$"; then
echo "Last commit is a release commit."
exit 0
fi
declare -r SHA="$(git rev-parse HEAD)"
declare -r RUNS="$(gh api \
-H "Accept: application/vnd.github+json" \
/repos/${{ github.repository }}/actions/runs?head_sha=$SHA)"
declare -r BUILD_SUCCESS="$(echo "$RUNS" | jq -r 'limit(1; .workflow_runs[] | select(.name == "Build" and .conclusion == "success")) | .conclusion')"
if [ -z "$BUILD_SUCCESS" ]; then
echo "Commit did not pass Build. Stopping release!"
exit 1
fi
echo "Last commit passed build."
exit 0
- name: Get versions
id: versions
env:
BRANCH: ${{ inputs.branch }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
MANUAL_VERSION: ${{ inputs.version }}
INCREMENT_SECTION: ${{ inputs.section }}
run: |
declare -r GIT_VERSION="$(git tag -l 'v[0-9]*' --merged HEAD --sort=-v:refname | grep -E "^v[0-9]+.[0-9]+.[0-9]+$" | head -n 1 | cut -c2-)"
declare -r VERSION=${GIT_VERSION:-0.0.0}
declare -r MAJOR="$(echo "$VERSION" | cut -d. -f1)"
declare -r MINOR="$(echo "$VERSION" | cut -d. -f2)"
declare -r PATCH="$(echo "$VERSION" | cut -d. -f3)"
declare NEXT_VERSION=""
if [ -n "$MANUAL_VERSION" ]; then
if [[ "$MANUAL_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
NEXT_VERSION="$MANUAL_VERSION"
else
echo "Invalid manual version: $MANUAL_VERSION" >&2
echo "Expected versions format: 1.2.3" >&2
exit 1
fi
elif [ "$INCREMENT_SECTION" == "PATCH" ]; then
NEXT_VERSION="$MAJOR.$MINOR.$(( PATCH + 1 ))"
elif [ "$INCREMENT_SECTION" == "MINOR" ]; then
NEXT_VERSION="$MAJOR.$(( MINOR + 1 )).0"
elif [ "$INCREMENT_SECTION" == "MAJOR" ]; then
NEXT_VERSION="$(( MAJOR + 1 )).0.0"
else
echo "Unrecognized option: $INCREMENT_SECTION" >&2
exit 1
fi
if [ "$BRANCH" != "$DEFAULT_BRANCH" ] && [ "$(echo "$NEXT_VERSION" | cut -d. -f1)" != "$MAJOR" ]; then
echo "New major version can be created only from the $DEFAULT_BRANCH branch" >&2
exit 1
fi
echo -e "VERSION: $VERSION\nNEXT_VERSION: $NEXT_VERSION"
echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Update version in files
id: commit
env:
PREV_VERSION: ${{ steps.versions.outputs.version }}
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
run: |
declare -r ESC_PREV_VERSION="${PREV_VERSION//./\\.}"
echo "Changing: $PREV_VERSION -> $NEXT_VERSION"
sed -i "s|${ESC_PREV_VERSION}|${NEXT_VERSION}|" README.md
sed -i "s|^version=${ESC_PREV_VERSION}|version=${NEXT_VERSION}|" gradle.properties
if [ "$NEXT_VERSION" == "${NEXT_VERSION%%-SNAPSHOT}" ]; then
if [ -n "$(git status --porcelain)" ]; then
git add -A
git commit -a -m "Update version $PREV_VERSION -> $NEXT_VERSION" -m "[ci skip]"
git push
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
else
echo "Nothing changed. Skipping commit."
fi
else
echo "Skipping committing updated version in config files for SNAPSHOT version."
fi
- name: Publish Release to Gradle Plugin Portal
id: publish
env:
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
run: |
./gradlew publishPlugins \
-Pgradle.publish.key=$GRADLE_PUBLISH_KEY \
-Pgradle.publish.secret=$GRADLE_PUBLISH_SECRET \
-Pversion=$NEXT_VERSION
echo "### Published release version $NEXT_VERSION 🚀" | tee -a $GITHUB_STEP_SUMMARY
- name: Revert version commit on failure
if: failure() && steps.publish.conclusion == 'failure'
env:
COMMIT_SHA: ${{ steps.commit.outputs.sha }}
run: |
if [ -n "$COMMIT_SHA" ]; then
git revert "$COMMIT_SHA"
git push
echo "Reverted version commit: $COMMIT_SHA"
fi
- name: Create release tag
env:
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
run: |
declare -r TAG_NAME="v$NEXT_VERSION"
git tag "$TAG_NAME"
git push origin "$TAG_NAME"
echo "name=$TAG_NAME" >> $GITHUB_OUTPUT
- name: Create major branch
id: tag
env:
BRANCH: ${{ inputs.branch }}
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
PREV_VERSION: ${{ steps.versions.outputs.version }}
run: |
declare -r NEXT_MAJOR="$(echo "$NEXT_VERSION" | cut -d. -f1)"
declare -r PREV_MAJOR="$(echo "$PREV_VERSION" | cut -d. -f1)"
if [ "$NEXT_MAJOR" != "$PREV_MAJOR" ]; then
NEW_BRANCH="v${PREV_MAJOR}.x.x"
if git rev-parse --verify "$NEW_BRANCH" &>/dev/null; then
echo "Repository already contains branch for previous major version: $NEW_BRANCH"
else
git checkout -b "$NEW_BRANCH"
git push origin "$NEW_BRANCH"
git checkout "$BRANCH"
echo "Created branch for new major version: $NEW_BRANCH"
echo "### Created branch for previous major version $NEW_BRANCH 🚀" | tee -a $GITHUB_STEP_SUMMARY
fi
else
echo "Next and prev major versions are the same: $NEXT_MAJOR"
fi
- name: Generate release notes
id: notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PREV_VERSION: ${{ steps.versions.outputs.version }}
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
run: |
declare -r PREV_TAG_NAME="$([ "$PREV_VERSION" == "0.0.0" ] && echo "" || echo "v$PREV_VERSION")"
declare -r NOTES="$(gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/${{ github.repository }}/releases/generate-notes \
-f tag_name="v$NEXT_VERSION" \
-f previous_tag_name="$PREV_TAG_NAME" \
| jq -r '.body')"
echo 'notes<<EOF' >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Create github release
if: steps.notes.conclusion == 'success'
uses: ncipollo/release-action@v1
with:
allowUpdates: true
body: ${{ steps.notes.outputs.notes }}
draft: ${{ inputs.publish == 'SKIP' }}
tag: v${{ steps.versions.outputs.next_version }}
token: ${{ secrets.GITHUB_TOKEN }}