Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions .github/workflows/fork-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -348,23 +348,53 @@ jobs:
# upstream's preview bundles. The release version replaces upstream's
# store version so Obtainium can match the APK to its release tag. It
# goes in .env because the Gradle bundling step reads app.config.ts again.
# The fork ships its own app: the ember icon always, and the package name,
# app name and Firebase config from repository settings when they are set.
# Without Firebase config the app builds without push notifications.
- name: Configure the build
env:
VERSION: ${{ needs.prepare.outputs.version }}
ANDROID_PACKAGE: ${{ vars.T3CODE_ANDROID_PACKAGE }}
APP_NAME: ${{ vars.T3CODE_APP_NAME }}
GOOGLE_SERVICES_JSON: ${{ secrets.ANDROID_GOOGLE_SERVICES_JSON }}
run: |
cp .env.example .env
echo "T3CODE_MOBILE_UPDATES_ENABLED=0" >> .env
echo "T3CODE_MOBILE_VERSION=$VERSION" >> .env
{
echo "T3CODE_MOBILE_UPDATES_ENABLED=0"
echo "T3CODE_MOBILE_VERSION=$VERSION"
echo "T3CODE_ANDROID_ICON_BACKGROUND=./assets/android-icon-background-ember.png"
echo "T3CODE_ANDROID_PACKAGE=$ANDROID_PACKAGE"
echo "T3CODE_APP_NAME=$APP_NAME"
} >> .env
if [ -n "$GOOGLE_SERVICES_JSON" ]; then
printf '%s' "$GOOGLE_SERVICES_JSON" > "$RUNNER_TEMP/google-services.json"
echo "T3CODE_ANDROID_GOOGLE_SERVICES_FILE=$RUNNER_TEMP/google-services.json" >> .env
fi

- name: Generate the native project
working-directory: apps/mobile
run: ./node_modules/.bin/expo prebuild --platform android --clean --no-install

# Release builds sign with the React Native template's debug keystore,
# the same key as the APK already installed from earlier fork builds.
# Signs with the repository's release keystore when one is set, and
# otherwise with the React Native template's public debug keystore.
- name: Build release APK
working-directory: apps/mobile/android
run: ./gradlew :app:assembleRelease -PreactNativeArchitectures=arm64-v8a -x lintVitalAnalyzeRelease --no-daemon
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
run: |
signing=()
if [ -n "$KEYSTORE_BASE64" ]; then
printf '%s' "$KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/release.keystore"
signing=(
"-Pandroid.injected.signing.store.file=$RUNNER_TEMP/release.keystore"
"-Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD"
"-Pandroid.injected.signing.key.alias=$KEY_ALIAS"
"-Pandroid.injected.signing.key.password=$KEYSTORE_PASSWORD"
)
fi
./gradlew :app:assembleRelease -PreactNativeArchitectures=arm64-v8a -x lintVitalAnalyzeRelease --no-daemon "${signing[@]}"

- name: Collect APK
env:
Expand Down
3 changes: 3 additions & 0 deletions FORK.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,6 @@ adds the feature, and remove it in the PR that drops the feature.
- #30 A checkout's pull requests and repository come from the remote `gh repo set-default`
chose, ahead of `upstream`, so a fork lists its own PRs:
`apps/server/src/project/RepositoryIdentityResolver.ts` (`parseGhDefaultRemote`).
- #32 The Android APK is the fork's own app: an ember icon, plus the package name, app name, release
keystore and Firebase config from repository variables and secrets when they are set:
`apps/mobile/app.config.ts` (`T3CODE_ANDROID_PACKAGE`), `.github/workflows/fork-release.yml`.
19 changes: 15 additions & 4 deletions apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ const iosBundleIdentifier = isIosPersonalTeamBuild
? personalTeamBundleIdentifier!
: variant.iosBundleIdentifier;

// Fork builds rebrand the Android app here; unset values keep the variant's.
const appName = repoEnv.T3CODE_APP_NAME?.trim() || variant.appName;
const androidPackage = repoEnv.T3CODE_ANDROID_PACKAGE?.trim() || variant.androidPackage;
const androidAdaptiveBackgroundImage =
repoEnv.T3CODE_ANDROID_ICON_BACKGROUND?.trim() || variant.assets.androidAdaptiveBackgroundImage;
if (!/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/.test(androidPackage)) {
throw new Error(
"T3CODE_ANDROID_PACKAGE must be an Android package name such as com.example.t3code.",
);
}

const dmSansFonts = {
regular: "@expo-google-fonts/dm-sans/400Regular/DMSans_400Regular.ttf",
medium: "@expo-google-fonts/dm-sans/500Medium/DMSans_500Medium.ttf",
Expand Down Expand Up @@ -228,7 +239,7 @@ const sharingPlugin: NonNullable<ExpoConfig["plugins"]>[number] = [
// Match iOS PostScript names on Android so RN and the native composer share fonts before runtime loading.

const config: ExpoConfig = {
name: variant.appName,
name: appName,
slug: "t3-code",
platforms: ["ios", "android"],
scheme: variant.scheme,
Expand Down Expand Up @@ -291,14 +302,14 @@ const config: ExpoConfig = {
},
android: {
icon: variant.assets.appIcon,
package: variant.androidPackage,
package: androidPackage,
...(repoEnv.T3CODE_ANDROID_GOOGLE_SERVICES_FILE
? { googleServicesFile: repoEnv.T3CODE_ANDROID_GOOGLE_SERVICES_FILE }
: {}),
adaptiveIcon: {
backgroundColor: variant.assets.androidAdaptiveBackgroundColor,
...(variant.assets.androidAdaptiveBackgroundImage
? { backgroundImage: variant.assets.androidAdaptiveBackgroundImage }
...(androidAdaptiveBackgroundImage
? { backgroundImage: androidAdaptiveBackgroundImage }
: {}),
foregroundImage: variant.assets.androidAdaptiveForeground,
monochromeImage: variant.assets.androidMonochromeIcon,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading