iOS build fixes/prep for TestFlight

This commit is contained in:
Juan José Mata
2026-02-18 10:11:16 +01:00
parent 3b0b2f7ada
commit 65f1daa995
7 changed files with 250 additions and 4 deletions

View File

@@ -151,6 +151,9 @@ The app includes automated CI/CD via GitHub Actions (`.github/workflows/flutter-
- **Android Build**: Generates release APK and AAB artifacts
- **iOS Build**: Generates iOS release build (unsigned)
- **Quality Checks**: Code analysis and tests run before building
- **TestFlight**: Use `.github/workflows/ios-testflight.yml` for signed distribution uploads to App Store Connect
See [mobile/docs/iOS_TESTFLIGHT](mobile/docs/iOS_TESTFLIGHT.md) for required secrets and setup.
### Downloading Build Artifacts

View File

@@ -0,0 +1,47 @@
# iOS TestFlight GitHub Action
This repository now includes `.github/workflows/ios-testflight.yml`, which builds a **signed** iOS IPA and uploads it to TestFlight.
## What must be in the repo
- The workflow file itself: `.github/workflows/ios-testflight.yml`
- Existing app signing identifiers in Xcode:
- Bundle ID `am.sure.mobile` (or your custom value in the workflow)
- Flutter assets and source already in `mobile/`
## Required GitHub Secrets
Set these in **Settings → Secrets and variables → Actions**:
- `APP_STORE_CONNECT_API_KEY_ID`
- `APP_STORE_CONNECT_API_ISSUER_ID`
- `APP_STORE_CONNECT_API_KEY_BASE64`
- Base64 version of the `.p8` private key content
- `IOS_TEAM_ID`
- `IOS_KEYCHAIN_PASSWORD`
- `IOS_DISTRIBUTION_P12_BASE64`
- `IOS_DISTRIBUTION_P12_PASSWORD`
- `IOS_DISTRIBUTION_CERT_NAME`
- Usually `iPhone Distribution`
- `IOS_PROVISIONING_PROFILE_NAME`
- `IOS_PROVISIONING_PROFILE_BASE64`
> Do **not** commit private keys, `.p12` files, or `.p8` files to the repository.
## Triggering
- Run manually: **Actions → iOS TestFlight → Run workflow**
- Push a tag that matches `ios-v*` (for example `ios-v1.2.3`)
## Recommended App Store Connect setup
- Use an API Key with App Manager or Developer role
- Create/download an iOS Distribution certificate (`.p12`), convert to base64 for `IOS_DISTRIBUTION_P12_BASE64`
- Create and distribute an **App Store** provisioning profile for `am.sure.mobile`
- Base64-encode the `.mobileprovision` file for `IOS_PROVISIONING_PROFILE_BASE64`
## Output
- IPA artifact: `ios-ipa-testflight`
- Uploaded IPA to TestFlight on successful upload step

View File

@@ -1,2 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"
#include "Generated.xcconfig"

View File

@@ -1,2 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@@ -37,6 +37,7 @@
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8D7D5C9B2EAF8B6A00F0A1B3 /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Profile.xcconfig; path = Flutter/Profile.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -68,7 +69,6 @@
FE30D351EF409EF61606DE07 /* Pods-Runner.release.xcconfig */,
1DC166D4710E23F2EDEDA52D /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
@@ -86,6 +86,7 @@
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
8D7D5C9B2EAF8B6A00F0A1B3 /* Profile.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
@@ -357,21 +358,28 @@
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
baseConfigurationReference = 8D7D5C9B2EAF8B6A00F0A1B3 /* Profile.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = C8WT3YC922;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Sure Finances";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = am.sure.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
@@ -494,17 +502,24 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = C8WT3YC922;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Sure Finances";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = am.sure.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@@ -516,16 +531,23 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = C8WT3YC922;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Sure Finances";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = am.sure.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;