Package changes implements Go module version management for a multi-module git repository.


The Repository struct is a representation of a git repository containing multiple Go modules. Repository handles the whole release process with respect to versioning, including tagging the git repository and updating CHANGELOG, version.go, and go.mod files. The sequence of steps required to create a release of the SDK can be run from the Repository's DoRelease function:

repo, err := changes.NewRepository("path/to/repository")
if err != nil {


After this code snippet runs, the versions of modules within the specified repository will be updated based on change metadata contained in the repository.


In order to make module versioning decisions during a release, the Repository's DoRelease function consumes metadata about changes included in the release. The metadata is stored in the root of the repository in a .changes directory. The Metadata struct provides a way to load, create, and modify the metadata in the .changes directory. The .changes directory is structured as follows:

	next-release/	contains Change metadata for pending changes (to be included in the next release).
	releases/	contains Release metadata for previous releases.
	versions.json	is a VersionEnclosure representing the state of the repository at the last release.

There are three file formats used in the .changes directory corresponding to three structs: Change, Release, and VersionEnclosure.


The Repository's DoRelease function pdates both a top level and per-module files. The in the root of the repository provides a consolidated view of all changelog entries for every module. This means that the root module does not have its own CHANGELOG.

The Release struct handles the rendering of CHANGELOG files, generating an entry that is prepended to CHANGELOG files during a release.

Dependencies within the SDK

As part of the Repository's release process, any module within the repository that depends upon another module in the repository will have its dependency updated to the latest version. So, after a release all modules in the SDK depend on the latest version of any other SDK module.



View Source
const SchemaVersion = 1

    SchemaVersion defines the current JSON schema version for persistent data types (Change, Release, ...)


    This section is empty.


    func AffectedModules

    func AffectedModules(changes []Change) []string

      AffectedModules returns a sorted list of all modules affected by the given Changes. A module is considered affected if it is the Module of one or more Changes that will result in a version increment.

      func ChangeToTemplate

      func ChangeToTemplate(change Change) ([]byte, error)

        ChangeToTemplate returns a Change template populated with the given Change's data.

        func GetChangesPath

        func GetChangesPath() (string, error)

          GetChangesPath searches upward from the current directory for a .changes directory, returning a relative path from the current directory to the .changes directory.

          func GetCurrentModule

          func GetCurrentModule() (string, error)

            GetCurrentModule returns a shortened module path (from the root of the repository to the module, not a full import path) for the Go module containing the current directory.

            func MatchWildcardModules

            func MatchWildcardModules(modules []string, wildcard string) ([]string, error)

              MatchWildcardModules filters modules, returning only the modules that match the given wildcard.

              func ModIsWildcard

              func ModIsWildcard(mod string) bool

                ModIsWildcard returns whether the given module ends in the wildcard pattern.


                type Change

                type Change struct {
                	ID            string     // ID is a unique identifier for this Change.
                	SchemaVersion int        // SchemaVersion is the version of the library's types used to create this Change.
                	Module        string     // Module is a shortened Go module path for the module affected by this Change. Module is the path from the root of the repository to the module.
                	Type          ChangeType // Type indicates what category of Change was made. Type may be either "feature" or "bugfix".
                	Description   string     // Description is a human readable description of this Change meant to be included in a CHANGELOG.
                	MinVersion    string     // MinVersion is a semver tag that the module should be minimally bumped to.
                	// AffectedModules is a list of modules affected by this Change. AffectedModules is only non-nil when the Change's
                	// Module has a wildcard, in which case AffectedModules contains all modules matching the wildcard Module that the
                	// Change affects.
                	AffectedModules []string

                  Change represents a change to a single Go module.

                  func NewChanges

                  func NewChanges(modules []string, changeType ChangeType, description string, minVersion string) ([]Change, error)

                    NewChanges returns a Change slice containing a Change with the given type and description for each of the specified modules.

                    func NewWildcardChange

                    func NewWildcardChange(modulePath string, changeType ChangeType, description string, affectedModules []string, minVersion string) (Change, error)

                      NewWildcardChange creates a wildcard Change.

                      func TemplateToChanges

                      func TemplateToChanges(filledTemplate []byte) ([]Change, error)

                        TemplateToChanges parses the provided filledTemplate into the provided Change. If Change has no ID, TemplateToChange will set the ID.

                        func (Change) IndentedDescription

                        func (c Change) IndentedDescription(indent string) string

                          IndentedDescription returns the Change's Description with each line except for the first prefixed with the given string.

                          func (Change) String

                          func (c Change) String() string

                            String returns a string representation of a Change suitable to be included in a Changelog.

                            type ChangeType

                            type ChangeType string

                              ChangeType describes the type of change made to a Go module.

                              const (
                              	// FeatureChangeType is a constant change type for a new feature.
                              	FeatureChangeType ChangeType = "feature"
                              	// BugFixChangeType is a constant change type for a bug fix.
                              	BugFixChangeType ChangeType = "bugfix"
                              	// MajorChangeType is a constant change type for a major version updates (from v0 => v1).
                              	MajorChangeType ChangeType = "major"
                              	// DependencyChangeType is a constant change type for a dependency update.
                              	DependencyChangeType ChangeType = "dependency"
                              	// AnnouncementChangeType is a constant change type for an SDK announcement.
                              	AnnouncementChangeType ChangeType = "announcement"

                              func ParseChangeType

                              func ParseChangeType(v string) (ChangeType, error)

                                ParseChangeType attempts to parse the given string v into a ChangeType, returning an error if the string is invalid.

                                func (ChangeType) ChangelogPrefix

                                func (c ChangeType) ChangelogPrefix() string

                                  ChangelogPrefix returns the CHANGELOG header the ChangeType should be grouped under.

                                  func (*ChangeType) Set

                                  func (c *ChangeType) Set(s string) error

                                    Set parses the given string and correspondingly sets the ChangeType, returning an error if the string could not be parsed.

                                    func (ChangeType) String

                                    func (c ChangeType) String() string

                                      String returns a string representation of the ChangeType

                                      func (*ChangeType) UnmarshalJSON

                                      func (c *ChangeType) UnmarshalJSON(data []byte) error

                                        UnmarshalJSON implements the encoding/json package's Unmarshaler interface, additionally providing change type validation.

                                        func (*ChangeType) UnmarshalYAML

                                        func (c *ChangeType) UnmarshalYAML(unmarshal func(interface{}) error) error

                                          UnmarshalYAML implements yaml.v2's Unmarshaler interface, additionally providing change type validation.

                                          func (ChangeType) VersionIncrement

                                          func (c ChangeType) VersionIncrement() VersionIncrement

                                            VersionIncrement returns the VersionIncrement corresponding to the given ChangeType.

                                            type Metadata

                                            type Metadata struct {
                                            	ChangePath      string           // ChangePath is the relative path from the current directory to .changes
                                            	Changes         []Change         // Changes holds all pending change metadata in the .changes/next-release directory
                                            	Releases        []*Release       // Releases contains all releases in the .changes/releases directory
                                            	CurrentVersions VersionEnclosure // CurrentVersions is the .changes/versions.json enclosure of current module versions

                                              Metadata is a representation of the change metadata stored in a .changes directory.

                                              func LoadMetadata

                                              func LoadMetadata(path string) (*Metadata, error)

                                                LoadMetadata loads the .changes directory at the given path.

                                                func (*Metadata) AddChange

                                                func (m *Metadata) AddChange(c Change) error

                                                  AddChange adds the given Change to the Metadata's Changes and saves the Change to the next-release directory.

                                                  func (*Metadata) AddChanges

                                                  func (m *Metadata) AddChanges(changes []Change) error

                                                    AddChanges adds the given Changes to Metadata's Changes and saves the Changes to the next-release directory.

                                                    func (*Metadata) AddChangesFromTemplate

                                                    func (m *Metadata) AddChangesFromTemplate(template []byte) ([]Change, error)

                                                      AddChangesFromTemplate parses the given YAML template, adding the resulting Changes to Metadata's Changes and saving the Changes to the next-release directory. AddChangesFromTemplate returns the created Changes.

                                                      func (*Metadata) ClearChanges

                                                      func (m *Metadata) ClearChanges() error

                                                        ClearChanges removes all Changes from the Metadata's Changes and deletes the Change files in the .changes/next-release directory.

                                                        func (*Metadata) CreateRelease

                                                        func (m *Metadata) CreateRelease(id string, bumps map[string]VersionBump, dryRun bool) (*Release, error)

                                                          CreateRelease consolidates the Metadata's pending Changes into a Release. This operation will remove all Changes from the Metadata and delete change files in .changes/next-release. A release file will also be created in .changes/releases. If dryRun is true, CreateRelease will return a Release, but not modify change or release files.

                                                          func (*Metadata) GetChangeByID

                                                          func (m *Metadata) GetChangeByID(id string) (Change, error)

                                                            GetChangeByID returns the pending Change with the given id.

                                                            func (*Metadata) GetChanges

                                                            func (m *Metadata) GetChanges(module string) []Change

                                                              GetChanges returns all pending Changes with a module matching the given module. If module is empty, returns all Changes.

                                                              func (*Metadata) RemoveChangeByID

                                                              func (m *Metadata) RemoveChangeByID(id string) error

                                                                RemoveChangeByID removes the Change with the specified id from the Metadata's Changes and also removes the Change from the .changes/next-release directory.

                                                                func (*Metadata) SaveChange

                                                                func (m *Metadata) SaveChange(c Change) error

                                                                  SaveChange saves the given change to the .changes/next-release directory.

                                                                  func (*Metadata) SaveEnclosure

                                                                  func (m *Metadata) SaveEnclosure(enc VersionEnclosure) error

                                                                    SaveEnclosure updates the Metadata's enclosure and updates the versions.json file.

                                                                    func (*Metadata) UpdateChangeFromTemplate

                                                                    func (m *Metadata) UpdateChangeFromTemplate(oldChange Change, template []byte) ([]Change, error)

                                                                      UpdateChangeFromTemplate removes oldChange and creates a new Change from the given template.

                                                                      type ModuleGraph

                                                                      type ModuleGraph map[string][]string

                                                                        ModuleGraph is a mapping between modules in a repository and a list of modules within the same repository that depend on that module.

                                                                        type Release

                                                                        type Release struct {
                                                                        	ID            string
                                                                        	SchemaVersion int
                                                                        	VersionBumps  map[string]VersionBump
                                                                        	Changes       []Change

                                                                          Release represents a single SDK release, which contains all change metadata and their resulting version bumps.

                                                                          func (*Release) AffectedModules

                                                                          func (r *Release) AffectedModules() []string

                                                                            AffectedModules returns a sorted list of all modules affected by this Release. A module is considered affected if it is the Module of one or more Changes in the Release.

                                                                            func (*Release) AnnouncementsSection

                                                                            func (r *Release) AnnouncementsSection() ([]string, error)

                                                                              AnnouncementsSection returns a list of Changelog bullet entries that should be included under the Announcements header.

                                                                              func (*Release) CoreSection

                                                                              func (r *Release) CoreSection() ([]string, error)

                                                                                CoreSection returns a list of Changelog bullet entries that should be included under the Core SDK header.

                                                                                func (*Release) RenderChangelog

                                                                                func (r *Release) RenderChangelog() (string, error)

                                                                                  RenderChangelog generates a top level for the Release r.

                                                                                  func (*Release) RenderChangelogForModule

                                                                                  func (r *Release) RenderChangelogForModule(module string, topLevel bool) (string, error)

                                                                                    RenderChangelogForModule returns a new markdown section of a module's CHANGELOG based on the Changes in the Release.

                                                                                    func (*Release) ServiceSection

                                                                                    func (r *Release) ServiceSection() ([]string, error)

                                                                                      ServiceSection returns a list of Changelog bullet entries that should be included under the Service Clients header.

                                                                                      type Repository

                                                                                      type Repository struct {
                                                                                      	RootPath string    // RootPath is the path to the root of the repository.
                                                                                      	Metadata *Metadata // Metadata is the repository's .changes metadata.
                                                                                      	// Logf is a logging function. If nil, Repository will not log anything.
                                                                                      	Logf func(string, ...interface{})
                                                                                      	// contains filtered or unexported fields

                                                                                        Repository is a representation of a git repository containing multiple Go modules.

                                                                                        func NewRepository

                                                                                        func NewRepository(path string) (*Repository, error)

                                                                                          NewRepository loads the repository at the given path.

                                                                                          func (*Repository) DiscoverVersions

                                                                                          func (r *Repository) DiscoverVersions(selector VersionSelector) (VersionEnclosure, map[string]VersionBump, error)

                                                                                            DiscoverVersions creates a VersionEnclosure containing all Go modules in the Repository. The version of each module is determined by the provided VersionSelector.

                                                                                            func (*Repository) DoRelease

                                                                                            func (r *Repository) DoRelease(releaseID string, push, interactive bool) error

                                                                                              DoRelease runs the automated release process, consuming the given Repository's Metadata, updating module's go.mod files, creating a release JSON file, committing changes, tagging the repository, and pushing.

                                                                                              func (*Repository) InitializeVersions

                                                                                              func (r *Repository) InitializeVersions() error

                                                                                                InitializeVersions creates an initial versions.json enclosure in the Repository's .changes directory. The VersionEnclosure created by InitializeVersions will include all modules that have a tagged version in git and their corresponding versions.

                                                                                                func (*Repository) ModuleHashes

                                                                                                func (r *Repository) ModuleHashes(enc VersionEnclosure) (map[string]string, error)

                                                                                                  ModuleHashes computes and returns a mapping between shortened module names and their corresponding Go module checksum. Since the version of a module is used to compute the Go checksum (i.e. two modules with the same directory contents have a different checksum if their versions are different), the versions of the given VersionEnclosure will be used for this purpose.

                                                                                                  func (*Repository) Modules

                                                                                                  func (r *Repository) Modules() ([]string, error)

                                                                                                    Modules returns all Go modules under the given Repository. The list of module names returns are shortened to be relative to the root of the repository.

                                                                                                    func (*Repository) Tidy

                                                                                                    func (r *Repository) Tidy() error

                                                                                                      Tidy runs go mod tidy on all modules in the repository.

                                                                                                      func (*Repository) UpdateAllChangelogs

                                                                                                      func (r *Repository) UpdateAllChangelogs(release *Release, pending bool) error

                                                                                                        UpdateAllChangelogs generates changelog entries for both the top level and per-module files.

                                                                                                        func (*Repository) UpdateChangelog

                                                                                                        func (r *Repository) UpdateChangelog(release *Release, pending bool) error

                                                                                                          UpdateChangelog generates a new CHANGELOG entry for the given release. If pending is true, the contents of will be replaced with the new entry. Otherwise, the entry will be prepended to

                                                                                                          func (*Repository) UpdateModuleChangelog

                                                                                                          func (r *Repository) UpdateModuleChangelog(release *Release, module string, pending bool) error

                                                                                                            UpdateModuleChangelog generates a changelog entry for the specified module, updating the module's file.

                                                                                                            func (*Repository) UpdateVersionFiles

                                                                                                            func (r *Repository) UpdateVersionFiles(enc VersionEnclosure) error

                                                                                                              UpdateVersionFiles updates the version.go file with the version present in the VersionEnclosure enc. If version.go does not exist for a module, UpdateVersionFiles does not create one.

                                                                                                              type Version

                                                                                                              type Version struct {
                                                                                                              	Module     string // Module is the repo relative module path of the Go module.
                                                                                                              	ImportPath string // ImportPath is the full module import path.
                                                                                                              	Version    string // Version is a valid Go module semantic version, which can potentially be a pseudo-version.
                                                                                                              	ModuleHash string // ModuleHash is the Go module checksum of the the Version's module.

                                                                                                                Version is the version of a Go module.

                                                                                                                type VersionBump

                                                                                                                type VersionBump struct {
                                                                                                                	From string // From is the old module version
                                                                                                                	To   string // To is the new module version

                                                                                                                  VersionBump describes a version increment to a module.

                                                                                                                  type VersionEnclosure

                                                                                                                  type VersionEnclosure struct {
                                                                                                                  	SchemaVersion  int                // SchemaVersion is the version of the library's types used to create this VersionEnclosure
                                                                                                                  	ModuleVersions map[string]Version // ModuleVersions is a mapping between shortened module paths and their corresponding Version.
                                                                                                                  	Packages       map[string]string  // Packages maps each package in the repo to the shortened module path that provides the package.

                                                                                                                    VersionEnclosure is a set of versions for Go modules in a given repository.

                                                                                                                    func (*VersionEnclosure) HashDiff

                                                                                                                    func (v *VersionEnclosure) HashDiff(hashes map[string]string) []string

                                                                                                                      HashDiff returns all modules whose hash provided in hashes differs from the has present in VersionEnclosure v. hashes is a map between shortened module names and their Go checksum.

                                                                                                                      type VersionIncrement

                                                                                                                      type VersionIncrement int

                                                                                                                        VersionIncrement describes how a Change should affect a module's version.

                                                                                                                        const (
                                                                                                                        	// NoBump indicates the module's version should not change.
                                                                                                                        	NoBump VersionIncrement = iota
                                                                                                                        	// PatchBump indicates the module's version should be incremented by a patch version bump.
                                                                                                                        	// MinorBump indicates the module's version should be incremented by a minor version bump.
                                                                                                                        	// MajorBump indicates the module's major version should be incremented from v0 to v1.
                                                                                                                        	// NewModule indicates that a new modules has been discovered and will be assigned a default version.

                                                                                                                        func DevelopmentVersionSelector

                                                                                                                        func DevelopmentVersionSelector(r *Repository, module string) (string, VersionIncrement, error)

                                                                                                                          DevelopmentVersionSelector returns a commit hash based version if the module has associated pending Changes, otherwise returns the latest version from the repo's metadata version enclosure.

                                                                                                                          func ReleaseVersionSelector

                                                                                                                          func ReleaseVersionSelector(r *Repository, module string) (string, VersionIncrement, error)

                                                                                                                            ReleaseVersionSelector returns a version for the given module suitable for use during the release process. A version will be returned based upon what type of version bump the Change metadata for the given module requires. ReleaseVersionSelector will properly version modules that are not present in the versions.json file by checking git tags for an existing version, or by providing a default version suitable for the module's major version.

                                                                                                                            func TaggedVersionSelector

                                                                                                                            func TaggedVersionSelector(r *Repository, module string) (string, VersionIncrement, error)

                                                                                                                              TaggedVersionSelector returns the greatest version of module tagged in the git repository.

                                                                                                                              type VersionSelector

                                                                                                                              type VersionSelector func(r *Repository, module string) (string, VersionIncrement, error)

                                                                                                                                VersionSelector is a function that decides what version of a Go module should be passed to code generation.

                                                                                                                                func (*VersionSelector) Set

                                                                                                                                func (v *VersionSelector) Set(s string) error

                                                                                                                                  Set parses the input s and correspondingly sets the appropriate VersionSelector.

                                                                                                                                  func (*VersionSelector) String

                                                                                                                                  func (v *VersionSelector) String() string

                                                                                                                                    String returns an empty string to satisfy the flag.Value interface.


                                                                                                                                    Path Synopsis