Skip to content

Commit 2ea640a

Browse files
authored
Split release job to sub tasks. (#9809)
* Split release job to sub tasks.
1 parent c0df0d4 commit 2ea640a

File tree

6 files changed

+326
-75
lines changed

6 files changed

+326
-75
lines changed

.github/workflows/prerelease.yml

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,29 @@ concurrency:
1414
cancel-in-progress: true
1515

1616
jobs:
17-
buildup_SpecsTesting_repo:
17+
specs_checking:
1818
# Don't run on private repo unless it is a PR.
1919
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'workflow_dispatch'
20+
runs-on: macos-12
2021
env:
2122
bot_token_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
22-
local_repo: specstesting
2323
# The SDK repo will be cloned to this dir and podspecs from
2424
# 'podspec_repo_branch' of this repo will be validated and pushed to the
2525
# testing repo.
2626
local_sdk_repo_dir: /tmp/test/firebase-ios-sdk
27+
local_repo: specstesting
2728
podspec_repo_branch: master
28-
runs-on: macos-12
29+
outputs:
30+
matrix: ${{ steps.generate_matrix.outputs.matrix }}
2931
steps:
30-
- uses: actions/checkout@v2
32+
- name: Checkout code
33+
uses: actions/checkout@v3
34+
- name: Generate matrix
35+
id: generate_matrix
36+
run: |
37+
cd "${GITHUB_WORKSPACE}/ReleaseTooling"
38+
swift run manifest --sdk-repo-url "${GITHUB_WORKSPACE}" --spec-output-file-path ./output.json
39+
echo "::set-output name=matrix::{\"include\":$( cat output.json )}"
3140
- name: Get token
3241
run: |
3342
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/oss-bot-access.txt.gpg \
@@ -38,13 +47,59 @@ jobs:
3847
run: |
3948
ossbotaccess=`cat oss-bot-access.txt`
4049
BOT_TOKEN="${ossbotaccess}" test_version="${nightly_version}" sdk_version_config="${GITHUB_WORKSPACE}/scripts/create_spec_repo/RC_firebase_sdk.textproto" local_sdk_repo_dir="${local_sdk_repo_dir}" podspec_repo_branch="${podspec_repo_branch}" scripts/release_testing_setup.sh prerelease_testing
50+
- name: Clean spec repo
51+
run: |
52+
ossbotaccess=`cat oss-bot-access.txt`
53+
git clone --quiet https://${ossbotaccess}@github.com/Firebase/SpecsTesting.git "${local_repo}"
54+
cd "${local_repo}"
55+
# Remove all unhidden dirs, i.e. all podspec dir from the spec repo.
56+
rm -Rf -- */
57+
git add .
58+
# commit without diff will throw an error. `git diff --exit-code` can avoid such error.
59+
git diff --staged --exit-code || git commit -m "Empty spec repo."
60+
git push
61+
- name: Clean Artifacts
62+
if: ${{ always() }}
63+
run: |
64+
rm -rf oss-bot-access.txt
65+
- uses: actions/upload-artifact@v3
66+
with:
67+
name: firebase-ios-sdk
68+
path: |
69+
${{ env.local_sdk_repo_dir }}/*.podspec
70+
${{ env.local_sdk_repo_dir }}/*.podspec.json
71+
buildup_SpecsTesting_repo:
72+
needs: specs_checking
73+
# Don't run on private repo unless it is a PR.
74+
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'workflow_dispatch'
75+
runs-on: macos-12
76+
strategy:
77+
fail-fast: false
78+
matrix: ${{fromJson(needs.specs_checking.outputs.matrix)}}
79+
env:
80+
bot_token_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
81+
local_repo: specstesting
82+
local_sdk_repo_dir: /tmp/test/firebase-ios-sdk
83+
targeted_pod: ${{ matrix.podspec }}
84+
steps:
85+
- uses: actions/checkout@v2
86+
- uses: actions/download-artifact@v3
87+
with:
88+
name: firebase-ios-sdk
89+
path: ${{ env.local_sdk_repo_dir }}
90+
- name: Get token
91+
run: |
92+
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/oss-bot-access.txt.gpg \
93+
oss-bot-access.txt "$bot_token_secret"
94+
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/bot-access.txt.gpg \
95+
bot-access.txt "$bot_token_secret"
4196
- name: Update SpecsTesting repo
4297
run: |
4398
botaccess=`cat bot-access.txt`
4499
cd scripts/create_spec_repo/
45100
swift build
46101
pod repo add --silent "${local_repo}" https://"$botaccess"@github.com/Firebase/SpecsTesting.git
47-
BOT_TOKEN="${botaccess}" .build/debug/spec-repo-builder --sdk-repo "${local_sdk_repo_dir}" --local-spec-repo-name "${local_repo}" --sdk-repo-name SpecsTesting --github-account Firebase --pod-sources 'https://${BOT_TOKEN}@github.com/Firebase/SpecsTesting' "https://github.com/firebase/SpecsDev.git" "https://github.com/firebase/SpecsStaging.git" "https://cdn.cocoapods.org/" --exclude-pods "FirebaseFirestoreTestingSupport" "FirebaseAuthTestingSupport" "FirebaseCombineSwift"
102+
BOT_TOKEN="${botaccess}" .build/debug/spec-repo-builder --sdk-repo "${local_sdk_repo_dir}" --local-spec-repo-name "${local_repo}" --sdk-repo-name SpecsTesting --github-account Firebase --pod-sources 'https://${BOT_TOKEN}@github.com/Firebase/SpecsTesting' "https://github.com/firebase/SpecsDev.git" "https://github.com/firebase/SpecsStaging.git" "https://github.com/CocoaPods/Specs.git" --include-pods "${targeted_pod}" --keep-repo
48103
- name: Clean Artifacts
49104
if: ${{ always() }}
50105
run: |

.github/workflows/release.yml

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,92 @@ concurrency:
1515
cancel-in-progress: true
1616

1717
jobs:
18-
buildup_SpecsTesting_repo:
18+
specs_checking:
1919
# Don't run on private repo unless it is a PR.
2020
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
21+
runs-on: macos-12
2122
env:
2223
bot_token_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
23-
local_repo: specstesting
2424
# The SDK repo will be cloned to this dir and podspecs from
25-
# the latest release branch of this repo will be validated and pushed to
26-
# the testing repo.
25+
# 'podspec_repo_branch' of this repo will be validated and pushed to the
26+
# testing repo.
2727
local_sdk_repo_dir: /tmp/test/firebase-ios-sdk
28+
local_repo: specstesting
2829
podspec_repo_branch: master
30+
outputs:
31+
matrix: ${{ steps.generate_matrix.outputs.matrix }}
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@v3
35+
- name: Generate matrix
36+
id: generate_matrix
37+
run: |
38+
cd "${GITHUB_WORKSPACE}/ReleaseTooling"
39+
swift run manifest --sdk-repo-url "${GITHUB_WORKSPACE}" --spec-output-file-path ./output.json
40+
echo "::set-output name=matrix::{\"include\":$( cat output.json )}"
41+
- name: Get token
42+
run: |
43+
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/bot-access.txt.gpg \
44+
bot-access.txt "$bot_token_secret"
45+
- name: Update SpecsTesting repo setup
46+
run: |
47+
botaccess=`cat bot-access.txt`
48+
BOT_TOKEN="${botaccess}" test_version="${nightly_version}" \
49+
sdk_version_config="${GITHUB_WORKSPACE}/scripts/create_spec_repo/RC_firebase_sdk.textproto" \
50+
local_sdk_repo_dir="${local_sdk_repo_dir}" \
51+
podspec_repo_branch="${podspec_repo_branch}" \
52+
scripts/release_testing_setup.sh prerelease_testing
53+
- name: Clean spec repo
54+
run: |
55+
botaccess=`cat bot-access.txt`
56+
git clone --quiet https://"$botaccess"@github.com/FirebasePrivate/SpecsTesting.git "${local_repo}"
57+
cd "${local_repo}"
58+
# Remove all unhided dirs, i.e. all podspec dir from the spec repo.
59+
rm -Rf -- */
60+
git add .
61+
# commit without diff will throw an error. `git diff --exit-code` can avoid such error.
62+
git diff --staged --exit-code || git commit -m "Empty spec repo."
63+
git push
64+
- name: Clean Artifacts
65+
if: ${{ always() }}
66+
run: |
67+
rm -rf bot-access.txt
68+
- uses: actions/upload-artifact@v3
69+
with:
70+
name: firebase-ios-sdk
71+
path: |
72+
${{ env.local_sdk_repo_dir }}/*.podspec
73+
${{ env.local_sdk_repo_dir }}/*.podspec.json
74+
buildup_SpecsTesting_repo:
75+
needs: specs_checking
76+
# Don't run on private repo unless it is a PR.
77+
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
2978
runs-on: macos-12
79+
strategy:
80+
fail-fast: false
81+
matrix: ${{fromJson(needs.specs_checking.outputs.matrix)}}
82+
env:
83+
bot_token_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
84+
local_repo: specstesting
85+
local_sdk_repo_dir: /tmp/test/firebase-ios-sdk
86+
targeted_pod: ${{ matrix.podspec }}
3087
steps:
3188
- uses: actions/checkout@v2
32-
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
89+
- uses: actions/download-artifact@v3
3390
with:
34-
ruby-version: '2.7'
91+
name: firebase-ios-sdk
92+
path: ${{ env.local_sdk_repo_dir }}
3593
- name: Get token
3694
run: |
37-
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/oss-bot-access.txt.gpg \
38-
oss-bot-access.txt "$bot_token_secret"
3995
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/bot-access.txt.gpg \
4096
bot-access.txt "$bot_token_secret"
41-
- name: Update SpecsTesting repo setup
42-
run: |
43-
ossbotaccess=`cat oss-bot-access.txt`
44-
BOT_TOKEN="${ossbotaccess}" scripts/release_testing_setup.sh release_testing
4597
- name: Update SpecsTesting repo
4698
run: |
4799
botaccess=`cat bot-access.txt`
48100
cd scripts/create_spec_repo/
49101
swift build
50102
pod repo add --silent "${local_repo}" https://"$botaccess"@github.com/FirebasePrivate/SpecsTesting.git
51-
BOT_TOKEN="${botaccess}" .build/debug/spec-repo-builder --sdk-repo "${local_sdk_repo_dir}" --local-spec-repo-name "${local_repo}" --pod-sources 'https://${BOT_TOKEN}@github.com/FirebasePrivate/SpecsTesting' "https://github.com/firebase/SpecsStaging.git" "https://cdn.cocoapods.org/" --exclude-pods "FirebaseFirestoreTestingSupport" "FirebaseAuthTestingSupport" "FirebaseCombineSwift"
103+
BOT_TOKEN="${botaccess}" .build/debug/spec-repo-builder --sdk-repo "${local_sdk_repo_dir}" --local-spec-repo-name "${local_repo}" --pod-sources 'https://${BOT_TOKEN}@github.com/FirebasePrivate/SpecsTesting' "https://github.com/firebase/SpecsStaging.git" "https://github.com/CocoaPods/Specs.git" --include-pods "${targeted_pod}" --keep-repo
52104
- name: Clean Artifacts
53105
if: ${{ always() }}
54106
run: |
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import ArgumentParser
18+
import FirebaseManifest
19+
import Foundation
20+
import Utils
21+
22+
/// SDKPodspec is to help generate an array of podspec in json file, e.g.
23+
/// ``` output.json
24+
/// [{"podspec":"FirebaseABTesting.podspec"},{"podspec":"FirebaseAnalytics.podspec.json"}]
25+
/// ```
26+
struct SDKPodspec: Codable {
27+
let podspec: String
28+
}
29+
30+
struct GHAMatrixSpecCollector {
31+
var SDKRepoURL: URL
32+
var outputSpecFileURL: URL
33+
var excludedSDKs: [String] = []
34+
35+
func getPodsInManifest(_ manifest: Manifest) -> [String] {
36+
var podsList: [String] = []
37+
for pod in manifest.pods {
38+
podsList.append(pod.name)
39+
}
40+
return podsList
41+
}
42+
43+
func getAllPodspecs() -> [String] {
44+
var output: [String] = []
45+
let fileManager = FileManager.default
46+
let podsSet = Set(getPodsInManifest(FirebaseManifest.shared))
47+
do {
48+
let fileURLs = try fileManager.contentsOfDirectory(
49+
at: SDKRepoURL,
50+
includingPropertiesForKeys: nil
51+
)
52+
for url in fileURLs {
53+
let fileNameComponents = url.lastPathComponent.components(separatedBy: ".")
54+
if fileNameComponents.count > 1, fileNameComponents[1] == "podspec" {
55+
let specName = fileNameComponents[0]
56+
podsSet.contains(specName) ? output
57+
.append(specName) : print("\(specName) is not in manifiest")
58+
}
59+
}
60+
} catch {
61+
print("Error while enumerating files: \(error.localizedDescription)")
62+
}
63+
return output
64+
}
65+
66+
func generateMatrixJson(to filePath: URL) throws {
67+
let testingSpecs = getAllPodspecs()
68+
var sdkPodspecs: [SDKPodspec] = []
69+
for spec in testingSpecs {
70+
sdkPodspecs.append(SDKPodspec(podspec: spec))
71+
}
72+
// Trim whitespaces so the GitHub Actions matrix can read.
73+
let str = try String(
74+
decoding: JSONEncoder().encode(sdkPodspecs),
75+
as: UTF8.self
76+
)
77+
try str.trimmingCharacters(in: .whitespacesAndNewlines).write(
78+
to: filePath,
79+
atomically: true,
80+
encoding: String.Encoding.utf8
81+
)
82+
}
83+
}

ReleaseTooling/Sources/ManifestParser/main.swift

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,25 @@ import Foundation
2020
import Utils
2121

2222
struct ManifestParser: ParsableCommand {
23+
@Option(help: "The path of the SDK repo.",
24+
transform: { str in
25+
if NSString(string: str).isAbsolutePath { return URL(fileURLWithPath: str) }
26+
let documentDir = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
27+
return documentDir.appendingPathComponent(str)
28+
})
29+
var SDKRepoURL: URL
30+
2331
/// Path of a text file for Firebase Pods' names.
24-
@Option(help: "Output path of a generated file with all Firebase Pods' names.",
25-
transform: URL.init(fileURLWithPath:))
26-
var podNameOutputFilePath: URL
32+
@Option(help: "An output file with Podspecs",
33+
transform: { str in
34+
if NSString(string: str).isAbsolutePath { return URL(fileURLWithPath: str) }
35+
let documentDir = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
36+
return documentDir.appendingPathComponent(str)
37+
})
38+
var specOutputFilePath: URL
39+
40+
@Option(parsing: .upToNextOption, help: "Podspec files that will not be included.")
41+
var excludedSpecs: [String]
2742

2843
func parsePodNames(_ manifest: Manifest) throws {
2944
var output: [String] = []
@@ -32,17 +47,20 @@ struct ManifestParser: ParsableCommand {
3247
}
3348
do {
3449
try output.joined(separator: ",")
35-
.write(to: podNameOutputFilePath, atomically: true,
50+
.write(to: specOutputFilePath, atomically: true,
3651
encoding: String.Encoding.utf8)
37-
print("\(output) is written in \n \(podNameOutputFilePath).")
52+
print("\(output) is written in \n \(specOutputFilePath).")
3853
} catch {
3954
throw error
4055
}
4156
}
4257

4358
func run() throws {
44-
let manifest = FirebaseManifest.shared
45-
try parsePodNames(manifest)
59+
let specCollector = GHAMatrixSpecCollector(
60+
SDKRepoURL: SDKRepoURL,
61+
outputSpecFileURL: specOutputFilePath
62+
)
63+
try specCollector.generateMatrixJson(to: specOutputFilePath)
4664
}
4765
}
4866

scripts/create_spec_repo/Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import PackageDescription
2020

2121
let package = Package(
2222
name: "PodSpecBuilder",
23+
platforms: [
24+
.macOS(.v10_13),
25+
],
2326
products: [
2427
.executable(name: "spec-repo-builder", targets: ["SpecRepoBuilder"]),
2528
],

0 commit comments

Comments
 (0)