refactor(brand): rename project to Pasahe #13
This file contains hidden or 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: 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" |