Skip to content

refactor(brand): rename project to Pasahe #13

refactor(brand): rename project to Pasahe

refactor(brand): rename project to Pasahe #13

Workflow file for this run

name: Release APK
on:
push:
branches:
- main
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write
jobs:
build-and-release:
name: Build and release
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version information
id: version
run: |
FULL_VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //' | tr -d ' \r')
VERSION_NAME=$(echo "$FULL_VERSION" | cut -d'+' -f1)
BUILD_NUMBER=$(echo "$FULL_VERSION" | cut -d'+' -f2)
if [ -z "$BUILD_NUMBER" ] || [ "$BUILD_NUMBER" = "$FULL_VERSION" ]; then
BUILD_NUMBER="1"
fi
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
echo "full_version=$FULL_VERSION" >> "$GITHUB_OUTPUT"
echo "version_name=$VERSION_NAME" >> "$GITHUB_OUTPUT"
echo "build_number=$BUILD_NUMBER" >> "$GITHUB_OUTPUT"
echo "short_sha=$SHORT_SHA" >> "$GITHUB_OUTPUT"
echo "tag_name=v${VERSION_NAME}" >> "$GITHUB_OUTPUT"
- name: Resolve release tag
id: tag_check
env:
BUILD_NUMBER: ${{ steps.version.outputs.build_number }}
run: |
BASE_TAG="${{ steps.version.outputs.tag_name }}"
if git ls-remote --tags origin | grep -q "refs/tags/${BASE_TAG}$"; then
UNIQUE_TAG="${BASE_TAG}.${BUILD_NUMBER}"
else
UNIQUE_TAG="$BASE_TAG"
fi
echo "unique_tag=$UNIQUE_TAG" >> "$GITHUB_OUTPUT"
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
cache: gradle
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Verify Flutter installation
run: flutter --version
- name: Install dependencies
run: flutter pub get
- name: Create environment placeholder
run: touch .env
- name: Generate code
run: dart run build_runner build --delete-conflicting-outputs
- name: Run analysis
run: flutter analyze --no-fatal-infos
continue-on-error: true
- name: Run tests
run: flutter test
continue-on-error: true
- name: Build release APKs
run: |
flutter build apk --release \
--split-per-abi \
--obfuscate \
--split-debug-info=build/debug-info \
--build-name=${{ steps.version.outputs.version_name }} \
--build-number=${{ steps.version.outputs.build_number }}
- name: Prepare APK files
id: apk_files
run: |
VERSION="${{ steps.version.outputs.version_name }}"
APK_DIR="build/app/outputs/flutter-apk"
mv "${APK_DIR}/app-arm64-v8a-release.apk" \
"${APK_DIR}/Pasahe-v${VERSION}-arm64.apk"
mv "${APK_DIR}/app-armeabi-v7a-release.apk" \
"${APK_DIR}/Pasahe-v${VERSION}-arm32.apk"
mv "${APK_DIR}/app-x86_64-release.apk" \
"${APK_DIR}/Pasahe-v${VERSION}-x86_64.apk"
echo "apk_arm64=Pasahe-v${VERSION}-arm64.apk" >> "$GITHUB_OUTPUT"
echo "apk_arm32=Pasahe-v${VERSION}-arm32.apk" >> "$GITHUB_OUTPUT"
echo "apk_x86_64=Pasahe-v${VERSION}-x86_64.apk" >> "$GITHUB_OUTPUT"
ls -la "${APK_DIR}"/*.apk
- name: Generate release notes
env:
RELEASE_TAG: ${{ steps.tag_check.outputs.unique_tag }}
REPOSITORY: ${{ github.repository }}
run: |
PREVIOUS_TAG=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags | head -n 1 || true)
export PREVIOUS_TAG
if [ -n "$PREVIOUS_TAG" ]; then
RANGE="${PREVIOUS_TAG}..HEAD"
else
RANGE="HEAD~20..HEAD"
fi
git log "$RANGE" --pretty=format:'%s' --no-merges > release-commits.txt
python - <<'PY'
import os
import re
from pathlib import Path
commit_lines = [line.strip() for line in Path('release-commits.txt').read_text(encoding='utf-8').splitlines() if line.strip()]
release_tag = os.environ['RELEASE_TAG']
repository = os.environ['REPOSITORY']
previous_tag = os.environ.get('PREVIOUS_TAG', '')
conventional = re.compile(r'^(?P<type>[a-z]+)(?:\((?P<scope>[^)]+)\))?!?:\s*(?P<desc>.+)$', re.IGNORECASE)
categories = {
'Features': [],
'Fixes': [],
'Maintenance': [],
}
def normalize_description(text: str) -> str:
text = text.strip()
if not text:
return text
return text[0].upper() + text[1:]
seen = set()
for subject in commit_lines:
match = conventional.match(subject)
if match:
commit_type = match.group('type').lower()
description = normalize_description(match.group('desc'))
else:
commit_type = 'other'
description = normalize_description(subject)
if description in seen:
continue
seen.add(description)
if commit_type == 'feat':
categories['Features'].append(description)
elif commit_type == 'fix':
categories['Fixes'].append(description)
else:
categories['Maintenance'].append(description)
lines = []
for heading, items in categories.items():
if not items:
continue
lines.append(f'## {heading}')
for item in items:
lines.append(f'- {item}')
if not lines:
lines = ['## Maintenance', '- Release packaging updated.']
if previous_tag:
lines.extend([
'',
f'Full Changelog: https://github.com/{repository}/compare/{previous_tag}...{release_tag}',
])
Path('RELEASE_NOTES.md').write_text('\n'.join(lines) + '\n', encoding='utf-8')
PY
shell: bash
- name: Create GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag_check.outputs.unique_tag }}
name: ${{ steps.tag_check.outputs.unique_tag }}
body_path: RELEASE_NOTES.md
draft: false
prerelease: false
files: |
build/app/outputs/flutter-apk/${{ steps.apk_files.outputs.apk_arm64 }}
build/app/outputs/flutter-apk/${{ steps.apk_files.outputs.apk_arm32 }}
build/app/outputs/flutter-apk/${{ steps.apk_files.outputs.apk_x86_64 }}
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Write workflow summary
run: |
echo "## Release published" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Field | Value |" >> "$GITHUB_STEP_SUMMARY"
echo "| --- | --- |" >> "$GITHUB_STEP_SUMMARY"
echo "| Version | v${{ steps.version.outputs.version_name }} |" >> "$GITHUB_STEP_SUMMARY"
echo "| Tag | ${{ steps.tag_check.outputs.unique_tag }} |" >> "$GITHUB_STEP_SUMMARY"
echo "| Commit | ${{ steps.version.outputs.short_sha }} |" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.tag_check.outputs.unique_tag }}" >> "$GITHUB_STEP_SUMMARY"