Skip to content

Commit 017a430

Browse files
[workflows] add firebase initial workflow
1 parent 695bf00 commit 017a430

1 file changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
name: Deploy to Firebase App Distribution
2+
3+
on:
4+
# push:
5+
# branches:
6+
# - main
7+
workflow_dispatch:
8+
9+
jobs:
10+
build-and-deploy:
11+
name: Build & Distribute
12+
runs-on: ubuntu-latest
13+
14+
# The Android code is located in the ./controller directory
15+
defaults:
16+
run:
17+
working-directory: ./controller
18+
19+
steps:
20+
- name: Checkout Code
21+
uses: actions/checkout@v4
22+
with:
23+
submodules: recursive
24+
fetch-depth: 0 # Required to read the commit history
25+
26+
# TODO: Add a step here to check if there are meaningful changes
27+
# before proceeding with the build to save CI minutes (similar to CoGo's workflow).
28+
# - name: Check for meaningful changes
29+
# id: check_changes
30+
# run: |
31+
# DIFF_COUNT=$(git diff --name-only origin/main..HEAD | wc -l | tr -d ' ' || echo "0")
32+
# if [[ "$DIFF_COUNT" -eq 0 ]]; then
33+
# echo "::notice::Skipping build for branch identical to main"
34+
# echo "must_build=false" >> $GITHUB_OUTPUT
35+
# else
36+
# echo "must_build=true" >> $GITHUB_OUTPUT
37+
# fi
38+
39+
- name: Set up JDK 17
40+
uses: actions/setup-java@v4
41+
with:
42+
distribution: 'zulu'
43+
java-version: '17'
44+
cache: 'gradle'
45+
46+
- name: Grant execute permission for gradlew
47+
run: chmod +x gradlew
48+
49+
# --- SECRETS MANAGEMENT ---
50+
51+
- name: Create google-services.json
52+
env:
53+
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
54+
run: |
55+
# This assumes the app module folder is named 'app' inside 'controller'
56+
echo "$GOOGLE_SERVICES_JSON" > app/google-services.json
57+
58+
- name: Decode Keystore
59+
env:
60+
ENCODED_STRING: ${{ secrets.KEYSTORE_BASE64 }}
61+
run: |
62+
echo "$ENCODED_STRING" | base64 -d > keystore.jks
63+
64+
# --- BUILD AND SIGNING ---
65+
# We use assembleRelease to match the production signature.
66+
# This prevents testers from having to uninstall the app (and lose data) between updates.
67+
- name: Build and Sign APK
68+
env:
69+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
70+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
71+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
72+
run: |
73+
# TODO: Add gradle start/end timers here for the CI performance script
74+
# echo "gradle_time_start=$(date +%s)" >> $GITHUB_ENV
75+
76+
./gradlew assembleRelease \
77+
-Pandroid.injected.signing.store.file=$(pwd)/keystore.jks \
78+
-Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD \
79+
-Pandroid.injected.signing.key.alias=$KEY_ALIAS \
80+
-Pandroid.injected.signing.key.password=$KEY_PASSWORD
81+
82+
# echo "gradle_time_end=$(date +%s)" >> $GITHUB_ENV
83+
84+
- name: Find APK
85+
id: find_apk
86+
run: |
87+
# Locate the compiled APK (adjust the path if building a universal APK)
88+
apk_path=$(find . -path "*/build/outputs/apk/release/*.apk" | head -n 1)
89+
echo "APK_PATH=$apk_path" >> $GITHUB_OUTPUT
90+
91+
# --- RELEASE NOTES ---
92+
93+
- name: Prepare Release Notes
94+
id: prepare_notes
95+
run: |
96+
COMMIT_MSG=$(git log -1 --pretty=%B | head -1)
97+
COMMIT_AUTHOR=$(git log -1 --pretty=%an)
98+
99+
# TODO: Integrate Jira API here to extract the ticket ID and fetch the title
100+
# JIRA_TICKET=$(echo "$COMMIT_MSG" | grep -o 'ADFA-[0-9]\+' | head -1)
101+
# if [ -n "$JIRA_TICKET" ] && [ -n "${{ secrets.JIRA_API_TOKEN }}" ]; then
102+
# JIRA_TITLE=$(curl -s -u "${{ secrets.JIRA_EMAIL }}:${{ secrets.JIRA_API_TOKEN }}" \
103+
# "https://appdevforall.atlassian.net/rest/api/3/issue/${JIRA_TICKET}?fields=summary" \
104+
# | jq -r '.fields.summary // ""')
105+
# [ -n "$JIRA_TITLE" ] && COMMIT_MSG="$JIRA_TITLE"
106+
# fi
107+
108+
# Create a temporary file with the release notes
109+
NOTES_FILE=$(mktemp)
110+
echo "Author: $COMMIT_AUTHOR" > "$NOTES_FILE"
111+
echo "Message: $COMMIT_MSG" >> "$NOTES_FILE"
112+
113+
echo "NOTES_FILE=$NOTES_FILE" >> $GITHUB_OUTPUT
114+
115+
# --- FIREBASE DEPLOYMENT ---
116+
117+
# TODO: Consider migrating to Workload Identity Federation (WIF)
118+
# Uncomment the block below and remove the Service Account JSON step when ready.
119+
# - name: Authenticate to Google Cloud via Workload Identity
120+
# uses: google-github-actions/auth@v2
121+
# with:
122+
# workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
123+
# service_account: ${{ secrets.IDENTITY_EMAIL }}
124+
125+
- name: Authenticate with Firebase
126+
uses: google-github-actions/auth@v2
127+
with:
128+
credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}
129+
130+
- name: Setup Firebase CLI
131+
run: npm install -g firebase-tools
132+
133+
# TODO: Run CI performance script before distributing
134+
# - name: Write CI Performance Data
135+
# run: |
136+
# apk_size_bytes=$(stat -c '%s' ${{ steps.find_apk.outputs.APK_PATH }})
137+
# uv run scripts/insert-ci-perf-data.py $(basename ${{ steps.find_apk.outputs.APK_PATH }}) ${{ env.gradle_time_start }} ${{ env.gradle_time_end }} $apk_size_bytes
138+
139+
- name: Upload to Firebase App Distribution
140+
env:
141+
APK_PATH: ${{ steps.find_apk.outputs.APK_PATH }}
142+
FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
143+
NOTES_FILE: ${{ steps.prepare_notes.outputs.NOTES_FILE }}
144+
run: |
145+
firebase appdistribution:distribute "$APK_PATH" \
146+
--app "$FIREBASE_APP_ID" \
147+
--groups "testers" \
148+
--release-notes-file "$NOTES_FILE"
149+
150+
# TODO: Add a step here to send a rich Slack notification
151+
# - name: Send Slack Notification
152+
# env:
153+
# SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
154+
# run: |
155+
# curl -X POST -H "Content-type: application/json" \
156+
# --data '{"text":"🚀 New build deployed to Firebase! Author: ${{ steps.prepare_notes.outputs.COMMIT_AUTHOR }}"}' \
157+
# "$SLACK_WEBHOOK"
158+
159+
# --- SECURITY CLEANUP ---
160+
161+
- name: Cleanup Secrets and Temp Files
162+
if: always()
163+
run: |
164+
rm -f keystore.jks
165+
rm -f app/google-services.json
166+
rm -f ${{ steps.prepare_notes.outputs.NOTES_FILE }}

0 commit comments

Comments
 (0)