feat(ci): Add iOS GitHub Actions workflows for automated builds and d…#3108
feat(ci): Add iOS GitHub Actions workflows for automated builds and d…#3108taymournajy wants to merge 1 commit intoopenMF:developmentfrom
Conversation
…istribution - Add ios-build.yml workflow for development builds with Debug/Release configs - Add ios-release.yml workflow with Firebase, TestFlight, and App Store distribution - Add comprehensive README-iOS-Builds.md documentation - Add exportOptions.plist for IPA export configuration - Support manual dispatch and automated builds on push/PR - Include code signing setup for production releases
📝 WalkthroughWalkthroughThe PR adds iOS build infrastructure including two GitHub Actions workflows for development and release builds, comprehensive documentation outlining workflows and setup, and iOS export configuration settings. Total: 4 new files with 579 lines of changes. Changes
Sequence DiagramssequenceDiagram
participant GitHub as GitHub Actions
participant macOS as macOS Runner
participant Xcode as Xcode
participant CocoaPods as CocoaPods
participant Gradle as Gradle
participant Artifact as Artifact Storage
GitHub->>macOS: Trigger build workflow
macOS->>macOS: Checkout code
macOS->>Gradle: Setup JDK 21 & build<br/>shared KMP XCFramework
Gradle-->>macOS: XCFramework ready
macOS->>CocoaPods: Install dependencies
CocoaPods-->>macOS: Pods installed
macOS->>Xcode: Build iOS app<br/>(Debug/Release)
Xcode-->>macOS: App binary created
alt create_ipa = true
macOS->>Xcode: Create & export IPA
Xcode-->>Artifact: Upload IPA artifact
end
macOS->>GitHub: Post build summary
sequenceDiagram
participant GitHub as GitHub Actions
participant macOS as macOS Runner
participant Xcode as Xcode
participant Certs as Code Signing
participant Fastlane as Fastlane
participant Firebase as Firebase
participant AppStore as App Store/TestFlight
participant Artifact as Artifact Storage
GitHub->>macOS: Trigger release workflow
macOS->>macOS: Checkout & setup<br/>(JDK, Xcode, CocoaPods)
alt distribution != firebase
macOS->>Certs: Import signing certificates
Certs-->>macOS: Certificates ready
end
macOS->>Fastlane: Install Fastlane
macOS->>Xcode: Build & sign iOS app
Xcode-->>macOS: Signed app ready
alt distribution_method = firebase
macOS->>Fastlane: Run Firebase lane
Fastlane->>Firebase: Upload to Firebase
Firebase-->>macOS: Distribution complete
else distribution_method = testflight
macOS->>Fastlane: Run TestFlight lane
Fastlane->>AppStore: Upload to TestFlight
AppStore-->>macOS: Upload complete
else distribution_method = appstore
macOS->>Fastlane: Run AppStore lane
Fastlane->>AppStore: Submit to App Store
AppStore-->>macOS: Submission complete
end
macOS->>Artifact: Upload IPA artifact
macOS->>GitHub: Post distribution summary
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In @.github/workflows/ios-build.yml:
- Around line 31-40: The pull_request trigger's path filter is missing the
workflow file so PRs that only modify the workflow won't run; update the
pull_request block (the pull_request trigger and its paths array) to include
".github/workflows/ios-build.yml" alongside the other path entries so
workflow-only PRs will trigger the job.
- Around line 114-135: The Create IPA Archive step hardcodes -configuration
Release and disables code signing which conflicts with exportOptions.plist
(method=development); update the archive xcodebuild invocation to use the
user-selected configuration (replace -configuration Release with -configuration
${{ inputs.build_configuration }} or the equivalent BUILD_CONFIGURATION variable
used earlier) and align code signing flags with the export method (either enable
signing by setting CODE_SIGNING_ALLOWED=YES and supply
CODE_SIGN_IDENTITY/PROVISIONING_PROFILE variables when using method=development,
or change exportOptions.plist to a method that doesn't require signing); ensure
the same configuration and signing settings are used in both the earlier build
step and the archive/export steps so the IPA matches the chosen
build_configuration and the export will succeed.
In @.github/workflows/ios-release.yml:
- Around line 63-80: The workflow sets CERTIFICATES_P12 to the wrong secret (it
uses secrets.CERTIFICATES_PASSWORD) so the base64 P12 will be the password and
security import will fail; change the env mapping to set CERTIFICATES_P12 to the
base64 certificate secret (e.g., secrets.CERTIFICATES_P12) while keeping
CERTIFICATE_PASSWORD mapped to secrets.CERTIFICATES_PASSWORD, then ensure the
decode/import steps that use CERTIFICATES_P12 and the security import commands
(security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD"
...) remain unchanged; also update the README Required Secrets section to
document the CERTIFICATES_P12 secret as the base64-encoded distribution
certificate.
- Around line 41-57: Add a Gradle cache step immediately after the "Cache
CocoaPods" step to avoid re-downloading dependencies for the ./gradlew
:cmp-shared:assembleXCFramework run; use actions/cache@v4 targeting Gradle
folders (e.g., ~/.gradle/caches and ~/.gradle/wrapper) with a key like ${{
runner.os }}-gradle-${{ hashFiles('**/*.gradle*','**/gradle-wrapper.properties')
}} and a suitable restore-keys fallback so the Gradle wrapper and dependency
caches persist across macOS runs and speed up the gradle invocation in the
"Build KMP Shared Framework" step.
- Around line 122-131: The Distribution Summary step currently echoes `${{
inputs.release_notes }}` directly into the shell which is a script-injection
risk; change the job/step to map `inputs.release_notes` into an environment
variable (e.g., RELEASE_NOTES) and use that env var in the step instead of
interpolating the input directly; update the step that writes to
GITHUB_STEP_SUMMARY (the "Distribution Summary" step) to reference
$RELEASE_NOTES when echoing Release Notes and ensure the env var is declared in
the step's env block so GITHUB Actions passes the value safely.
- Around line 103-113: The "Distribute to Firebase" step uses the firebase CLI
and interpolates inputs.release_notes directly into the shell; add a preceding
step to install the CLI (e.g., run npm install -g firebase-tools) so the
firebase command is available, and change the distribute step to pass release
notes via an environment variable (e.g., set RELEASE_NOTES from
inputs.release_notes and use "$RELEASE_NOTES" in the script) to avoid shell
injection; keep existing env vars FIREBASE_APP_ID and FIREBASE_TOKEN and ensure
the install step runs before the firebase appdistribution:distribute invocation.
In `@cmp-ios/exportOptions.plist`:
- Around line 1-14: The exportOptions.plist currently forces method=development
and signingStyle=automatic while your CI sets CODE_SIGNING_ALLOWED=NO, which
will cause xcodebuild -exportArchive to fail when create_ipa is true; either
enable signing in the archive step or stop exporting an IPA for unsigned
archives. Fix by making the behavior conditional: when the pipeline flag
create_ipa is true and CODE_SIGNING_ALLOWED is not NO, keep <key>method</key>
value "development" and <key>signingStyle</key> "automatic" and ensure
provisioning is provided; otherwise, change the workflow to skip IPA export and
produce an unsigned .app (or remove/replace method/signingStyle from
exportOptions.plist) so xcodebuild -exportArchive is not invoked with an
unsigned archive. Ensure you update references to exportOptions.plist (method
and signingStyle) and the ios-build.yml create_ipa/CODE_SIGNING_ALLOWED logic
accordingly.
🧹 Nitpick comments (2)
.github/workflows/ios-build.yml (1)
50-80: Duplicate Gradle caching.
actions/setup-javawithcache: 'gradle'(line 55) already caches Gradle dependencies. The separateCache Gradlestep (lines 72–80) is redundant. Pick one approach — usingsetup-java's built-in cache is simpler and sufficient. Note thatios-release.ymlusessetup-javawithcache: 'gradle'but has no separate Gradle cache step, so removing lines 72–80 would also improve consistency..github/workflows/README-iOS-Builds.md (1)
71-92: Add language specifiers to fenced code blocks.Static analysis (markdownlint MD040) flags multiple fenced code blocks without a language identifier. Use
```textfor plain-text blocks like secret lists and UI navigation paths (lines 71, 79, 89, 101, 121, 208).
| pull_request: | ||
| branches: | ||
| - development | ||
| - main | ||
| paths: | ||
| - 'cmp-ios/**' | ||
| - 'cmp-shared/**' | ||
| - 'core/**' | ||
| - 'feature/**' | ||
|
|
There was a problem hiding this comment.
PR path filter missing the workflow file itself.
The push trigger (line 29) includes .github/workflows/ios-build.yml in its path filter, but the pull_request trigger (lines 36–39) does not. This means PRs that only modify this workflow file won't trigger it, making it impossible to test workflow changes via PR builds.
♻️ Proposed fix
paths:
- 'cmp-ios/**'
- 'cmp-shared/**'
- 'core/**'
- 'feature/**'
+ - '.github/workflows/ios-build.yml'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pull_request: | |
| branches: | |
| - development | |
| - main | |
| paths: | |
| - 'cmp-ios/**' | |
| - 'cmp-shared/**' | |
| - 'core/**' | |
| - 'feature/**' | |
| pull_request: | |
| branches: | |
| - development | |
| - main | |
| paths: | |
| - 'cmp-ios/**' | |
| - 'cmp-shared/**' | |
| - 'core/**' | |
| - 'feature/**' | |
| - '.github/workflows/ios-build.yml' |
🤖 Prompt for AI Agents
In @.github/workflows/ios-build.yml around lines 31 - 40, The pull_request
trigger's path filter is missing the workflow file so PRs that only modify the
workflow won't run; update the pull_request block (the pull_request trigger and
its paths array) to include ".github/workflows/ios-build.yml" alongside the
other path entries so workflow-only PRs will trigger the job.
| - name: Create IPA Archive | ||
| if: inputs.create_ipa == true | ||
| working-directory: cmp-ios | ||
| run: | | ||
| echo "Creating IPA archive..." | ||
|
|
||
| xcodebuild \ | ||
| -workspace iosApp.xcworkspace \ | ||
| -scheme iosApp \ | ||
| -configuration Release \ | ||
| -archivePath ./build/iosApp.xcarchive \ | ||
| archive \ | ||
| CODE_SIGN_IDENTITY="" \ | ||
| CODE_SIGNING_REQUIRED=NO \ | ||
| CODE_SIGNING_ALLOWED=NO | ||
|
|
||
| # Export archive to IPA | ||
| xcodebuild \ | ||
| -exportArchive \ | ||
| -archivePath ./build/iosApp.xcarchive \ | ||
| -exportPath ./build/ipa \ | ||
| -exportOptionsPlist ./exportOptions.plist |
There was a problem hiding this comment.
IPA archive hardcodes Release configuration, ignoring the user-selected build_configuration.
Line 123 hardcodes -configuration Release for the archive step, but the preceding build step (line 99) uses the user-selected configuration. If a user selects Debug and enables create_ipa, the app is built in Debug mode first, then archived again in Release mode — doubling the build time and producing an IPA that doesn't match the configuration they selected.
Additionally, as noted in the exportOptions.plist review, the archive is built without code signing (CODE_SIGNING_ALLOWED=NO) but the export step uses method=development which requires a signed archive — this will fail at export time.
♻️ Proposed fix for configuration consistency
xcodebuild \
-workspace iosApp.xcworkspace \
-scheme iosApp \
- -configuration Release \
+ -configuration ${{ inputs.build_configuration || 'Release' }} \
-archivePath ./build/iosApp.xcarchive \
archive \📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Create IPA Archive | |
| if: inputs.create_ipa == true | |
| working-directory: cmp-ios | |
| run: | | |
| echo "Creating IPA archive..." | |
| xcodebuild \ | |
| -workspace iosApp.xcworkspace \ | |
| -scheme iosApp \ | |
| -configuration Release \ | |
| -archivePath ./build/iosApp.xcarchive \ | |
| archive \ | |
| CODE_SIGN_IDENTITY="" \ | |
| CODE_SIGNING_REQUIRED=NO \ | |
| CODE_SIGNING_ALLOWED=NO | |
| # Export archive to IPA | |
| xcodebuild \ | |
| -exportArchive \ | |
| -archivePath ./build/iosApp.xcarchive \ | |
| -exportPath ./build/ipa \ | |
| -exportOptionsPlist ./exportOptions.plist | |
| - name: Create IPA Archive | |
| if: inputs.create_ipa == true | |
| working-directory: cmp-ios | |
| run: | | |
| echo "Creating IPA archive..." | |
| xcodebuild \ | |
| -workspace iosApp.xcworkspace \ | |
| -scheme iosApp \ | |
| -configuration ${{ inputs.build_configuration || 'Release' }} \ | |
| -archivePath ./build/iosApp.xcarchive \ | |
| archive \ | |
| CODE_SIGN_IDENTITY="" \ | |
| CODE_SIGNING_REQUIRED=NO \ | |
| CODE_SIGNING_ALLOWED=NO | |
| # Export archive to IPA | |
| xcodebuild \ | |
| -exportArchive \ | |
| -archivePath ./build/iosApp.xcarchive \ | |
| -exportPath ./build/ipa \ | |
| -exportOptionsPlist ./exportOptions.plist |
🤖 Prompt for AI Agents
In @.github/workflows/ios-build.yml around lines 114 - 135, The Create IPA
Archive step hardcodes -configuration Release and disables code signing which
conflicts with exportOptions.plist (method=development); update the archive
xcodebuild invocation to use the user-selected configuration (replace
-configuration Release with -configuration ${{ inputs.build_configuration }} or
the equivalent BUILD_CONFIGURATION variable used earlier) and align code signing
flags with the export method (either enable signing by setting
CODE_SIGNING_ALLOWED=YES and supply CODE_SIGN_IDENTITY/PROVISIONING_PROFILE
variables when using method=development, or change exportOptions.plist to a
method that doesn't require signing); ensure the same configuration and signing
settings are used in both the earlier build step and the archive/export steps so
the IPA matches the chosen build_configuration and the export will succeed.
| - name: Cache CocoaPods | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| cmp-ios/Pods | ||
| ~/Library/Caches/CocoaPods | ||
| key: ${{ runner.os }}-pods-${{ hashFiles('cmp-ios/Podfile.lock') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-pods- | ||
|
|
||
| - name: Grant execute permission for gradlew | ||
| run: chmod +x gradlew | ||
|
|
||
| - name: Build KMP Shared Framework | ||
| run: | | ||
| echo "Building shared framework for iOS..." | ||
| ./gradlew :cmp-shared:assembleXCFramework |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Missing Gradle cache — adds unnecessary build time on macOS runners.
Unlike ios-build.yml which caches both CocoaPods and Gradle, this workflow only caches CocoaPods. The ./gradlew :cmp-shared:assembleXCFramework step (line 57) will re-download all Gradle dependencies on every run. macOS runners are more expensive, so caching matters here.
♻️ Proposed fix — add Gradle cache
Add after the CocoaPods cache step:
+ - name: Cache Gradle
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+
- name: Grant execute permission for gradlew
run: chmod +x gradlew📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Cache CocoaPods | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| cmp-ios/Pods | |
| ~/Library/Caches/CocoaPods | |
| key: ${{ runner.os }}-pods-${{ hashFiles('cmp-ios/Podfile.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pods- | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x gradlew | |
| - name: Build KMP Shared Framework | |
| run: | | |
| echo "Building shared framework for iOS..." | |
| ./gradlew :cmp-shared:assembleXCFramework | |
| - name: Cache CocoaPods | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| cmp-ios/Pods | |
| ~/Library/Caches/CocoaPods | |
| key: ${{ runner.os }}-pods-${{ hashFiles('cmp-ios/Podfile.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pods- | |
| - name: Cache Gradle | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x gradlew | |
| - name: Build KMP Shared Framework | |
| run: | | |
| echo "Building shared framework for iOS..." | |
| ./gradlew :cmp-shared:assembleXCFramework |
🤖 Prompt for AI Agents
In @.github/workflows/ios-release.yml around lines 41 - 57, Add a Gradle cache
step immediately after the "Cache CocoaPods" step to avoid re-downloading
dependencies for the ./gradlew :cmp-shared:assembleXCFramework run; use
actions/cache@v4 targeting Gradle folders (e.g., ~/.gradle/caches and
~/.gradle/wrapper) with a key like ${{ runner.os }}-gradle-${{
hashFiles('**/*.gradle*','**/gradle-wrapper.properties') }} and a suitable
restore-keys fallback so the Gradle wrapper and dependency caches persist across
macOS runs and speed up the gradle invocation in the "Build KMP Shared
Framework" step.
| - name: Import Code Signing Certificates | ||
| if: inputs.distribution_method != 'firebase' | ||
| env: | ||
| CERTIFICATES_P12: ${{ secrets.CERTIFICATES_PASSWORD }} | ||
| CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATES_PASSWORD }} | ||
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | ||
| run: | | ||
| # Create keychain | ||
| security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | ||
| security default-keychain -s build.keychain | ||
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | ||
| security set-keychain-settings -t 3600 -u build.keychain | ||
|
|
||
| # Import certificate | ||
| echo "$CERTIFICATES_P12" | base64 --decode > certificate.p12 | ||
| security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign | ||
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain | ||
| rm certificate.p12 |
There was a problem hiding this comment.
CERTIFICATES_P12 is mapped to the wrong secret — certificate import will fail.
Both CERTIFICATES_P12 (line 66) and CERTIFICATE_PASSWORD (line 67) reference secrets.CERTIFICATES_PASSWORD. The P12 environment variable should contain the base64-encoded certificate data, not the password. Line 77 decodes this value as a certificate file, which will produce an invalid .p12 and the security import will fail.
🐛 Proposed fix
env:
- CERTIFICATES_P12: ${{ secrets.CERTIFICATES_PASSWORD }}
+ CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATES_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}Also update the README's "Required Secrets" section to document the CERTIFICATES_P12 secret (the base64-encoded distribution certificate).
🤖 Prompt for AI Agents
In @.github/workflows/ios-release.yml around lines 63 - 80, The workflow sets
CERTIFICATES_P12 to the wrong secret (it uses secrets.CERTIFICATES_PASSWORD) so
the base64 P12 will be the password and security import will fail; change the
env mapping to set CERTIFICATES_P12 to the base64 certificate secret (e.g.,
secrets.CERTIFICATES_P12) while keeping CERTIFICATE_PASSWORD mapped to
secrets.CERTIFICATES_PASSWORD, then ensure the decode/import steps that use
CERTIFICATES_P12 and the security import commands (security import
certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" ...) remain
unchanged; also update the README Required Secrets section to document the
CERTIFICATES_P12 secret as the base64-encoded distribution certificate.
| - name: Distribute to Firebase | ||
| if: inputs.distribution_method == 'firebase' | ||
| env: | ||
| FIREBASE_APP_ID: ${{ secrets.FIREBASE_IOS_APP_ID }} | ||
| FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} | ||
| run: | | ||
| firebase appdistribution:distribute \ | ||
| cmp-ios/build/iosApp.ipa \ | ||
| --app "$FIREBASE_APP_ID" \ | ||
| --release-notes "${{ inputs.release_notes }}" \ | ||
| --groups "mifos-mobile-apps" |
There was a problem hiding this comment.
Two issues: Firebase CLI not installed, and script injection risk via release_notes.
-
Missing Firebase CLI installation: The
firebasecommand (line 109) is used but never installed. Add a step to install it (e.g.,npm install -g firebase-tools). -
Script injection via
release_notes: On line 112,${{ inputs.release_notes }}is directly interpolated into the shell script. Since this is a free-text input, a user could inject arbitrary shell commands. Use an environment variable instead.
🔒 Proposed fix
Add a Firebase CLI installation step before the distribute step:
+ - name: Install Firebase CLI
+ if: inputs.distribution_method == 'firebase'
+ run: npm install -g firebase-tools
+
- name: Distribute to Firebase
if: inputs.distribution_method == 'firebase'
env:
FIREBASE_APP_ID: ${{ secrets.FIREBASE_IOS_APP_ID }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
+ RELEASE_NOTES: ${{ inputs.release_notes }}
run: |
firebase appdistribution:distribute \
cmp-ios/build/iosApp.ipa \
--app "$FIREBASE_APP_ID" \
- --release-notes "${{ inputs.release_notes }}" \
+ --release-notes "$RELEASE_NOTES" \
--groups "mifos-mobile-apps"🤖 Prompt for AI Agents
In @.github/workflows/ios-release.yml around lines 103 - 113, The "Distribute to
Firebase" step uses the firebase CLI and interpolates inputs.release_notes
directly into the shell; add a preceding step to install the CLI (e.g., run npm
install -g firebase-tools) so the firebase command is available, and change the
distribute step to pass release notes via an environment variable (e.g., set
RELEASE_NOTES from inputs.release_notes and use "$RELEASE_NOTES" in the script)
to avoid shell injection; keep existing env vars FIREBASE_APP_ID and
FIREBASE_TOKEN and ensure the install step runs before the firebase
appdistribution:distribute invocation.
| - name: Distribution Summary | ||
| if: success() | ||
| run: | | ||
| echo "### ✅ iOS Release Build Successful!" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Distribution Method:** ${{ inputs.distribution_method }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Configuration:** Release" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Build Number:** #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Release Notes:** ${{ inputs.release_notes }}" >> $GITHUB_STEP_SUMMARY |
There was a problem hiding this comment.
release_notes should also use an env var in the summary step.
Line 131 directly interpolates ${{ inputs.release_notes }} into the shell script. While the risk here (writing to $GITHUB_STEP_SUMMARY) is lower than in the Firebase distribute step, it's still a script injection vector. For consistency and defense-in-depth, use an environment variable here as well.
🛡️ Proposed fix
- name: Distribution Summary
if: success()
+ env:
+ RELEASE_NOTES: ${{ inputs.release_notes }}
run: |
echo "### ✅ iOS Release Build Successful!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Distribution Method:** ${{ inputs.distribution_method }}" >> $GITHUB_STEP_SUMMARY
echo "**Configuration:** Release" >> $GITHUB_STEP_SUMMARY
echo "**Build Number:** #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Release Notes:** ${{ inputs.release_notes }}" >> $GITHUB_STEP_SUMMARY
+ echo "**Release Notes:** $RELEASE_NOTES" >> $GITHUB_STEP_SUMMARY🤖 Prompt for AI Agents
In @.github/workflows/ios-release.yml around lines 122 - 131, The Distribution
Summary step currently echoes `${{ inputs.release_notes }}` directly into the
shell which is a script-injection risk; change the job/step to map
`inputs.release_notes` into an environment variable (e.g., RELEASE_NOTES) and
use that env var in the step instead of interpolating the input directly; update
the step that writes to GITHUB_STEP_SUMMARY (the "Distribution Summary" step) to
reference $RELEASE_NOTES when echoing Release Notes and ensure the env var is
declared in the step's env block so GITHUB Actions passes the value safely.
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <key>method</key> | ||
| <string>development</string> | ||
| <key>compileBitcode</key> | ||
| <false/> | ||
| <key>uploadSymbols</key> | ||
| <false/> | ||
| <key>signingStyle</key> | ||
| <string>automatic</string> | ||
| </dict> | ||
| </plist> |
There was a problem hiding this comment.
Unsigned archive + method=development export will likely fail.
In ios-build.yml (lines 120–135), the archive is created with CODE_SIGNING_ALLOWED=NO, but this plist specifies method=development with signingStyle=automatic. The xcodebuild -exportArchive step requires a signed archive when method is set to development—it needs a valid provisioning profile to produce the IPA. Since the archive is unsigned, the export will fail with a signing error.
Either:
- Sign the archive properly when
create_ipais true (provide provisioning for dev builds), or - Change the approach to produce a
.appbundle instead of an IPA for unsigned dev builds.
🤖 Prompt for AI Agents
In `@cmp-ios/exportOptions.plist` around lines 1 - 14, The exportOptions.plist
currently forces method=development and signingStyle=automatic while your CI
sets CODE_SIGNING_ALLOWED=NO, which will cause xcodebuild -exportArchive to fail
when create_ipa is true; either enable signing in the archive step or stop
exporting an IPA for unsigned archives. Fix by making the behavior conditional:
when the pipeline flag create_ipa is true and CODE_SIGNING_ALLOWED is not NO,
keep <key>method</key> value "development" and <key>signingStyle</key>
"automatic" and ensure provisioning is provided; otherwise, change the workflow
to skip IPA export and produce an unsigned .app (or remove/replace
method/signingStyle from exportOptions.plist) so xcodebuild -exportArchive is
not invoked with an unsigned archive. Ensure you update references to
exportOptions.plist (method and signingStyle) and the ios-build.yml
create_ipa/CODE_SIGNING_ALLOWED logic accordingly.
|
Closing this on behalf of #3122 |
…istribution
Fixes - Jira-#Issue_Number
Didn't create a Jira ticket, click here to create new.
Please Add Screenshots If there are any UI changes.
Please make sure these boxes are checked before submitting your pull request - thanks!
Run the static analysis check
./gradlew checkorci-prepush.shto make sure you didn't break anythingIf you have multiple commits please combine them into one commit by squashing them.
Summary by CodeRabbit
Documentation
Chores