Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLOUDP-267267: Update changelog creation to use the exemption file #170

Merged
merged 28 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
68a0dea
feat: update the changelog create command to save changelog and chang…
andreaangiolillo Aug 14, 2024
3696637
Delete tools/cli/cmd/changelog.json.yaml
andreaangiolillo Aug 14, 2024
4f2b81e
fixed bug
andreaangiolillo Aug 14, 2024
cb6d14d
Update squash.go
andreaangiolillo Aug 14, 2024
339f86b
Update squash.go
andreaangiolillo Aug 14, 2024
f7e260b
Update squash.go
andreaangiolillo Aug 14, 2024
ef96d58
Update message.go
andreaangiolillo Aug 14, 2024
1db27af
Merge remote-tracking branch 'origin/main' into fix_changelog
andreaangiolillo Aug 15, 2024
5c8c14a
Merge remote-tracking branch 'origin/main' into CLOUDP-266429_add_v
andreaangiolillo Aug 15, 2024
ea868b4
CLOUDP-266429: Update the changelog create command to compare all the…
andreaangiolillo Aug 15, 2024
fc3ee44
Update changelog.go
andreaangiolillo Aug 15, 2024
3e7c9b8
fixes
andreaangiolillo Aug 15, 2024
a3fd56c
Update create.go
andreaangiolillo Aug 15, 2024
64e8457
CLOUDP-267267: Update changelog creation to use the exemption file
andreaangiolillo Aug 15, 2024
c0fe99a
Update exemptions.go
andreaangiolillo Aug 15, 2024
0728350
updates
andreaangiolillo Aug 15, 2024
fde0208
merged master
andreaangiolillo Aug 15, 2024
40395a2
Update changelog.go
andreaangiolillo Aug 15, 2024
5f7cf2f
fixes
andreaangiolillo Aug 16, 2024
5fa95b5
Update hide.go
andreaangiolillo Aug 19, 2024
b85dc47
Update merge.go
andreaangiolillo Aug 19, 2024
fa6865b
Update squash.go
andreaangiolillo Aug 19, 2024
afef51f
Update create.go
andreaangiolillo Aug 19, 2024
0ab924e
Merge remote-tracking branch 'origin/main' into CLOUDP-267267
andreaangiolillo Aug 19, 2024
2b899c6
Update changelog_test.go
andreaangiolillo Aug 19, 2024
838f616
Update outputfilter.go
andreaangiolillo Aug 19, 2024
b08f060
fixes
andreaangiolillo Aug 19, 2024
221b2af
CLOUDP-267018: [Unit Test] migrate test_openapi_spec.py
andreaangiolillo Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tools/cli/internal/breakingchanges/exemptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Exemption struct {
BreakingChangeDescription string `yaml:"breaking_change_description"`
ExemptUntil string `yaml:"exempt_until"`
Reason string `yaml:"reason"`
HideFromChangelog string `yaml:"hide_from_changelog:omitempty"`
HideFromChangelog string `yaml:"hide_from_changelog,omitempty"`
}

func (e *Exemption) isHidden() bool {
Expand Down
49 changes: 27 additions & 22 deletions tools/cli/internal/changelog/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@ type Changelog struct {
}

type Metadata struct {
Path string
ActiveVersion string
Path string `json:"path,omitempty"`
ActiveVersion string `json:"activeVersion,omitempty"`
RunDate string `json:"runDate"`
SpecRevision string `json:"specRevision"`
SpecRevision string `json:"specRevision,omitempty"`
Versions []string `json:"versions"`
}

type Entry struct {
Date string `json:"date"`
Paths []*Path `json:"paths"`
FromVersion string
ToVersion string
FromVersion string `json:"fromVersion,omitempty"`
ToVersion string `json:"toVersion,omitempty"`
}

type Path struct {
Expand Down Expand Up @@ -98,7 +98,7 @@ type Change struct {
// NewEntries generates the changelog entries between the base and revision specs.
// The returned entries includes all the changes between the base and revision specs included the one
// marked as hidden.
func NewEntries(basePath, revisionPath string) ([]*Entry, error) {
func NewEntries(basePath, revisionPath, exceptionFilePath string) ([]*Entry, error) {
baseMetadata, err := newMetadataFromFile(basePath)
if err != nil {
return nil, err
Expand Down Expand Up @@ -142,7 +142,7 @@ func NewEntries(basePath, revisionPath string) ([]*Entry, error) {
baseMetadata.ActiveVersion = baseActiveVersionOnPreviousRunDate
revisionMetadata.ActiveVersion = revisionActiveVersionOnPreviousRunDate

changelog, err := newChangelog(baseMetadata, revisionMetadata, nil)
changelog, err := newChangelog(baseMetadata, revisionMetadata, exceptionFilePath, nil)
if err != nil {
return nil, err
}
Expand All @@ -160,7 +160,7 @@ func NewEntries(basePath, revisionPath string) ([]*Entry, error) {
// baseActiveVersionOnPreviousRunDate with revisionActiveVersionOnPreviousRunDate)
baseMetadata.ActiveVersion = baseActiveVersionOnRunDate
revisionMetadata.ActiveVersion = revisionActiveVersionOnRunDate
changelog, err = newChangelog(baseMetadata, revisionMetadata, changelogEntries)
changelog, err = newChangelog(baseMetadata, revisionMetadata, exceptionFilePath, changelogEntries)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -193,17 +193,17 @@ func NewEntries(basePath, revisionPath string) ([]*Entry, error) {
// NewEntriesWithoutHidden generates the changelog entries between the base and revision specs.
// The returned entries includes the changes between the base and revision specs that are not
// marked as hidden.
func NewEntriesWithoutHidden(basePath, revisionPath string) ([]*Entry, error) {
entries, err := NewEntries(basePath, revisionPath)
func NewEntriesWithoutHidden(basePath, revisionPath, exceptionFilePath string) ([]*Entry, error) {
entries, err := NewEntries(basePath, revisionPath, exceptionFilePath)
if err != nil {
return nil, err
}

return NewNotHiddenEntries(entries), nil
return NewNotHiddenEntries(entries)
}

// NewEntriesBetweenRevisionVersions generates the changelog entries between the revision versions.
func NewEntriesBetweenRevisionVersions(revisionPath string) ([]*Entry, error) {
func NewEntriesBetweenRevisionVersions(revisionPath, exceptionFilePath string) ([]*Entry, error) {
revisionMetadata, err := newMetadataFromFile(revisionPath)
if err != nil {
return nil, err
Expand All @@ -212,7 +212,7 @@ func NewEntriesBetweenRevisionVersions(revisionPath string) ([]*Entry, error) {
entries := []*Entry{}
for idx, fromVersion := range revisionMetadata.Versions {
for _, toVersion := range revisionMetadata.Versions[idx+1:] {
entry, err := newEntriesBetweenVersion(revisionMetadata, fromVersion, toVersion)
entry, err := newEntriesBetweenVersion(revisionMetadata, fromVersion, toVersion, exceptionFilePath)
if err != nil {
return nil, err
}
Expand All @@ -223,7 +223,7 @@ func NewEntriesBetweenRevisionVersions(revisionPath string) ([]*Entry, error) {
return newVersionEntries(entries), nil
}

func newEntriesBetweenVersion(metadata *Metadata, fromVersion, toVersion string) (*Entry, error) {
func newEntriesBetweenVersion(metadata *Metadata, fromVersion, toVersion, exceptionFilePath string) (*Entry, error) {
baseMetadata := &Metadata{
Path: metadata.Path,
ActiveVersion: fromVersion,
Expand All @@ -240,7 +240,7 @@ func newEntriesBetweenVersion(metadata *Metadata, fromVersion, toVersion string)
Versions: metadata.Versions,
}

changelog, err := newChangelog(baseMetadata, revisionMetadata, []*Entry{})
changelog, err := newChangelog(baseMetadata, revisionMetadata, exceptionFilePath, []*Entry{})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -307,7 +307,7 @@ func newVersionedPaths(paths []*Path, version string) []*Path {
return versionedPaths
}

func newChangelog(baseMetadata, revisionMetadata *Metadata, baseChangelog []*Entry) (*Changelog, error) {
func newChangelog(baseMetadata, revisionMetadata *Metadata, exceptionFilePath string, baseChangelog []*Entry) (*Changelog, error) {
var err error
if baseChangelog == nil {
baseChangelog, err = newEntriesFromPath(fmt.Sprintf("%s/%s", baseMetadata.Path, "changelog.json"))
Expand All @@ -332,7 +332,7 @@ func newChangelog(baseMetadata, revisionMetadata *Metadata, baseChangelog []*Ent
BaseMetadata: baseMetadata,
RevisionMetadata: revisionMetadata,
Config: changelogConfig,
ExemptionFilePath: fmt.Sprintf("%s/%s", revisionMetadata.Path, "exemptions.yaml"),
ExemptionFilePath: exceptionFilePath,
OasDiff: openapi.NewOasDiffWithSpecInfo(baseSpec, revisionSpec, &diff.Config{
IncludePathParams: true,
}),
Expand All @@ -355,7 +355,7 @@ func newEntriesFromPath(path string) ([]*Entry, error) {

func newBaseAndRevisionSpecs(baseMetadata, revisionMetadata *Metadata) (baseSpec, revisionSpec *load.SpecInfo, err error) {
if baseMetadata.ActiveVersion != revisionMetadata.ActiveVersion {
log.Printf("Base spec revision %s is different from the active version %s", baseMetadata.SpecRevision, baseMetadata.ActiveVersion)
log.Printf("Base spec version %s is different from the active version %s", baseMetadata.ActiveVersion, revisionMetadata.ActiveVersion)
log.Println("Normalizing the specs: replace versioned media-types with corresponding standard media-types")
baseSpec, err = openapi.CreateNormalizedOpenAPISpecFromPath(fmt.Sprintf("%s/openapi-%s.json", baseMetadata.Path, baseMetadata.ActiveVersion))
if err != nil {
Expand Down Expand Up @@ -489,9 +489,14 @@ func newStringFromStruct(data interface{}) string {
// 2. Remove all empty versions
// 3. Remove all empty paths
// 4. Shift changelog entry if it turns out empty
func NewNotHiddenEntries(changelog []*Entry) []*Entry {
func NewNotHiddenEntries(changelog []*Entry) ([]*Entry, error) {
if len(changelog) == 0 {
return changelog
return changelog, nil
}

changelog, err := duplicateEntries(changelog)
if err != nil {
return nil, err
}

// Get changes only for the last date, which is what was recently merged
Expand Down Expand Up @@ -524,11 +529,11 @@ func NewNotHiddenEntries(changelog []*Entry) []*Entry {
}

if len(paths) == 0 {
return changelog[1:]
return changelog[1:], nil
}

changelog[0].Paths = paths
return changelog
return changelog, nil
}

func newNotHiddenChanges(changes []*Change) []*Change {
Expand Down
11 changes: 7 additions & 4 deletions tools/cli/internal/changelog/changelog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewNotHiddenEntries(t *testing.T) {
Expand Down Expand Up @@ -232,7 +233,8 @@ func TestNewNotHiddenEntries(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := NewNotHiddenEntries(tt.changelog)
actual, err := NewNotHiddenEntries(tt.changelog)
require.NoError(t, err)
assert.Equal(t, tt.expected, actual)
})
}
Expand Down Expand Up @@ -300,7 +302,7 @@ func TestMultipleHiddenEntries(t *testing.T) {
Changes: []*Change{
{
Code: "request-property-removed",
Description: "added 'replicationSpecs.regionConfigs' request property",
Description: "removed 'replicationSpecs.regionConfigs' request property",
BackwardCompatible: true,
},
},
Expand Down Expand Up @@ -339,7 +341,7 @@ func TestMultipleHiddenEntries(t *testing.T) {
Changes: []*Change{
{
Code: "request-property-removed",
Description: "added 'replicationSpecs.regionConfigs' request property",
Description: "removed 'replicationSpecs.regionConfigs' request property",
BackwardCompatible: true,
},
},
Expand Down Expand Up @@ -593,7 +595,8 @@ func TestMultipleHiddenEntries(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := NewNotHiddenEntries(tt.changelog)
actual, err := NewNotHiddenEntries(tt.changelog)
require.NoError(t, err)
assert.Equal(t, tt.expected, actual)
})
}
Expand Down
1 change: 0 additions & 1 deletion tools/cli/internal/changelog/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ func (m *Changelog) newEntryFromOasDiff() ([]*Entry, error) {
}

log.Printf("Found %d changes between %s and %s", len(changes), m.Base.Url, m.Revision.Url)
log.Printf("Changes: %s", newStringFromStruct(changes))

conf := outputfilter.NewOperationConfigs(m.Base, m.Revision)

Expand Down
1 change: 1 addition & 0 deletions tools/cli/internal/changelog/outputfilter/hide.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func MarkHiddenEntries(entries []*OasDiffEntry, exemptionsFilePath string, fs af
if err != nil {
return nil, err
}

return hideByIDs(entries, hideIDs)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,61 @@ import (
"testing"

"github.com/getkin/kin-openapi/openapi3"
"github.com/mongodb/openapi/tools/cli/internal/openapi"
"github.com/stretchr/testify/require"
"github.com/tufin/oasdiff/load"
)

func TestOpenApiSpecMethods(t *testing.T) {
loader := openapi.NewOpenAPI3().WithExcludedPrivatePaths()
spec, err := loader.CreateOpenAPISpecFromPath("../../../test/data/changelog/test_spec.json")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] can we capture the sha/branch of this file for history purposes? can be a comment!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the same file we have in the mms-repo and it was manually generated . I will add this comment in the spec in a follow up PR. Thanks!

require.NoError(t, err)

expectedConfig := map[string]*OperationConfig{
"createCluster": {
Path: "/api/atlas/v2/groups/{groupId}/clusters",
HTTPMethod: "POST",
Tag: "Multi-Cloud Clusters",
Sunset: "2025-06-01",
ManualChangelogEntries: map[string]interface{}{},
},
"deleteCluster": {
Path: "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
HTTPMethod: "DELETE",
Tag: "Multi-Cloud Clusters",
Sunset: "2025-06-01",
ManualChangelogEntries: map[string]interface{}{},
},
"getCluster": {
Path: "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
HTTPMethod: "GET",
Tag: "Multi-Cloud Clusters",
Sunset: "2025-06-01",
ManualChangelogEntries: map[string]interface{}{
"2023-07-07": "July 7th changelog entry",
"2023-08-08": "August announcement for /api/atlas/v2/clusters",
},
},
"listClusters": {
Path: "/api/atlas/v2/groups/{groupId}/clusters",
HTTPMethod: "GET",
Tag: "Multi-Cloud Clusters",
Sunset: "2025-06-01",
ManualChangelogEntries: map[string]interface{}{},
},
"updateCluster": {
Path: "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}",
HTTPMethod: "PATCH",
Tag: "Multi-Cloud Clusters",
Sunset: "2025-06-01",
ManualChangelogEntries: map[string]interface{}{},
},
}

operationConfigs := newOperationConfigFromSpec(spec)
require.True(t, reflect.DeepEqual(expectedConfig, operationConfigs))
}

func TestOperationConfigs_Tag(t *testing.T) {
tests := []struct {
name string
Expand Down
14 changes: 7 additions & 7 deletions tools/cli/internal/changelog/outputfilter/outputfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ func NewChangelogEntries(checkers checker.Changes, specInfoPair *load.SpecInfoPa
}

func transformEntries(entries []*OasDiffEntry, exemptionsFilePath string) ([]*OasDiffEntry, error) {
fs := afero.NewOsFs()
entries, err := MarkHiddenEntries(entries, exemptionsFilePath, fs)
if err != nil {
return nil, err
}

newEntries := make([]*OasDiffEntry, 0)
for _, entry := range entries {
// only changes linked to endpoints are currently considered.
Expand All @@ -78,13 +84,7 @@ func transformEntries(entries []*OasDiffEntry, exemptionsFilePath string) ([]*Oa
newEntries = append(newEntries, entry)
}

newEntries, err := squashEntries(newEntries)
if err != nil {
return nil, err
}

fs := afero.NewOsFs()
newEntries, err = MarkHiddenEntries(newEntries, exemptionsFilePath, fs)
newEntries, err = squashEntries(newEntries)
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions tools/cli/internal/changelog/outputfilter/squash.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func squashEntries(entries []*OasDiffEntry) ([]*OasDiffEntry, error) {

return squashedEntries, nil
}

func sortEntriesByDescription(entries []*OasDiffEntry) []*OasDiffEntry {
sort.Slice(entries, func(i, j int) bool {
return entries[i].Text < entries[j].Text
Expand Down
18 changes: 11 additions & 7 deletions tools/cli/internal/cli/changelog/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ type Opts struct {
}

func (o *Opts) Run() error {
entries, err := changelog.NewEntries(o.basePath, o.revisionPath)
entries, err := changelog.NewEntries(o.basePath, o.revisionPath, o.exceptionsPaths)
if err != nil {
return err
}

notHiddenEntries := changelog.NewNotHiddenEntries(entries)
versionedEntries, err := changelog.NewEntriesBetweenRevisionVersions(o.revisionPath)
notHiddenEntries, err := changelog.NewNotHiddenEntries(entries)
if err != nil {
return err
}

versionedEntries, err := changelog.NewEntriesBetweenRevisionVersions(o.revisionPath, o.exceptionsPaths)
if err != nil {
return err
}
Expand All @@ -60,14 +64,14 @@ func (o *Opts) Run() error {
return nil
}

if errSaveFile := openapi.SaveToFile(o.newOutputFilePath(changelogFileName), "", notHiddenEntries, o.fs); errSaveFile != nil {
return errSaveFile
}

if err := o.fs.MkdirAll(fmt.Sprintf("%s/%s", o.outputPath, changelogAllFolderName), 0o755); err != nil {
return err
}

if errSaveFile := openapi.SaveToFile(o.newOutputFilePath(changelogFileName), "", notHiddenEntries, o.fs); errSaveFile != nil {
return errSaveFile
}

if errSaveFile := openapi.SaveToFile(
o.newOutputFilePath(fmt.Sprintf("%s/%s", changelogAllFolderName, changelogAllFileName)), "", entries, o.fs); errSaveFile != nil {
return errSaveFile
Expand Down
Loading
Loading