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
12 changes: 6 additions & 6 deletions .github/workflows/build_LoopFollow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ jobs:
if: steps.workflow-permission.outputs.has_permission != 'true'
run: |
echo "### :calendar: Scheduled Sync and Build Disabled :mobile_phone_off:" >> $GITHUB_STEP_SUMMARY
echo "You have not yet configured the scheduled sync and build for LoopFollow's browser build." >> $GITHUB_STEP_SUMMARY
echo "Synchronizing your fork of <code>LoopFollow</code> with the upstream repository <code>loopandlearn/LoopFollow</code> will be skipped." >> $GITHUB_STEP_SUMMARY
echo "If you want to enable automatic builds and updates for your LoopFollow, please follow the instructions \
under the following path <code>LoopFollow/fastlane/testflight.md</code>." >> $GITHUB_STEP_SUMMARY
echo "You have not yet configured the scheduled sync and build for ${{ github.event.repository.name }}'s browser build." >> $GITHUB_STEP_SUMMARY
echo "Synchronizing your fork of <code>${{ github.event.repository.name }}</code> with the upstream repository <code>${{ env.UPSTREAM_REPO }}</code> will be skipped." >> $GITHUB_STEP_SUMMARY
echo "If you want to enable automatic builds and updates for your ${{ github.event.repository.name }}, please follow the instructions \
under the following path <code>${{ github.event.repository.name }}/fastlane/testflight.md</code>." >> $GITHUB_STEP_SUMMARY

# Set a logic flag if this is the second instance of this day-of-week in this month
- name: Check if this is the second time this day-of-week happens this month
Expand All @@ -161,7 +161,7 @@ jobs:
(vars.SCHEDULED_BUILD != 'false' && needs.check_status.outputs.IS_SECOND_IN_MONTH == 'true') ||
(vars.SCHEDULED_SYNC != 'false' && needs.check_status.outputs.NEW_COMMITS == 'true' )

# Builds LoopFollow
# Builds the app
build:
name: Build
needs: [check_certs, check_status]
Expand Down Expand Up @@ -203,7 +203,7 @@ jobs:
- name: Sync clock
run: sudo sntp -sS time.windows.com

# Build signed LoopFollow IPA file
# Build signed IPA file
- name: Fastlane Build & Archive
run: bundle exec fastlane build_LoopFollow
env:
Expand Down
49 changes: 35 additions & 14 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ DEVICE_NAME = ENV["DEVICE_NAME"]
DEVICE_ID = ENV["DEVICE_ID"]
ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"

# Reads the per-app suffix from LoopFollowDisplayNameConfig.xcconfig so the same
# Fastfile produces the correct bundle identifiers in every sister repository
# (LoopFollow, LoopFollow_Second, LoopFollow_Third) without per-repo edits.
def loopfollow_app_suffix
root = GITHUB_WORKSPACE || File.expand_path("..", __dir__)
path = File.join(root, "LoopFollowDisplayNameConfig.xcconfig")
return "" unless File.exist?(path)

File.foreach(path) do |line|
next if line.strip.start_with?("//")
if (match = line.match(/^\s*app_suffix\s*=\s*(.*)$/))
return match[1].strip
end
end
""
end

APP_SUFFIX = loopfollow_app_suffix
APP_IDENTIFIER = "com.#{TEAMID}.LoopFollow#{APP_SUFFIX}"
LA_IDENTIFIER = "#{APP_IDENTIFIER}.LoopFollowLAExtension"

platform :ios do
desc "Build Loop Follow"
lane :build_LoopFollow do
Expand All @@ -40,7 +61,7 @@ platform :ios do
)

previous_build_number = latest_testflight_build_number(
app_identifier: "com.#{TEAMID}.LoopFollow",
app_identifier: APP_IDENTIFIER,
api_key: api_key,
)

Expand All @@ -55,8 +76,8 @@ platform :ios do
type: "appstore",
git_basic_authorization: Base64.strict_encode64("#{GITHUB_REPOSITORY_OWNER}:#{GH_PAT}"),
app_identifier: [
"com.#{TEAMID}.LoopFollow",
"com.#{TEAMID}.LoopFollow.LoopFollowLAExtension"
APP_IDENTIFIER,
LA_IDENTIFIER
]
)

Expand All @@ -66,14 +87,14 @@ platform :ios do

update_code_signing_settings(
path: "#{GITHUB_WORKSPACE}/LoopFollow.xcodeproj",
profile_name: mapping["com.#{TEAMID}.LoopFollow"],
profile_name: mapping[APP_IDENTIFIER],
code_sign_identity: "iPhone Distribution",
targets: ["LoopFollow"]
)

update_code_signing_settings(
path: "#{GITHUB_WORKSPACE}/LoopFollow.xcodeproj",
profile_name: mapping["com.#{TEAMID}.LoopFollow.LoopFollowLAExtension"],
path: "#{GITHUB_WORKSPACE}/LoopFollow.xcodeproj",
profile_name: mapping[LA_IDENTIFIER],
code_sign_identity: "iPhone Distribution",
targets: ["LoopFollowLAExtensionExtension"]
)
Expand All @@ -87,10 +108,10 @@ platform :ios do
buildlog_path: 'buildlog',
export_options: {
provisioningProfiles: {
"com.#{TEAMID}.LoopFollow" => mapping["com.#{TEAMID}.LoopFollow"],
"com.#{TEAMID}.LoopFollow.LoopFollowLAExtension" => mapping["com.#{TEAMID}.LoopFollow.LoopFollowLAExtension"]
APP_IDENTIFIER => mapping[APP_IDENTIFIER],
LA_IDENTIFIER => mapping[LA_IDENTIFIER]
}
}
}
)

copy_artifacts(
Expand Down Expand Up @@ -138,12 +159,12 @@ platform :ios do
end
end

configure_bundle_id("LoopFollow", "com.#{TEAMID}.LoopFollow", [
configure_bundle_id("LoopFollow", APP_IDENTIFIER, [
Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
Spaceship::ConnectAPI::BundleIdCapability::Type::PUSH_NOTIFICATIONS
])
configure_bundle_id("LoopFollow Live Activity Extension", "com.#{TEAMID}.LoopFollow.LoopFollowLAExtension", [

configure_bundle_id("LoopFollow Live Activity Extension", LA_IDENTIFIER, [
Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS
])

Expand All @@ -166,8 +187,8 @@ platform :ios do
verbose: true,
git_basic_authorization: Base64.strict_encode64("#{GITHUB_REPOSITORY_OWNER}:#{GH_PAT}"),
app_identifier: [
"com.#{TEAMID}.LoopFollow",
"com.#{TEAMID}.LoopFollow.LoopFollowLAExtension"
APP_IDENTIFIER,
LA_IDENTIFIER
]
)
end
Expand Down
67 changes: 37 additions & 30 deletions release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ VERSION_FILE="Config.xcconfig"
MARKETING_KEY="LOOP_FOLLOW_MARKETING_VERSION"
DEV_BRANCH="dev"
MAIN_BRANCH="main"
PATCH_DIR="../${APP_NAME}_update_patches"
# ---------------------------------------

# --- functions here ---
Expand All @@ -26,38 +25,49 @@ queue_push() { push_cmds+=("git -C \"$(pwd)\" $*"); echo "+ [queued] (in $(pwd))

update_follower () {
local DIR="$1"
local build_minute="$2" # staggered Sunday-build minute (see calls below)
local suffix=".${DIR#${APP_NAME}_}" # LoopFollow_Second -> .Second
local display="$DIR" # LoopFollow_Second
local upstream="loopandlearn/${DIR}" # loopandlearn/LoopFollow_Second

echo; echo "🔄 Updating $DIR …"
cd "$DIR"

echo; echo "If there are custom changes needed to the patch, make the change before continuing"
pause

# 1 · Make sure we’re on a clean, up-to-date main
echo_run git switch "$MAIN_BRANCH"
echo_run git fetch
echo_run git pull

# 2 · Apply the patch
if ! git apply --whitespace=nowarn "$PATCH_FILE"; then
echo "‼️ Some changes could not be applied, so no changes were made."
echo "The command used was: git apply --whitespace=nowarn $PATCH_FILE"
echo; echo "Use a different terminal to fix and apply the patch before continuing"
pause
# 2 · Full mirror of the release tree from the primary repo.
# Every tracked file (including the overlay files) is synced; only git
# metadata and local/build dirs are protected. --delete makes the tree an
# exact mirror, auto-correcting any drift.
echo_run rsync -a --delete \
--exclude='.git/' \
--exclude='.claude/' \
--exclude='build/' \
"$PRIMARY_ABS_PATH"/ ./

# 3 · Re-apply this instance's overlay on top of the mirror
perl -i -pe "s|^app_suffix\s*=.*|app_suffix = ${suffix}|" LoopFollowDisplayNameConfig.xcconfig
perl -i -pe "s|^display_name\s*=.*|display_name = ${display}|" LoopFollowDisplayNameConfig.xcconfig
perl -i -pe "s|^(\s*)UPSTREAM_REPO:.*|\${1}UPSTREAM_REPO: ${upstream}|" .github/workflows/build_LoopFollow.yml
perl -i -pe "s|^(\s*)- cron:.*|\${1}- cron: \"${build_minute} 10 * * 0\" # Sunday at UTC 10:${build_minute}|" .github/workflows/build_LoopFollow.yml

# 4 · Rename the synced workspace to this instance's name
rm -rf "${DIR}.xcworkspace"
if [ -d "${APP_NAME}.xcworkspace" ]; then
mv "${APP_NAME}.xcworkspace" "${DIR}.xcworkspace"
fi

# 3 · Pause if any conflict markers remain
if git ls-files -u | grep -q .; then
echo "⚠️ Conflicts detected."
echo " If Fastfile or build_LoopFollow.yml were modified, these are expected."
echo " Open your merge tool, resolve, then press Enter."
pause
# 5 · Single commit capturing the mirror + overlay
git add -A
if git diff --cached --quiet; then
echo "✓ $DIR already up to date — nothing to commit."
else
echo_run git commit -m "transfer v${new_ver} updates from LF to ${DIR}"
fi

# 4 · Single commit capturing all staged changes
git add -u
git add $(git ls-files --others --exclude-standard) 2>/dev/null || true
git commit -m "transfer v${new_ver} updates from LF to ${DIR}"

echo_run git status
echo "💻 Build & test $DIR now."; pause # build & test checkpoint
queue_push push origin "$MAIN_BRANCH"
Expand Down Expand Up @@ -109,16 +119,13 @@ echo_run git commit -m "update version to ${new_ver} [skip ci]" "$VERSION_FILE"
echo "💻 Build & test release branch now."; pause
queue_push push origin "$RELEASE_BRANCH"

# --- create a patch from main..release branch (includes the bump) -----
mkdir -p "$PATCH_DIR"
PATCH_FILE="${PATCH_DIR}/LF_diff_${old_ver}_to_${new_ver}.patch"

git diff -M --binary "$MAIN_BRANCH" "$RELEASE_BRANCH" \
> "$PATCH_FILE"

# --- mirror the release tree into the sister repos ----
# Second arg = each app's scheduled browser-build minute (Sundays at 10:xx UTC),
# staggered from the main app (:17) so a user who forked all three apps doesn't
# trigger three simultaneous builds.
cd ..
update_follower "$SECOND_DIR"
update_follower "$THIRD_DIR"
update_follower "$SECOND_DIR" "27"
update_follower "$THIRD_DIR" "40"

# ---------- GitHub Actions Test ---------
echo;
Expand Down
Loading