internal/commands/update.go (101 lines of code) (raw):
package commands
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
"gitlab.com/gitlab-org/release-cli/internal/flags"
"gitlab.com/gitlab-org/release-cli/internal/gitlab"
)
// Update defines the update command to be used by the CLI
func Update(log logrus.FieldLogger, httpClientFn httpClientFn) *cli.Command {
return &cli.Command{
Name: "update",
Usage: "Update a release using GitLab's Releases API https://docs.gitlab.com/ee/api/releases/#update-a-release",
Action: func(ctx *cli.Context) error {
client, err := httpClientFn(ctx, log)
if err != nil {
return err
}
return updateRelease(ctx, log, client)
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: flags.TagName,
Usage: "The Git tag the release is associated with",
Required: true,
EnvVars: []string{"CI_COMMIT_TAG"},
},
&cli.StringFlag{
Name: flags.Name,
Usage: "The release name",
Required: false,
},
&cli.StringFlag{
Name: flags.Description,
Usage: "The description of the release; you can use Markdown. A file can be used to read the description contents, must exist inside the working directory; if it contains any whitespace, it will be treated as a string",
Required: false,
},
&cli.StringSliceFlag{
Name: flags.Milestone,
Usage: `List of the titles of each milestone the release is associated with (e.g. --milestone "v1.0" --milestone "v1.0-rc)"; each milestone needs to exist. Pass an empty string to remove all milestones from the release.`,
Required: false,
},
&cli.StringFlag{
Name: flags.ReleasedAt,
Usage: `The date when the release will be/was ready; defaults to the current time; expected in ISO 8601 format (2019-03-15T08:00:00Z)`,
Required: false,
},
},
}
}
func updateRelease(ctx *cli.Context, log logrus.FieldLogger, httpClient gitlab.HTTPClient) error {
projectID := ctx.String(flags.ProjectID)
serverURL := ctx.String(flags.ServerURL)
jobToken := ctx.String(flags.JobToken)
privateToken := ctx.String(flags.PrivateToken)
l := log.WithFields(logrus.Fields{
"command": ctx.Command.Name,
flags.ServerURL: serverURL,
flags.ProjectID: projectID,
flags.Name: ctx.String(flags.Name),
flags.TagName: ctx.String(flags.TagName),
})
l.Info("Updating Release...")
gitlabClient, err := gitlab.New(serverURL, jobToken, privateToken, projectID, httpClient, log)
if err != nil {
return fmt.Errorf("create GitLab client: %w", err)
}
crr, err := newUpdateReleaseReq(ctx, log)
if err != nil {
return fmt.Errorf("new UpdateReleaseRequest: %w", err)
}
release, err := gitlabClient.UpdateRelease(ctx.Context, crr)
if err != nil {
return fmt.Errorf("update release: %w", err)
}
printReleaseOutput(ctx.App.Writer, release, log)
l.Info("Release updated successfully!")
return nil
}
func newUpdateReleaseReq(ctx *cli.Context, log logrus.FieldLogger) (*gitlab.UpdateReleaseRequest, error) {
description := ctx.String(flags.Description)
releasedAt := ctx.String(flags.ReleasedAt)
descriptionString, err := getDescription(description, log)
if err != nil {
return nil, err
}
request := &gitlab.UpdateReleaseRequest{
ID: ctx.String(flags.ProjectID),
Name: ctx.String(flags.Name),
Description: descriptionString,
TagName: ctx.String(flags.TagName),
Milestones: ctx.StringSlice(flags.Milestone),
}
if releasedAt != "" {
timeReleasedAt, err := gitlab.ParseDateTime(releasedAt)
if err != nil {
return nil, fmt.Errorf("parse released-at: %w", err)
}
request.ReleasedAt = &timeReleasedAt
}
return request, nil
}