diff --git a/Package.swift b/Package.swift index 0d164c8..46293df 100644 --- a/Package.swift +++ b/Package.swift @@ -15,13 +15,13 @@ let package = Package( dependencies: [ // dev .package(url: "https://github.com/danger/swift", from: "3.0.0"), // dev .package(path: "Submodules/WeTransfer-iOS-CI/Danger-Swift"), - .package(url: "https://github.com/WeTransfer/Mocker.git", from: "2.0.0"), + // dev .package(url: "https://github.com/WeTransfer/Mocker.git", from: "2.1.0"), // .package(url: "https://github.com/nerdishbynature/octokit.swift", from: "0.9.0"), .package(url: "https://github.com/nerdishbynature/octokit.swift", .branch("feature/bugfixes")), .package(url: "https://github.com/apple/swift-package-manager.git", from: "0.1.0") ], targets: [ - .testTarget(name: "GitBuddyTests", dependencies: ["GitBuddy", "Mocker"]), + // dev .testTarget(name: "GitBuddyTests", dependencies: ["GitBuddy", "Mocker"]), // dev .target(name: "DangerDependencies", dependencies: ["Danger", "WeTransferPRLinter"], path: "Submodules/WeTransfer-iOS-CI/Danger-Swift", sources: ["DangerFakeSource.swift"]), .target(name: "GitBuddy", dependencies: ["GitBuddyCore"]), .target(name: "GitBuddyCore", dependencies: ["OctoKit", "SPMUtility"]) diff --git a/README.md b/README.md index dc186c3..ca497b6 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,10 @@ $ gitbuddy changelog --help OVERVIEW: Create a changelog for GitHub repositories OPTIONS: - --baseBranch, -b The base branch to compare with. Defaults to master. - --sinceTag, -s The tag to use as a base. Defaults to the latest tag. - --verbose Show extra logging for debugging purposes + --base-branch, -b The base branch to compare with. Defaults to master. + --help Display available options + --since-tag, -s The tag to use as a base. Defaults to the latest tag. + --verbose Show extra logging for debugging purposes ``` This command generates a changelog based on merged PRs and fixed issues. Once a PR contains a reference like `"Fixed #30"`, the title of issue 30 will be included in the changelog. Otherwise, the Pull Request title will be used. @@ -44,9 +45,11 @@ $ gitbuddy release --help OVERVIEW: Create a new release including a changelog and publish comments on related issues OPTIONS: - --changelogPath, -c The path to the Changelog to update it with the latest changes - --skipComments, -s Disable commenting on issues and PRs about the new release - --verbose Show extra logging for debugging purposes + --changelog-path, -c The path to the Changelog to update it with the latest changes + --help Display available options + --skip-comments, -s Disable commenting on issues and PRs about the new release + --use-pre-release, -p Create the release as a pre-release + --verbose Show extra logging for debugging purposes ``` The `release` command can be used to transform the latest tag into a GitHub release including the changelog as a body. diff --git a/Sources/GitBuddyCore/Release/ReleaseProducer.swift b/Sources/GitBuddyCore/Release/ReleaseProducer.swift index 2fa0099..cccce2f 100644 --- a/Sources/GitBuddyCore/Release/ReleaseProducer.swift +++ b/Sources/GitBuddyCore/Release/ReleaseProducer.swift @@ -15,15 +15,18 @@ struct ReleaseCommand: Command { static let description = "Create a new release including a changelog and publish comments on related issues" let changelogPath: OptionArgument let skipComments: OptionArgument + let isPrelease: OptionArgument init(subparser: ArgumentParser) { changelogPath = subparser.add(option: "--changelog-path", shortName: "-c", kind: String.self, usage: "The path to the Changelog to update it with the latest changes") skipComments = subparser.add(option: "--skip-comments", shortName: "-s", kind: Bool.self, usage: "Disable commenting on issues and PRs about the new release") + isPrelease = subparser.add(option: "--use-pre-release", shortName: "-p", kind: Bool.self, usage: "Create the release as a pre-release") } @discardableResult func run(using arguments: ArgumentParser.Result) throws -> String { let changelogProducer = try ReleaseProducer(changelogPath: arguments.get(changelogPath), - skipComments: arguments.get(skipComments) ?? false) + skipComments: arguments.get(skipComments) ?? false, + isPrelease: arguments.get(isPrelease) ?? false) Log.debug("Result of creating the release:\n") return try changelogProducer.run().url.absoluteString @@ -36,14 +39,16 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { private lazy var octoKit: Octokit = Octokit() let changelogURL: Foundation.URL? let skipComments: Bool + let isPrelease: Bool - init(changelogPath: String?, skipComments: Bool) throws { + init(changelogPath: String?, skipComments: Bool, isPrelease: Bool) throws { if let changelogPath = changelogPath { changelogURL = URL(string: changelogPath) } else { changelogURL = nil } self.skipComments = skipComments + self.isPrelease = isPrelease } @discardableResult public func run() throws -> Release { @@ -108,7 +113,7 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { group.enter() var result: Result! - octoKit.postRelease(urlSession, owner: project.organisation, repository: project.repository, tagName: tag.name, name: tag.name, body: body, prerelease: false, draft: false) { (response) in + octoKit.postRelease(urlSession, owner: project.organisation, repository: project.repository, tagName: tag.name, name: tag.name, body: body, prerelease: isPrelease, draft: false) { (response) in switch response { case .success(let release): result = .success(release.htmlURL) diff --git a/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift b/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift index 6f8bbcc..277ec0a 100644 --- a/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift +++ b/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift @@ -41,6 +41,28 @@ final class ReleaseProducerTests: XCTestCase { XCTAssertEqual(releaseURL, "https://github.com/WeTransfer/ChangelogProducer/releases/tag/1.0.1") } + /// It should set the parameters correctly. + func testPostBodyArguments() throws { + let mockExpectation = expectation(description: "Mocks should be called") + var mock = Mocker.mockRelease() + mock.onRequest = { _, parameters in + guard let parameters = try? XCTUnwrap(parameters) else { return } + XCTAssertEqual(parameters["prerelease"] as? Bool, false) + XCTAssertEqual(parameters["draft"] as? Bool, false) + XCTAssertEqual(parameters["tag_name"] as? String, "1.0.1") + XCTAssertEqual(parameters["name"] as? String, "1.0.1") + XCTAssertEqual(parameters["body"] as? String, """ + - Add charset utf-8 to html head ([#50](https://github.com/WeTransfer/Diagnostics/pull/50)) via @AvdLee + - Get warning for file 'style.css' after building ([#39](https://github.com/WeTransfer/Diagnostics/issues/39)) via @AvdLee + """) + mockExpectation.fulfill() + } + mock.register() + + _ = try GitBuddy.run(arguments: ["GitBuddy", "release", "-s"], configuration: configuration) + wait(for: [mockExpectation], timeout: 0.3) + } + /// It should update the changelog file if the argument is set. func testChangelogUpdating() throws { let existingChangelog = """ @@ -83,7 +105,7 @@ final class ReleaseProducerTests: XCTestCase { /// It should not post comments if --skipComments is passed as an argument. func testSkippingComments() throws { - let mockExpectation = expectation(description: "Mocks should be called") + let mockExpectation = expectation(description: "Mock should not be called") mockExpectation.isInverted = true var mock = Mocker.mockForCommentingOn(issueNumber: 39) mock.completion = { @@ -94,4 +116,19 @@ final class ReleaseProducerTests: XCTestCase { _ = try GitBuddy.run(arguments: ["GitBuddy", "release", "-s"], configuration: configuration) wait(for: [mockExpectation], timeout: 0.3) } + + /// It should use the prerelease setting. + func testPrerelease() throws { + let mockExpectation = expectation(description: "Mocks should be called") + var mock = Mocker.mockRelease() + mock.onRequest = { _, parameters in + guard let parameters = try? XCTUnwrap(parameters) else { return } + XCTAssertTrue(parameters["prerelease"] as? Bool == true) + mockExpectation.fulfill() + } + mock.register() + + _ = try GitBuddy.run(arguments: ["GitBuddy", "release", "-s", "-p"], configuration: configuration) + wait(for: [mockExpectation], timeout: 0.3) + } } diff --git a/Tests/GitBuddyTests/TestHelpers/Mocks.swift b/Tests/GitBuddyTests/TestHelpers/Mocks.swift index fe43345..b1e8b70 100644 --- a/Tests/GitBuddyTests/TestHelpers/Mocks.swift +++ b/Tests/GitBuddyTests/TestHelpers/Mocks.swift @@ -79,9 +79,11 @@ extension Mocker { Mock(url: urlComponents.url!, dataType: .json, statusCode: 200, data: [.get: issueJSONData]).register() } - static func mockRelease() { + @discardableResult static func mockRelease() -> Mock { let releaseJSONData = ReleaseJSON.data(using: .utf8)! - Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases")!, dataType: .json, statusCode: 201, data: [.post: releaseJSONData]).register() + let mock = Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases")!, dataType: .json, statusCode: 201, data: [.post: releaseJSONData]) + mock.register() + return mock } static func mockForCommentingOn(issueNumber: Int) -> Mock {