From 1858dd205ee57611ca4a04a9794ff4301798ece1 Mon Sep 17 00:00:00 2001 From: Huy Hoang Date: Thu, 2 Jan 2025 14:31:15 +0700 Subject: [PATCH] [#558] Create Dev scheme and deploy_dev_firebase workflow --- .../project_workflows/deploy_dev_firebase.yml | 111 ++++++++++++++++++ .../workflows/test_swiftui_install_script.yml | 2 +- .../workflows/test_uikit_install_script.yml | 2 +- .../test_upload_build_to_firebase.yml | 2 +- .../test_upload_build_to_test_flight.yml | 2 +- .../test_upload_dev_build_to_firebase.yml | 92 +++++++++++++++ Project.swift | 1 + .../Models/EnvironmentKey.swift | 1 + .../iOSTemplateMaker/SetUpTestFirebase.swift | 3 + .../iOSTemplateMaker/SetUpiOSProject.swift | 14 +++ .../iOSTemplateMaker/iOSTemplateMaker.swift | 5 + .../BuildConfiguration.swift | 36 +++--- .../Scheme+Initializing.swift | 17 +++ fastlane/Constants/Constant.swift | 12 +- fastlane/Fastfile.swift | 38 ++++++ .../Dev/GoogleService-Info.plist | 7 ++ .../XCConfigs/DebugDev.xcconfig | 13 ++ .../XCConfigs/ReleaseDev.xcconfig | 12 ++ 18 files changed, 351 insertions(+), 19 deletions(-) create mode 100644 .github/project_workflows/deploy_dev_firebase.yml create mode 100644 .github/workflows/test_upload_dev_build_to_firebase.yml create mode 100644 {PROJECT_NAME}/Configurations/Plists/GoogleService/Dev/GoogleService-Info.plist create mode 100644 {PROJECT_NAME}/Configurations/XCConfigs/DebugDev.xcconfig create mode 100644 {PROJECT_NAME}/Configurations/XCConfigs/ReleaseDev.xcconfig diff --git a/.github/project_workflows/deploy_dev_firebase.yml b/.github/project_workflows/deploy_dev_firebase.yml new file mode 100644 index 00000000..467797bb --- /dev/null +++ b/.github/project_workflows/deploy_dev_firebase.yml @@ -0,0 +1,111 @@ +name: Deploy Dev Build To Firebase + +# SECRETS needed: +### SSH_PRIVATE_KEY for Match Repo +### MATCH_PASS +### FIREBASE_GOOGLE_APPLICATION_CREDENTIALS_BASE64 + +on: + push: + branches: [ develop ] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Run SwiftLint + uses: docker://norionomura/swiftlint:0.53.0_swift-5.7 + with: + args: swiftlint --strict + + build: + name: Build + runs-on: macOS-latest + steps: + - uses: actions/checkout@v3 + # Set fetch-depth (default: 1) to get whole tree + with: + fetch-depth: 0 + + - name: Install SSH key + uses: webfactory/ssh-agent@v0.7.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Install Firebase-Tools + run: | + yarn global add firebase-tools + echo "$(yarn global bin)" >> $GITHUB_PATH + + - name: Setup ENV file + env: + ENV: ${{ secrets.ENV }} + run: | + touch .env + echo $ENV | base64 --decode > .env + + - name: Read Google Service Account + id: firebase_service_account + uses: timheuer/base64-to-file@v1.2 + with: + fileName: 'firebase_service_account.json' + encodedString: ${{ secrets.FIREBASE_GOOGLE_APPLICATION_CREDENTIALS_BASE64 }} + + - name: Bundle install + # if: steps.bundleCache.outputs.cache-hit != 'true' + run: bundle install + + - name: Run Arkana + run: bundle exec arkana + + - name: Cache Pods + uses: actions/cache@v2 + id: cocoapodCache + with: + path: Pods + key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods- + + - name: Install Pods Dependencies + run: bundle exec pod install + shell: bash + + - name: Build and Test + run: bundle exec fastlane buildAndTestDev + + - name: Match Ad-hoc + run: bundle exec fastlane syncAdHocDevCodeSigning + env: + MATCH_PASSWORD: ${{ secrets.MATCH_PASS }} + + - name: Build App and Distribute to Firebase + run: bundle exec fastlane buildDevAndUploadToFirebase + env: + GOOGLE_APPLICATION_CREDENTIALS: ${{ steps.firebase_service_account.outputs.filePath }} + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ format('v{0}({1})-{2}', env.VERSION_NUMBER, env.BUILD_NUMBER, env.TAG_TYPE) }} + path: | + ${{ env.IPA_OUTPUT_PATH }} + ${{ env.DSYM_OUTPUT_PATH }} + env: + TAG_TYPE: Dev_Firebase + + - name: Remove keychain + if: ${{ always() }} + run: bundle exec fastlane removeKeychain + continue-on-error: true diff --git a/.github/workflows/test_swiftui_install_script.yml b/.github/workflows/test_swiftui_install_script.yml index f9566740..9ec4716d 100644 --- a/.github/workflows/test_swiftui_install_script.yml +++ b/.github/workflows/test_swiftui_install_script.yml @@ -19,7 +19,7 @@ jobs: run: bundle install - name: Start Install Script for SwiftUI Template App - run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --project-name TemplateApp --interface SwiftUI + run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --bundle-id-dev co.nimblehq.ios.templates.dev --project-name TemplateApp --interface SwiftUI - name: Build and Test run: bundle exec fastlane buildAndTest diff --git a/.github/workflows/test_uikit_install_script.yml b/.github/workflows/test_uikit_install_script.yml index 3f4d0a60..aaed9633 100644 --- a/.github/workflows/test_uikit_install_script.yml +++ b/.github/workflows/test_uikit_install_script.yml @@ -19,7 +19,7 @@ jobs: run: bundle install - name: Start Install Script for UIKit Template App - run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --project-name TemplateApp --interface UIKit + run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --bundle-id-dev co.nimblehq.ios.templates.dev --project-name TemplateApp --interface UIKit - name: Build and Test run: bundle exec fastlane buildAndTest diff --git a/.github/workflows/test_upload_build_to_firebase.yml b/.github/workflows/test_upload_build_to_firebase.yml index 8aff8251..0dc4b3f2 100644 --- a/.github/workflows/test_upload_build_to_firebase.yml +++ b/.github/workflows/test_upload_build_to_firebase.yml @@ -54,7 +54,7 @@ jobs: ${{ runner.os }}-pods- - name: Start Install Script for Template App - run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --project-name TemplateApp --interface UIKit + run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --bundle-id-dev co.nimblehq.ios.templates.dev --project-name TemplateApp --interface UIKit - name: Start Setup Script for Template App Firebase Upload run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make-test-firebase diff --git a/.github/workflows/test_upload_build_to_test_flight.yml b/.github/workflows/test_upload_build_to_test_flight.yml index 9d68acba..d9dd5ad3 100644 --- a/.github/workflows/test_upload_build_to_test_flight.yml +++ b/.github/workflows/test_upload_build_to_test_flight.yml @@ -44,7 +44,7 @@ jobs: ${{ runner.os }}-pods- - name: Start Install Script for Template App - run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --project-name TemplateApp --interface UIKit + run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --bundle-id-dev co.nimblehq.ios.templates.dev --project-name TemplateApp --interface UIKit - name: Start Setup Script for Template App TestFlight Upload run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make-test-test-flight diff --git a/.github/workflows/test_upload_dev_build_to_firebase.yml b/.github/workflows/test_upload_dev_build_to_firebase.yml new file mode 100644 index 00000000..0e4e2ee3 --- /dev/null +++ b/.github/workflows/test_upload_dev_build_to_firebase.yml @@ -0,0 +1,92 @@ +name: Test Upload Dev Build to Firebase + +# SECRETS needed: +### SSH_PRIVATE_KEY for Match Repo +### MATCH_PASS +### FIREBASE_GOOGLE_APPLICATION_CREDENTIALS_BASE64 +### DEV_FIREBASE_APP_ID +### TEAM_ID + +on: + pull_request + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build + runs-on: macOS-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install SSH key + uses: webfactory/ssh-agent@v0.7.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Install Firebase-Tools + run: | + yarn global add firebase-tools + echo "$(yarn global bin)" >> $GITHUB_PATH + + - name: Read Google Service Account + id: firebase_service_account + uses: timheuer/base64-to-file@v1.2 + with: + fileName: 'firebase_service_account.json' + encodedString: ${{ secrets.FIREBASE_GOOGLE_APPLICATION_CREDENTIALS_BASE64 }} + + - name: Bundle install + run: bundle install + + - name: Cache Pods + uses: actions/cache@v3 + id: cocoapodCache + with: + path: Pods + key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods- + + - name: Start Install Script for Template App + run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make --bundle-id-production co.nimblehq.ios.templates --bundle-id-staging co.nimblehq.ios.templates.staging --bundle-id-dev co.nimblehq.ios.templates.dev --project-name TemplateApp --interface UIKit + + - name: Start Setup Script for Template App Firebase Upload + run: swift run --package-path Scripts/Swift/iOSTemplateMaker iOSTemplateMaker make-test-firebase + env: + MATCH_REPO: ${{ secrets.MATCH_REPO }} + DEV_FIREBASE_APP_ID: ${{ secrets.DEV_FIREBASE_APP_ID }} + TEAM_ID: ${{ secrets.TEAM_ID }} + + - name: Set Up Test Project for Firebase + run: bundle exec fastlane setUpTestProject + + - name: Sync Ad Hoc Code Signing + run: bundle exec fastlane syncAdHocDevCodeSigning + env: + MATCH_PASSWORD: ${{ secrets.MATCH_PASS }} + + - name: Build Dev App and Distribute to Firebase + run: bundle exec fastlane buildDevAndUploadToFirebase + env: + GOOGLE_APPLICATION_CREDENTIALS: ${{ steps.firebase_service_account.outputs.filePath }} + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ format('v{0}({1})-{2}', env.VERSION_NUMBER, env.BUILD_NUMBER, env.TAG_TYPE) }} + path: | + ${{ env.IPA_OUTPUT_PATH }} + ${{ env.DSYM_OUTPUT_PATH }} + env: + TAG_TYPE: Dev_Firebase + + - name: Remove keychain + if: ${{ always() }} + run: bundle exec fastlane removeKeychain + continue-on-error: true diff --git a/Project.swift b/Project.swift index c58b5cd2..b59b0b93 100644 --- a/Project.swift +++ b/Project.swift @@ -22,6 +22,7 @@ extension Project { schemes: [ .productionScheme(name: name), .stagingScheme(name: name), + .devScheme(name: name), .kifUITestsScheme(name: name) ] ) diff --git a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/Models/EnvironmentKey.swift b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/Models/EnvironmentKey.swift index 8fc4fa20..18b51f23 100644 --- a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/Models/EnvironmentKey.swift +++ b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/Models/EnvironmentKey.swift @@ -8,6 +8,7 @@ enum EnvironmentKey: String { case matchRepo = "MATCH_REPO" + case devFirebaseAppId = "DEV_FIREBASE_APP_ID" case stagingFirebaseAppId = "STAGING_FIREBASE_APP_ID" case teamId = "TEAM_ID" case apiKey = "API_KEY_ID" diff --git a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpTestFirebase.swift b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpTestFirebase.swift index 5f23b513..63e93535 100644 --- a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpTestFirebase.swift +++ b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpTestFirebase.swift @@ -3,6 +3,7 @@ import Foundation struct SetUpTestFirebase { private let teamIdPlaceholder = "<#teamId#>" + private let devFirebaseAppIdPlaceholder = "<#devFirebaseAppId#>" private let stagingFirebaseAppIdPlaceholder = "<#stagingFirebaseAppId#>" private let firebaseTesterGroupsPlaceholder = "<#group1#>, <#group2#>" private let matchRepoPlaceholder = "git@github.com:{organization}/{repo}.git" @@ -11,11 +12,13 @@ struct SetUpTestFirebase { private let fileManager = FileManager.default let matchRepo: String + let devFirebaseAppId: String let stagingFirebaseAppId: String let teamId: String func perform() { fileManager.replaceAllOccurrences(of: teamIdPlaceholder, to: teamId) + fileManager.replaceAllOccurrences(of: devFirebaseAppIdPlaceholder, to: devFirebaseAppId) fileManager.replaceAllOccurrences(of: stagingFirebaseAppIdPlaceholder, to: stagingFirebaseAppId) fileManager.replaceAllOccurrences(of: firebaseTesterGroupsPlaceholder, to: firebaseTesterGroup) fileManager.replaceAllOccurrences(of: matchRepoPlaceholder, to: matchRepo) diff --git a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift index 2504a54b..98099216 100644 --- a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift +++ b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift @@ -6,11 +6,13 @@ class SetUpIOSProject { private let CONSTANT_PROJECT_NAME = "{PROJECT_NAME}" private let CONSTANT_BUNDLE_PRODUCTION = "{BUNDLE_ID_PRODUCTION}" private let CONSTANT_BUNDLE_STAGING = "{BUNDLE_ID_STAGING}" + private let CONSTANT_BUNDLE_DEV = "{BUNDLE_ID_DEV}" private let CONSTANT_MINIMUM_VERSION = "{TARGET_VERSION}" private let fileManager = FileManager.default private var bundleIdProduction = "" private var bundleIdStaging = "" + private var bundleIdDev = "" private var projectName = "" private var minimumVersion = "" private var interface: SetUpInterface.Interface? @@ -20,12 +22,14 @@ class SetUpIOSProject { init( bundleIdProduction: String = "", bundleIdStaging: String = "", + bundleIdDev: String = "", projectName: String = "", minimumVersion: String = "", interface: String = "" ) { self.bundleIdProduction = bundleIdProduction self.bundleIdStaging = bundleIdStaging + self.bundleIdDev = bundleIdDev self.projectName = projectName self.minimumVersion = minimumVersion self.interface = .init(interface) @@ -110,6 +114,15 @@ class SetUpIOSProject { onValidate: validatePackageName ) } + + if bundleIdDev.isEmpty { + tryMoveDown() + bundleIdDev = ask( + "Which is the bundle ID for the dev environment?", + note: "Ex: com.example.project.dev", + onValidate: validatePackageName + ) + } if projectName.isEmpty { tryMoveDown() @@ -159,6 +172,7 @@ class SetUpIOSProject { } private func replaceTextInFiles() throws { + fileManager.replaceAllOccurrences(of: CONSTANT_BUNDLE_DEV, to: bundleIdDev) fileManager.replaceAllOccurrences(of: CONSTANT_BUNDLE_STAGING, to: bundleIdStaging) fileManager.replaceAllOccurrences(of: CONSTANT_BUNDLE_PRODUCTION, to: bundleIdProduction) fileManager.replaceAllOccurrences(of: CONSTANT_PROJECT_NAME, to: projectNameNoSpace) diff --git a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift index 7050547e..54aca47e 100644 --- a/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift +++ b/Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift @@ -23,6 +23,8 @@ extension iOSTemplateMaker { var bundleIdProduction: String? @Option(help: "The staging id (i.e. com.example.package.staging)") var bundleIdStaging: String? + @Option(help: "The dev id (i.e. com.example.package.dev)") + var bundleIdDev: String? @Option(help: "The project name (i.e. MyApp)") var projectName: String? @Option(help: "The minimum iOS version (14.0)") @@ -34,6 +36,7 @@ extension iOSTemplateMaker { SetUpIOSProject( bundleIdProduction: bundleIdProduction.string, bundleIdStaging: bundleIdStaging.string, + bundleIdDev: bundleIdDev.string, projectName: projectName.string, minimumVersion: minimumVersion.string, interface: interface.string @@ -48,11 +51,13 @@ extension iOSTemplateMaker { mutating func run() { let envMatchRepo = EnvironmentValue.value(for: .matchRepo).string + let envDevFirebaseAppId = EnvironmentValue.value(for: .devFirebaseAppId).string let envStagingFirebaseAppId = EnvironmentValue.value(for: .stagingFirebaseAppId).string let envTeamId = EnvironmentValue.value(for: .teamId).string SetUpTestFirebase( matchRepo: envMatchRepo, + devFirebaseAppId: envDevFirebaseAppId, stagingFirebaseAppId: envStagingFirebaseAppId, teamId: envTeamId ).perform() diff --git a/Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift b/Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift index 930edded..1010530b 100644 --- a/Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift +++ b/Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift @@ -2,6 +2,8 @@ import ProjectDescription public enum BuildConfiguration: CaseIterable { + case debugDev + case releaseDev case debugStaging case releaseStaging case debugProduction @@ -9,33 +11,39 @@ public enum BuildConfiguration: CaseIterable { var name: ConfigurationName { switch self { - case .debugStaging: return .configuration("Debug Staging") - case .releaseStaging: return .configuration("Release Staging") - case .debugProduction: return .configuration("Debug Production") - case .releaseProduction: return .configuration("Release Production") + case .debugDev: .configuration("Debug Dev") + case .releaseDev: .configuration("Release Dev") + case .debugStaging: .configuration("Debug Staging") + case .releaseStaging: .configuration("Release Staging") + case .debugProduction: .configuration("Debug Production") + case .releaseProduction: .configuration("Release Production") } } private var path: String { let rootPath = "Configurations/XCConfigs/" switch self { - case .debugStaging: - return "\(rootPath)DebugStaging.xcconfig" - case .releaseStaging: - return "\(rootPath)ReleaseStaging.xcconfig" - case .debugProduction: - return "\(rootPath)DebugProduction.xcconfig" - case .releaseProduction: - return "\(rootPath)ReleaseProduction.xcconfig" + case .debugDev: + return "\(rootPath)DebugDev.xcconfig" + case .releaseDev: + return "\(rootPath)ReleaseDev.xcconfig" + case .debugStaging: + return "\(rootPath)DebugStaging.xcconfig" + case .releaseStaging: + return "\(rootPath)ReleaseStaging.xcconfig" + case .debugProduction: + return "\(rootPath)DebugProduction.xcconfig" + case .releaseProduction: + return "\(rootPath)ReleaseProduction.xcconfig" } } public func createConfiguration(projectName: String) -> Configuration { let xcconfig = Path("\(projectName)/\(path)") switch self { - case .debugStaging, .debugProduction: + case .debugDev, .debugStaging, .debugProduction: return .debug(name: name, xcconfig: xcconfig) - case .releaseStaging, .releaseProduction: + case .releaseDev, .releaseStaging, .releaseProduction: return .release(name: name, xcconfig: xcconfig) } } diff --git a/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift b/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift index cda644fd..1813f9c6 100644 --- a/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift +++ b/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift @@ -36,6 +36,23 @@ extension Scheme { ) } + public static func devScheme(name: String) -> Scheme { + let debugConfigName = BuildConfiguration.debugDev.name + let releaseConfigName = BuildConfiguration.releaseDev.name + let testModules = testSchemes(name) + + return Scheme( + name: "\(name) Dev", + shared: true, + buildAction: .buildAction(targets: ["\(name)"]), + testAction: .targets(testModules, configuration: debugConfigName), + runAction: .runAction(configuration: debugConfigName), + archiveAction: .archiveAction(configuration: releaseConfigName), + profileAction: .profileAction(configuration: debugConfigName), + analyzeAction: .analyzeAction(configuration: debugConfigName) + ) + } + public static func kifUITestsScheme(name: String) -> Scheme { return Scheme( name: "\(name)KIFUITests", diff --git a/fastlane/Constants/Constant.swift b/fastlane/Constants/Constant.swift index 155852e1..5c430a7f 100644 --- a/fastlane/Constants/Constant.swift +++ b/fastlane/Constants/Constant.swift @@ -16,12 +16,15 @@ enum Constant { // MARK: - Firebase + static let devFirebaseAppId = "<#devFirebaseAppId#>" static let stagingFirebaseAppId = "<#stagingFirebaseAppId#>" static let productionFirebaseAppId = "<#productionFirebaseAppId#>" static let firebaseTesterGroups = "<#group1#>, <#group2#>" // MARK: - Match + static let appleDevUserName = "<#userName#>" + static let appleDevTeamId = "<#teamId#>" static let appleStagingUserName = "<#userName#>" static let appleStagingTeamId = "<#teamId#>" static let appleProductionUserName = "<#userName#>" @@ -67,6 +70,7 @@ enum Constant { // MARK: - Project + static let devBundleId = "{BUNDLE_ID_DEV}" static let stagingBundleId = "{BUNDLE_ID_STAGING}" static let productionBundleId = "{BUNDLE_ID_PRODUCTION}" static let projectName = "{PROJECT_NAME}" @@ -89,6 +93,7 @@ extension Constant { enum Environment: String { + case dev = "Dev" case staging = "Staging" case production = "Production" @@ -96,13 +101,14 @@ extension Constant { var scheme: String { switch self { - case .staging: return "\(Constant.projectName) \(rawValue)".trimmed + case .dev, .staging: return "\(Constant.projectName) \(rawValue)".trimmed case .production: return Constant.projectName.trimmed } } var bundleId: String { switch self { + case .dev: return Constant.devBundleId case .staging: return Constant.stagingBundleId case .production: return Constant.productionBundleId } @@ -110,6 +116,7 @@ extension Constant { var firebaseAppId: String { switch self { + case .dev: return Constant.devFirebaseAppId case .staging: return Constant.stagingFirebaseAppId case .production: return Constant.productionFirebaseAppId } @@ -119,6 +126,7 @@ extension Constant { let infoName = "GoogleService-Info.plist" let googleServiceFolder = "./\(Constant.projectName)/Configurations/Plists/GoogleService" switch self { + case .dev: return "\(googleServiceFolder)/Dev/\(infoName)" case .staging: return "\(googleServiceFolder)/Staging/\(infoName)" case .production: return "\(googleServiceFolder)/Production/\(infoName)" } @@ -131,6 +139,7 @@ extension Constant { var appleUsername: String { switch self { + case .dev: return Constant.appleDevUserName case .staging: return Constant.appleStagingUserName case .production: return Constant.appleProductionUserName } @@ -138,6 +147,7 @@ extension Constant { var appleTeamId: String { switch self { + case .dev: return appleDevTeamId case .staging: return Constant.appleStagingTeamId case .production: return Constant.appleProductionTeamId } diff --git a/fastlane/Fastfile.swift b/fastlane/Fastfile.swift index d8e1f09d..8635a5a8 100644 --- a/fastlane/Fastfile.swift +++ b/fastlane/Fastfile.swift @@ -27,6 +27,14 @@ class Fastfile: LaneFile { environment: .production ) } + + func syncAdHocDevCodeSigningLane() { + desc("Sync the Ad Hoc match signing for the Dev build") + Match.syncCodeSigning( + type: .adHoc, + environment: .dev + ) + } func syncAdHocStagingCodeSigningLane() { desc("Sync the Ad Hoc match signing for the Staging build") @@ -58,6 +66,12 @@ class Fastfile: LaneFile { } // MARK: - Build + + func buildAdHocDevLane() { + desc("Build ad-hoc dev") + Build.adHoc(environment: .dev) + } + func buildAdHocStagingLane() { desc("Build ad-hoc staging") @@ -75,6 +89,22 @@ class Fastfile: LaneFile { } // MARK: - Upload builds to Firebase and AppStore + + func buildDevAndUploadToFirebaseLane() { + desc("Build Dev app and upload to Firebase") + + setAppVersion() + bumpBuild() + + buildAdHocDevLane() + + // TODO: - Make release notes + Distribution.uploadToFirebase(environment: .staging, releaseNotes: "") + + Symbol.uploadToCrashlytics(environment: .dev) + + Build.saveBuildContextToCI() + } func buildStagingAndUploadToFirebaseLane() { desc("Build Staging app and upload to Firebase") @@ -154,6 +184,14 @@ class Fastfile: LaneFile { ) } + func buildAndTestDevLane() { + desc("Build and Test dev project") + Test.buildAndTest( + environment: .dev, + devices: Constant.devices + ) + } + func setUpTestProjectLane() { desc("Disable Exempt Encryption") Test.disableExemptEncryption() diff --git a/{PROJECT_NAME}/Configurations/Plists/GoogleService/Dev/GoogleService-Info.plist b/{PROJECT_NAME}/Configurations/Plists/GoogleService/Dev/GoogleService-Info.plist new file mode 100644 index 00000000..e154fa36 --- /dev/null +++ b/{PROJECT_NAME}/Configurations/Plists/GoogleService/Dev/GoogleService-Info.plist @@ -0,0 +1,7 @@ + + + + + + + diff --git a/{PROJECT_NAME}/Configurations/XCConfigs/DebugDev.xcconfig b/{PROJECT_NAME}/Configurations/XCConfigs/DebugDev.xcconfig new file mode 100644 index 00000000..ee787bbd --- /dev/null +++ b/{PROJECT_NAME}/Configurations/XCConfigs/DebugDev.xcconfig @@ -0,0 +1,13 @@ +BUILD_ACTIVE_RESOURCES_ONLY = YES +DEBUG_INFORMATION_FORMAT = dwarf +ENABLE_NS_ASSERTIONS = YES +ENABLE_TESTABILITY = YES +GCC_OPTIMIZATION_LEVEL = 0 +ONLY_ACTIVE_ARCH = YES +SWIFT_OPTIMIZATION_LEVEL = -Onone + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 DEV=1 +APP_DISPLAY_NAME = $(TARGET_NAME) Dev +PRODUCT_BUNDLE_IDENTIFIER = {BUNDLE_ID_DEV} +SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG DEV +OTHER_SWIFT_FLAGS = $(inherited) -Xfrontend -warn-long-expression-type-checking=300 -Xfrontend -warn-long-function-bodies=300 diff --git a/{PROJECT_NAME}/Configurations/XCConfigs/ReleaseDev.xcconfig b/{PROJECT_NAME}/Configurations/XCConfigs/ReleaseDev.xcconfig new file mode 100644 index 00000000..add9a956 --- /dev/null +++ b/{PROJECT_NAME}/Configurations/XCConfigs/ReleaseDev.xcconfig @@ -0,0 +1,12 @@ +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym +ENABLE_NS_ASSERTIONS = NO +GCC_OPTIMIZATION_LEVEL = s +SWIFT_COMPILATION_MODE = wholemodule +SWIFT_OPTIMIZATION_LEVEL = -O +ENABLE_BITCODE = NO + +ENABLE_BITCODE = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEV=1 +APP_DISPLAY_NAME = $(TARGET_NAME) Dev +PRODUCT_BUNDLE_IDENTIFIER = {BUNDLE_ID_DEV} +SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEV RELEASE