From 510ce6657041043e70475a621a67fc79d0e77e8b Mon Sep 17 00:00:00 2001 From: decentral1se Date: Sat, 23 Sep 2023 09:15:27 +0200 Subject: [PATCH] feat: version arguments, local tag lookups & release notes See: * https://git.coopcloud.tech/coop-cloud/organising/issues/441 * https://git.coopcloud.tech/coop-cloud/organising/issues/204 * https://git.coopcloud.tech/coop-cloud/organising/issues/493 --- cli/app/deploy.go | 38 +++++++++++++++-------- cli/app/rollback.go | 40 +++++++++++++++++++----- cli/app/upgrade.go | 69 ++++++++++++++++++++++++++++++++++-------- cli/internal/deploy.go | 13 ++------ 4 files changed, 118 insertions(+), 42 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 81fd780a..f4bfb390 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -23,7 +23,7 @@ var appDeployCommand = cli.Command{ Name: "deploy", Aliases: []string{"d"}, Usage: "Deploy an app", - ArgsUsage: "", + ArgsUsage: " []", Flags: []cli.Flag{ internal.DebugFlag, internal.NoInputFlag, @@ -99,9 +99,17 @@ recipes. } } - isLatestHash := false version := deployedVersion - if !internal.Chaos { + specificVersion := c.Args().Get(1) + if specificVersion != "" { + version = specificVersion + logrus.Debugf("choosing %s as version to deploy", version) + if err := recipe.EnsureVersion(app.Recipe, version); err != nil { + logrus.Fatal(err) + } + } + + if !internal.Chaos && specificVersion == "" { catl, err := recipe.ReadRecipeCatalogue(internal.Offline) if err != nil { logrus.Fatal(err) @@ -110,7 +118,21 @@ recipes. if err != nil { logrus.Fatal(err) } - if len(versions) > 0 { + + if len(versions) == 0 && !internal.Chaos { + logrus.Warn("no published versions in catalogue, trying local recipe repository") + recipeVersions, err := recipe.GetRecipeVersions(app.Recipe, internal.Offline) + if err != nil { + logrus.Warn(err) + } + for _, recipeVersion := range recipeVersions { + for version := range recipeVersion { + versions = append(versions, version) + } + } + } + + if len(versions) > 0 && !internal.Chaos { version = versions[len(versions)-1] logrus.Debugf("choosing %s as version to deploy", version) if err := recipe.EnsureVersion(app.Recipe, version); err != nil { @@ -121,19 +143,11 @@ recipes. if err != nil { logrus.Fatal(err) } - isLatestHash = true version = formatter.SmallSHA(head.String()) logrus.Warn("no versions detected, using latest commit") } } - if version != "unknown" && !internal.Chaos && !isLatestHash { - logrus.Debugf("choosing %s as version to deploy", version) - if err := recipe.EnsureVersion(app.Recipe, version); err != nil { - logrus.Fatal(err) - } - } - if internal.Chaos { logrus.Warnf("chaos mode engaged") var err error diff --git a/cli/app/rollback.go b/cli/app/rollback.go index afb70b9e..feec6b78 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -22,7 +22,7 @@ var appRollbackCommand = cli.Command{ Name: "rollback", Aliases: []string{"rl"}, Usage: "Roll an app back to a previous version", - ArgsUsage: "", + ArgsUsage: " []", Flags: []cli.Flag{ internal.DebugFlag, internal.NoInputFlag, @@ -107,16 +107,41 @@ recipes. } if len(versions) == 0 && !internal.Chaos { - logrus.Fatalf("no published releases for %s in the recipe catalogue?", app.Recipe) + logrus.Warn("no published versions in catalogue, trying local recipe repository") + recipeVersions, err := recipe.GetRecipeVersions(app.Recipe, internal.Offline) + if err != nil { + logrus.Warn(err) + } + for _, recipeVersion := range recipeVersions { + for version := range recipeVersion { + versions = append(versions, version) + } + } } var availableDowngrades []string if deployedVersion == "unknown" { availableDowngrades = versions - logrus.Warnf("failed to determine version of deployed %s", app.Name) + logrus.Warnf("failed to determine deployed version of %s", app.Name) } - if deployedVersion != "unknown" && !internal.Chaos { + specificVersion := c.Args().Get(1) + if specificVersion != "" { + parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) + if err != nil { + logrus.Fatal(err) + } + parsedSpecificVersion, err := tagcmp.Parse(specificVersion) + if err != nil { + logrus.Fatal(err) + } + if parsedSpecificVersion.IsGreaterThan(parsedDeployedVersion) || parsedSpecificVersion.Equals(parsedDeployedVersion) { + logrus.Fatalf("%s is not a downgrade for %s?", deployedVersion, specificVersion) + } + availableDowngrades = append(availableDowngrades, specificVersion) + } + + if deployedVersion != "unknown" && !internal.Chaos && specificVersion == "" { for _, version := range versions { parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) if err != nil { @@ -126,12 +151,12 @@ recipes. if err != nil { logrus.Fatal(err) } - if parsedVersion != parsedDeployedVersion && parsedVersion.IsLessThan(parsedDeployedVersion) { + if parsedVersion.IsLessThan(parsedDeployedVersion) && !(parsedVersion.Equals(parsedDeployedVersion)) { availableDowngrades = append(availableDowngrades, version) } } - if len(availableDowngrades) == 0 { + if len(availableDowngrades) == 0 && !internal.Force { logrus.Info("no available downgrades, you're on oldest ✌️") return nil } @@ -139,7 +164,7 @@ recipes. var chosenDowngrade string if len(availableDowngrades) > 0 && !internal.Chaos { - if internal.Force || internal.NoInput { + if internal.Force || internal.NoInput || specificVersion != "" { chosenDowngrade = availableDowngrades[len(availableDowngrades)-1] logrus.Debugf("choosing %s as version to downgrade to (--force/--no-input)", chosenDowngrade) } else { @@ -197,6 +222,7 @@ recipes. config.SetChaosVersionLabel(compose, stackName, chosenDowngrade) config.SetUpdateLabel(compose, stackName, app.Env) + // NOTE(d1): no release notes implemeneted for rolling back if err := internal.NewVersionOverview(app, deployedVersion, chosenDowngrade, ""); err != nil { logrus.Fatal(err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 7bb85fbf..bc31f484 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -22,7 +22,7 @@ var appUpgradeCommand = cli.Command{ Name: "upgrade", Aliases: []string{"up"}, Usage: "Upgrade an app", - ArgsUsage: "", + ArgsUsage: " []", Flags: []cli.Flag{ internal.DebugFlag, internal.NoInputFlag, @@ -108,26 +108,52 @@ recipes. } if len(versions) == 0 && !internal.Chaos { - logrus.Fatalf("no published releases for %s in the recipe catalogue?", app.Recipe) + logrus.Warn("no published versions in catalogue, trying local recipe repository") + recipeVersions, err := recipePkg.GetRecipeVersions(app.Recipe, internal.Offline) + if err != nil { + logrus.Warn(err) + } + for _, recipeVersion := range recipeVersions { + for version := range recipeVersion { + versions = append(versions, version) + } + } } var availableUpgrades []string if deployedVersion == "unknown" { availableUpgrades = versions - logrus.Warnf("failed to determine version of deployed %s", app.Name) + logrus.Warnf("failed to determine deployed version of %s", app.Name) } - if deployedVersion != "unknown" && !internal.Chaos { + specificVersion := c.Args().Get(1) + if specificVersion != "" { + parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) + if err != nil { + logrus.Fatal(err) + } + parsedSpecificVersion, err := tagcmp.Parse(specificVersion) + if err != nil { + logrus.Fatal(err) + } + if parsedSpecificVersion.IsLessThan(parsedDeployedVersion) || parsedSpecificVersion.Equals(parsedDeployedVersion) { + logrus.Fatalf("%s is not an upgrade for %s?", deployedVersion, specificVersion) + } + availableUpgrades = append(availableUpgrades, specificVersion) + } + + parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) + if err != nil { + logrus.Fatal(err) + } + + if deployedVersion != "unknown" && !internal.Chaos && specificVersion == "" { for _, version := range versions { - parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) - if err != nil { - logrus.Fatal(err) - } parsedVersion, err := tagcmp.Parse(version) if err != nil { logrus.Fatal(err) } - if parsedVersion.IsGreaterThan(parsedDeployedVersion) { + if parsedVersion.IsGreaterThan(parsedDeployedVersion) && !(parsedVersion.Equals(parsedDeployedVersion)) { availableUpgrades = append(availableUpgrades, version) } } @@ -140,7 +166,7 @@ recipes. var chosenUpgrade string if len(availableUpgrades) > 0 && !internal.Chaos { - if internal.Force || internal.NoInput { + if internal.Force || internal.NoInput || specificVersion != "" { chosenUpgrade = availableUpgrades[len(availableUpgrades)-1] logrus.Debugf("choosing %s as version to upgrade to", chosenUpgrade) } else { @@ -162,9 +188,26 @@ recipes. // if release notes written after git tag published, read them before we // check out the tag and then they'll appear to be missing. this covers // when we obviously will forget to write release notes before publishing - releaseNotes, err := internal.GetReleaseNotes(app.Recipe, chosenUpgrade) - if err != nil { - return err + var releaseNotes string + for _, version := range versions { + parsedVersion, err := tagcmp.Parse(version) + if err != nil { + logrus.Fatal(err) + } + parsedChosenUpgrade, err := tagcmp.Parse(chosenUpgrade) + if err != nil { + logrus.Fatal(err) + } + + if !(parsedVersion.Equals(parsedDeployedVersion)) && parsedVersion.IsLessThan(parsedChosenUpgrade) { + note, err := internal.GetReleaseNotes(app.Recipe, version) + if err != nil { + return err + } + if note != "" { + releaseNotes += fmt.Sprintf("%s\n", note) + } + } } if !internal.Chaos { diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index 410fa97d..ca30aa57 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -32,17 +32,9 @@ func NewVersionOverview(app config.App, currentVersion, newVersion, releaseNotes table.Append([]string{server, app.Recipe, deployConfig, app.Domain, currentVersion, newVersion}) table.Render() - if releaseNotes == "" { - var err error - releaseNotes, err = GetReleaseNotes(app.Recipe, newVersion) - if err != nil { - return err - } - } - if releaseNotes != "" && newVersion != "" { fmt.Println() - fmt.Println(fmt.Sprintf("%s release notes:\n\n%s", newVersion, releaseNotes)) + fmt.Print(releaseNotes) } else { logrus.Warnf("no release notes available for %s", newVersion) } @@ -80,7 +72,8 @@ func GetReleaseNotes(recipeName, version string) (string, error) { if err != nil { return "", err } - return string(releaseNotes), nil + withTitle := fmt.Sprintf("%s release notes:\n%s", version, string(releaseNotes)) + return withTitle, nil } return "", nil