Skip to content

Commit fb17d38

Browse files
authored
chore: update sample app build info (#492)
1 parent 310428a commit fb17d38

File tree

5 files changed

+168
-43
lines changed

5 files changed

+168
-43
lines changed

.github/workflows/reusable_build_sample_apps.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ jobs:
2222
- "kotlin_compose"
2323
include: # Add additional variables to each sample app build: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude
2424
- sample-app: "java_layout"
25+
cio-workspace-name: "Mobile: Native iOS & Android"
2526
cio-cdpapikey-secret-key: "CUSTOMERIO_JAVA_WORKSPACE_CDP_API_KEY"
2627
cio-siteid-secret-key: "CUSTOMERIO_JAVA_WORKSPACE_SITE_ID"
2728
- sample-app: "kotlin_compose"
29+
cio-workspace-name: "Mobile: xiOS CocoaPods FCM + Kotlin Android"
2830
cio-cdpapikey-secret-key: "CUSTOMERIO_KOTLIN_WORKSPACE_CDP_API_KEY"
2931
cio-siteid-secret-key: "CUSTOMERIO_KOTLIN_WORKSPACE_SITE_ID"
3032

@@ -91,8 +93,10 @@ jobs:
9193
touch "samples/local.properties"
9294
echo "cdpApiKey=${{ secrets[matrix.cio-cdpapikey-secret-key] }}" >> "samples/local.properties"
9395
echo "siteId=${{ secrets[matrix.cio-siteid-secret-key] }}" >> "samples/local.properties"
94-
echo "branch=$BRANCH_NAME" >> "samples/local.properties"
95-
echo "commit=${COMMIT_HASH:0:7}" >> "samples/local.properties"
96+
echo "workspace=${{ matrix.cio-workspace-name }}" >> "samples/local.properties"
97+
echo "branchName=$BRANCH_NAME" >> "samples/local.properties"
98+
echo "commitHash=${COMMIT_HASH:0:7}" >> "samples/local.properties"
99+
echo "commitsAheadCount=$(git rev-list $(git describe --tags --abbrev=0)..HEAD --count)" >> samples/local.properties
96100
if [ "${{ inputs.use_latest_sdk_version == true }}" ]; then
97101
echo "sdkVersion=${{ steps.latest-sdk-version-step.outputs.LATEST_TAG }}" >> "samples/local.properties"
98102
fi
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package io.customer.android.sample.java_layout.buildinfo;
2+
3+
import android.graphics.Typeface;
4+
import android.text.SpannableString;
5+
import android.text.SpannableStringBuilder;
6+
import android.text.Spanned;
7+
import android.text.style.StyleSpan;
8+
9+
import androidx.annotation.NonNull;
10+
11+
import java.util.Locale;
12+
13+
import io.customer.android.sample.java_layout.BuildConfig;
14+
import io.customer.sdk.Version;
15+
16+
/**
17+
* Contains metadata about the build environment.
18+
*/
19+
public class BuildInfoMetadata {
20+
private final String sdkVersion;
21+
private final String appVersion;
22+
private final String buildDate;
23+
private final String gitMetadata;
24+
private final String defaultWorkspace;
25+
private final String language;
26+
private final String uiFramework;
27+
private final String sdkIntegration;
28+
29+
public BuildInfoMetadata() {
30+
this.sdkVersion = BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.SDK_VERSION, () -> String.format(
31+
Locale.ENGLISH, "%s-%s",
32+
Version.version,
33+
BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.COMMITS_AHEAD_COUNT, () -> "as-source")));
34+
this.appVersion = String.valueOf(BuildConfig.VERSION_CODE);
35+
this.buildDate = BuildInfoMetadataUtils.formatBuildDateWithRelativeTime(BuildConfig.BUILD_TIMESTAMP);
36+
this.gitMetadata = String.format(Locale.ENGLISH, "%s-%s",
37+
BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.BRANCH_NAME, () -> "working branch"),
38+
BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.COMMIT_HASH, () -> "untracked"));
39+
this.defaultWorkspace = BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.DEFAULT_WORKSPACE);
40+
this.language = BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.LANGUAGE);
41+
this.uiFramework = BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.UI_FRAMEWORK);
42+
this.sdkIntegration = BuildInfoMetadataUtils.resolveValidOrElse(BuildConfig.SDK_INTEGRATION);
43+
}
44+
45+
@NonNull
46+
@Override
47+
public String toString() {
48+
return toFormattedString().toString();
49+
}
50+
51+
@NonNull
52+
public CharSequence toFormattedString() {
53+
SpannableStringBuilder builder = new SpannableStringBuilder();
54+
55+
appendBold(builder, "SDK Version: ");
56+
builder.append(sdkVersion).append(" \t");
57+
appendBold(builder, "App version: ");
58+
builder.append(appVersion).append("\n");
59+
appendBold(builder, "Build Date: ");
60+
builder.append(buildDate).append("\n");
61+
appendBold(builder, "Branch: ");
62+
builder.append(gitMetadata).append("\n");
63+
appendBold(builder, "Default Workspace: ");
64+
builder.append(defaultWorkspace).append("\n");
65+
appendBold(builder, "Language: ");
66+
builder.append(language).append(" \t");
67+
appendBold(builder, "UI Framework: ");
68+
builder.append(uiFramework).append("\n");
69+
appendBold(builder, "SDK Integration: ");
70+
builder.append(sdkIntegration);
71+
72+
return builder;
73+
}
74+
75+
private void appendBold(@NonNull SpannableStringBuilder builder, @NonNull String text) {
76+
SpannableString spannable = new SpannableString(text);
77+
spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
78+
builder.append(spannable);
79+
}
80+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.customer.android.sample.java_layout.buildinfo;
2+
3+
import android.text.TextUtils;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.annotation.Nullable;
7+
8+
import java.text.DateFormat;
9+
import java.util.Date;
10+
import java.util.Locale;
11+
import java.util.concurrent.TimeUnit;
12+
13+
public class BuildInfoMetadataUtils {
14+
public static String resolveValidOrElse(@Nullable String text) {
15+
return resolveValidOrElse(text, () -> "unknown");
16+
}
17+
18+
public static String resolveValidOrElse(@Nullable String text, @NonNull ValueProvider<String> fallbackProvider) {
19+
// When local properties are not set, they have a string value of "null"
20+
if (!TextUtils.isEmpty(text) && !"null".equalsIgnoreCase(text)) {
21+
return text;
22+
}
23+
24+
return fallbackProvider.get();
25+
}
26+
27+
public static String formatBuildDateWithRelativeTime(long buildTimestamp) {
28+
Date buildDate = new Date(buildTimestamp);
29+
String formattedDate = DateFormat.getDateTimeInstance().format(buildDate);
30+
31+
long diffInMillis = System.currentTimeMillis() - buildTimestamp;
32+
long daysAgo = TimeUnit.MILLISECONDS.toDays(diffInMillis);
33+
String relativeTime = daysAgo == 0 ? "(Today)" : String.format(Locale.ENGLISH, "(%d days ago)", daysAgo);
34+
35+
return String.format(Locale.ENGLISH, "%s %s", formattedDate, relativeTime);
36+
}
37+
38+
/**
39+
* Provides a value when the original value is not valid using lambda expressions.
40+
* This can be simplified with Java 8+ or Kotlin later if needed.
41+
*/
42+
public interface ValueProvider<T> {
43+
@NonNull
44+
T get();
45+
}
46+
}

samples/java_layout/src/main/java/io/customer/android/sample/java_layout/utils/ViewUtils.java

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,8 @@
1515
import com.google.android.material.textfield.TextInputEditText;
1616
import com.google.android.material.textfield.TextInputLayout;
1717

18-
import java.text.DateFormat;
19-
import java.util.Date;
20-
import java.util.Locale;
21-
22-
import io.customer.android.sample.java_layout.BuildConfig;
2318
import io.customer.android.sample.java_layout.R;
19+
import io.customer.android.sample.java_layout.buildinfo.BuildInfoMetadata;
2420

2521
public class ViewUtils {
2622
public static void prepareForAutomatedTests(@NonNull View view, @StringRes int contentDescResId) {
@@ -55,38 +51,8 @@ public static void setError(@NonNull TextInputLayout textInputLayout, @Nullable
5551
}
5652

5753
public static void setBuildInfo(@NonNull TextView textView) {
58-
String buildInfo = String.format(
59-
Locale.ENGLISH,
60-
"SDK version: %s\n" +
61-
"Build date: %s\n" +
62-
"Branch: %s\n" +
63-
"Default workspace: Native iOS & Android\n" +
64-
"App version: %s",
65-
getSdkVersion(),
66-
getBuildTime(),
67-
getBranchName(),
68-
BuildConfig.VERSION_CODE
69-
);
70-
textView.setText(buildInfo);
71-
}
72-
73-
private static String getBuildTime() {
74-
return DateFormat.getDateTimeInstance().format(new Date(BuildConfig.BUILD_TIMESTAMP));
75-
}
76-
77-
private static String getSdkVersion() {
78-
if (isEmptyOrUnset(BuildConfig.SDK_VERSION)) return "as source code";
79-
return BuildConfig.SDK_VERSION;
80-
}
81-
82-
private static String getBranchName() {
83-
if (isEmptyOrUnset(BuildConfig.BRANCH)) return "local development";
84-
return BuildConfig.BRANCH + "." + BuildConfig.COMMIT;
85-
}
86-
87-
private static boolean isEmptyOrUnset(String text) {
88-
// When local properties are not set, they have a string value of "null"
89-
return TextUtils.isEmpty(text) || "null".equalsIgnoreCase(text);
54+
BuildInfoMetadata buildInfo = new BuildInfoMetadata();
55+
textView.setText(buildInfo.toFormattedString());
9056
}
9157

9258
@NonNull

samples/sample-app.gradle

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,52 @@ android {
1313
Closure<String> getConfigWithPrefix = { String key ->
1414
localProperties."${configKeyPrefix}${key}" ?: localProperties."${key}"
1515
}
16+
// Helper methods to retrieve language and UI framework from prefix
17+
Closure<String> getLanguageFromPrefix = { String prefix ->
18+
String normalizedPrefix = prefix.toLowerCase()
19+
if (normalizedPrefix.startsWith("java")) {
20+
return "Java"
21+
} else if (normalizedPrefix.startsWith("kotlin")) {
22+
return "Kotlin"
23+
}
24+
return null
25+
}
26+
Closure<String> getUIFrameworkFromPrefix = { String prefix ->
27+
String normalizedPrefix = prefix.toLowerCase()
28+
if (normalizedPrefix.contains("layout")) {
29+
return "Android XML"
30+
} else if (normalizedPrefix.contains("compose")) {
31+
return "Jetpack Compose"
32+
}
33+
return null
34+
}
1635

1736
// Retrieve API keys using the helper method to allow key prefixing
1837
// e.g. Java Layout sample app has prefix javaLayout_ for API keys
1938
// javaLayout_cdpApiKey=KEY has higher priority than cdpApiKey=KEY
2039
// cdpApiKey=KEY can be used as a fallback for all sample apps
2140
String cdpApiKey = getConfigWithPrefix("cdpApiKey")
2241
String siteId = getConfigWithPrefix("siteId")
42+
String workspace = getConfigWithPrefix("workspace")
43+
String language = getConfigWithPrefix("language") ?: getLanguageFromPrefix(configKeyPrefix)
44+
String uiFramework = getConfigWithPrefix("uiFramework") ?: getUIFrameworkFromPrefix(configKeyPrefix)
45+
String sdkIntegration = "Maven"
2346
String sdkVersion = localProperties["sdkVersion"]
24-
String branch = localProperties["branch"]
25-
String commit = localProperties["commit"]
47+
String branchName = localProperties["branchName"]
48+
String commitHash = localProperties["commitHash"]
49+
String commitsAheadCount = localProperties["commitsAheadCount"]
2650

2751
// Set build config fields for API keys
2852
buildConfigField "String", "CDP_API_KEY", "\"${cdpApiKey}\""
2953
buildConfigField "String", "SITE_ID", "\"${siteId}\""
54+
buildConfigField "String", "DEFAULT_WORKSPACE", "\"${workspace}\""
55+
buildConfigField "String", "LANGUAGE", "\"${language}\""
56+
buildConfigField "String", "UI_FRAMEWORK", "\"${uiFramework}\""
57+
buildConfigField "String", "SDK_INTEGRATION", "\"${sdkIntegration}\""
3058
buildConfigField "String", "SDK_VERSION", "\"${sdkVersion}\""
31-
buildConfigField "String", "BRANCH", "\"${branch}\""
32-
buildConfigField "String", "COMMIT", "\"${commit}\""
59+
buildConfigField "String", "BRANCH_NAME", "\"${branchName}\""
60+
buildConfigField "String", "COMMIT_HASH", "\"${commitHash}\""
61+
buildConfigField "String", "COMMITS_AHEAD_COUNT", "\"${commitsAheadCount}\""
3362
buildConfigField "long", "BUILD_TIMESTAMP", System.currentTimeMillis() + "L"
3463
}
3564
// Avoid redefining signing configs in sample apps to avoid breaking release

0 commit comments

Comments
 (0)