Skip to content

Commit a27ed6b

Browse files
committed
ci(example): add Play Store internal track publish workflow
Adds a GitHub Actions workflow to build and publish the React Native SDK example app (com.klaviyoreactnativesdkexample) to the Google Play internal track. Fires on SDK releases and manual workflow_dispatch. Includes Node 20 + Yarn 3 setup, JS bundle generation via the RN Gradle plugin (bundleRelease), signing with r0adkll/sign-android-release, and Slack notifications for both success and failure. Part of MAGE-464
1 parent 45c423d commit a27ed6b

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Publish the React Native SDK example app to Google Play Console internal track.
2+
#
3+
# Triggers:
4+
# - workflow_dispatch: Manual publish (preferred — SDK releases don't map 1:1 to example app publishes)
5+
# - release: published: Fires on every SDK release to keep the example app in sync
6+
#
7+
# Required secrets (set in repo Settings → Secrets and variables → Actions):
8+
# GOOGLE_SERVICES_JSON - Contents of google-services.json for Firebase
9+
# SIGNING_KEY - Base64-encoded release keystore
10+
# ALIAS - Key alias in the keystore
11+
# KEY_STORE_PASSWORD - Keystore password
12+
# KEY_PASSWORD - Key password
13+
# SERVICE_ACCOUNT_JSON - Google Play service account JSON (plain text)
14+
# KLAVIYO_EXAMPLE_API_KEY - Klaviyo public API key for the example app build.
15+
# Required: the build fails if unset.
16+
17+
name: Publish Example App to Play Store Internal Track
18+
19+
on:
20+
workflow_dispatch:
21+
release:
22+
types: [ published ]
23+
24+
jobs:
25+
deploy:
26+
runs-on: ubuntu-22.04
27+
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
# Node + Yarn 3 + workspace deps. Required because the React Native Gradle plugin
32+
# invokes the Metro bundler during bundleRelease to generate the JS bundle. Installs
33+
# the example workspace too, making react-native and its CLI available to Gradle.
34+
- name: Setup
35+
uses: ./.github/actions/setup
36+
37+
- name: Set up JDK 17
38+
uses: actions/setup-java@v4
39+
with:
40+
distribution: 'zulu'
41+
java-version: '17'
42+
java-package: jdk
43+
44+
- name: Add Google Services from Secrets
45+
run: 'echo "$GOOGLE_SERVICES_JSON" > ./example/android/app/google-services.json'
46+
shell: bash
47+
env:
48+
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
49+
50+
# Write the Klaviyo public API key into example/.env so react-native-dotenv
51+
# can expose it to the JS layer as KLAVIYO_API_KEY (imported from '@env').
52+
# App.tsx throws at module load if the key is missing, so an unset secret
53+
# will fail the bundling step with a clear error.
54+
- name: Write .env with Klaviyo API key
55+
run: echo "KLAVIYO_API_KEY=${KLAVIYO_EXAMPLE_API_KEY}" > example/.env
56+
env:
57+
KLAVIYO_EXAMPLE_API_KEY: ${{ secrets.KLAVIYO_EXAMPLE_API_KEY }}
58+
59+
# bundleRelease triggers react-native bundle automatically via the RN Gradle plugin.
60+
# We cd into the android directory so that relative paths in settings.gradle resolve correctly.
61+
- name: Assemble Release Bundle
62+
run: cd example/android && ./gradlew :app:bundleRelease
63+
env:
64+
# Prevent Metro from trying to start a dev server during the build
65+
CI: true
66+
67+
- name: Sign Release
68+
id: sign_release
69+
uses: r0adkll/sign-android-release@v1
70+
with:
71+
releaseDirectory: example/android/app/build/outputs/bundle/release
72+
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
73+
alias: ${{ secrets.ALIAS }}
74+
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
75+
keyPassword: ${{ secrets.KEY_PASSWORD }}
76+
77+
- name: Deploy to Internal Track
78+
uses: r0adkll/[email protected]
79+
with:
80+
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
81+
packageName: com.klaviyoreactnativesdkexample
82+
releaseFiles: ${{ steps.sign_release.outputs.signedReleaseFile }}
83+
track: internal
84+
status: completed
85+
86+
- name: Notify Slack on success
87+
if: success()
88+
uses: slackapi/[email protected]
89+
with:
90+
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
91+
webhook-type: incoming-webhook
92+
payload: |
93+
text: "✅ RN SDK Example App published to Play Store internal track"
94+
blocks:
95+
- type: "section"
96+
text:
97+
type: "mrkdwn"
98+
text: "*Repository:* ${{ github.repository }}\n*Workflow:* ${{ github.workflow }}\n*Release:* `${{ github.event.release.tag_name || 'manual' }}`\n*Commit:* `${{ github.sha }}`\n*Author:* ${{ github.actor }}"
99+
- type: "section"
100+
text:
101+
type: "mrkdwn"
102+
text: "*Workflow Run:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>"
103+
104+
- name: Notify Slack on failure
105+
if: failure()
106+
uses: slackapi/[email protected]
107+
with:
108+
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
109+
webhook-type: incoming-webhook
110+
payload: |
111+
text: "🚨 RN SDK Example App Play Store publish failed"
112+
blocks:
113+
- type: "section"
114+
text:
115+
type: "mrkdwn"
116+
text: "*Repository:* ${{ github.repository }}\n*Workflow:* ${{ github.workflow }}\n*Release:* `${{ github.event.release.tag_name || 'manual' }}`\n*Commit:* `${{ github.sha }}`\n*Author:* ${{ github.actor }}"
117+
- type: "section"
118+
text:
119+
type: "mrkdwn"
120+
text: "*Workflow Run:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>"

0 commit comments

Comments
 (0)