do-github-release #494
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: do-github-release | |
# This workflow automates the app release process and supports multiple triggers: | |
# - Manual dispatch: Releases unconditionally with a specified version bump. | |
# - Dispatch from `process-pr-merge`: Releases unconditionally using the version bump from `process-pr-merge`. | |
# - Weekly schedule: Runs every Monday at 3:00 PM EST and performs a patch release if the app directory has changed since the last release. | |
# Key steps: | |
# - Optionally checks for changes in `/app` and determines the release type (major, minor, or patch). | |
# - Extracts unreleased notes from `CHANGELOG.md`, updates it, and syncs `changelog.xml`. | |
# - Bumps the app version, builds, and signs the APK. | |
# - Commits changes and creates a GitHub release with the APK and changelog details. | |
on: | |
schedule: | |
# Run every Monday at 3:00 PM EST | |
- cron: "0 20 * * 1" | |
workflow_dispatch: | |
inputs: | |
bump_type: | |
description: "Specify the type of version bump (major, minor, patch)" | |
required: false | |
default: "patch" | |
repository_dispatch: | |
types: [trigger-release] | |
jobs: | |
check-changes: | |
runs-on: ubuntu-latest | |
outputs: | |
release_required: ${{ steps.release-check.outputs.release_required }} | |
bump_type: ${{ steps.release-check.outputs.bump_type }} | |
steps: | |
- name: Checkout Repo | |
uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.ACTIONS_PAT }} | |
fetch-depth: 0 | |
- name: Determine Release Type and Necessity | |
id: release-check | |
run: | | |
if [ "${{ github.event_name }}" == "schedule" ]; then | |
LAST_RELEASE_TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) | |
echo "LAST_RELEASE_TAG: $LAST_RELEASE_TAG" | |
LAST_RELEASE_COMMIT=$(git rev-list -n 1 $LAST_RELEASE_TAG) | |
echo "LAST_RELEASE_COMMIT: $LAST_RELEASE_COMMIT" | |
changed_files=$(git diff-tree --no-commit-id --name-only $LAST_RELEASE_COMMIT HEAD | grep '^app' || echo "none") | |
echo "Changed files: $changed_files" | |
if [ "$changed_files" != "none" ]; then | |
echo "App directory has changed since the last release, proceeding with new release" | |
echo "release_required=true" >> $GITHUB_OUTPUT | |
echo "bump_type=patch" >> $GITHUB_OUTPUT | |
else | |
echo "No app directory changes since the last release. Skipping release." | |
echo "release_required=false" >> $GITHUB_OUTPUT | |
fi | |
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | |
echo "release_required=true" >> $GITHUB_OUTPUT | |
echo "bump_type=${{ github.event.inputs.bump_type }}" >> $GITHUB_OUTPUT | |
elif [ "${{ github.event_name }}" == "repository_dispatch" ]; then | |
echo "release_required=true" >> $GITHUB_OUTPUT | |
echo "bump_type=${{ github.event.client_payload.bump_type }}" >> $GITHUB_OUTPUT | |
else | |
echo "Unknown trigger source." | |
exit 1 | |
fi | |
release: | |
runs-on: ubuntu-latest | |
needs: check-changes | |
if: needs.check-changes.outputs.release_required == 'true' | |
steps: | |
- name: Checkout Repo | |
uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.ACTIONS_PAT }} | |
fetch-depth: 0 | |
- name: Bump Version in version.properties | |
id: bump-version | |
run: | | |
bump_type="${{ needs.check-changes.outputs.bump_type }}" | |
echo "Bumping version with BUMP_TYPE: $bump_type" | |
source version.properties | |
if [ "$bump_type" == "major" ]; then | |
majorVersion=$((majorVersion + 1)) | |
minorVersion=0 | |
patchVersion=0 | |
elif [ "$bump_type" == "minor" ]; then | |
minorVersion=$((minorVersion + 1)) | |
patchVersion=0 | |
else | |
patchVersion=$((patchVersion + 1)) | |
fi | |
echo "majorVersion=$majorVersion" > version.properties | |
echo "minorVersion=$minorVersion" >> version.properties | |
echo "patchVersion=$patchVersion" >> version.properties | |
VERSION=$majorVersion.$minorVersion.$patchVersion | |
VERSION_CODE=$((majorVersion * 10000 + minorVersion * 100 + patchVersion)) | |
echo "VERSION=$VERSION" >> $GITHUB_ENV | |
echo "VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV | |
- name: Update changelog.xml | |
id: update-changelog-xml | |
run: | | |
# Read the Unreleased section and process notes based on type | |
RELEASE_CONTENT="" CURRENT_TYPE="" | |
while IFS= read -r note; do | |
if [[ "$note" == "### Added"* ]]; then | |
CURRENT_TYPE="new" | |
elif [[ "$note" == "### Changed"* ]]; then | |
CURRENT_TYPE="info" | |
elif [[ "$note" == "### Fixed"* ]]; then | |
CURRENT_TYPE="bugfix" | |
elif [[ "$note" =~ ^- ]]; then | |
clean_note=$(echo "$note" | sed -E 's/^- //; s/ *\(.*\)//') | |
RELEASE_CONTENT+=" <${CURRENT_TYPE}>${clean_note}</${CURRENT_TYPE}>\n" | |
#pr_number=$(echo "$note" | grep -oP 'pull/\K[0-9]+' || echo "N/A") | |
#RELEASE_CONTENT+=" <${CURRENT_TYPE}>${clean_note} (#${pr_number})</${CURRENT_TYPE}>\n" | |
fi | |
done < <(sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed '1,2d' | sed '$d') | |
# Generate, insert, and log the new release block | |
today=$(date +'%Y-%m-%d') | |
RELEASE_BLOCK=" <release date=\"$today\" versionCode=\"$VERSION_CODE\" versionName=\"v$VERSION\">\n" | |
RELEASE_BLOCK+="$RELEASE_CONTENT" | |
RELEASE_BLOCK+=" </release>" | |
sed -i "/<changelog>/a \\\n$RELEASE_BLOCK" app/src/main/res/raw/changelog.xml | |
echo "Generated release block:" | |
echo -e "$RELEASE_BLOCK" | |
- name: Process CHANGELOG.md | |
id: process-changelog | |
run: | | |
unreleased_section=$(sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed '1,2d' | sed '$d') | |
if [ -z "$unreleased_section" ]; then | |
changelog_escaped="No release notes" | |
else | |
changelog_escaped=$(echo "$unreleased_section" | sed 's/^- /✔ /g' | sed ':a;N;$!ba;s/\n/%0A/g') | |
fi | |
echo "changelog_additions=$changelog_escaped" >> $GITHUB_OUTPUT | |
today=$(date +'%Y-%m-%d') | |
sed -i "s/## \[Unreleased\]/## [v$VERSION] - $today/" CHANGELOG.md | |
sed -i '/## \[v'$VERSION'\]/i ## [Unreleased]\n\n### Added\n\n### Changed\n\n### Fixed\n' CHANGELOG.md | |
REPO_URL="https://github.com/${{ github.repository }}/releases/tag" | |
printf "\n[v$VERSION]: $REPO_URL/$VERSION" >> CHANGELOG.md | |
- name: Set Up Build Environment | |
uses: actions/setup-java@v3 | |
with: | |
java-version: '17' | |
distribution: 'temurin' | |
- name: Setup Android SDK | |
uses: android-actions/setup-android@v3 | |
- name: Install Build Tools 29.0.3 | |
run: sdkmanager "build-tools;29.0.3" | |
- name: Make gradlew executable | |
run: chmod +x ./gradlew | |
- name: Build APK | |
run: ./gradlew app:assembleRelease | |
- name: Sign APK | |
uses: r0adkll/sign-android-release@v1 | |
with: | |
releaseDirectory: app/build/outputs/apk/release | |
signingKeyBase64: ${{ secrets.SIGNING_KEY }} | |
alias: ${{ secrets.ALIAS }} | |
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }} | |
keyPassword: ${{ secrets.KEY_PASSWORD }} | |
- name: Upload Built APK | |
uses: actions/upload-artifact@v4 | |
with: | |
name: Signed APK | |
path: app/build/outputs/ | |
- name: Commit Version and Changelog Changes | |
if: ${{ success() }} | |
uses: EndBug/add-and-commit@v7 | |
with: | |
add: "version.properties CHANGELOG.md app/src/main/res/raw/changelog.xml" | |
message: "Bump ${{ env.BUMP_TYPE }} and update changelog for v${{ env.VERSION }}" | |
token: ${{ secrets.ACTIONS_PAT }} | |
- name: Push Changes | |
uses: ad-m/github-push-action@master | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
branch: ${{ github.ref }} | |
- name: Make GitHub Release | |
uses: svenstaro/upload-release-action@v2 | |
with: | |
repo_token: ${{ secrets.GITHUB_TOKEN }} | |
release_name: "v${{ env.VERSION }}" | |
tag: "${{ env.VERSION }}" | |
file: app/build/outputs/apk/release/app-release-unsigned-signed.apk | |
asset_name: "Field-Book-v${{ env.VERSION }}.apk" | |
body: ${{ steps.process-changelog.outputs.changelog_additions }} | |
- name: Check date for Google Play upload | |
id: date_check | |
run: | | |
CURRENT_DATE=$(date +%m%d) | |
echo "CURRENT_DATE: $CURRENT_DATE" | |
if [ "$CURRENT_DATE" -ge 0415 ] && [ "$CURRENT_DATE" -le 0915 ]; then | |
echo "UPLOAD_TO_PLAY_STORE=false" >> $GITHUB_ENV | |
else | |
echo "UPLOAD_TO_PLAY_STORE=true" >> $GITHUB_ENV | |
fi | |
- name: Release APK to Play Store | |
if: env.UPLOAD_TO_PLAY_STORE == 'true' | |
uses: r0adkll/upload-google-play@v1 | |
with: | |
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} | |
packageName: com.fieldbook.tracker | |
releaseFiles: app/build/outputs/apk/release/app-release-unsigned-signed.apk | |
track: alpha |