From f0074fdca0f0bc4e19b9eb70b57304688dcc3802 Mon Sep 17 00:00:00 2001 From: Josh Elkins Date: Tue, 14 Jan 2025 16:16:17 -0600 Subject: [PATCH] chore: Don't fail prepare-release when build request is missing (#1865) --- .../Subcommands/PrepareRelease.swift | 12 ++++ .../AWSSDKSwiftCLI/Models/Features.swift | 13 +++-- .../Commands/PrepareReleaseTests.swift | 56 +++++++++++++++---- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/PrepareRelease.swift b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/PrepareRelease.swift index 8052a3017f1..f4abb8a35af 100644 --- a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/PrepareRelease.swift +++ b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Commands/AWSSDKSwiftCLI/Subcommands/PrepareRelease.swift @@ -86,6 +86,18 @@ struct PrepareRelease { /// Empty manifest file makes GitHubReleasePublisher be no-op. /// The manifest file is required regardless of whether there should /// be a release or not. + log("Repo has no changes to publish.") + log("Writing empty manifest and exiting.") + try createEmptyReleaseManifest() + /// Return without creating new commit or tag in local repos. + /// This makes GitPublisher be no-op. + return + } + guard FeaturesReader.buildRequestAndMappingExist() else { + /// If the build request or mapping input files + /// don't exist, create an empty release-manifest.json file. + log("build-request.json and/or feature-service-id.json don't exist.") + log("Writing empty manifest and exiting.") try createEmptyReleaseManifest() /// Return without creating new commit or tag in local repos. /// This makes GitPublisher be no-op. diff --git a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Models/Features.swift b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Models/Features.swift index 275708ba0bc..197830415c4 100644 --- a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Models/Features.swift +++ b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Models/Features.swift @@ -10,16 +10,21 @@ import AWSCLIUtils /// Reads the Trebuchet request & service mapping files from the parent of the current working directory. struct FeaturesReader { - private let requestFile = "../build-request.json" - private let mappingFile = "../feature-service-id.json" + private static let requestFile = "../build-request.json" + private static let mappingFile = "../feature-service-id.json" + + public static func buildRequestAndMappingExist() -> Bool { + return FileManager.default.fileExists(atPath: requestFile) && + FileManager.default.fileExists(atPath: mappingFile) + } public func getFeaturesFromFile() throws -> Features { - let fileContents = try FileManager.default.loadContents(atPath: requestFile) + let fileContents = try FileManager.default.loadContents(atPath: Self.requestFile) return try JSONDecoder().decode(Features.self, from: fileContents) } public func getFeaturesIDToServiceNameDictFromFile() throws -> [String: String] { - let fileContents = try FileManager.default.loadContents(atPath: mappingFile) + let fileContents = try FileManager.default.loadContents(atPath: Self.mappingFile) return try JSONDecoder().decode([String: String].self, from: fileContents) } } diff --git a/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/PrepareReleaseTests.swift b/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/PrepareReleaseTests.swift index 974192fc5ab..8d036daccb3 100644 --- a/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/PrepareReleaseTests.swift +++ b/AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Commands/PrepareReleaseTests.swift @@ -45,15 +45,7 @@ class PrepareReleaseTests: CLITestCase { createPackageVersion(previousVersion) createNextPackageVersion(newVersion) - let buildRequest = """ - { - "features": [] - } - """ - FileManager.default.createFile(atPath: "../build-request.json", contents: Data(buildRequest.utf8)) - - let mapping = "{}" - FileManager.default.createFile(atPath: "../feature-service-id.json", contents: Data(mapping.utf8)) + createBuildRequestAndMapping() let subject = PrepareRelease.mock(repoType: .awsSdkSwift, diffChecker: { _,_ in true }) try! subject.run() @@ -87,15 +79,45 @@ class PrepareReleaseTests: CLITestCase { createPackageVersion(previousVersion) createNextPackageVersion(newVersion) + createBuildRequestAndMapping() + let subject = PrepareRelease.mock(diffChecker: { _,_ in false }) try! subject.run() - + let versionFromFile = try! Version.fromFile("Package.version") XCTAssertEqual(versionFromFile, previousVersion) - + XCTAssertTrue(commands.isEmpty) + + // Verify that an empty release manifest was written + let data = try FileManager.default.loadContents(atPath: "release-manifest.json") + XCTAssertTrue(data.isEmpty) } - + + func testRunBailsEarlyIfThereAreNoBuildRequestAndMapping() throws { + var commands: [String] = [] + let runner = ProcessRunner { + commands.append($0.commandString) + } + ProcessRunner.testRunner = runner + let previousVersion = try Version("1.2.3") + let newVersion = try Version("1.2.4") + createPackageVersion(previousVersion) + createNextPackageVersion(newVersion) + + let subject = PrepareRelease.mock(diffChecker: { _,_ in true }) + try! subject.run() + + let versionFromFile = try! Version.fromFile("Package.version") + XCTAssertEqual(versionFromFile, previousVersion) + + XCTAssertTrue(commands.isEmpty) + + // Verify that an empty release manifest was written + let data = try FileManager.default.loadContents(atPath: "release-manifest.json") + XCTAssertTrue(data.isEmpty) + } + // MARK: createNewVersion() func testCreateNewSDKVersion() async throws { @@ -175,6 +197,16 @@ class PrepareReleaseTests: CLITestCase { try! subject.stageFiles() XCTAssertTrue(command.hasSuffix("git add Package.version Package.version.next")) } + + // MARK: - Private methods + + private func createBuildRequestAndMapping() { + let buildRequest = "{\"features\":[]}" + FileManager.default.createFile(atPath: "../build-request.json", contents: Data(buildRequest.utf8)) + + let mapping = "{}" + FileManager.default.createFile(atPath: "../feature-service-id.json", contents: Data(mapping.utf8)) + } } // MARK: - Mocks