Skip to content

feat: update getCurrentUser method to require token and refactor sess… #38

feat: update getCurrentUser method to require token and refactor sess…

feat: update getCurrentUser method to require token and refactor sess… #38

Workflow file for this run

name: 🚀 Build and Release Android
on:
push:
branches: [ main ]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
# ─────────────────────────────────────────────
# Job 1 — Resolve the next semantic version
# Runs semantic-release in dry-run mode so we
# know the version before the build starts.
# ─────────────────────────────────────────────
resolve-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.semver.outputs.version }}
version_code: ${{ steps.semver.outputs.version_code }}
will_release: ${{ steps.semver.outputs.will_release }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"
- name: Install semantic-release
run: |
npm install --save-dev semantic-release \
@semantic-release/changelog \
@semantic-release/git \
@semantic-release/github \
conventional-changelog-conventionalcommits
- name: Write .releaserc.json (dry-run config)
run: |
cat > .releaserc.json << 'EOF'
{
"branches": ["main"],
"plugins": [
["@semantic-release/commit-analyzer", { "preset": "conventionalcommits" }],
["@semantic-release/release-notes-generator", { "preset": "conventionalcommits" }]
]
}
EOF
- name: Determine next version (dry-run)
id: semver
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# semantic-release exits 1 when no release is triggered — that's not an
# error for us, so we capture the exit code manually instead of letting
# bash -e kill the step.
set +e
OUTPUT=$(npx semantic-release --dry-run --no-ci 2>&1)
SR_EXIT=$?
set -e
echo "$OUTPUT"
echo "--- semantic-release exit code: $SR_EXIT ---"
VERSION=$(echo "$OUTPUT" | grep -oP 'The next release version is \K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
# Exit code 2+ means a real error (bad config, auth failure, etc.)
if [ $SR_EXIT -ge 2 ]; then
echo "❌ semantic-release failed with exit code $SR_EXIT"
exit $SR_EXIT
fi
if [ -z "$VERSION" ]; then
echo "⚠️ No release triggered — using last tag or 1.0.0"
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "1.0.0")
echo "will_release=false" >> $GITHUB_OUTPUT
else
echo "will_release=true" >> $GITHUB_OUTPUT
fi
# versionCode: major*10000 + minor*100 + patch (e.g. 1.2.3 → 10203)
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
VERSION_CODE=$(( MAJOR * 10000 + MINOR * 100 + PATCH ))
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
echo "✅ Version: $VERSION (code: $VERSION_CODE)"
# ─────────────────────────────────────────────
# Job 2 — Build & release
# Uses the version resolved above.
# ─────────────────────────────────────────────
build-and-release:
runs-on: ubuntu-latest
needs: resolve-version
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Cache Gradle dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Cache Android build
uses: actions/cache@v3
with:
path: |
~/.android/build-cache
app/build
key: ${{ runner.os }}-android-${{ hashFiles('**/build.gradle*', '**/gradle.properties', '**/settings.gradle*') }}
restore-keys: |
${{ runner.os }}-android-
- name: Cache Kotlin
uses: actions/cache@v3
with:
path: |
~/.kotlin/cache
~/.konan
key: ${{ runner.os }}-kotlin-${{ hashFiles('**/*.kt', '**/*.kts') }}
restore-keys: |
${{ runner.os }}-kotlin-
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Decode Keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > $RUNNER_TEMP/release.keystore
- name: Build Release APK + AAB (signed, versioned)
env:
VERSION: ${{ needs.resolve-version.outputs.version }}
VERSION_CODE: ${{ needs.resolve-version.outputs.version_code }}
KEYSTORE_PATH: ${{ runner.temp }}/release.keystore
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
run: |
echo "🏗️ Building v$VERSION (code $VERSION_CODE)"
./gradlew assembleRelease bundleRelease \
-PversionName="$VERSION" \
-PversionCode="$VERSION_CODE" \
-Pandroid.injected.signing.store.file=$RUNNER_TEMP/release.keystore \
-Pandroid.injected.signing.store.password=${{ secrets.KEYSTORE_PASSWORD }} \
-Pandroid.injected.signing.key.alias=${{ secrets.KEY_ALIAS }} \
-Pandroid.injected.signing.key.password=${{ secrets.KEYSTORE_PASSWORD }} \
--build-cache
- name: Rename and verify outputs
id: outputs
env:
VERSION: ${{ needs.resolve-version.outputs.version }}
run: |
# Debug: show what was actually produced
echo "📂 Build outputs:"
find app/build/outputs -type f 2>/dev/null || echo " (nothing found)"
APK_SRC="app/build/outputs/apk/release/app-release.apk"
AAB_SRC="app/build/outputs/bundle/release/app-release.aab"
[ ! -f "$APK_SRC" ] && APK_SRC=$(find app/build/outputs -name "*release*.apk" -type f | head -1)
[ ! -f "$AAB_SRC" ] && AAB_SRC=$(find app/build/outputs -name "*release*.aab" -type f | head -1)
if [ -z "$APK_SRC" ] || [ ! -f "$APK_SRC" ]; then
echo "❌ APK release non trouvé"
exit 1
fi
if [ -z "$AAB_SRC" ] || [ ! -f "$AAB_SRC" ]; then
echo "❌ AAB release non trouvé"
exit 1
fi
APK_OUT="app/build/outputs/apk/release/app-release-v${VERSION}.apk"
AAB_OUT="app/build/outputs/bundle/release/app-release-v${VERSION}.aab"
mv "$APK_SRC" "$APK_OUT"
mv "$AAB_SRC" "$AAB_OUT"
echo "APK_PATH=$APK_OUT" >> $GITHUB_OUTPUT
echo "AAB_PATH=$AAB_OUT" >> $GITHUB_OUTPUT
echo "✅ APK: $APK_OUT"
echo "✅ AAB: $AAB_OUT"
- name: Setup Node.js for semantic-release
uses: actions/setup-node@v4
with:
node-version: "lts/*"
- name: Install semantic-release
run: |
npm install --save-dev semantic-release \
@semantic-release/changelog \
@semantic-release/git \
@semantic-release/github
- name: Write .releaserc.json (real release with assets)
env:
APK_PATH: ${{ steps.outputs.outputs.APK_PATH }}
AAB_PATH: ${{ steps.outputs.outputs.AAB_PATH }}
VERSION: ${{ needs.resolve-version.outputs.version }}
run: |
cat << 'EOF' > .releaserc.json
{
"branches": ["main"],
"plugins": [
["@semantic-release/commit-analyzer", { "preset": "angular" }],
["@semantic-release/release-notes-generator", { "preset": "angular" }],
"@semantic-release/changelog",
["@semantic-release/github", {
"assets": [
{
"path": "${{ env.APK_PATH }}",
"name": "app-release-v${{ env.VERSION }}.apk",
"label": "Android APK v${{ env.VERSION }} (universal)"
},
{
"path": "${{ env.AAB_PATH }}",
"name": "app-release-v${{ env.VERSION }}.aab",
"label": "Android App Bundle v${{ env.VERSION }} (Play Store)"
}
]
}],
["@semantic-release/git", {
"assets": ["CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
]
}
EOF
- name: Run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
- name: Publish AAB to Play Store
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.mirage.bob1
releaseFiles: ${{ steps.outputs.outputs.AAB_PATH }}
track: internal
status: completed
- name: Upload APK artifact
if: steps.outputs.outputs.APK_PATH != ''
uses: actions/upload-artifact@v4
with:
name: bob1-apk
path: ${{ steps.outputs.outputs.APK_PATH }}
retention-days: 30
- name: Upload AAB artifact
if: steps.outputs.outputs.AAB_PATH != ''
uses: actions/upload-artifact@v4
with:
name: bob1-aab
path: ${{ steps.outputs.outputs.AAB_PATH }}
retention-days: 30