-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
456 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
ZipBuilder/Sources/FirebaseManifest/FirebaseManifest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
/// The manifest contents for a release. | ||
/// Version should be updated every release. | ||
/// The version and releasing fields of the non-Firebase pods should be reviewed every release. | ||
public let shared = Manifest( | ||
version: "7.0.0", | ||
pods: [ | ||
Pod("GoogleUtilities", isFirebase: false, podVersion: "7.0.0", releasing: false), | ||
Pod("GoogleDataTransport", isFirebase: false, podVersion: "8.0.0", releasing: true), | ||
|
||
Pod("FirebaseCoreDiagnostics"), | ||
Pod("FirebaseCore"), | ||
Pod("FirebaseInstallations"), | ||
Pod("FirebaseInstanceID"), | ||
Pod("GoogleAppMeasurement", isClosedSource: true), | ||
Pod("FirebaseAnalytics", isClosedSource: true), | ||
Pod("FirebaseABTesting"), | ||
Pod("FirebaseAppDistribution", isBeta: true), | ||
Pod("FirebaseAuth"), | ||
Pod("FirebaseCrashlytics"), | ||
Pod("FirebaseDatabase"), | ||
Pod("FirebaseDynamicLinks"), | ||
Pod("FirebaseFirestore", allowWarnings: true), | ||
Pod("FirebaseFirestoreSwift", isBeta: true), | ||
Pod("FirebaseFunctions"), | ||
Pod("FirebaseInAppMessaging", isBeta: true), | ||
Pod("FirebaseMessaging"), | ||
Pod("FirebasePerformance", isClosedSource: true), | ||
Pod("FirebaseRemoteConfig"), | ||
Pod("FirebaseStorage"), | ||
Pod("FirebaseStorageSwift", isBeta: true), | ||
Pod("FirebaseMLCommon", isClosedSource: true, isBeta: true), | ||
Pod("FirebaseMLModelInterpreter", isClosedSource: true, isBeta: true), | ||
Pod("FirebaseMLVision", isClosedSource: true, isBeta: true), | ||
Pod("Firebase", allowWarnings: true), | ||
] | ||
) | ||
|
||
/// Manifest describing the contents of a Firebase release. | ||
public struct Manifest { | ||
public let version: String | ||
public let pods: [Pod] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
/// Struct describing Firebase pods to release. | ||
public struct Pod { | ||
public let name: String | ||
public let isClosedSource: Bool | ||
public let isBeta: Bool | ||
public let isFirebase: Bool | ||
public let allowWarnings: Bool // Allow validation warnings. Ideally these should all be false | ||
public let podVersion: String? // Non-Firebase pods have their own version | ||
public let releasing: Bool // Non-Firebase pods may not release | ||
|
||
init(_ name: String, | ||
isClosedSource: Bool = false, | ||
isBeta: Bool = false, | ||
isFirebase: Bool = true, | ||
allowWarnings: Bool = false, | ||
podVersion: String? = nil, | ||
releasing: Bool = true) { | ||
self.name = name | ||
self.isClosedSource = isClosedSource | ||
self.isBeta = isBeta | ||
self.isFirebase = isFirebase | ||
self.allowWarnings = allowWarnings | ||
self.podVersion = podVersion | ||
self.releasing = releasing | ||
} | ||
|
||
public func podspecName() -> String { | ||
return isClosedSource ? "\(name).podspec.json" : "\(name).podspec" | ||
} | ||
|
||
/// Closed source pods do not validate on Xcode 12 until they support the ARM simulator slice. | ||
public func skipImportValidation() -> String { | ||
if isClosedSource || name == "Firebase" { | ||
return "-skip-import-validation" | ||
} else { | ||
return "" | ||
} | ||
} | ||
} |
135 changes: 135 additions & 0 deletions
135
ZipBuilder/Sources/FirebaseReleaser/InitializeRelease.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
import FirebaseManifest | ||
import Utils | ||
|
||
struct InitializeRelease { | ||
static func setupRepo(gitRoot: URL) -> String { | ||
let manifest = FirebaseManifest.shared | ||
let branch = createReleaseBranch(path: gitRoot, version: manifest.version) | ||
updatePodspecs(path: gitRoot, manifest: manifest) | ||
updatePodfiles(path: gitRoot, version: manifest.version) | ||
return branch | ||
} | ||
|
||
/// The branch is based on the minor version to represent this is the branch for subsequent | ||
/// patches. | ||
private static func createReleaseBranch(path: URL, version: String) -> String { | ||
let versionParts = version.split(separator: ".") | ||
let minorVersion = "\(versionParts[0]).\(versionParts[1])" | ||
let branch = "release-\(minorVersion)" | ||
Shell.executeCommand("git checkout master", workingDir: path) | ||
Shell.executeCommand("git pull", workingDir: path) | ||
Shell.executeCommand("git checkout -b \(branch)", workingDir: path) | ||
return branch | ||
} | ||
|
||
/// Update the podspec versions. | ||
private static func updatePodspecs(path: URL, manifest: FirebaseManifest.Manifest) { | ||
for pod in manifest.pods { | ||
if !pod.isClosedSource { | ||
if pod.name == "Firebase" { | ||
updateFirebasePodspec(path: path, manifest: manifest) | ||
} else { | ||
let version = pod.podVersion ?? | ||
(pod.isBeta ? manifest.version + "-beta" : manifest.version) | ||
|
||
// Patch the new version to the podspec's version attribute. | ||
Shell.executeCommand("sed -i.bak -e \"s/\\(\\.version.*=[[:space:]]*'\\).*'/\\1" + | ||
"\(version)'/\" \(pod.name).podspec", workingDir: path) | ||
} | ||
} | ||
} | ||
} | ||
|
||
// This function patches the versions in the Firebase.podspec. It uses Swift instead of sed | ||
// like the other version patching. | ||
// TODO: Choose one or the other mechanism. | ||
// TODO: If we keep Swift, consider using Scanner. | ||
private static func updateFirebasePodspec(path: URL, manifest: FirebaseManifest.Manifest) { | ||
let podspecFile = path.appendingPathComponent("Firebase.podspec") | ||
var contents = "" | ||
do { | ||
contents = try String(contentsOfFile: podspecFile.path, encoding: .utf8) | ||
} catch { | ||
fatalError("Could not read Firebase podspec. \(error)") | ||
} | ||
let firebaseVersion = manifest.version | ||
for firebasePod in manifest.pods { | ||
if !firebasePod.isFirebase { | ||
continue | ||
} | ||
let pod = firebasePod.name | ||
let version = firebasePod.isBeta ? firebaseVersion + "-beta" : firebaseVersion | ||
if pod == "Firebase" { | ||
// TODO: This then block is redundant with the updatePodspecs function above and is left | ||
// until we decide to go with Swift or sed. | ||
// Replace version in string like s.version = '6.9.0' | ||
guard let range = contents.range(of: "s.version") else { | ||
fatalError("Could not find version of Firebase pod in podspec at \(podspecFile)") | ||
} | ||
var versionStartIndex = contents.index(range.upperBound, offsetBy: 1) | ||
while contents[versionStartIndex] != "'" { | ||
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1) | ||
} | ||
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1) | ||
while contents[versionEndIndex] != "'" { | ||
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1) | ||
} | ||
contents.removeSubrange(versionStartIndex ... versionEndIndex) | ||
contents.insert(contentsOf: "'" + version + "'", at: versionStartIndex) | ||
} else { | ||
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0' | ||
guard let range = contents.range(of: pod) else { | ||
// This pod is not a top-level Firebase pod dependency. | ||
continue | ||
} | ||
var versionStartIndex = contents.index(range.upperBound, offsetBy: 2) | ||
while !contents[versionStartIndex].isWholeNumber { | ||
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1) | ||
} | ||
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1) | ||
while contents[versionEndIndex] != "'" { | ||
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1) | ||
} | ||
contents.removeSubrange(versionStartIndex ... versionEndIndex) | ||
contents.insert(contentsOf: version + "'", at: versionStartIndex) | ||
} | ||
} | ||
do { | ||
try contents.write(to: podspecFile, atomically: false, encoding: .utf8) | ||
} catch { | ||
fatalError("Failed to write \(podspecFile.path). \(error)") | ||
} | ||
} | ||
|
||
private static func updatePodfiles(path: URL, version: String) { | ||
// Update the Podfiles across the repo. | ||
let firestorePodfile = path.appendingPathComponent("Firestore") | ||
.appendingPathComponent("Example") | ||
let collisionPodfile = path.appendingPathComponent("SymbolCollisionTest") | ||
let sedCommand = "sed -i.bak -e \"s#\\(pod " + | ||
"'Firebase/CoreOnly',[[:space:]]*'\\).*'#\\1\(version)'#\" Podfile" | ||
Shell.executeCommand(sedCommand, workingDir: firestorePodfile) | ||
|
||
let sedCommand2 = "sed -i.bak -e \"s#\\(pod " + | ||
"'Firebase',[[:space:]]*'\\).*'#\\1\(version)'#\" Podfile" | ||
Shell.executeCommand(sedCommand2, workingDir: collisionPodfile) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
import FirebaseManifest | ||
import Utils | ||
|
||
enum Push { | ||
static func pushPodsToCPDC(gitRoot: URL) { | ||
let cpdcLocation = findCpdc(gitRoot: gitRoot) | ||
let manifest = FirebaseManifest.shared | ||
|
||
for pod in manifest.pods { | ||
if !pod.releasing { | ||
continue | ||
} | ||
let warningsOK = pod.allowWarnings ? " --allow-warnings" : "" | ||
|
||
Shell.executeCommand("pod repo push --skip-tests --use-json \(warningsOK) \(cpdcLocation) " + | ||
pod.skipImportValidation() + " \(pod.podspecName()) " + | ||
"--sources=sso://cpdc-internal/firebase.git,https://cdn.cocoapods.org", | ||
workingDir: gitRoot) | ||
} | ||
} | ||
|
||
private static func findCpdc(gitRoot: URL) -> String { | ||
let command = "pod repo list | grep -B2 sso://cpdc-internal/firebase | head -1" | ||
let result = Shell.executeCommandFromScript(command, workingDir: gitRoot) | ||
switch result { | ||
case let .error(code, output): | ||
fatalError(""" | ||
`pod --version` failed with exit code \(code) | ||
Output from `pod repo list`: | ||
\(output) | ||
""") | ||
case let .success(output): | ||
print(output) | ||
return output.trimmingCharacters(in: .whitespacesAndNewlines) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
import FirebaseManifest | ||
import Utils | ||
|
||
enum Tags { | ||
static func create(gitRoot: URL) { | ||
let manifest = FirebaseManifest.shared | ||
createTag(gitRoot: gitRoot, tag: "CocoaPods-\(manifest.version)") | ||
createTag(gitRoot: gitRoot, tag: "CocoaPods-\(manifest.version)-beta") | ||
|
||
for pod in manifest.pods { | ||
if pod.isFirebase { | ||
continue | ||
} | ||
if !pod.name.starts(with: "Google") { | ||
fatalError("Unrecognized Other Pod: \(pod.name). Only Google prefix is recognized") | ||
} | ||
guard let version = pod.podVersion else { | ||
fatalError("Non-Firebase pod \(pod.name) is missing a version") | ||
} | ||
let tag = pod.name.replacingOccurrences(of: "Google", with: "") + "-" + version | ||
createTag(gitRoot: gitRoot, tag: tag) | ||
} | ||
} | ||
|
||
private static func createTag(gitRoot: URL, tag: String) { | ||
Shell.executeCommand("git tag \(tag)", workingDir: gitRoot) | ||
Shell.executeCommand("git push origin \(tag)", workingDir: gitRoot) | ||
} | ||
} |
Oops, something went wrong.