-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Service client release notes (#1783)
* Add features struct and feature struct for grabbing info we need from build request and feature to service name mapping JSON files. * Add service feature & service documentation sections to release notes generation. Also, refactor it for consistent spacing between the lines even when sections are omitted. * Update existing code that uses ReleaseNotesBuilder to reflect new changes. * Update test that fails; possibly from previous package manifest change. * Add regression tests for release notes builder. * Only build service client sections in release notes if the repo is aws-sdk-swift. * Add test flag (grr) to ReleaseNotesBuilder to allow tests. In real scenarios the JSON files we need are located in parent directory of aws-sdk-swift, but due to sandboxing, we can't save the dummy files to parent directory and instead can only save it in current directory. Use the flag to differentiate the path to retrieve JSON files from. * Resolve Josh's PR comments * Temporarily comment out repo has change check for running E2E test. * Uncomment temporarily commented logic for generating empty manfiest if repo has no changes. * Change SDK changes section name from AWS SDK for Swift to Miscellaneous & change commit filter criteria from discaring chore and Update, to including feat and fix. * Handle null value for releaseNotes and add test for it. * Temporarily disable diff checker for running E2E tests * Uncomment temporarily commented out diff logic. --------- Co-authored-by: Sichan Yoo <[email protected]>
- Loading branch information
Showing
6 changed files
with
331 additions
and
16 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
50 changes: 50 additions & 0 deletions
50
AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Models/Features.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,50 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
import Foundation | ||
import AWSCLIUtils | ||
|
||
struct FeaturesReader: Decodable { | ||
private let requestFilePath: String | ||
private let mappingFilePath: String | ||
|
||
public init( | ||
requestFilePath: String = "../build-request.json", | ||
mappingFilePath: String = "../feature-service-id.json" | ||
) { | ||
self.requestFilePath = requestFilePath | ||
self.mappingFilePath = mappingFilePath | ||
} | ||
|
||
public func getFeaturesFromFile() throws -> Features { | ||
let fileContents = try FileManager.default.loadContents(atPath: requestFilePath) | ||
return try JSONDecoder().decode(Features.self, from: fileContents) | ||
} | ||
|
||
public func getFeaturesIDToServiceNameDictFromFile() throws -> [String: String] { | ||
let fileContents = try FileManager.default.loadContents(atPath: mappingFilePath) | ||
return try JSONDecoder().decode([String: String].self, from: fileContents) | ||
} | ||
} | ||
|
||
struct Features: Decodable { | ||
let features: [Feature] | ||
} | ||
|
||
struct Feature: Decodable { | ||
let releaseNotes: String? | ||
let featureMetadata: FeatureMetadata | ||
|
||
struct FeatureMetadata: Decodable { | ||
let trebuchet: Trebuchet | ||
|
||
struct Trebuchet: Decodable { | ||
let featureId: String | ||
let featureType: String | ||
} | ||
} | ||
} |
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
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
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
218 changes: 218 additions & 0 deletions
218
AWSSDKSwiftCLI/Tests/AWSSDKSwiftCLITests/Models/ReleaseNotesBuilderTests.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,218 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
@testable import AWSSDKSwiftCLI | ||
import AWSCLIUtils | ||
import XCTest | ||
|
||
/* | ||
* Regression tests for protection against change in generated release notes markdown content. | ||
*/ | ||
class ReleaseNotesBuilderTests: XCTestCase { | ||
/* Reusable feature strings */ | ||
|
||
// New feature 1 | ||
private let feature1 = """ | ||
{ | ||
"releaseNotes": "New feature description A.", | ||
"featureMetadata": { | ||
"trebuchet": { | ||
"featureId": "feature-id-a", | ||
"featureType": "NEW_FEATURE", | ||
} | ||
} | ||
} | ||
""" | ||
|
||
// New feature 2 | ||
private let feature2 = """ | ||
{ | ||
"releaseNotes": "New feature description B.", | ||
"featureMetadata": { | ||
"trebuchet": { | ||
"featureId": "feature-id-b", | ||
"featureType": "NEW_FEATURE", | ||
} | ||
} | ||
} | ||
""" | ||
|
||
// Documentation update | ||
private let feature3 = """ | ||
{ | ||
"releaseNotes": "Doc update description C.", | ||
"featureMetadata": { | ||
"trebuchet": { | ||
"featureId": "feature-id-c", | ||
"featureType": "DOC_UPDATE", | ||
} | ||
} | ||
} | ||
""" | ||
|
||
// Feature with null releaseNotes field | ||
private let feature4 = """ | ||
{ | ||
"releaseNotes": null, | ||
"featureMetadata": { | ||
"trebuchet": { | ||
"featureId": "feature-id-d", | ||
"featureType": "DOC_UPDATE", | ||
} | ||
} | ||
} | ||
""" | ||
|
||
// Dictionary of feature ID to name of the service | ||
private let mapping = """ | ||
{ | ||
"feature-id-a": "Service 1", | ||
"feature-id-b": "Service 2", | ||
"feature-id-c": "Service 3", | ||
"feature-id-d": "Service 4" | ||
} | ||
""" | ||
|
||
func testAllSectionsPresent() throws { | ||
let buildRequest = """ | ||
{ "features": [\(feature1), \(feature2), \(feature3)] } | ||
""" | ||
setUpBuildRequestAndMappingJSONs(buildRequest, mapping) | ||
let builder = try setUpBuilder(testCommits: ["fix: Fix X", "feat: Feat Y"]) | ||
let releaseNotes = try builder.build() | ||
let expected = """ | ||
## What's Changed | ||
### Service Features | ||
* **AWS Service 1**: New feature description A. | ||
* **AWS Service 2**: New feature description B. | ||
### Service Documentation | ||
* **AWS Service 3**: Doc update description C. | ||
### Miscellaneous | ||
* fix: Fix X | ||
* feat: Feat Y | ||
**Full Changelog**: https://github.com/awslabs/aws-sdk-swift/compare/1.0.0...1.0.1 | ||
""" | ||
XCTAssertEqual(releaseNotes, expected) | ||
} | ||
|
||
func testNoServiceFeatureSectionPresent() throws { | ||
let buildRequest = """ | ||
{ "features": [\(feature3)] } | ||
""" | ||
setUpBuildRequestAndMappingJSONs(buildRequest, mapping) | ||
let builder = try setUpBuilder(testCommits: ["fix: Fix X", "feat: Feat Y"]) | ||
let releaseNotes = try builder.build() | ||
let expected = """ | ||
## What's Changed | ||
### Service Documentation | ||
* **AWS Service 3**: Doc update description C. | ||
### Miscellaneous | ||
* fix: Fix X | ||
* feat: Feat Y | ||
**Full Changelog**: https://github.com/awslabs/aws-sdk-swift/compare/1.0.0...1.0.1 | ||
""" | ||
XCTAssertEqual(releaseNotes, expected) | ||
} | ||
|
||
func testNoServiceDocSectionPresent() throws { | ||
let buildRequest = """ | ||
{ "features": [\(feature1), \(feature2)] } | ||
""" | ||
setUpBuildRequestAndMappingJSONs(buildRequest, mapping) | ||
let builder = try setUpBuilder(testCommits: ["fix: Fix X", "feat: Feat Y"]) | ||
let releaseNotes = try builder.build() | ||
let expected = """ | ||
## What's Changed | ||
### Service Features | ||
* **AWS Service 1**: New feature description A. | ||
* **AWS Service 2**: New feature description B. | ||
### Miscellaneous | ||
* fix: Fix X | ||
* feat: Feat Y | ||
**Full Changelog**: https://github.com/awslabs/aws-sdk-swift/compare/1.0.0...1.0.1 | ||
""" | ||
XCTAssertEqual(releaseNotes, expected) | ||
} | ||
|
||
func testNoSDKChangeSectionPresent() throws { | ||
let buildRequest = """ | ||
{ "features": [\(feature1), \(feature2), \(feature3)] } | ||
""" | ||
setUpBuildRequestAndMappingJSONs(buildRequest, mapping) | ||
let builder = try setUpBuilder() | ||
let releaseNotes = try builder.build() | ||
let expected = """ | ||
## What's Changed | ||
### Service Features | ||
* **AWS Service 1**: New feature description A. | ||
* **AWS Service 2**: New feature description B. | ||
### Service Documentation | ||
* **AWS Service 3**: Doc update description C. | ||
**Full Changelog**: https://github.com/awslabs/aws-sdk-swift/compare/1.0.0...1.0.1 | ||
""" | ||
XCTAssertEqual(releaseNotes, expected) | ||
} | ||
|
||
func testNoSectionsPresentAndIrrelevantCommitsAreFiltered() throws { | ||
let buildRequest = """ | ||
{ "features":[] } | ||
""" | ||
setUpBuildRequestAndMappingJSONs(buildRequest, mapping) | ||
let builder = try setUpBuilder(testCommits: ["chore: Commit A", "Update X"]) | ||
let releaseNotes = try builder.build() | ||
let expected = """ | ||
## What's Changed | ||
**Full Changelog**: https://github.com/awslabs/aws-sdk-swift/compare/1.0.0...1.0.1 | ||
""" | ||
XCTAssertEqual(releaseNotes, expected) | ||
} | ||
|
||
func testNullReleaseNotesFieldGetsHandledWithoutError() throws { | ||
let buildRequest = """ | ||
{ "features": [\(feature4)] } | ||
""" | ||
setUpBuildRequestAndMappingJSONs(buildRequest, mapping) | ||
let builder = try setUpBuilder() | ||
let releaseNotes = try builder.build() | ||
let expected = """ | ||
## What's Changed | ||
### Service Documentation | ||
* **AWS Service 4**: No description provided. | ||
**Full Changelog**: https://github.com/awslabs/aws-sdk-swift/compare/1.0.0...1.0.1 | ||
""" | ||
XCTAssertEqual(releaseNotes, expected) | ||
} | ||
|
||
private func setUpBuildRequestAndMappingJSONs(_ buildRequest: String, _ mapping: String) { | ||
// In real scenario, the JSON files we need are located one level above, in the workspace directory. | ||
// For tests, due to sandboxing, the dummy files are created in current directory instead of | ||
// in parent directory. | ||
FileManager.default.createFile(atPath: "build-request.json", contents: Data(buildRequest.utf8)) | ||
FileManager.default.createFile(atPath: "feature-service-id.json", contents: Data(mapping.utf8)) | ||
} | ||
|
||
private func setUpBuilder(testCommits: [String] = []) throws -> ReleaseNotesBuilder { | ||
return try ReleaseNotesBuilder( | ||
previousVersion: Version("1.0.0"), | ||
newVersion: Version("1.0.1"), | ||
repoOrg: .awslabs, | ||
repoType: .awsSdkSwift, | ||
commits: testCommits, | ||
// Parametrize behavior of FeaturesReader with paths used to create JSON test files | ||
featuresReader: FeaturesReader( | ||
requestFilePath: "build-request.json", | ||
mappingFilePath: "feature-service-id.json" | ||
) | ||
) | ||
} | ||
} |