Skip to content

Prettier workflow w/ comments & better output. #46

Prettier workflow w/ comments & better output.

Prettier workflow w/ comments & better output. #46

name: 🚀 EAS Android Build & Release
on:
push:
branches: [main]
workflow_dispatch:
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build-android:
name: 🛠️ Build Android APK
runs-on: ubuntu-latest
outputs:
build_id: ${{ steps.build.outputs.BUILD_ID }}
steps:
# ========================
# 🔍 Repository Setup
# ========================
- name: 🔍 Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for changelog generation
# ========================
# ⚙️ Environment Setup
# ========================
- name: ⚙️ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: "npm" # Cache npm dependencies for faster builds
- name: 📦 Install dependencies
run: npm ci # Use `npm ci` for reproducible builds
- name: 📥 Install EAS CLI
run: npm install -g eas-cli@latest
# ========================
# 🔐 Expo Authentication
# ========================
- name: 🔐 Debug Expo Authentication
run: |
echo "🔍 Checking Expo authentication..."
npx eas whoami --token $EXPO_TOKEN || echo "❌ Expo authentication check failed!"
# ========================
# 🚀 Start EAS Build
# ========================
- name: 🚀 Start EAS Build
id: build
run: |
echo "🚀 Starting EAS build..."
sudo apt-get install -y jq # Install jq for JSON parsing
# Start the build and capture JSON output
BUILD_JSON=$(npx eas build -p android --profile production --non-interactive --json)
echo "📄 Raw build output: $BUILD_JSON"
# Extract BUILD_ID from JSON output
BUILD_ID=$(echo "$BUILD_JSON" | jq -r '.[0].id')
if [[ -z "$BUILD_ID" || "$BUILD_ID" == "null" ]]; then
echo "❌ Error: Failed to retrieve BUILD_ID!"
exit 1
fi
echo "✅ EAS Build started with ID: $BUILD_ID"
echo "BUILD_ID=$BUILD_ID" >> $GITHUB_ENV
echo "BUILD_ID=$BUILD_ID" >> $GITHUB_OUTPUT
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
download-apk:
name: 📥 Download APK
runs-on: ubuntu-latest
needs: build-android
outputs:
apk_path: ${{ steps.download.outputs.APK_PATH }}
steps:
# ========================
# 🔍 Repository Setup
# ========================
- name: 🔍 Checkout repository
uses: actions/checkout@v4
# ========================
# ⚙️ Environment Setup
# ========================
- name: ⚙️ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: 🛠️ Install Required Tools
run: |
npm install -g eas-cli@latest
sudo apt-get update
sudo apt-get install -y jq curl # Install tools for JSON parsing and file downloads
- name: 📦 Install Project Dependencies (Including dotenv)
run: npm ci
# ========================
# 🔍 Verify Project Files
# ========================
- name: 🔍 Verify Project Files
run: |
echo "📂 Current directory contents:"
ls -la
echo "🔍 Checking for eas.json:"
cat eas.json || echo "❌ No eas.json found!"
# ========================
# ⏳ Wait for EAS Build to Complete
# ========================
- name: ⏳ Wait for EAS Build to Complete
run: |
cd $GITHUB_WORKSPACE
BUILD_ID=${{ needs.build-android.outputs.build_id }}
echo "🔍 Starting build monitoring for BUILD_ID: $BUILD_ID"
# Initial check without JSON for better error visibility
npx eas build:view $BUILD_ID || true
RETRY_COUNT=0
MAX_RETRIES=120
SLEEP_TIME=30
while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do
echo -e "\n=== Attempt $((RETRY_COUNT+1))/$MAX_RETRIES ==="
# Fetch build status in JSON format
BUILD_STATUS_JSON=$(npx eas build:view --json $BUILD_ID)
echo "📄 Raw API response: $BUILD_STATUS_JSON"
# Validate JSON and check for empty response
if ! echo "$BUILD_STATUS_JSON" | jq empty >/dev/null 2>&1 || [[ -z "$BUILD_STATUS_JSON" ]]; then
echo "❌ Error: Invalid or empty response from EAS API! Retrying..."
RETRY_COUNT=$((RETRY_COUNT+1))
sleep $SLEEP_TIME
continue
fi
BUILD_STATUS=$(echo "$BUILD_STATUS_JSON" | jq -r '.status')
ERROR_MESSAGE=$(echo "$BUILD_STATUS_JSON" | jq -r '.error.message // empty')
echo "🔍 Parsed status: $BUILD_STATUS"
[[ -n "$ERROR_MESSAGE" ]] && echo "❌ Error message: $ERROR_MESSAGE"
case $BUILD_STATUS in
"FINISHED")
APK_URL=$(echo "$BUILD_STATUS_JSON" | jq -r '.artifacts.buildUrl')
if [[ -z "$APK_URL" || "$APK_URL" == "null" ]]; then
echo "❌ Error: Successful build but no APK URL found!"
exit 1
fi
echo "✅ APK_URL=$APK_URL" >> $GITHUB_ENV
exit 0
;;
"ERRORED"|"CANCELLED")
echo "❌ Build failed! Error details:"
echo "$BUILD_STATUS_JSON" | jq .
exit 1
;;
"NEW"|"IN_QUE"|"IN_PROGRESS"|"PENDING")
echo "⏳ Build is still in progress..."
;;
*)
echo "❌ Unknown build status: $BUILD_STATUS"
exit 1
;;
esac
RETRY_COUNT=$((RETRY_COUNT+1))
sleep $SLEEP_TIME
done
echo "❌ Error: Build did not complete within the expected time!"
exit 1
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
# ========================
# 📥 Download APK
# ========================
- name: 📥 Download APK
id: download
run: |
echo "📥 Downloading APK from: $APK_URL"
curl -L "$APK_URL" -o app-release.apk
ls -lh app-release.apk
echo "✅ APK_PATH=app-release.apk" >> $GITHUB_OUTPUT
echo "📦 Downloaded APK size: $(du -h app-release.apk | cut -f1)"
# ========================
# 📤 Upload APK as Artifact
# ========================
- name: 📤 Upload APK as artifact
uses: actions/upload-artifact@v4
with:
name: android-apk
path: app-release.apk
generate-changelog:
name: 📝 Generate Changelog
runs-on: ubuntu-latest
needs: build-android
outputs:
changelog: ${{ steps.changelog.outputs.CHANGELOG }}
steps:
# ========================
# 🔍 Repository Setup
# ========================
- name: 🔍 Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for changelog generation
# ========================
# 📝 Generate Changelog
# ========================
- name: 📝 Generate Changelog
id: changelog
run: |
echo "📝 Generating changelog..."
# Generate formatted changelog (last 10 commits)
CHANGELOG=$(git log --pretty=format:"- %s (%h) by %an" -n 10)
echo "📄 Changelog content:"
echo "$CHANGELOG"
# Set as an output using the proper multiline format
echo "CHANGELOG<<EOF" >> $GITHUB_ENV
echo "$CHANGELOG" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
# Save to a file as well
echo "$CHANGELOG" > changelog.txt
shell: bash
# ========================
# 📤 Upload Changelog as Artifact
# ========================
- name: 📤 Upload Changelog as artifact
uses: actions/upload-artifact@v4
with:
name: changelog
path: changelog.txt
create-release:
name: 🚀 Create GitHub Release
runs-on: ubuntu-latest
needs: [download-apk, generate-changelog]
steps:
# ========================
# 📥 Download Artifacts
# ========================
- name: 📥 Download APK artifact
uses: actions/download-artifact@v4
with:
name: android-apk
- name: 📥 Download Changelog artifact
uses: actions/download-artifact@v4
with:
name: changelog
# ========================
# 🚀 Create GitHub Release
# ========================
- name: 🚀 Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v1.0.${{ github.run_number }}
name: Release v1.0.${{ github.run_number }}
body_path: changelog.txt
draft: false
prerelease: false
files: app-release.apk