From bb4045106678089a30945fe09c1ac8647bc753eb Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 25 Jun 2025 19:32:24 +1000 Subject: [PATCH] Add automation to strip Wormholy from non-Debug builds --- ...ail-non-debug-build-if-wormholy-present.sh | 36 +++++++++++++++++++ .../WooCommerce.xcodeproj/project.pbxproj | 20 +++++++++++ fastlane/Fastfile | 33 +++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100755 Scripts/build-phases/fail-non-debug-build-if-wormholy-present.sh diff --git a/Scripts/build-phases/fail-non-debug-build-if-wormholy-present.sh b/Scripts/build-phases/fail-non-debug-build-if-wormholy-present.sh new file mode 100755 index 00000000000..cecab0afa3d --- /dev/null +++ b/Scripts/build-phases/fail-non-debug-build-if-wormholy-present.sh @@ -0,0 +1,36 @@ +#!/bin/bash -eu + +# Checks if the SwiftPM setup includes Wormholy during a build that is not Debug. +# +# If that's the case, it fails the build, because we don't want the library in non Debug builds. +# +# See counterpart method remove_wormholy_dependency_from_package_swift in fastlane/Fastfile. + +MODULES_PATH="${SRCROOT}/../Modules" +PACKAGE_PATH="${MODULES_PATH}/Package.swift" +# Note: when/if we'll remove the workspace, this will change to ${MODULES_PATH}/Package.resolved +PACKAGE_RESOLVED_PATH="${SRCROOT}/../WooCommerce.xcworkspace/xcshareddata/swiftpm/Package.resolved" + +if [ "${CONFIGURATION}" == "Debug" ]; then + echo "info: Running in Debug build configuration. Skipping Wormholy check." + exit 0 +else + echo "info: Running with a build configuration that is not Debug (${CONFIGURATION}). Checking Wormholy is not part of the SwiftPM setup..." +fi + +EXPLANATION="You are likely running a distribution build from Xcode, which cannot strip Wormholy. Please build for distribution using Fastlane (\`bundle exec fastlane build_for_app_store_connect\` or \`bundle exec fastlane build_for_prototype_build\`)." + +if grep --quiet "Wormholy" "${PACKAGE_PATH}"; then + echo "error: Wormholy reference found in Package.swift. $EXPLANATION" + exit 1 +fi + +# This is not necessary from the build point of view, because Package.swift is the source of truth. +# But checking it ensures that the packages were resolved before starting the build. + +if grep --quiet "Wormholy" "${PACKAGE_RESOLVED_PATH}"; then + echo "error: Wormholy reference found in Package.resolved. $EXPLANATION" + exit 1 +fi + +echo "info: Wormholy not found in SwiftPM setup. Proceeding with the build..." diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 476973dedbf..964d36bc15a 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -14479,6 +14479,7 @@ isa = PBXNativeTarget; buildConfigurationList = B56DB3E62049BFAA00D4AA8E /* Build configuration list for PBXNativeTarget "WooCommerce" */; buildPhases = ( + 3F4278632E0BD6B700B11B9E /* Prevent Wormholy in non-Debug builds */, 57CCFFD4249D2A5700825FCF /* SwiftLint */, 3F50FE4528CAEE9F00C89201 /* Enforce AppLocalizedString usages */, B56DB3C22049BFAA00D4AA8E /* Sources */, @@ -15056,6 +15057,25 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 3F4278632E0BD6B700B11B9E /* Prevent Wormholy in non-Debug builds */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Prevent Wormholy in non-Debug builds"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "${SRCROOT}/../Scripts/build-phases/fail-non-debug-build-if-wormholy-present.sh\n"; + }; 3F50FE4528CAEE9F00C89201 /* Enforce AppLocalizedString usages */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 2ac95dbbe18..1d446763ff4 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -720,6 +720,8 @@ platform :ios do lane :build_for_app_store_connect do |fetch_code_signing: true| update_certs_and_profiles_app_store if fetch_code_signing + remove_wormholy_dependency_from_package_swift + gym( scheme: 'WooCommerce', workspace: WORKSPACE_PATH, @@ -784,6 +786,8 @@ platform :ios do lane :build_for_prototype_build do |fetch_code_signing: true| update_certs_and_profiles_enterprise if fetch_code_signing + remove_wormholy_dependency_from_package_swift + build_number = ENV.fetch('BUILDKITE_BUILD_NUMBER', '0') pr_or_branch = pull_request_number&.then { |num| "PR ##{num}" } || ENV.fetch('BUILDKITE_BRANCH', nil) @@ -1555,3 +1559,32 @@ def report_milestone_error(error_title:) buildkite_annotate(style: 'warning', context: 'error-with-milestone', message: error_message) if is_ci end + +# Removes all Wormholy entries from a given `Package.swift` +# +# Wormholy is a library we only need in Debug builds. +# We don't want to bloat other builds with it, despite how small it might be. +# +# Thanks to all our Swift dependencies being declared in `Modules/Package.swift`, removing Wormholy from the file safely removes if from Xcode. +# No need to edit the Xcode project. +# +# See counterpart build phase script fail-non-debug-build-if-wormholy-present.sh +def remove_wormholy_dependency_from_package_swift( + package_path: File.join(PROJECT_ROOT_FOLDER, 'Modules', 'Package.swift') +) + content = File.read(package_path) + + # Remove any line containing Wormholy. + # + # This relies on Package.swift being straightforward in how it defines dependencies. + # Given the code is only for usage in this repo at this time, it seems safe to do. + # + # This also assumes no other dependency, target, etc. includes "Wormholy" in its name. + # That also seem safe. + cleaned_content = content.lines.reject do |line| + line.include? 'Wormholy' + end.join + + File.write(package_path, cleaned_content) + UI.success("Stripped Wormholy from #{package_path}") +end