Skip to content

Commit 4c4fc4c

Browse files
authored
Merge pull request #551 from nimblehq/feature/546-add-support-to-adding-new-devices-directly-from-github-actions
[#546] Support adding new devices directly from Github Action
2 parents 7bf00ff + 711068f commit 4c4fc4c

File tree

5 files changed

+125
-25
lines changed

5 files changed

+125
-25
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Test Add device and regenerate profiles with fastlane match
2+
3+
# SECRETS needed:
4+
### SSH_PRIVATE_KEY for the match Repo
5+
### MATCH_PASSWORD
6+
### APPSTORE_CONNECT_API_KEY
7+
### API_KEY_ID
8+
### ISSUER_ID
9+
10+
on:
11+
pull_request:
12+
workflow_dispatch:
13+
inputs:
14+
devices:
15+
description: 'JSON of devices. `{"Luka iPhone 6":"1234567890123456789012345678901234567890","Felix iPad Air 2":"abcdefghijklmnopqrstvuwxyzabcdefghijklmn"}`'
16+
required: true
17+
type: string
18+
platform:
19+
description: 'The platform'
20+
required: true
21+
default: 'ios'
22+
type: choice
23+
options:
24+
- ios
25+
- mac
26+
27+
jobs:
28+
create_files:
29+
name: Create certificates and profiles
30+
runs-on: macOS-latest
31+
steps:
32+
- name: Checkout the repository
33+
uses: actions/checkout@v2
34+
with:
35+
fetch-depth: 0
36+
37+
- name: Install SSH key
38+
uses: webfactory/[email protected]
39+
with:
40+
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
41+
42+
- name: Bundle install
43+
run: bundle install
44+
45+
- name: Add device and regenerate profiles with match
46+
run: bundle exec fastlane addDevicesGenerateProfiles
47+
env:
48+
MATCH_PASSWORD: ${{ secrets.MATCH_PASS }}
49+
DEVICES: ${{ inputs.devices }}
50+
APPSTORE_CONNECT_API_KEY: ${{ secrets.APPSTORE_CONNECT_API_KEY }}
51+
API_KEY_ID: ${{ secrets.API_KEY_ID }}
52+
ISSUER_ID: ${{ secrets.ISSUER_ID }}
53+
PLATFORM: ${{ inputs.platform }}
54+
55+
- name: Clean up keychain
56+
if: ${{ always() }}
57+
run: bundle exec fastlane remove_keychain
58+
continue-on-error: true

Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpCICDService.swift

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,44 @@ struct SetUpCICDService {
77
case github, bitrise, codemagic, later
88

99
init?(_ name: String) {
10-
switch name.lowercased() {
11-
case "g", "github":
12-
self = .github
13-
case "b", "bitrise":
14-
self = .bitrise
15-
case "c", "codemagic":
16-
self = .codemagic
17-
case "l", "later":
18-
self = .later
19-
default:
10+
let name = name.lowercased()
11+
let mappings: [String: Self] = [
12+
"g": .github,
13+
"github": .github,
14+
"b": .bitrise,
15+
"bitrise": .bitrise,
16+
"c": .codemagic,
17+
"codemagic": .codemagic,
18+
"l": .later,
19+
"later": .later
20+
]
21+
22+
if let matchedCase = mappings[name] {
23+
self = matchedCase
24+
} else {
2025
return nil
2126
}
2227
}
2328
}
24-
29+
2530
enum GithubRunnerType {
2631

2732
case macOSLatest, selfHosted, later
2833

2934
init?(_ name: String) {
30-
switch name.lowercased() {
31-
case "m", "macOS":
32-
self = .macOSLatest
33-
case "s", "self-hosted":
34-
self = .selfHosted
35-
case "l", "later":
36-
self = .later
37-
default:
35+
let mappings: [String: Self] = [
36+
"m": .macOSLatest,
37+
"macos": .macOSLatest,
38+
"s": .selfHosted,
39+
"self-hosted": .selfHosted,
40+
"l": .later,
41+
"later": .later
42+
]
43+
44+
let name = name.lowercased()
45+
if let matchedCase = mappings[name] {
46+
self = matchedCase
47+
} else {
3848
return nil
3949
}
4050
}
@@ -63,10 +73,12 @@ struct SetUpCICDService {
6373
fileManager.createDirectory(path: ".github/workflows")
6474
switch runnerType {
6575
case .macOSLatest:
76+
print("Configured to run on the latest macOS.")
6677
fileManager.moveFiles(in: ".github/project_workflows", to: ".github/workflows")
6778
fileManager.removeItems(in: ".github/project_workflows")
6879
fileManager.removeItems(in: ".github/self_hosted_project_workflows")
6980
case .selfHosted:
81+
print("Configured to run on self-hosted.")
7082
fileManager.moveFiles(in: ".github/self_hosted_project_workflows", to: ".github/workflows")
7183
fileManager.removeItems(in: ".github/project_workflows")
7284
fileManager.removeItems(in: ".github/self_hosted_project_workflows")

fastlane/Constants/Constant.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,20 @@ enum Constant {
2828
static let appleProductionTeamId = "<#teamId#>"
2929
static let keychainName = "{PROJECT_NAME}_keychain"
3030
static let matchURL = "[email protected]:{organization}/{repo}.git"
31-
static let apiKey: [String: Any] = [
32-
"key_id" : Secret.appStoreKeyIdKey,
33-
"issuer_id": Secret.appStoreIssuerIdKey,
34-
"key": Secret.appstoreConnectAPIKey,
35-
"in_house": false
36-
]
31+
static let apiKey: [String: Any] = {
32+
var key = Secret.appstoreConnectAPIKey
33+
if let data = Data(base64Encoded: Secret.appstoreConnectAPIKey),
34+
let decodedKey = String(data: data, encoding: .utf8) {
35+
key = decodedKey
36+
}
37+
38+
return [
39+
"key_id" : Secret.appStoreKeyIdKey,
40+
"issuer_id": Secret.appStoreIssuerIdKey,
41+
"key": key,
42+
"in_house": false
43+
]
44+
}()
3745

3846
// MARK: - Path
3947

fastlane/Constants/Secret.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ enum Secret {
1818
static let appStoreIssuerIdKey = EnvironmentParser.string(key: "ISSUER_ID")
1919

2020
static let bumpAppStoreBuildNumber = EnvironmentParser.bool(key: "BUMP_APP_STORE_BUILD_NUMBER")
21+
22+
static let devices = EnvironmentParser.string(key: "DEVICES")
23+
24+
static let platform = EnvironmentParser.string(key: "PLATFORM")
2125
}

fastlane/Fastfile.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,24 @@ class Fastfile: LaneFile {
176176
Match.syncCodeSigning(type: .adHoc, environment: .staging, isForce: true)
177177
}
178178

179+
func addDevicesGenerateProfilesLane() {
180+
desc("Add device and regenerate profiles with match")
181+
182+
guard let data = Secret.devices.data(using: .utf8),
183+
let devices = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
184+
return
185+
}
186+
registerDevices(
187+
devices: .userDefined(devices),
188+
apiKey: .userDefined(Constant.apiKey),
189+
teamId: .userDefined(Constant.appleStagingTeamId),
190+
platform: Secret.platform
191+
)
192+
193+
Match.syncCodeSigning(type: .development, environment: .staging, isForce: true)
194+
Match.syncCodeSigning(type: .adHoc, environment: .staging, isForce: true)
195+
}
196+
179197
// MARK: - Utilities
180198

181199
func cleanUpOutputLane() {

0 commit comments

Comments
 (0)