Skip to content

Commit

Permalink
ci: Fix release flow
Browse files Browse the repository at this point in the history
  • Loading branch information
osipxd authored Jul 31, 2024
1 parent 54b6857 commit 9ada442
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 11 deletions.
18 changes: 7 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ name: CI
on:
push:
branches: [main]
# Release tag format is [module-name]-[namespace-name]-v[version]-[sub-version]
# For example: fragment-ktx-v1.3.5-0, compose-gears-v.1.1.1-1
tags:
- '*-ktx-v*-[0-9]+'
- '*-gears-v*-[0-9]+'
# Release tag format is [library-name]-v[version]
# Examples: fragment-ktx-v1.3.5-0, gears-compose-v1.1.1, resultflow-v0.1.0
tags: ['*-v*']
pull_request:
branches: [main]

Expand Down Expand Up @@ -36,7 +34,7 @@ jobs:
run: ./gradlew detektAll detektReleaseAll

publish:
name: Publish gears
name: Publish
needs: check
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref, 'refs/tags/') }}
Expand All @@ -51,20 +49,18 @@ jobs:
distribution: 'temurin'
java-version: 17

- name: Get namespace and module name from tag
- name: Get module name from tag
id: parse-tag
run: |
tag=${GITHUB_REF#refs/tags/}
module=$(echo "${tag%-*-v*}")
namespace=$(echo "${tag/-v*}" | rev | cut -d '-' -f 1 | rev)
module=$(./scripts/get-module-name.sh "$tag")
echo "module=$module" >> "$GITHUB_OUTPUT"
echo "namespace=$namespace" >> "$GITHUB_OUTPUT"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Run Publish
run: ./gradlew :${{ steps.parse-tag.outputs.namespace }}:${{ steps.parse-tag.outputs.module }}:publish
run: ./gradlew ${{ steps.parse-tag.outputs.module }}:publish
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }}
Expand Down
39 changes: 39 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Releasing

1. Run the script `release.sh` with release name in format `[library]-v[version]`:
```bash
./release.sh gears-compose-v1.0.0
````

2. The script will ask you if you want to push the release branch and create a release tag.

3. Ensure `CHANGELOG.md` looks good and is ready to be published.
Make the necessary edits.

4. Type "yes" to the console if everything is okay.

5. Click the link printed in the console to create a Pull Request for release branch.

6. Merge the Pull Request as soon as the "Check" workflow succeeds.

Release tag push triggers a GitHub Actions workflow, which publishes the release artifacts to Maven Central and creates a GitHub release.

## Manual release preparation

To prepare the release manually, follow the steps the script does:

1. Ensure the repository is up to date, and the main branch is checked out.

2. Create the release branch with the name `release/[library]-v[version]`

3. Update the version in `gradle.properties`, `build.gradle.kts` and `README.md` ("Usage" section).

4. Update the `CHANGELOG.md`:
1. Replace `Unreleased` section with the release version
2. Add a link to the diff between the previous and the new version (if possible)
3. Add a new empty `Unreleased` section on the top

5. Commit the changes, create a tag on the commit, and push it to the remote repository.
The tag should follow the format `[library]-v[version]`.

6. Create a Pull Request for the release branch and merge it.
131 changes: 131 additions & 0 deletions release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/env bash
#
# Prepares the specified library for release. Creates a release branch from the 'main'.
#
# Usage: ./release.sh [release-name]
# Where `release-name` is: [library-name]-v[version]
#
# Example: ./release.sh gears-compose-v1.0.0
#
# Original release script: https://github.com/RedMadRobot/android-library-template/blob/main/release.sh

set -euo pipefail

# The script could be run from any directory.
cd "$(dirname "$0")"

# Handle release input parameter
release=${1:?Please specify the release to be released as a parameter}
module=$(./scripts/get-module-name.sh "$release")
module_path=${module#:} # :gears:gears-compose -> gears:gears-compose
module_path=${module_path//://} # gears:gears-compose -> gears/gears-compose
library=${release%-v*} # gears-compose-v1.0.0 -> gears-compose

# Configure the script
properties="$module_path/gradle.properties"
changelog="$module_path/CHANGELOG.md"
readme="$module_path/README.md"
build_script="$module_path/build.gradle.kts"
files_to_update_version=("$properties" "$build_script" "$readme")
github_repository_url="https://github.com/RedMadRobot/gears-android"

#region Utils
function error() {
echo "$1"
return 1
}

function get_current_version() {
local version=""
if [[ -f $properties ]]; then
version=$(grep "^version=" "$properties")
fi

if [[ -z $version && -f $build_script ]]; then
version=$(grep "^version = \"" "$build_script")
fi

if [[ -z $version ]]; then
error "Can't find current version. Checked locations: $properties, $build_script"
fi

echo "$version" | cut -d'=' -f2 | tr -d ' "'
}

function replace() {
local file=$3

# Escape linebreaks
local replacement=${2//$'\n'/\\\n}
# Portable in-place edit.
# See: https://stackoverflow.com/a/4247319
sed -i".bak" -E "s~$1~$replacement~g" "$file"
rm "$file.bak"
}

function diff_link() {
echo -n "$github_repository_url/compare/${1}...${2}"
}
#endregion

# Check if the module exists
[[ -d $module_path ]] || error "Module '$module' not found on path '$module_path'."

# 0. Fetch remote changes
echo "️⏳ Creating release branch..."
release_branch="release/$release"
git checkout --quiet -b "$release_branch"
git pull --quiet --rebase origin main
echo "✅ Branch '$release_branch' created"
echo

# 1. Calculate module and version values for later
last_version=$(get_current_version)
version=${release##*-v} # library-v1.0.0 -> 1.0.0
if [[ "$last_version" == "$version" ]]; then
echo "🤔 Version $version is already set."
exit 0
fi
echo "🚀 [$module] Update $last_version$version"
echo

# 2. Update version everywhere
for file in "${files_to_update_version[@]}" ; do
if [[ -f $file ]]; then
replace "$last_version" "$version" "$file"
echo "✅ Updated version in $file"
fi
done

# 3. Update header in CHANGELOG.md
date=$(date -u +%Y-%m-%d)
header_replacement=\
"## Unreleased
- *No changes*
## $version ($date)"
replace "^## Unreleased.*" "$header_replacement" "$changelog"
echo "✅ Updated CHANGELOG.md header"

# 4. Ask if the changes should be pushed to remote branch
echo
echo "Do you want to commit the changes and push the release branch and tag?"
echo "The release tag push triggers a release workflow on CI."
read -p " Enter 'yes' to continue: " -r input
if [[ "$input" != "yes" ]]; then
echo "👌 SKIPPED."
exit 0
fi



# 5. Push changes, trigger release on CI, and give a link to open PR
echo
echo "⏳ Pushing the changes to the remote repository..."
git add "$readme" "$changelog" "$properties" "$build_script"
git commit --quiet --message "$library: $version"
git tag "$release"
git push --quiet origin HEAD "$release"
echo "🎉 DONE."
echo "Create a Pull Request: $(diff_link main "$release_branch")"
23 changes: 23 additions & 0 deletions scripts/get-module-name.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
#
# Retrieves Gradle module name from the given version tag.
# Examples:
# gears-compose-v1.0.0 -> :gears:gears-compose
# core-ktx-v1.0.0-1 -> :ktx:core-ktx
# resultflow-v1.0.0 -> :resultflow
#

set -eu

tag=$1
library=${tag%-v*} # Remove version suffix

# Handle prefix for inner modules
prefix=":"
if [[ $library == *-ktx ]]; then
prefix=":ktx:"
elif [[ $library == gears-* ]]; then
prefix=":gears:"
fi

echo "$prefix$library"

0 comments on commit 9ada442

Please sign in to comment.