Skip to content

Commit 85e0eb7

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 d126ffe commit 85e0eb7

1 file changed

Lines changed: 136 additions & 0 deletions

File tree

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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 will fail at runtime if missing.
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 is required because the React Native Gradle plugin invokes the Metro bundler
32+
# during bundleRelease to generate the JS bundle. Without it, the Gradle task fails.
33+
- name: Set up Node
34+
uses: actions/setup-node@v4
35+
with:
36+
node-version: '20'
37+
38+
# Enable Yarn 3 (corepack ships with Node 16+; activate it so `yarn` resolves to 3.x)
39+
- name: Enable Corepack / Yarn 3
40+
run: corepack enable
41+
42+
# Install all workspace dependencies from the repo root. This also installs the
43+
# example workspace, making react-native and its CLI available for the Gradle plugin.
44+
- name: Install JS dependencies
45+
run: yarn install --immutable
46+
47+
- name: Set up JDK 17
48+
uses: actions/setup-java@v3
49+
with:
50+
distribution: 'zulu'
51+
java-version: '17'
52+
java-package: jdk
53+
54+
- name: Add Google Services from Secrets
55+
run: 'echo "$GOOGLE_SERVICES_JSON" > ./example/android/app/google-services.json'
56+
shell: bash
57+
env:
58+
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
59+
60+
# Write the Klaviyo public API key into example/.env so react-native-dotenv picks
61+
# it up at bundle time. If the secret is unset, the resulting .env will contain an
62+
# empty value and Klaviyo.initialize() will throw "Klaviyo API key not configured"
63+
# at runtime — that's intentional: fail loudly rather than ship a placeholder.
64+
- name: Write .env with Klaviyo API key
65+
run: echo "KLAVIYO_API_KEY=${{ secrets.KLAVIYO_EXAMPLE_API_KEY }}" > example/.env
66+
67+
# bundleRelease triggers react-native bundle automatically via the RN Gradle plugin.
68+
# We cd into the android directory so that relative paths in settings.gradle resolve correctly.
69+
- name: Assemble Release Bundle
70+
run: cd example/android && ./gradlew :app:bundleRelease
71+
env:
72+
# Prevent Metro from trying to start a dev server during the build
73+
CI: true
74+
75+
- name: Sign Release
76+
id: sign_release
77+
uses: r0adkll/sign-android-release@v1
78+
with:
79+
releaseDirectory: example/android/app/build/outputs/bundle/release
80+
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
81+
alias: ${{ secrets.ALIAS }}
82+
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
83+
keyPassword: ${{ secrets.KEY_PASSWORD }}
84+
85+
- name: Deploy to Internal Track
86+
uses: r0adkll/[email protected]
87+
with:
88+
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
89+
packageName: com.klaviyoreactnativesdkexample
90+
releaseFiles: example/android/app/build/outputs/bundle/release/app-release.aab
91+
track: internal
92+
status: completed
93+
94+
- name: Notify Slack on success
95+
if: success()
96+
uses: slackapi/[email protected]
97+
with:
98+
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
99+
webhook-type: incoming-webhook
100+
payload: |
101+
text: "✅ RN SDK Example App published to Play Store internal track"
102+
blocks:
103+
- type: "section"
104+
text:
105+
type: "mrkdwn"
106+
text: "✅ Published to Play Store internal track"
107+
- type: "section"
108+
text:
109+
type: "mrkdwn"
110+
text: "*Repository:* ${{ github.repository }}\n*Workflow:* ${{ github.workflow }}\n*Release:* `${{ github.event.release.tag_name || 'manual' }}`\n*Commit:* `${{ github.sha }}`\n*Author:* ${{ github.actor }}"
111+
- type: "section"
112+
text:
113+
type: "mrkdwn"
114+
text: "*Workflow Run:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>"
115+
116+
- name: Notify Slack on failure
117+
if: failure()
118+
uses: slackapi/[email protected]
119+
with:
120+
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
121+
webhook-type: incoming-webhook
122+
payload: |
123+
text: "🚨 RN SDK Example App Play Store publish failed"
124+
blocks:
125+
- type: "section"
126+
text:
127+
type: "mrkdwn"
128+
text: "🚨 Play Store publish failed"
129+
- type: "section"
130+
text:
131+
type: "mrkdwn"
132+
text: "*Repository:* ${{ github.repository }}\n*Workflow:* ${{ github.workflow }}\n*Release:* `${{ github.event.release.tag_name || 'manual' }}`\n*Commit:* `${{ github.sha }}`\n*Author:* ${{ github.actor }}"
133+
- type: "section"
134+
text:
135+
type: "mrkdwn"
136+
text: "*Workflow Run:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>"

0 commit comments

Comments
 (0)