Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat setup release pipeline ios #10

Merged
merged 18 commits into from
May 27, 2024
Merged
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
17 changes: 11 additions & 6 deletions .github/actions/build_ios/action.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
name: 'Build iOS App'
description: 'Builds the iOS app using Fastlane'
name: 'Build & Upload iOS App'
description: 'Build and upload the iOS app using Fastlane'

runs:
using: 'composite'

steps:
- name: Hello Function
run: echo "Hello!"
shell: bash

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'

- name: Install Fastlane
run: gem install fastlane
shell: bash

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc

- name: Run Fastlane
run: cd ios && fastlane ios release
shell: bash
12 changes: 10 additions & 2 deletions .github/workflows/build_ios.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "iOS Test"
name: "Build & Upload iOS App"

on:
push:
Expand All @@ -16,5 +16,13 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3

- name: Build iOS
- name: Build & Upload iOS App
uses: ./.github/actions/build_ios
env:
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
APP_STORE_CONNECT_KEY_CONTENT: ${{ secrets.APP_STORE_CONNECT_KEY_CONTENT }}
6 changes: 3 additions & 3 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
boost: 57d2868c099736d80fcd648bf211b4431e51a558
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
Expand Down Expand Up @@ -1141,7 +1141,7 @@ SPEC CHECKSUMS:
Permission-PhotoLibrary: ddb5a158725b29cb12e9e477e8a5f5151c66cc3c
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
QRCodeReader.swift: 373a389fe9a22d513c879a32a6f647c58f4ef572
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
RCTRequired: 83bca1c184feb4d2e51c72c8369b83d641443f95
RCTTypeSafety: 13c4a87a16d7db6cd66006ce9759f073402ef85b
React: e67aa9f99957c7611c392b5e49355d877d6525e2
Expand Down Expand Up @@ -1225,4 +1225,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 5aa659dbdffe4dac60d7c41c77158d6182cc0f9c

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
6 changes: 3 additions & 3 deletions ios/developerapp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 23;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = BC32QNM6AD;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = BC32QNM6AD;
Expand Down Expand Up @@ -803,7 +803,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 23;
DEVELOPMENT_TEAM = BC32QNM6AD;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = BC32QNM6AD;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -1068,7 +1068,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 23;
DEVELOPMENT_TEAM = BC32QNM6AD;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = BC32QNM6AD;
ENABLE_BITCODE = NO;
Expand Down
4 changes: 1 addition & 3 deletions ios/fastlane/Appfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
app_identifier "com.mendix.developerapp.native.mx10" # The bundle identifier of your app
app_identifier("com.mendix.developerapp.native.mx10")

team_id "BC32QNM6AD" # Developer Portal Team ID

# More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md
218 changes: 42 additions & 176 deletions ios/fastlane/Fastfile
Original file line number Diff line number Diff line change
@@ -1,212 +1,78 @@
# If you want to automatically update fastlane if a new version is available:
#update_fastlane

# This is the minimum version number required.
# Update this, if you use features of a newer version
fastlane_version "2.213.0"

default_platform :ios

# Constants
APPLE_STORE_VERSION = sh("node -p -e \"require('../../package.json')['store-versions']['apple-store']\"").chomp
BUILD_NUMBER = 1
ORIGINAL_CHANGELOG_PATH = "../../CHANGELOG.ios.txt"
FASTLANE_CHANGELOG_PATH = "./metadata/default/release_notes.txt"

platform :ios do
lane :install_dev_certificate do
# Improve DX. We cannot use an empty password, so we use the public password.
ENV["MATCH_PASSWORD"] = "AppleDeveloper1!"
match(
type: "development",
git_branch: "appdev",
profile_name: "Make It Native 9 Dev (Match)",
readonly: true,
)
end

desc "Build an internal version for automation"
desc "It always uses v.0.0.0 and build number 0 by design"
lane :internal do
sh("npm", "ci", "--legacy-peer-deps")
cocoapods
increment_version_number(
version_number: "0.0.0",
)
gym(scheme: "DeveloperApp", configuration: "ReleaseDevToolsEnabled", export_method: "development", build_path: "./builds/internal/intermediate", output_directory: "./builds/internal/output")
end
default_platform(:ios)

desc "Builds and install DeveloperApp into the simulator"
desc "This will use iPhone 13 Pro simulator with OS 15.5"
lane :debug_internal do
UI.message("Installing dependencies")
sh("npm", "i", "--legacy-peer-deps")
cocoapods
UI.message("Building and installing DeveloperApp")
gym(
scheme: "DeveloperApp",
configuration: "Debug",
skip_package_ipa: true,
skip_package_pkg: true,
sdk: "iphonesimulator",
destination: "platform=iOS Simulator,name=iPhone 13 Pro,OS=15.5",
xcargs: "ONLY_ACTIVE_ARCH=NO",
platform :ios do
desc "Upload a new build to AppStore"
lane :release do
keychain_name = "MiN_10_keychain"
create_keychain(
name: keychain_name,
default_keychain: true,
unlock: true,
timeout: 3600,
password: ENV["KEYCHAIN_PASSWORD"],
lock_when_sleeps: false
)
end

desc "Submit a new Beta Build to Apple TestFlight"
desc "This will also make sure the profile is up to date"
lane :beta do |options|
keychain_name = "min_10_ios"
sh("npm", "ci", "--legacy-peer-deps")
cocoapods

UI.message("Connect API key")
app_store_connect_api_key(
is_key_content_base64: true,
)

create_keychain(
name: keychain_name,
unlock: true,
timeout: 0,
default_keychain: true,
api_key = app_store_connect_api_key(
key_id: ENV["APP_STORE_CONNECT_KEY_ID"],
issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
key_content: ENV["APP_STORE_CONNECT_KEY_CONTENT"],
duration: 1200, # Session Length in seconds (maximum: 1200).
)

UI.message("Retrieve iOS certificate and profile")
UI.message("Disabling automatic signing on Xcode")
disable_automatic_code_signing

UI.message("Get the certificates and profiles")
match(
type: "appstore",
keychain_name: keychain_name,
type:"appstore",
api_key:api_key,
keychain_name:keychain_name,
keychain_password: ENV["KEYCHAIN_PASSWORD"],
profile_name: "match AppStore com.mendix.developerapp.native.mx10",
readonly: true,
git_basic_authorization:ENV["MATCH_GIT_BASIC_AUTHORIZATION"],
readonly: false,
)

UI.message("Set version number")
increment_version_number(
version_number: APPLE_STORE_VERSION,
)

UI.message("Set build number")
increment_build_number(
build_number: app_store_build_number(live: false, version: APPLE_STORE_VERSION, initial_build_number: 0) + 1,
UI.message("Get the latest build number from AppStore Connect")
build_num = app_store_build_number(
live: false,
initial_build_number: 0,
api_key: api_key,
version: APPLE_STORE_VERSION,
)

unlock_keychain( # Unlock an existing keychain and add it to the keychain search list
path: keychain_name,
password: ENV["KEYCHAIN_PASSWORD"],
)

update_project_provisioning(
UI.message("Set build number")
increment_build_number(
xcodeproj: "developerapp.xcodeproj",
code_signing_identity: "Apple Distribution",
profile: ENV["sigh_com.mendix.developerapp.native.mx10_appstore_profile-path"],
build_configuration: "Release",
target_filter: "DeveloperApp",
build_number: build_num + 1,
)


UI.message("Replacing Google Maps API key from environment variables")
Dir.chdir("../DeveloperApp/Config") do
googleMapsApiKey = ENV["GOOGLE_MAPS_API_KEY"] || "GOOGLE_MAPS_API_KEY"
sh("sed -i '' 's/{{google-maps-api-key}}/#{googleMapsApiKey}/g' ApiKeys.xcconfig")
end

UI.message("Build iOS app")
gym(
build_app(
workspace: "DeveloperApp.xcworkspace",
scheme: "DeveloperApp",
export_method: "app-store",
configuration: "Release",
output_directory: "./build/beta/output",
)

if options[:submit] == true
UI.message("Send iOS app to TestFlight")
pilot(
groups: ["Internal Testers"],
skip_submission: true,
skip_waiting_for_build_processing: true,
distribute_external: false
)
end

UI.message("Copy artifacts")
copy_artifacts(
target_path: "../artifacts",
artifacts: ["./build/beta/output/DeveloperApp.ipa",
"./build/beta/output/DeveloperApp.app.dSYM.zip"],
)
end

lane :beta_manually do
sh("npm", "ci", "--legacy-peer-deps")
cocoapods

UI.message("Retrieve iOS certificate and profile")
match(
type: "appstore",
profile_name: "match AppStore com.mendix.developerapp.native.mx10",
readonly: true,
)

UI.message("Set version number")
increment_version_number(
version_number: APPLE_STORE_VERSION,
build_path:"./build",
output_directory:"./build"
)

UI.message("Set build number")
increment_build_number(
build_number: app_store_build_number(live: false, version: APPLE_STORE_VERSION, initial_build_number: 0) + 1,
)

UI.message("Build iOS app")
gym(
scheme: "DeveloperApp",
export_method: "app-store",
configuration: "Release",
output_directory: "./build/beta/output",
)

UI.message("Send iOS app to TestFlight")
pilot(
skip_submission: true,
upload_to_testflight(
skip_waiting_for_build_processing: true,
)

UI.message("Copy artifacts")
copy_artifacts(
target_path: "../artifacts",
artifacts: ["./build/beta/output/DeveloperApp.ipa",
"./build/beta/output/DeveloperApp.app.dSYM.zip"],
)
end

desc "Send appstore version to review"
lane :promote_to_production do |options|
if !options[:build_number]
UI.user_error!("build_number is required to release app")
end

FileUtils.copy(ORIGINAL_CHANGELOG_PATH, FASTLANE_CHANGELOG_PATH)

UI.message("Connect API key")
app_store_connect_api_key(
is_key_content_base64: true,
)

deliver(
app_version: APPLE_STORE_VERSION,
build_number: options[:build_number],
submit_for_review: true,
automatic_release: true,
force: true,
skip_metadata: false,
skip_screenshots: true,
skip_binary_upload: true,
precheck_include_in_app_purchases: false,
submission_information: {
add_id_info_uses_idfa: false,
export_compliance_uses_encryption: false,
},
)
end
end
10 changes: 3 additions & 7 deletions ios/fastlane/Matchfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
git_url("git@ssh.gitlab.rnd.mendix.com:mobile-offline/ios-credentials-min-10.git")

git_url("https://github.com/mendix/make-it-native-ios-credentials.git")
storage_mode("git")

type("appstore") # The default type, can be: appstore, adhoc, enterprise or development

app_identifier(["com.mendix.developerapp.native.mx10"])

# The docs are available on https://docs.fastlane.tools/actions/match
type("appstore")
app_identifier("com.mendix.developerapp.native.mx10")
Loading