Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ Built packages can also be published to the global package registry service.

For details on how to enable dependency management, see the [HOWTO guide](https://github.com/elastic/elastic-package/blob/main/docs/howto/dependency_management.md).

### `elastic-package changelog`

_Context: package_

Use this command to work with the changelog of the package.

You can use this command to modify the changelog following the expected format and good practices.
This can be useful when introducing changelog entries for changes done by automated processes.


### `elastic-package check`

_Context: package_
Expand Down
174 changes: 174 additions & 0 deletions cmd/changelog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package cmd

import (
"io/ioutil"
"path/filepath"

"github.com/Masterminds/semver"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/elastic/elastic-package/internal/cobraext"
"github.com/elastic/elastic-package/internal/packages"
"github.com/elastic/elastic-package/internal/packages/changelog"
)

const changelogLongDescription = `Use this command to work with the changelog of the package.

You can use this command to modify the changelog following the expected format and good practices.
This can be useful when introducing changelog entries for changes done by automated processes.
`

const changelogAddLongDescription = `Use this command to add an entry to the changelog file.

The entry added will include the given description, type and link. It is added on top of the
last entry in the current version

Alternatively, you can start a new version indicating the specific version, or if it should
be the next major, minor or patch version.
`

func setupChangelogCommand() *cobraext.Command {
addChangelogCmd := &cobra.Command{
Use: "add",
Short: "Add an entry to the changelog file",
Long: changelogAddLongDescription,
RunE: changelogAddCmd,
}
addChangelogCmd.Flags().String(cobraext.ChangelogAddNextFlagName, "", cobraext.ChangelogAddNextFlagDescription)
addChangelogCmd.Flags().String(cobraext.ChangelogAddVersionFlagName, "", cobraext.ChangelogAddVersionFlagDescription)
addChangelogCmd.Flags().String(cobraext.ChangelogAddDescriptionFlagName, "", cobraext.ChangelogAddDescriptionFlagDescription)
addChangelogCmd.MarkFlagRequired(cobraext.ChangelogAddDescriptionFlagName)
addChangelogCmd.Flags().String(cobraext.ChangelogAddTypeFlagName, "", cobraext.ChangelogAddTypeFlagDescription)
addChangelogCmd.MarkFlagRequired(cobraext.ChangelogAddTypeFlagName)
addChangelogCmd.Flags().String(cobraext.ChangelogAddLinkFlagName, "", cobraext.ChangelogAddLinkFlagDescription)
addChangelogCmd.MarkFlagRequired(cobraext.ChangelogAddLinkFlagName)

cmd := &cobra.Command{
Use: "changelog",
Short: "Utilities to work with the changelog of the package",
Long: changelogLongDescription,
}
cmd.AddCommand(addChangelogCmd)

return cobraext.NewCommand(cmd, cobraext.ContextPackage)
}

func changelogAddCmd(cmd *cobra.Command, args []string) error {
packageRoot, err := packages.MustFindPackageRoot()
if err != nil {
return errors.Wrap(err, "locating package root failed")
}

version, _ := cmd.Flags().GetString(cobraext.ChangelogAddVersionFlagName)
nextMode, _ := cmd.Flags().GetString(cobraext.ChangelogAddNextFlagName)
if version != "" && nextMode != "" {
return errors.Errorf("flags %q and %q cannot be used at the same time",
cobraext.ChangelogAddVersionFlagName,
cobraext.ChangelogAddNextFlagName)
}
if version == "" {
v, err := changelogCmdVersion(nextMode, packageRoot)
if err != nil {
return err
}
version = v.String()
}

description, _ := cmd.Flags().GetString(cobraext.ChangelogAddDescriptionFlagName)
changeType, _ := cmd.Flags().GetString(cobraext.ChangelogAddTypeFlagName)
link, _ := cmd.Flags().GetString(cobraext.ChangelogAddLinkFlagName)

entry := changelog.Revision{
Version: version,
Changes: []changelog.Entry{
{
Description: description,
Type: changeType,
Link: link,
},
},
}

err = patchChangelogFile(packageRoot, entry)
if err != nil {
return err
}

err = setManifestVersion(packageRoot, version)
if err != nil {
return err
}

return nil
}

func changelogCmdVersion(nextMode, packageRoot string) (*semver.Version, error) {
revisions, err := changelog.ReadChangelogFromPackageRoot(packageRoot)
if err != nil {
return nil, errors.Wrap(err, "failed to read current changelog")
}
if len(revisions) == 0 {
return semver.MustParse("0.0.0"), nil
}

version, err := semver.NewVersion(revisions[0].Version)
if err != nil {
return nil, errors.Wrapf(err, "invalid version in changelog %q", revisions[0].Version)
}

switch nextMode {
case "":
break
case "major":
v := version.IncMajor()
version = &v
case "minor":
v := version.IncMinor()
version = &v
case "patch":
v := version.IncPatch()
version = &v
default:
return nil, errors.Errorf("invalid value for %q: %s",
cobraext.ChangelogAddNextFlagName, nextMode)
}

return version, nil
}

// patchChangelogFile looks for the proper place to add the new revision in the changelog,
// trying to conserve original format and comments.
func patchChangelogFile(packageRoot string, patch changelog.Revision) error {
changelogPath := filepath.Join(packageRoot, changelog.PackageChangelogFile)
d, err := ioutil.ReadFile(changelogPath)
if err != nil {
return err
}

d, err = changelog.PatchYAML(d, patch)
if err != nil {
return err
}

return ioutil.WriteFile(changelogPath, d, 0644)
}

func setManifestVersion(packageRoot string, version string) error {
manifestPath := filepath.Join(packageRoot, packages.PackageManifestFile)
d, err := ioutil.ReadFile(manifestPath)
if err != nil {
return err
}

d, err = changelog.SetManifestVersion(d, version)
if err != nil {
return err
}

return ioutil.WriteFile(manifestPath, d, 0644)
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

var commands = []*cobraext.Command{
setupBuildCommand(),
setupChangelogCommand(),
setupCheckCommand(),
setupCleanCommand(),
setupCreateCommand(),
Expand Down
15 changes: 15 additions & 0 deletions internal/cobraext/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ const (
BuildZipFlagName = "zip"
BuildZipFlagDescription = "archive the built package"

ChangelogAddNextFlagName = "next"
ChangelogAddNextFlagDescription = "changelog entry is added in the next `major`, `minor` or `patch` version"

ChangelogAddVersionFlagName = "version"
ChangelogAddVersionFlagDescription = "changelog entry is added in the given version"

ChangelogAddDescriptionFlagName = "description"
ChangelogAddDescriptionFlagDescription = "description for the changelog entry"

ChangelogAddTypeFlagName = "type"
ChangelogAddTypeFlagDescription = "type of change (bugfix, enhancement or breaking-change) for the changelog entry"

ChangelogAddLinkFlagName = "link"
ChangelogAddLinkFlagDescription = "link to the pull request or issue with more information about the changelog entry"

CheckConditionFlagName = "check-condition"
CheckConditionFlagDescription = "check if the condition is met for the package, but don't install the package (e.g. kibana.version=7.10.0)"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# newer versions go on top
- version: "1.0.0"
changes:
- description: One change
type: enhancement
link: http://github.com/elastic/elastic-package
- description: Other change
type: enhancement
link: http://github.com/elastic/elastic-package
- description: Initial version
type: enhancement
link: http://github.com/elastic/elastic-package
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# newer versions go on top
- version: "2.0.0"
changes:
- description: One change
type: enhancement
link: http://github.com/elastic/elastic-package
- version: "1.0.0"
changes:
- description: Initial version
type: enhancement
link: http://github.com/elastic/elastic-package
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# newer versions go on top
- version: "1.0.0"
changes:
- description: One change
type: enhancement
link: http://github.com/elastic/elastic-package
- description: Initial version
type: enhancement
link: http://github.com/elastic/elastic-package
6 changes: 6 additions & 0 deletions internal/packages/changelog/testdata/changelog-one.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# newer versions go on top
- version: "1.0.0"
changes:
- description: Initial version
type: enhancement
link: http://github.com/elastic/elastic-package
Loading