Skip to content

Commit

Permalink
chore: update sample app build info (#383)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrehan27 authored Feb 14, 2025
1 parent 85b6fdb commit 0e74e8c
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 39 deletions.
59 changes: 37 additions & 22 deletions .github/workflows/build-sample-apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,21 @@ jobs:
sample-app:
# List all sample apps you want to have compiled.
# List item is name of directory inside of "Apps" directory for the corresponding app to compile.
- "APN"
- "FCM"
- name: "APN"
cio-workspace-name: "Mobile: React Native"
- name: "FCM"
cio-workspace-name: "Mobile: xReact Native FCM workspace"
defaults:
run:
working-directory: apps/${{ matrix.sample-app }}
working-directory: apps/${{ matrix.sample-app.name }}
runs-on: macos-14
name: Building sample app ${{ matrix.sample-app }}
name: Building sample app ${{ matrix.sample-app.name }}

steps:
- uses: actions/checkout@v4
- name: Check out code with conditional fetch-depth
uses: actions/checkout@v4
with:
fetch-depth: 0 # Workaround for bug https://github.com/actions/checkout/issues/1471

# Install CLI tools, Ruby, and Ruby dependencies for Fastlane

Expand All @@ -80,7 +85,7 @@ jobs:
NEXT_BUILDS_GROUP: next
PUBLIC_BUILDS_GROUP: public
# Input variables
IS_PRIMARY_APP: ${{ matrix.sample-app == 'APN' }}
IS_PRIMARY_APP: ${{ matrix.sample-app.name == 'APN' }}
CURRENT_BRANCH: ${{ github.ref }}
run: |
# Initialize with the default distribution group
Expand All @@ -107,21 +112,21 @@ jobs:
with:
ruby-version: ${{ env.RUBY_VERSION }}
bundler-cache: true # cache tools to make builds faster in future
working-directory: apps/${{ matrix.sample-app }}
working-directory: apps/${{ matrix.sample-app.name }}

# Update version numbers and workspace credentials before building the app

- name: Generate New Version
uses: maierj/fastlane-action@v3.1.0
with:
subdirectory: Apps/${{ matrix.sample-app }}
subdirectory: Apps/${{ matrix.sample-app.name }}
lane: "generate_new_version"
options: '{"branch_name":"${{ github.ref_name }}", "pull_request_number":"${{ github.event.pull_request.number }}"}'

- name: Update React Native SDK Version
uses: maierj/fastlane-action@v3.1.0
with:
subdirectory: Apps/${{ matrix.sample-app }}
subdirectory: Apps/${{ matrix.sample-app.name }}
lane: "update_react_native_sdk_version"
env:
SDK_VERSION_NAME: ${{ env.SDK_VERSION_NAME }}
Expand All @@ -131,14 +136,17 @@ jobs:
- name: Update Sample App Version
uses: maierj/fastlane-action@v3.1.0
with:
subdirectory: Apps/${{ matrix.sample-app }}
subdirectory: Apps/${{ matrix.sample-app.name }}
lane: "update_react_native_app_version"
env:
SDK_VERSION_NAME: ${{ env.SDK_VERSION_NAME }}
APP_VERSION_NAME: ${{ env.APP_VERSION_NAME }}
APP_VERSION_CODE: ${{ env.APP_VERSION_CODE }}

- name: Setup workspace credentials in React Native environment files
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
COMMIT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
run: |
# Determine the correct file extension (.js or .ts)
if [ -f "env.sample.js" ]; then
Expand All @@ -153,15 +161,22 @@ jobs:
fi
# Update keys in the environment file
sd "siteId: '.*'" "siteId: '${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_SITE_ID', matrix.sample-app)] }}'" "$ENV_FILE"
sd "cdpApiKey: '.*'" "cdpApiKey: '${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_CDP_API_KEY', matrix.sample-app)] }}'" "$ENV_FILE"
sd "buildTimestamp: .*" "buildTimestamp: $(date +%s)," "$ENV_FILE"
sd "cdpApiKey: '.*'" "cdpApiKey: '${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_CDP_API_KEY', matrix.sample-app.name)] }}'" "$ENV_FILE"
sd "siteId: '.*'" "siteId: '${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_SITE_ID', matrix.sample-app.name)] }}'" "$ENV_FILE"
sd "workspaceName: '.*'" "workspaceName: '${{ matrix.sample-app.cio-workspace-name }}'" "$ENV_FILE"
sd "branchName: '.*'" "branchName: '$BRANCH_NAME'" "$ENV_FILE"
sd "commitHash: '.*'" "commitHash: '${COMMIT_HASH:0:7}'" "$ENV_FILE"
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "untagged")
COMMITS_AHEAD=$(git rev-list $LAST_TAG..HEAD --count 2>/dev/null || echo "untracked")
sd "commitsAheadCount: '.*'" "commitsAheadCount: '$COMMITS_AHEAD'" "$ENV_FILE"
- name: Setup workspace credentials in iOS environment files
working-directory: Apps/${{ matrix.sample-app }}/ios
working-directory: Apps/${{ matrix.sample-app.name }}/ios
run: |
cp "Env.swift.example" "Env.swift"
sd 'siteId: String = ".*"' "siteId: String = \"${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_SITE_ID', matrix.sample-app)] }}\"" "Env.swift"
sd 'cdpApiKey: String = ".*"' "cdpApiKey: String = \"${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_CDP_API_KEY', matrix.sample-app)] }}\"" "Env.swift"
sd 'siteId: String = ".*"' "siteId: String = \"${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_SITE_ID', matrix.sample-app.name)] }}\"" "Env.swift"
sd 'cdpApiKey: String = ".*"' "cdpApiKey: String = \"${{ secrets[format('CUSTOMERIO_{0}_WORKSPACE_CDP_API_KEY', matrix.sample-app.name)] }}\"" "Env.swift"
# Make sure to fetch dependencies only after updating version numbers and workspace credentials

Expand All @@ -175,10 +190,10 @@ jobs:
- name: Cache CocoaPods downloaded dependencies for faster builds in the future
uses: actions/cache@v4
with:
path: Apps/${{ matrix.sample-app }}/Pods
key: ${{ runner.os }}-${{ matrix.sample-app }}-Pods-${{ github.ref }}
path: Apps/${{ matrix.sample-app.name }}/Pods
key: ${{ runner.os }}-${{ matrix.sample-app.name }}-Pods-${{ github.ref }}
restore-keys: |
${{ runner.os }}-${{ matrix.sample-app }}-Pods
${{ runner.os }}-${{ matrix.sample-app.name }}-Pods
- name: Install dependencies to build SDK
run: npm ci
Expand All @@ -196,7 +211,7 @@ jobs:
id: android_build
uses: maierj/fastlane-action@v3.1.0
with:
subdirectory: Apps/${{ matrix.sample-app }}
subdirectory: Apps/${{ matrix.sample-app.name }}
lane: 'android build'
options: '{"distribution_groups": "${{ env.firebase_distribution_groups }}"}'
env:
Expand All @@ -214,7 +229,7 @@ jobs:
id: ios_build
uses: maierj/fastlane-action@v3.1.0
with:
subdirectory: Apps/${{ matrix.sample-app }}
subdirectory: Apps/${{ matrix.sample-app.name }}
lane: "ios build"
options: '{"distribution_groups": "${{ env.firebase_distribution_groups }}"}'
env:
Expand All @@ -238,7 +253,7 @@ jobs:
issue-number: ${{ github.event.pull_request.number }}
# the variables APP_VERSION_NAME, APP_VERSION_CODE are generated above in generate_new_version lane
body: |
* ${{ matrix.sample-app }}: `${{ env.APP_VERSION_NAME }} (${{ env.APP_VERSION_CODE }})`
* ${{ matrix.sample-app.name }}: `${{ env.APP_VERSION_NAME }} (${{ env.APP_VERSION_CODE }})`
edit-mode: append # append new line to the existing PR comment to build a list of all sample app builds.

- name: Update sample builds PR comment with build failure message
Expand All @@ -248,5 +263,5 @@ jobs:
comment-id: ${{ needs.update-pr-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
* ${{ matrix.sample-app }}: Build failed. See [CI job logs](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}) to determine the issue and try re-building.
* ${{ matrix.sample-app.name }}: Build failed. See [CI job logs](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}) to determine the issue and try re-building.
edit-mode: append # append new line to the existing PR comment to build a list of all sample app builds.
9 changes: 7 additions & 2 deletions Apps/APN/env.sample.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
const Env = {
siteId: 'YourSiteId',
cdpApiKey: 'YourCdpApiKey',
buildTimestamp: Math.floor(Date.now() / 1000),
cdpApiKey: 'CDP_API_KEY',
siteId: 'SITE_ID',
workspaceName: 'WORKSPACE_NAME',
branchName: 'BRANCH_NAME',
commitHash: 'COMMIT_HASH',
commitsAheadCount: 'COMMITS_AHEAD_COUNT',
};

export default Env;
24 changes: 9 additions & 15 deletions Apps/APN/src/components/BuildInfoText.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { getBuildNumber, getVersion } from 'react-native-device-info';
import { BuildMetadata } from '../utils/build';
import { Caption } from './Text';

const BuildInfoText = () => {
const [buildInfo, setBuildInfo] = useState('');

useEffect(() => {
const sdkPackageJson = require('customerio-reactnative/package.json');

const value =
`Customer.io` +
` React Native SDK ${sdkPackageJson.version}` +
` APN Sample ${getVersion()} (${getBuildNumber()})`;
setBuildInfo(value);
}, [buildInfo]);
const metadata = BuildMetadata.toString();

return (
<View style={styles.buildInfoContainer}>
<Caption>{buildInfo}</Caption>
<Caption style={styles.buildInfoText}>{metadata}</Caption>
</View>
);
};
Expand All @@ -27,9 +17,13 @@ const styles = StyleSheet.create({
buildInfoContainer: {
alignItems: 'center',
justifyContent: 'center',
marginBottom: 32,
marginBottom: 16,
paddingHorizontal: 16,
},
buildInfoText: {
width: '100%',
textAlign: 'left',
},
});

export default BuildInfoText;
91 changes: 91 additions & 0 deletions Apps/APN/src/utils/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { getVersion } from 'react-native-device-info';
import Env from '../../env';

const BuildMetadata = {
sdkVersion: getSdkVersion(),
appVersion: resolveValidOrElse(getVersion()),
buildDate: formatBuildDateWithRelativeTime(Env.buildTimestamp),
gitMetadata: `${resolveValidOrElse(
Env.branchName,
() => 'development build'
)}-${resolveValidOrElse(Env.commitHash, () => 'untracked')}`,
defaultWorkspace: resolveValidOrElse(Env.workspaceName),
language: 'JavaScript',
uiFramework: 'React Native',
sdkIntegration: 'npm',

toString() {
return `
SDK Version: ${this.sdkVersion} \tApp Version: ${this.appVersion}
Build Date: ${this.buildDate}
Branch: ${this.gitMetadata}
Default Workspace: ${this.defaultWorkspace}
Language: ${this.language} \tUI Framework: ${this.uiFramework}
SDK Integration: ${this.sdkIntegration}
`;
},
};

function resolveValidOrElse(value, fallback = () => 'unknown') {
return value && value.trim() ? value : fallback();
}

function formatBuildDateWithRelativeTime(timestamp) {
if (!timestamp) return 'unavailable';
const parsedTimestamp = parseInt(timestamp, 10);
if (isNaN(parsedTimestamp)) return 'invalid timestamp';

const buildDate = new Date(parsedTimestamp * 1000);
const now = new Date();
const daysAgo = Math.floor((now - buildDate) / (1000 * 60 * 60 * 24));

return `${buildDate.toLocaleString()} ${
daysAgo === 0 ? '(Today)' : `(${daysAgo} days ago)`
}`;
}

function getSdkVersion() {
const sdkPackageName = 'customerio-reactnative';
try {
const sdkPackage = getSdkMetadataFromPackageLock(sdkPackageName);
if (!sdkPackage) {
console.warn(`${sdkPackageName} not found in package-lock.json`);
return undefined;
}

const version = resolveValidOrElse(sdkPackage.version);
const isPathDependency =
sdkPackage.resolved && sdkPackage.resolved.startsWith('file:');
if (isPathDependency) {
return `${version}-${resolveValidOrElse(
Env.commitsAheadCount,
() => 'as-source'
)}`;
}

return version;
} catch (error) {
console.warn(
`Failed to read ${sdkPackageName} sdk version: ${error.message}`
);
return undefined;
}
}

function getSdkMetadataFromPackageLock(packageName) {
const packageLockPath = '../../package-lock.json';
try {
const packageLock = require(packageLockPath);
const packages = packageLock.packages || {};
const resolvedPackageName = `node_modules/${packageName}`;
const sdkPackage = packages[resolvedPackageName];
if (sdkPackage) {
return sdkPackage;
}
} catch (error) {
console.warn(`Failed to read ${packageLockPath}: ${error.message}`);
}
return undefined;
}

export { BuildMetadata };

0 comments on commit 0e74e8c

Please sign in to comment.