Skip to content

Commit ab56ca1

Browse files
authored
Merge pull request #2 from dantech0xff/copilot/fix-161b9bf0-872f-44f6-b45c-15a500dcfdc2
Add GitHub Actions CI/CD for automated APK building and release attachment
2 parents d63e0e5 + 84ff98a commit ab56ca1

5 files changed

Lines changed: 298 additions & 0 deletions

File tree

.github/CICD.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# CI/CD Workflows
2+
3+
This repository includes GitHub Actions workflows for automated building and releasing of the QR Code Scanner app.
4+
5+
## Workflows
6+
7+
### 1. Build Test (`build.yml`)
8+
- **Triggers**: Pull requests and pushes to main/master branches
9+
- **Purpose**: Validates that the code builds successfully and runs tests
10+
- **Outputs**: Debug APK as an artifact
11+
12+
### 2. Build and Release APK (`release.yml`)
13+
- **Triggers**:
14+
- When a release is published on GitHub
15+
- When a tag starting with 'v' is pushed (e.g., `v1.0.0`)
16+
- **Purpose**: Builds the release APK and attaches it to the GitHub release
17+
- **Outputs**:
18+
- Release APK attached to the GitHub release
19+
- Release APK as an artifact for tag pushes
20+
21+
## Creating a Release
22+
23+
### Option 1: Using the Release Script (Recommended)
24+
25+
The repository includes a helper script to streamline the release process:
26+
27+
```bash
28+
./scripts/release.sh v1.0.0-alpha-06
29+
```
30+
31+
This script will:
32+
- Validate the version format
33+
- Check if you're on the main/master branch
34+
- Optionally update the version in `app/build.gradle.kts`
35+
- Create and push the git tag
36+
- Provide links to track the build progress
37+
38+
### Option 2: Manual Process
39+
40+
To create a new release manually:
41+
42+
1. **Create and push a tag**:
43+
```bash
44+
git tag v1.0.0-alpha-06
45+
git push origin v1.0.0-alpha-06
46+
```
47+
48+
2. **Create a GitHub release**:
49+
- Go to the repository's Releases page
50+
- Click "Create a new release"
51+
- Select the tag you just created
52+
- Fill in the release title and description
53+
- Click "Publish release"
54+
55+
3. **Automatic APK build**:
56+
- The workflow will automatically trigger
57+
- Build the release APK
58+
- Attach the APK to the release
59+
60+
## APK Naming
61+
62+
The generated APK will be named: `qr-code-scanner-{version}.apk`
63+
64+
Where `{version}` is extracted from either:
65+
- The git tag (if triggered by tag push)
66+
- The `versionName` from `app/build.gradle.kts`
67+
68+
## Build Environment
69+
70+
The workflows use:
71+
- Ubuntu latest
72+
- Java 17 (Temurin distribution)
73+
- Android SDK (via android-actions/setup-android)
74+
- Gradle caching for faster builds

.github/workflows/build.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Build Test
2+
3+
on:
4+
pull_request:
5+
branches: [ main, master ]
6+
push:
7+
branches: [ main, master ]
8+
9+
env:
10+
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4096m -Dorg.gradle.daemon=false"
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up JDK 17
21+
uses: actions/setup-java@v4
22+
with:
23+
java-version: '17'
24+
distribution: 'temurin'
25+
26+
- name: Setup Android SDK
27+
uses: android-actions/setup-android@v3
28+
29+
- name: Cache Gradle dependencies
30+
uses: actions/cache@v4
31+
with:
32+
path: |
33+
~/.gradle/caches
34+
~/.gradle/wrapper
35+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
36+
restore-keys: |
37+
${{ runner.os }}-gradle-
38+
39+
- name: Make gradlew executable
40+
run: chmod +x ./gradlew
41+
42+
- name: Run tests
43+
run: ./gradlew test
44+
45+
- name: Build debug APK
46+
run: ./gradlew assembleDebug
47+
48+
- name: Upload debug APK
49+
uses: actions/upload-artifact@v4
50+
with:
51+
name: debug-apk
52+
path: app/build/outputs/apk/debug/*.apk

.github/workflows/release.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Build and Release APK
2+
3+
on:
4+
release:
5+
types: [published]
6+
push:
7+
tags:
8+
- 'v*'
9+
10+
env:
11+
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4096m -Dorg.gradle.daemon=false"
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Set up JDK 17
22+
uses: actions/setup-java@v4
23+
with:
24+
java-version: '17'
25+
distribution: 'temurin'
26+
27+
- name: Setup Android SDK
28+
uses: android-actions/setup-android@v3
29+
30+
- name: Cache Gradle dependencies
31+
uses: actions/cache@v4
32+
with:
33+
path: |
34+
~/.gradle/caches
35+
~/.gradle/wrapper
36+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
37+
restore-keys: |
38+
${{ runner.os }}-gradle-
39+
40+
- name: Make gradlew executable
41+
run: chmod +x ./gradlew
42+
43+
- name: Clean and Build Release APK
44+
run: |
45+
./gradlew clean
46+
./gradlew assembleRelease
47+
48+
- name: Get APK info
49+
id: apk-info
50+
run: |
51+
APK_PATH=$(find app/build/outputs/apk/release -name "*.apk" | head -1)
52+
if [ -z "$APK_PATH" ]; then
53+
echo "APK not found!"
54+
exit 1
55+
fi
56+
echo "apk_path=$APK_PATH" >> $GITHUB_OUTPUT
57+
58+
# Extract version info from the APK path or use git tag
59+
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
60+
VERSION=${GITHUB_REF#refs/tags/}
61+
else
62+
VERSION=$(grep 'versionName' app/build.gradle.kts | sed 's/.*"\(.*\)".*/\1/')
63+
fi
64+
65+
APK_NAME="qr-code-scanner-${VERSION}.apk"
66+
echo "apk_name=$APK_NAME" >> $GITHUB_OUTPUT
67+
echo "version=$VERSION" >> $GITHUB_OUTPUT
68+
69+
- name: Rename APK
70+
run: |
71+
mv "${{ steps.apk-info.outputs.apk_path }}" "app/build/outputs/apk/release/${{ steps.apk-info.outputs.apk_name }}"
72+
73+
- name: Upload APK to Release
74+
if: github.event_name == 'release'
75+
uses: softprops/action-gh-release@v1
76+
with:
77+
files: app/build/outputs/apk/release/${{ steps.apk-info.outputs.apk_name }}
78+
env:
79+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
80+
81+
- name: Upload APK as Artifact (for tag pushes)
82+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
83+
uses: actions/upload-artifact@v4
84+
with:
85+
name: qr-code-scanner-${{ steps.apk-info.outputs.version }}
86+
path: app/build/outputs/apk/release/${{ steps.apk-info.outputs.apk_name }}

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# Android QR Code Scanner by Dan Tech
22
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/dantech0xff/compose-barcode-scanner)
3+
[![Build Test](https://github.com/dantech0xff/compose-qr-code-scanner/actions/workflows/build.yml/badge.svg)](https://github.com/dantech0xff/compose-qr-code-scanner/actions/workflows/build.yml)
34
![](https://img.shields.io/badge/Kotlin-Compose-green)
45
![](https://img.shields.io/badge/Google--Billing-blue)
56
![](https://img.shields.io/badge/Camera--X-red)
67
![](https://img.shields.io/badge/MLKit-white)
78
![](https://img.shields.io/badge/Hilt-gray)
89
![](https://img.shields.io/badge/Flow-yellow)
910
![](https://img.shields.io/badge/Room--Database-black)
11+
![](https://img.shields.io/badge/CI%2FCD-GitHub%20Actions-blue)
1012

1113
This project is built with Jetpack Compose, CameraX, ML Kit and my handsome attitude.
1214
This is for my learning purpose in order to get familiar with Jetpack Compose, MLKit and CameraX.
@@ -49,6 +51,10 @@ Feel free to use it in your project.
4951

5052
### Download, Clone, or do anything for your own purpose, I don't care!
5153

54+
## Download APK
55+
56+
Get the latest APK from the [Releases](../../releases) page. Each release automatically includes a built APK file ready for installation.
57+
5258
### Love it? Give me a star, I will be happy!
5359

5460
### Happy Coding!

scripts/release.sh

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/bin/bash
2+
3+
# Release script for QR Code Scanner
4+
# Usage: ./scripts/release.sh <version>
5+
# Example: ./scripts/release.sh v1.0.0-alpha-06
6+
7+
set -e
8+
9+
if [ $# -eq 0 ]; then
10+
echo "Usage: $0 <version>"
11+
echo "Example: $0 v1.0.0-alpha-06"
12+
exit 1
13+
fi
14+
15+
VERSION=$1
16+
17+
# Validate version format
18+
if [[ ! $VERSION =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
19+
echo "Error: Version must start with 'v' and follow semantic versioning (e.g., v1.0.0-alpha-06)"
20+
exit 1
21+
fi
22+
23+
echo "Creating release for version: $VERSION"
24+
25+
# Check if tag already exists
26+
if git rev-parse "$VERSION" >/dev/null 2>&1; then
27+
echo "Error: Tag $VERSION already exists"
28+
exit 1
29+
fi
30+
31+
# Get current branch
32+
CURRENT_BRANCH=$(git branch --show-current)
33+
echo "Current branch: $CURRENT_BRANCH"
34+
35+
# Ensure we're on main/master branch
36+
if [[ "$CURRENT_BRANCH" != "main" && "$CURRENT_BRANCH" != "master" ]]; then
37+
echo "Warning: You're not on main/master branch. Continue? (y/N)"
38+
read -n 1 -r
39+
echo
40+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
41+
echo "Aborted"
42+
exit 1
43+
fi
44+
fi
45+
46+
# Ensure working directory is clean
47+
if ! git diff-index --quiet HEAD --; then
48+
echo "Error: Working directory is not clean. Please commit your changes first."
49+
exit 1
50+
fi
51+
52+
# Update version in build.gradle.kts if needed
53+
echo "Current version in build.gradle.kts:"
54+
grep 'versionName' app/build.gradle.kts || echo "Version not found"
55+
56+
echo "Do you want to update the version in build.gradle.kts? (y/N)"
57+
read -n 1 -r
58+
echo
59+
if [[ $REPLY =~ ^[Yy]$ ]]; then
60+
# Extract version without 'v' prefix
61+
VERSION_NUMBER=${VERSION#v}
62+
sed -i.bak "s/versionName = \".*\"/versionName = \"$VERSION_NUMBER\"/" app/build.gradle.kts
63+
echo "Updated versionName to $VERSION_NUMBER"
64+
65+
# Commit version update
66+
git add app/build.gradle.kts
67+
git commit -m "Bump version to $VERSION_NUMBER"
68+
fi
69+
70+
# Create and push tag
71+
echo "Creating tag: $VERSION"
72+
git tag -a "$VERSION" -m "Release $VERSION"
73+
74+
echo "Pushing tag to origin..."
75+
git push origin "$VERSION"
76+
77+
echo "✅ Tag $VERSION has been pushed!"
78+
echo "🚀 GitHub Actions will now build the APK automatically."
79+
echo "📱 You can find the APK in the releases page once the build completes."
80+
echo "🔗 https://github.com/$(git config --get remote.origin.url | sed 's/.*github.com[:/]\(.*\)\.git/\1/')/releases"

0 commit comments

Comments
 (0)