forked from toolshed/abra
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			main
			...
			better-err
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4866cfd31c | |||
| e58a716fe1 | |||
| d09a19a385 | |||
| cee808ff06 | |||
| 4326d1d259 | |||
| b976872f77 | |||
| 7b6ea76437 | |||
| 9069758969 | |||
| 15d6b1a2a5 | 
| @ -261,7 +261,7 @@ func init() { | ||||
| 	AppCmdCommand.Flags().BoolVarP( | ||||
| 		&requestTTY, | ||||
| 		"tty", | ||||
| 		"t", | ||||
| 		"T", | ||||
| 		false, | ||||
| 		"request remote TTY", | ||||
| 	) | ||||
|  | ||||
| @ -46,7 +46,8 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 	ValidArgsFunction: func( | ||||
| 		cmd *cobra.Command, | ||||
| 		args []string, | ||||
| 		toComplete string) ([]string, cobra.ShellCompDirective) { | ||||
| 		toComplete string, | ||||
| 	) ([]string, cobra.ShellCompDirective) { | ||||
| 		switch l := len(args); l { | ||||
| 		case 0: | ||||
| 			return autocomplete.AppNameComplete() | ||||
| @ -65,8 +66,6 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 		var ( | ||||
| 			deployWarnMessages []string | ||||
| 			toDeployVersion    string | ||||
| 			isChaosCommit        bool | ||||
| 			toDeployChaosVersion = config.CHAOS_DEFAULT | ||||
| 		) | ||||
|  | ||||
| 		app := internal.ValidateApp(args) | ||||
| @ -79,10 +78,6 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if err := lint.LintForErrors(app.Recipe); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		cl, err := client.New(app.Server) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(err) | ||||
| @ -99,48 +94,22 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 			log.Fatalf("%s is already deployed", app.Name) | ||||
| 		} | ||||
|  | ||||
| 		if len(args) == 2 && args[1] != "" { | ||||
| 			toDeployVersion = args[1] | ||||
| 		} | ||||
|  | ||||
| 		if !deployMeta.IsDeployed && | ||||
| 			toDeployVersion == "" && | ||||
| 			app.Recipe.EnvVersion != "" && !internal.IgnoreEnvVersion { | ||||
| 			log.Debugf("new deployment, choosing .env version: %s", app.Recipe.EnvVersion) | ||||
| 			toDeployVersion = app.Recipe.EnvVersion | ||||
| 		} | ||||
|  | ||||
| 		if !internal.Chaos && toDeployVersion == "" { | ||||
| 			if err := getLatestVersionOrCommit(app, &toDeployVersion); err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if internal.Chaos { | ||||
| 			if err := getChaosVersion(app, &toDeployVersion, &toDeployChaosVersion); err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
| 		toDeployVersion, err = getDeployVersion(args, deployMeta, app) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(fmt.Errorf("get deploy version: %s", err)) | ||||
| 		} | ||||
|  | ||||
| 		if !internal.Chaos { | ||||
| 			isChaosCommit, err = app.Recipe.EnsureVersion(toDeployVersion) | ||||
| 			_, err = app.Recipe.EnsureVersion(toDeployVersion) | ||||
| 			if err != nil { | ||||
| 				log.Fatalf("ensure recipe: %s", err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := lint.LintForErrors(app.Recipe); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 			if isChaosCommit { | ||||
| 				log.Debugf("assuming chaos commit: %s", toDeployVersion) | ||||
|  | ||||
| 				internal.Chaos = true | ||||
| 				toDeployChaosVersion = toDeployVersion | ||||
|  | ||||
| 				toDeployVersion, err = app.Recipe.GetVersionLabelLocal() | ||||
| 				if err != nil { | ||||
| 					log.Fatal(err) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := validateSecrets(cl, app); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
| @ -171,18 +140,14 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		toDeployChaosVersionLabel := toDeployChaosVersion | ||||
| 		if app.Recipe.Dirty { | ||||
| 			toDeployChaosVersionLabel = formatter.AddDirtyMarker(toDeployChaosVersionLabel) | ||||
| 		} | ||||
|  | ||||
| 		appPkg.ExposeAllEnv(stackName, compose, app.Env) | ||||
| 		appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name) | ||||
| 		appPkg.SetChaosLabel(compose, stackName, internal.Chaos) | ||||
| 		if internal.Chaos { | ||||
| 			appPkg.SetChaosVersionLabel(compose, stackName, toDeployChaosVersionLabel) | ||||
| 			appPkg.SetChaosVersionLabel(compose, stackName, toDeployVersion) | ||||
| 		} | ||||
| 		appPkg.SetUpdateLabel(compose, stackName, app.Env) | ||||
| 		appPkg.SetVersionLabel(compose, stackName, toDeployVersion) | ||||
|  | ||||
| 		envVars, err := appPkg.CheckEnv(app) | ||||
| 		if err != nil { | ||||
| @ -214,19 +179,12 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 			deployedVersion = deployMeta.Version | ||||
| 		} | ||||
|  | ||||
| 		toWriteVersion := toDeployVersion | ||||
| 		if internal.Chaos || isChaosCommit { | ||||
| 			toWriteVersion = toDeployChaosVersion | ||||
| 		} | ||||
|  | ||||
| 		if err := internal.DeployOverview( | ||||
| 			app, | ||||
| 			deployWarnMessages, | ||||
| 			deployedVersion, | ||||
| 			deployMeta.ChaosVersion, | ||||
| 			toDeployVersion, | ||||
| 			toDeployChaosVersion, | ||||
| 			toWriteVersion, | ||||
| 			"", | ||||
| 			deployWarnMessages, | ||||
| 		); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
| @ -250,53 +208,28 @@ checkout as-is. Recipe commit hashes are also supported as values for | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := app.WriteRecipeVersion(toWriteVersion, false); err != nil { | ||||
| 		if err := app.WriteRecipeVersion(toDeployVersion, false); err != nil { | ||||
| 			log.Fatalf("writing recipe version failed: %s", err) | ||||
| 		} | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| func getChaosVersion(app app.App, toDeployVersion, toDeployChaosVersion *string) error { | ||||
| 	var err error | ||||
| 	*toDeployChaosVersion, err = app.Recipe.ChaosVersion() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*toDeployVersion, err = app.Recipe.GetVersionLabelLocal() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func getLatestVersionOrCommit(app app.App, toDeployVersion *string) error { | ||||
| func getLatestVersionOrCommit(app app.App) (string, error) { | ||||
| 	versions, err := app.Recipe.Tags() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	if len(versions) > 0 && !internal.Chaos { | ||||
| 		*toDeployVersion = versions[len(versions)-1] | ||||
|  | ||||
| 		log.Debugf("choosing %s as version to deploy", *toDeployVersion) | ||||
|  | ||||
| 		if _, err := app.Recipe.EnsureVersion(*toDeployVersion); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 		return versions[len(versions)-1], nil | ||||
| 	} | ||||
|  | ||||
| 	head, err := app.Recipe.Head() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	*toDeployVersion = formatter.SmallSHA(head.String()) | ||||
|  | ||||
| 	return nil | ||||
| 	return formatter.SmallSHA(head.String()), nil | ||||
| } | ||||
|  | ||||
| // validateArgsAndFlags ensures compatible args/flags. | ||||
| @ -323,6 +256,43 @@ func validateSecrets(cl *dockerClient.Client, app app.App) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App) (string, error) { | ||||
| 	// Chaos mode overrides everything | ||||
| 	if internal.Chaos { | ||||
| 		v, err := app.Recipe.ChaosVersion() | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		log.Debugf("version: taking chaos version: %s", v) | ||||
| 		return v, nil | ||||
| 	} | ||||
|  | ||||
| 	// Check if the deploy version is set with a cli argument | ||||
| 	if len(cliArgs) == 2 && cliArgs[1] != "" { | ||||
| 		log.Debugf("version: taking version from cli arg: %s", cliArgs[1]) | ||||
| 		return cliArgs[1], nil | ||||
| 	} | ||||
|  | ||||
| 	// Check if the recipe has a version in the .env file | ||||
| 	if app.Recipe.EnvVersion != "" && !internal.IgnoreEnvVersion { | ||||
| 		log.Debugf("version: taking version from .env file: %s", app.Recipe.EnvVersion) | ||||
| 		return app.Recipe.EnvVersion, nil | ||||
| 	} | ||||
|  | ||||
| 	// Take deployed version | ||||
| 	if deployMeta.IsDeployed { | ||||
| 		log.Debugf("version: taking deployed version: %s", deployMeta.Version) | ||||
| 		return deployMeta.Version, nil | ||||
| 	} | ||||
|  | ||||
| 	v, err := getLatestVersionOrCommit(app) | ||||
| 	log.Debugf("version: taking new recipe version: %s", v) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return v, nil | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	AppDeployCommand.Flags().BoolVarP( | ||||
| 		&internal.Chaos, | ||||
|  | ||||
| @ -81,35 +81,8 @@ var AppNewCommand = &cobra.Command{ | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
|  | ||||
| 			// NOTE(d1): rely on tags as there is no recipe.EnvVersion yet because | ||||
| 			// the app has not been fully created. we rely on the local git state of | ||||
| 			// the repository | ||||
| 			tags, err := recipe.Tags() | ||||
| 			if err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
|  | ||||
| 			internal.SortVersionsDesc(tags) | ||||
|  | ||||
| 			if len(tags) == 0 { | ||||
| 				// NOTE(d1): this is a new recipe with no released versions | ||||
| 				recipeVersion = config.UNKNOWN_DEFAULT | ||||
| 			recipeVersion = chaosVersion | ||||
| 		} else { | ||||
| 				recipeVersion = tags[len(tags)-1] | ||||
| 			} | ||||
|  | ||||
| 			if err := recipe.IsDirty(); err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
|  | ||||
| 			if !internal.Offline && !recipe.Dirty { | ||||
| 				if err := recipe.EnsureUpToDate(); err != nil { | ||||
| 					log.Fatal(err) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if !internal.Chaos { | ||||
| 			if err := recipe.EnsureIsClean(); err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
| @ -236,16 +209,7 @@ var AppNewCommand = &cobra.Command{ | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if err := app.Recipe.IsDirty(); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		toWriteVersion := recipeVersion | ||||
| 		if internal.Chaos || app.Recipe.Dirty { | ||||
| 			toWriteVersion = chaosVersion | ||||
| 		} | ||||
|  | ||||
| 		if err := app.WriteRecipeVersion(toWriteVersion, false); err != nil { | ||||
| 		if err := app.WriteRecipeVersion(recipeVersion, false); err != nil { | ||||
| 			log.Fatalf("writing recipe version failed: %s", err) | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| @ -123,6 +123,13 @@ Pass "--all-services/-a" to restart all services.`, | ||||
| var allServices bool | ||||
|  | ||||
| func init() { | ||||
| 	AppRestartCommand.Flags().BoolVarP( | ||||
| 		&internal.Chaos, | ||||
| 		"chaos", | ||||
| 		"C", | ||||
| 		false, | ||||
| 		"ignore uncommitted recipes changes", | ||||
| 	) | ||||
| 	AppRestartCommand.Flags().BoolVarP( | ||||
| 		&allServices, | ||||
| 		"all-services", | ||||
|  | ||||
| @ -183,20 +183,13 @@ beforehand. See "abra app backup" for more.`, | ||||
| 		} | ||||
| 		appPkg.SetUpdateLabel(compose, stackName, app.Env) | ||||
|  | ||||
| 		chaosVersion := config.CHAOS_DEFAULT | ||||
| 		if deployMeta.IsChaos { | ||||
| 			chaosVersion = deployMeta.ChaosVersion | ||||
| 		} | ||||
|  | ||||
| 		// NOTE(d1): no release notes implemeneted for rolling back | ||||
| 		if err := internal.NewVersionOverview( | ||||
| 		if err := internal.DeployOverview( | ||||
| 			app, | ||||
| 			downgradeWarnMessages, | ||||
| 			"rollback", | ||||
| 			deployMeta.Version, | ||||
| 			chaosVersion, | ||||
| 			chosenDowngrade, | ||||
| 			"", | ||||
| 			downgradeWarnMessages, | ||||
| 		); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| @ -49,11 +49,11 @@ var AppSecretGenerateCommand = &cobra.Command{ | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if len(args) == 1 && !generateAllSecrets { | ||||
| 		if len(args) <= 2 && !generateAllSecrets { | ||||
| 			log.Fatal("missing arguments [secret]/[version] or '--all'") | ||||
| 		} | ||||
|  | ||||
| 		if len(args) > 1 && generateAllSecrets { | ||||
| 		if len(args) > 2 && generateAllSecrets { | ||||
| 			log.Fatal("cannot use '[secret] [version]' and '--all' together") | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -54,21 +54,12 @@ Passing "--prune/-p" does not remove those volumes.`, | ||||
| 			log.Fatalf("%s is not deployed?", app.Name) | ||||
| 		} | ||||
|  | ||||
| 		chaosVersion := config.CHAOS_DEFAULT | ||||
| 		if deployMeta.IsChaos { | ||||
| 			chaosVersion = deployMeta.ChaosVersion | ||||
| 		} | ||||
|  | ||||
| 		toWriteVersion := deployMeta.Version | ||||
| 		if deployMeta.IsChaos { | ||||
| 			toWriteVersion = chaosVersion | ||||
| 		} | ||||
|  | ||||
| 		if err := internal.UndeployOverview( | ||||
| 		if err := internal.DeployOverview( | ||||
| 			app, | ||||
| 			deployMeta.Version, | ||||
| 			chaosVersion, | ||||
| 			toWriteVersion, | ||||
| 			config.NO_DOMAIN_DEFAULT, | ||||
| 			"", | ||||
| 			nil, | ||||
| 		); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
| @ -87,7 +78,7 @@ Passing "--prune/-p" does not remove those volumes.`, | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := app.WriteRecipeVersion(toWriteVersion, false); err != nil { | ||||
| 		if err := app.WriteRecipeVersion(deployMeta.Version, false); err != nil { | ||||
| 			log.Fatalf("writing recipe version failed: %s", err) | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| @ -43,7 +43,8 @@ beforehand. See "abra app backup" for more.`, | ||||
| 	ValidArgsFunction: func( | ||||
| 		cmd *cobra.Command, | ||||
| 		args []string, | ||||
| 		toComplete string) ([]string, cobra.ShellCompDirective) { | ||||
| 		toComplete string, | ||||
| 	) ([]string, cobra.ShellCompDirective) { | ||||
| 		switch l := len(args); l { | ||||
| 		case 0: | ||||
| 			return autocomplete.AppNameComplete() | ||||
| @ -206,23 +207,21 @@ beforehand. See "abra app backup" for more.`, | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		chaosVersion := config.CHAOS_DEFAULT | ||||
| 		if deployMeta.IsChaos { | ||||
| 			chaosVersion = deployMeta.ChaosVersion | ||||
|  | ||||
| 			if deployMeta.ChaosVersion == "" { | ||||
| 				chaosVersion = config.UNKNOWN_DEFAULT | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := internal.NewVersionOverview( | ||||
| 			app, | ||||
| 		if upgradeReleaseNotes != "" && chosenUpgrade != "" { | ||||
| 			fmt.Print(upgradeReleaseNotes) | ||||
| 		} else { | ||||
| 			upgradeWarnMessages = append( | ||||
| 				upgradeWarnMessages, | ||||
| 			"upgrade", | ||||
| 				fmt.Sprintf("no release notes available for %s", chosenUpgrade), | ||||
| 			) | ||||
| 		} | ||||
|  | ||||
| 		if err := internal.DeployOverview( | ||||
| 			app, | ||||
| 			deployMeta.Version, | ||||
| 			chaosVersion, | ||||
| 			chosenUpgrade, | ||||
| 			upgradeReleaseNotes, | ||||
| 			upgradeWarnMessages, | ||||
| 		); err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
| @ -365,7 +364,7 @@ func validateUpgradeVersionArg( | ||||
|  | ||||
| 	parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return fmt.Errorf("'%s' is not a known version", deployMeta.Version) | ||||
| 	} | ||||
|  | ||||
| 	if parsedSpecificVersion.IsLessThan(parsedDeployedVersion) && | ||||
| @ -397,9 +396,7 @@ func ensureDeployed(cl *dockerClient.Client, app app.App) (stack.DeployMeta, err | ||||
| 	return deployMeta, nil | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	showReleaseNotes bool | ||||
| ) | ||||
| var showReleaseNotes bool | ||||
|  | ||||
| func init() { | ||||
| 	AppUpgradeCommand.Flags().BoolVarP( | ||||
|  | ||||
| @ -10,7 +10,6 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/formatter" | ||||
| 	"coopcloud.tech/abra/pkg/log" | ||||
| 	"coopcloud.tech/abra/pkg/recipe" | ||||
| 	"coopcloud.tech/tagcmp" | ||||
| 	"github.com/AlecAivazis/survey/v2" | ||||
| 	"github.com/charmbracelet/lipgloss" | ||||
| @ -38,109 +37,21 @@ func horizontal(left, mid, right string) string { | ||||
| 	return lipgloss.JoinHorizontal(lipgloss.Left, left, mid, right) | ||||
| } | ||||
|  | ||||
| // NewVersionOverview shows an upgrade or downgrade overview | ||||
| func NewVersionOverview( | ||||
| 	app appPkg.App, | ||||
| 	warnMessages []string, | ||||
| 	kind, | ||||
| 	deployedVersion, | ||||
| 	deployedChaosVersion, | ||||
| 	toDeployVersion, | ||||
| 	releaseNotes string) error { | ||||
| 	deployConfig := "compose.yml" | ||||
| 	if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { | ||||
| 		deployConfig = composeFiles | ||||
| 	} | ||||
|  | ||||
| 	server := app.Server | ||||
| 	if app.Server == "default" { | ||||
| 		server = "local" | ||||
| 	} | ||||
|  | ||||
| 	domain := app.Domain | ||||
| 	if domain == "" { | ||||
| 		domain = config.NO_DOMAIN_DEFAULT | ||||
| 	} | ||||
|  | ||||
| 	upperKind := strings.ToUpper(kind) | ||||
|  | ||||
| 	envVersion, err := recipe.GetEnvVersionRaw(app.Recipe.Name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if envVersion == "" { | ||||
| 		envVersion = config.NO_VERSION_DEFAULT | ||||
| 	} | ||||
|  | ||||
| 	rows := [][]string{ | ||||
| 		{"DOMAIN", domain}, | ||||
| 		{"RECIPE", app.Recipe.Name}, | ||||
| 		{"SERVER", server}, | ||||
| 		{"CONFIG", deployConfig}, | ||||
|  | ||||
| 		{"CURRENT DEPLOYMENT", "---"}, | ||||
| 		{"VERSION", formatter.BoldDirtyDefault(deployedVersion)}, | ||||
| 		{"CHAOS ", formatter.BoldDirtyDefault(deployedChaosVersion)}, | ||||
|  | ||||
| 		{upperKind, "---"}, | ||||
| 		{"VERSION", formatter.BoldDirtyDefault(toDeployVersion)}, | ||||
|  | ||||
| 		{fmt.Sprintf("%s.ENV", strings.ToUpper(app.Domain)), "---"}, | ||||
| 		{"CURRENT VERSION", formatter.BoldDirtyDefault(envVersion)}, | ||||
| 		{"NEW VERSION", formatter.BoldDirtyDefault(toDeployVersion)}, | ||||
| 	} | ||||
|  | ||||
| 	overview := formatter.CreateOverview( | ||||
| 		fmt.Sprintf("%s OVERVIEW", upperKind), | ||||
| 		rows, | ||||
| 	) | ||||
|  | ||||
| 	fmt.Println(overview) | ||||
|  | ||||
| 	if releaseNotes != "" && toDeployVersion != "" { | ||||
| 		fmt.Print(releaseNotes) | ||||
| 	} else { | ||||
| 		warnMessages = append( | ||||
| 			warnMessages, | ||||
| 			fmt.Sprintf("no release notes available for %s", toDeployVersion), | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	for _, msg := range warnMessages { | ||||
| 		log.Warn(msg) | ||||
| 	} | ||||
|  | ||||
| 	if NoInput { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	response := false | ||||
| 	prompt := &survey.Confirm{Message: "proceed?"} | ||||
| 	if err := survey.AskOne(prompt, &response); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if !response { | ||||
| 		log.Fatal("deployment cancelled") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| func formatComposeFiles(composeFiles string) string { | ||||
| 	return strings.ReplaceAll(composeFiles, ":", "\n") | ||||
| } | ||||
|  | ||||
| // DeployOverview shows a deployment overview | ||||
| func DeployOverview( | ||||
| 	app appPkg.App, | ||||
| 	warnMessages []string, | ||||
| 	deployedVersion string, | ||||
| 	deployedChaosVersion string, | ||||
| 	toDeployVersion, | ||||
| 	toDeployChaosVersion string, | ||||
| 	toWriteVersion string, | ||||
| 	toDeployVersion string, | ||||
| 	info string, | ||||
| 	warnMessages []string, | ||||
| ) error { | ||||
| 	deployConfig := "compose.yml" | ||||
| 	if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { | ||||
| 		deployConfig = composeFiles | ||||
| 		deployConfig = formatComposeFiles(composeFiles) | ||||
| 	} | ||||
|  | ||||
| 	server := app.Server | ||||
| @ -153,21 +64,7 @@ func DeployOverview( | ||||
| 		domain = config.NO_DOMAIN_DEFAULT | ||||
| 	} | ||||
|  | ||||
| 	if app.Recipe.Dirty { | ||||
| 		toWriteVersion = formatter.AddDirtyMarker(toWriteVersion) | ||||
| 		toDeployChaosVersion = formatter.AddDirtyMarker(toDeployChaosVersion) | ||||
| 	} | ||||
|  | ||||
| 	recipeName, exists := app.Env["RECIPE"] | ||||
| 	if !exists { | ||||
| 		recipeName = app.Env["TYPE"] | ||||
| 	} | ||||
|  | ||||
| 	envVersion, err := recipe.GetEnvVersionRaw(recipeName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	envVersion := app.Recipe.EnvVersionRaw | ||||
| 	if envVersion == "" { | ||||
| 		envVersion = config.NO_VERSION_DEFAULT | ||||
| 	} | ||||
| @ -177,24 +74,21 @@ func DeployOverview( | ||||
| 		{"RECIPE", app.Recipe.Name}, | ||||
| 		{"SERVER", server}, | ||||
| 		{"CONFIG", deployConfig}, | ||||
|  | ||||
| 		{"CURRENT DEPLOYMENT", "---"}, | ||||
| 		{"VERSION", formatter.BoldDirtyDefault(deployedVersion)}, | ||||
| 		{"CHAOS", formatter.BoldDirtyDefault(deployedChaosVersion)}, | ||||
|  | ||||
| 		{"NEW DEPLOYMENT", "---"}, | ||||
| 		{"VERSION", formatter.BoldDirtyDefault(toDeployVersion)}, | ||||
| 		{"CHAOS", formatter.BoldDirtyDefault(toDeployChaosVersion)}, | ||||
|  | ||||
| 		{fmt.Sprintf("%s.ENV", strings.ToUpper(app.Name)), "---"}, | ||||
| 		{"CURRENT VERSION", formatter.BoldDirtyDefault(envVersion)}, | ||||
| 		{"NEW VERSION", formatter.BoldDirtyDefault(toWriteVersion)}, | ||||
| 		{"", ""}, | ||||
| 		{"CURRENT DEPLOYMENT", formatter.BoldDirtyDefault(deployedVersion)}, | ||||
| 		{"ENV VERSION", formatter.BoldDirtyDefault(envVersion)}, | ||||
| 		{"NEW DEPLOYMENT", formatter.BoldDirtyDefault(toDeployVersion)}, | ||||
| 	} | ||||
|  | ||||
| 	overview := formatter.CreateOverview("DEPLOY OVERVIEW", rows) | ||||
| 	deployType := getDeployType(deployedVersion, toDeployVersion) | ||||
| 	overview := formatter.CreateOverview(fmt.Sprintf("%s OVERVIEW", deployType), rows) | ||||
|  | ||||
| 	fmt.Println(overview) | ||||
|  | ||||
| 	if info != "" { | ||||
| 		fmt.Println(info) | ||||
| 	} | ||||
|  | ||||
| 	for _, msg := range warnMessages { | ||||
| 		log.Warn(msg) | ||||
| 	} | ||||
| @ -216,76 +110,34 @@ func DeployOverview( | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UndeployOverview shows an undeployment overview | ||||
| func UndeployOverview( | ||||
| 	app appPkg.App, | ||||
| 	deployedVersion, | ||||
| 	deployedChaosVersion, | ||||
| 	toWriteVersion string, | ||||
| ) error { | ||||
| 	deployConfig := "compose.yml" | ||||
| 	if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { | ||||
| 		deployConfig = composeFiles | ||||
| func getDeployType(currentVersion, newVersion string) string { | ||||
| 	if newVersion == config.NO_DOMAIN_DEFAULT { | ||||
| 		return "UNDEPLOY" | ||||
| 	} | ||||
|  | ||||
| 	server := app.Server | ||||
| 	if app.Server == "default" { | ||||
| 		server = "local" | ||||
| 	if strings.Contains(newVersion, "+U") { | ||||
| 		return "CHAOS DEPLOY" | ||||
| 	} | ||||
|  | ||||
| 	domain := app.Domain | ||||
| 	if domain == "" { | ||||
| 		domain = config.NO_DOMAIN_DEFAULT | ||||
| 	if strings.Contains(currentVersion, "+U") { | ||||
| 		return "UNCHAOS DEPLOY" | ||||
| 	} | ||||
|  | ||||
| 	recipeName, exists := app.Env["RECIPE"] | ||||
| 	if !exists { | ||||
| 		recipeName = app.Env["TYPE"] | ||||
| 	if currentVersion == newVersion { | ||||
| 		return "REDEPLOY" | ||||
| 	} | ||||
|  | ||||
| 	envVersion, err := recipe.GetEnvVersionRaw(recipeName) | ||||
| 	if currentVersion == config.NO_VERSION_DEFAULT { | ||||
| 		return "NEW DEPLOY" | ||||
| 	} | ||||
| 	currentParsed, err := tagcmp.Parse(currentVersion) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return "DEPLOY" | ||||
| 	} | ||||
|  | ||||
| 	if envVersion == "" { | ||||
| 		envVersion = config.NO_VERSION_DEFAULT | ||||
| 	newParsed, err := tagcmp.Parse(newVersion) | ||||
| 	if err != nil { | ||||
| 		return "DEPLOY" | ||||
| 	} | ||||
|  | ||||
| 	rows := [][]string{ | ||||
| 		{"DOMAIN", domain}, | ||||
| 		{"RECIPE", app.Recipe.Name}, | ||||
| 		{"SERVER", server}, | ||||
| 		{"CONFIG", deployConfig}, | ||||
|  | ||||
| 		{"CURRENT DEPLOYMENT", "---"}, | ||||
| 		{"VERSION", formatter.BoldDirtyDefault(deployedVersion)}, | ||||
| 		{"CHAOS", formatter.BoldDirtyDefault(deployedChaosVersion)}, | ||||
|  | ||||
| 		{fmt.Sprintf("%s.ENV", strings.ToUpper(app.Name)), "---"}, | ||||
| 		{"CURRENT VERSION", formatter.BoldDirtyDefault(envVersion)}, | ||||
| 		{"NEW VERSION", formatter.BoldDirtyDefault(toWriteVersion)}, | ||||
| 	if currentParsed.IsLessThan(newParsed) { | ||||
| 		return "UPGRADE" | ||||
| 	} | ||||
|  | ||||
| 	overview := formatter.CreateOverview("UNDEPLOY OVERVIEW", rows) | ||||
|  | ||||
| 	fmt.Println(overview) | ||||
|  | ||||
| 	if NoInput { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	response := false | ||||
| 	prompt := &survey.Confirm{Message: "proceed?"} | ||||
| 	if err := survey.AskOne(prompt, &response); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if !response { | ||||
| 		log.Fatal("undeploy cancelled") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return "DOWNGRADE" | ||||
| } | ||||
|  | ||||
| // PostCmds parses a string of commands and executes them inside of the respective services | ||||
|  | ||||
							
								
								
									
										64
									
								
								cli/internal/error.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								cli/internal/error.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"runtime" | ||||
|  | ||||
| 	"github.com/charmbracelet/log" | ||||
| ) | ||||
|  | ||||
| func Error(msg string) HelpError { | ||||
| 	caller := "" | ||||
| 	if Debug { | ||||
| 		_, file, line, _ := runtime.Caller(1) | ||||
| 		caller = log.ShortCallerFormatter(file, line, "") | ||||
|  | ||||
| 	} | ||||
| 	return HelpError{err: msg, caller: caller} | ||||
| } | ||||
|  | ||||
| func Errorf(format string, a ...any) HelpError { | ||||
| 	caller := "" | ||||
| 	if Debug { | ||||
| 		_, file, line, _ := runtime.Caller(1) | ||||
| 		caller = log.ShortCallerFormatter(file, line, "") | ||||
|  | ||||
| 	} | ||||
| 	return HelpError{err: fmt.Sprintf(format, a...), caller: caller} | ||||
| } | ||||
|  | ||||
| type HelpError struct { | ||||
| 	err    string | ||||
| 	caller string | ||||
| 	help   string | ||||
| } | ||||
|  | ||||
| func (e HelpError) Help(help string) HelpError { | ||||
| 	e.help = help | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| func (e HelpError) Helpf(format string, a ...any) HelpError { | ||||
| 	e.help = fmt.Sprintf(format, a...) | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| func (e HelpError) Error() string { | ||||
| 	return e.format() | ||||
| } | ||||
|  | ||||
| func (e HelpError) format() string { | ||||
| 	msg := "" | ||||
| 	if e.caller != "" { | ||||
| 		msg += fmt.Sprintf("<%s> ", e.caller) | ||||
| 	} | ||||
|  | ||||
| 	msg += e.err | ||||
| 	if e.help == "" { | ||||
| 		return msg | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf(`%s | ||||
|  | ||||
| Help: %s `, msg, e.help) | ||||
| } | ||||
							
								
								
									
										16
									
								
								cli/run.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cli/run.go
									
									
									
									
									
								
							| @ -3,6 +3,7 @@ package cli | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
|  | ||||
| 	"coopcloud.tech/abra/cli/app" | ||||
| 	"coopcloud.tech/abra/cli/catalogue" | ||||
| @ -40,7 +41,7 @@ func Run(version, commit string) { | ||||
| 			} | ||||
|  | ||||
| 			for _, path := range paths { | ||||
| 				if err := os.Mkdir(path, 0764); err != nil { | ||||
| 				if err := os.Mkdir(path, 0o764); err != nil { | ||||
| 					if !os.IsExist(err) { | ||||
| 						log.Fatal(err) | ||||
| 					} | ||||
| @ -66,6 +67,9 @@ func Run(version, commit string) { | ||||
| 	} | ||||
|  | ||||
| 	rootCmd.CompletionOptions.DisableDefaultCmd = true | ||||
| 	// We handle errors ourself | ||||
| 	rootCmd.SilenceUsage = true | ||||
| 	rootCmd.SilenceErrors = true | ||||
|  | ||||
| 	manCommand := &cobra.Command{ | ||||
| 		Use:     "man [flags]", | ||||
| @ -212,7 +216,15 @@ func Run(version, commit string) { | ||||
| 		app.AppEnvCommand, | ||||
| 	) | ||||
|  | ||||
| 	if err := rootCmd.Execute(); err != nil { | ||||
| 	if cmd, err := rootCmd.ExecuteC(); err != nil { | ||||
| 		fmt.Printf("Error: %s\n", err) | ||||
| 		if strings.HasPrefix(err.Error(), "unknown flag") { | ||||
| 			fmt.Println() | ||||
| 			cmd.Usage() | ||||
| 		} else if !internal.Debug { | ||||
| 			fmt.Println() | ||||
| 			fmt.Printf("Run with --debug for more info.\n") | ||||
| 		} | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| package server | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| @ -41,19 +43,20 @@ developer machine. The domain is then set to "default".`, | ||||
| 	ValidArgsFunction: func( | ||||
| 		cmd *cobra.Command, | ||||
| 		args []string, | ||||
| 		toComplete string) ([]string, cobra.ShellCompDirective) { | ||||
| 		toComplete string, | ||||
| 	) ([]string, cobra.ShellCompDirective) { | ||||
| 		if !local { | ||||
| 			return autocomplete.ServerNameComplete() | ||||
| 		} | ||||
| 		return nil, cobra.ShellCompDirectiveDefault | ||||
| 	}, | ||||
| 	Run: func(cmd *cobra.Command, args []string) { | ||||
| 	RunE: func(cmd *cobra.Command, args []string) error { | ||||
| 		if len(args) > 0 && local { | ||||
| 			log.Fatal("cannot use [server] and --local together") | ||||
| 			return errors.New("cannot use [server] and --local together") | ||||
| 		} | ||||
|  | ||||
| 		if len(args) == 0 && !local { | ||||
| 			log.Fatal("missing argument or --local/-l flag") | ||||
| 			return errors.New("missing argument or --local/-l flag") | ||||
| 		} | ||||
|  | ||||
| 		name := "default" | ||||
| @ -69,14 +72,14 @@ developer machine. The domain is then set to "default".`, | ||||
| 		if local { | ||||
| 			created, err := createServerDir(name) | ||||
| 			if err != nil { | ||||
| 				log.Fatal(err) | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			log.Debugf("attempting to create client for %s", name) | ||||
|  | ||||
| 			if _, err := client.New(name, timeout); err != nil { | ||||
| 				cleanUp(name) | ||||
| 				log.Fatal(err) | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if created { | ||||
| @ -85,18 +88,18 @@ developer machine. The domain is then set to "default".`, | ||||
| 				log.Warn("local server already exists") | ||||
| 			} | ||||
|  | ||||
| 			return | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		_, err := createServerDir(name) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(err) | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		created, err := newContext(name) | ||||
| 		if err != nil { | ||||
| 			cleanUp(name) | ||||
| 			log.Fatalf("unable to create local context: %s", err) | ||||
| 			return fmt.Errorf("unable to create local context: %s", err) | ||||
| 		} | ||||
|  | ||||
| 		log.Debugf("attempting to create client for %s", name) | ||||
| @ -104,7 +107,7 @@ developer machine. The domain is then set to "default".`, | ||||
| 		if _, err := client.New(name, timeout); err != nil { | ||||
| 			cleanUp(name) | ||||
| 			log.Debugf("ssh %s error: %s", name, sshPkg.Fatal(name, err)) | ||||
| 			log.Fatalf("can't ssh to %s, make sure \"ssh %s\" works", name, name) | ||||
| 			return internal.Errorf("can't ssh to %s", name).Helpf("make sure \"ssh %s\" works", name) | ||||
| 		} | ||||
|  | ||||
| 		if created { | ||||
| @ -114,10 +117,11 @@ developer machine. The domain is then set to "default".`, | ||||
| 				log.Warnf("unable to resolve IPv4 for %s", name) | ||||
| 			} | ||||
|  | ||||
| 			return | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		log.Warnf("%s already exists", name) | ||||
| 		return nil | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| @ -189,9 +193,7 @@ func createServerDir(name string) (bool, error) { | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	local bool | ||||
| ) | ||||
| var local bool | ||||
|  | ||||
| func init() { | ||||
| 	ServerAddCommand.Flags().BoolVarP( | ||||
|  | ||||
| @ -655,19 +655,6 @@ func (a App) WriteRecipeVersion(version string, dryRun bool) error { | ||||
|  | ||||
| 		splitted := strings.Split(line, ":") | ||||
|  | ||||
| 		if a.Recipe.Dirty { | ||||
| 			dirtyVersion = fmt.Sprintf("%s%s", version, config.DIRTY_DEFAULT) | ||||
| 			if strings.Contains(line, dirtyVersion) { | ||||
| 				skipped = true | ||||
| 				lines = append(lines, line) | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			line = fmt.Sprintf("%s:%s", splitted[0], dirtyVersion) | ||||
| 			lines = append(lines, line) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		line = fmt.Sprintf("%s:%s", splitted[0], version) | ||||
| 		lines = append(lines, line) | ||||
| 	} | ||||
|  | ||||
| @ -223,16 +223,4 @@ func TestWriteRecipeVersionOverwrite(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	assert.Equal(t, "foo", app.Recipe.EnvVersion) | ||||
|  | ||||
| 	app.Recipe.Dirty = true | ||||
| 	if err := app.WriteRecipeVersion("foo+U", false); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	app, err = appPkg.GetApp(testPkg.ExpectedAppFiles, testPkg.AppName) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	assert.Equal(t, "foo+U", app.Recipe.EnvVersion) | ||||
| } | ||||
|  | ||||
| @ -44,6 +44,16 @@ func SetChaosVersionLabel(compose *composetypes.Config, stackName string, chaosV | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetVersionLabel(compose *composetypes.Config, stackName string, version string) { | ||||
| 	for _, service := range compose.Services { | ||||
| 		if service.Name == "app" { | ||||
| 			log.Debugf("set label 'coop-cloud.%s.version' to %v for %s", stackName, version, stackName) | ||||
| 			labelKey := fmt.Sprintf("coop-cloud.%s.version", stackName) | ||||
| 			service.Deploy.Labels[labelKey] = version | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SetUpdateLabel adds env ENABLE_AUTO_UPDATE as label to enable/disable the | ||||
| // auto update process for this app. The default if this variable is not set is to disable | ||||
| // the auto update process. | ||||
|  | ||||
| @ -4,11 +4,14 @@ import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"slices" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
|  | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/formatter" | ||||
| 	gitPkg "coopcloud.tech/abra/pkg/git" | ||||
| 	"coopcloud.tech/abra/pkg/log" | ||||
| 	"coopcloud.tech/tagcmp" | ||||
| 	"github.com/distribution/reference" | ||||
| 	"github.com/go-git/go-git/v5" | ||||
| 	"github.com/go-git/go-git/v5/plumbing" | ||||
| @ -43,6 +46,9 @@ func (r Recipe) Ensure(ctx EnsureContext) error { | ||||
|  | ||||
| 	if r.EnvVersion != "" && !ctx.IgnoreEnvVersion { | ||||
| 		log.Debugf("ensuring env version %s", r.EnvVersion) | ||||
| 		if strings.Contains(r.EnvVersion, "+U") { | ||||
| 			log.Fatalf("can not redeploy chaos version (%s) without --chaos", r.EnvVersion) | ||||
| 		} | ||||
|  | ||||
| 		if _, err := r.EnsureVersion(r.EnvVersion); err != nil { | ||||
| 			return err | ||||
| @ -272,19 +278,14 @@ func (r Recipe) EnsureUpToDate() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // IsDirty checks whether a recipe is dirty or not. N.B., if you call IsDirty | ||||
| // from another Recipe method, you should propagate the pointer reference (*). | ||||
| func (r *Recipe) IsDirty() error { | ||||
| // IsDirty checks whether a recipe is dirty or not. | ||||
| func (r *Recipe) IsDirty() (bool, error) { | ||||
| 	isClean, err := gitPkg.IsClean(r.Dir) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	if !isClean { | ||||
| 		r.Dirty = true | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return !isClean, nil | ||||
| } | ||||
|  | ||||
| // ChaosVersion constructs a chaos mode recipe version. | ||||
| @ -298,8 +299,12 @@ func (r *Recipe) ChaosVersion() (string, error) { | ||||
|  | ||||
| 	version = formatter.SmallSHA(head.String()) | ||||
|  | ||||
| 	if err := r.IsDirty(); err != nil { | ||||
| 		return version, err | ||||
| 	dirty, err := r.IsDirty() | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	if dirty { | ||||
| 		return fmt.Sprintf("%s%s", version, config.DIRTY_DEFAULT), nil | ||||
| 	} | ||||
|  | ||||
| 	return version, nil | ||||
| @ -345,6 +350,18 @@ func (r Recipe) Tags() ([]string, error) { | ||||
| 		return tags, err | ||||
| 	} | ||||
|  | ||||
| 	sort.Slice(tags, func(i, j int) bool { | ||||
| 		version1, err := tagcmp.Parse(tags[i]) | ||||
| 		if err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 		version2, err := tagcmp.Parse(tags[j]) | ||||
| 		if err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 		return version1.IsLessThan(version2) | ||||
| 	}) | ||||
|  | ||||
| 	log.Debugf("detected %s as tags for recipe %s", strings.Join(tags, ", "), r.Name) | ||||
|  | ||||
| 	return tags, nil | ||||
|  | ||||
| @ -15,10 +15,6 @@ func TestIsDirty(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if err := r.IsDirty(); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	assert.False(t, r.Dirty) | ||||
|  | ||||
| 	fpath := filepath.Join(r.Dir, "foo.txt") | ||||
| @ -31,9 +27,10 @@ func TestIsDirty(t *testing.T) { | ||||
| 		os.Remove(fpath) | ||||
| 	}) | ||||
|  | ||||
| 	if err := r.IsDirty(); err != nil { | ||||
| 	dirty, err := r.IsDirty() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	assert.True(t, r.Dirty) | ||||
| 	assert.True(t, dirty) | ||||
| } | ||||
|  | ||||
| @ -12,6 +12,8 @@ import ( | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/go-git/go-git/v5" | ||||
|  | ||||
| 	"coopcloud.tech/abra/pkg/catalogue" | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/formatter" | ||||
| @ -20,7 +22,6 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/log" | ||||
| 	"coopcloud.tech/abra/pkg/web" | ||||
| 	"coopcloud.tech/tagcmp" | ||||
| 	"github.com/go-git/go-git/v5" | ||||
| ) | ||||
|  | ||||
| // RecipeCatalogueURL is the only current recipe catalogue available. | ||||
| @ -119,22 +120,9 @@ type Features struct { | ||||
| 	SSO         string `json:"sso"` | ||||
| } | ||||
|  | ||||
| func GetEnvVersionRaw(name string) (string, error) { | ||||
| 	var version string | ||||
|  | ||||
| 	if strings.Contains(name, ":") { | ||||
| 		split := strings.Split(name, ":") | ||||
| 		if len(split) > 2 { | ||||
| 			return version, fmt.Errorf("version seems invalid: %s", name) | ||||
| 		} | ||||
| 		version = split[1] | ||||
| 	} | ||||
|  | ||||
| 	return version, nil | ||||
| } | ||||
|  | ||||
| func Get(name string) Recipe { | ||||
| 	version := "" | ||||
| 	versionRaw := "" | ||||
| 	if strings.Contains(name, ":") { | ||||
| 		split := strings.Split(name, ":") | ||||
| 		if len(split) > 2 { | ||||
| @ -143,6 +131,7 @@ func Get(name string) Recipe { | ||||
| 		name = split[0] | ||||
|  | ||||
| 		version = split[1] | ||||
| 		versionRaw = version | ||||
| 		if strings.HasSuffix(version, config.DIRTY_DEFAULT) { | ||||
| 			version = strings.Replace(split[1], config.DIRTY_DEFAULT, "", 1) | ||||
| 			log.Debugf("removed dirty suffix from .env version: %s -> %s", split[1], version) | ||||
| @ -169,6 +158,7 @@ func Get(name string) Recipe { | ||||
| 	r := Recipe{ | ||||
| 		Name:          name, | ||||
| 		EnvVersion:    version, | ||||
| 		EnvVersionRaw: versionRaw, | ||||
| 		Dir:           dir, | ||||
| 		GitURL:        gitURL, | ||||
| 		SSHURL:        sshURL, | ||||
| @ -179,9 +169,11 @@ func Get(name string) Recipe { | ||||
| 		AbraShPath:    path.Join(dir, "abra.sh"), | ||||
| 	} | ||||
|  | ||||
| 	if err := r.IsDirty(); err != nil && !errors.Is(err, git.ErrRepositoryNotExists) { | ||||
| 	dirty, err := r.IsDirty() | ||||
| 	if err != nil && !errors.Is(err, git.ErrRepositoryNotExists) { | ||||
| 		log.Fatalf("failed to check git status of %s: %s", r.Name, err) | ||||
| 	} | ||||
| 	r.Dirty = dirty | ||||
|  | ||||
| 	return r | ||||
| } | ||||
| @ -189,6 +181,7 @@ func Get(name string) Recipe { | ||||
| type Recipe struct { | ||||
| 	Name          string | ||||
| 	EnvVersion    string | ||||
| 	EnvVersionRaw string | ||||
| 	Dirty         bool // NOTE(d1): git terminology for unstaged changes | ||||
| 	Dir           string | ||||
| 	GitURL        string | ||||
|  | ||||
| @ -34,6 +34,7 @@ func TestGet(t *testing.T) { | ||||
| 			recipe: Recipe{ | ||||
| 				Name:          "foo", | ||||
| 				EnvVersion:    "1.2.3", | ||||
| 				EnvVersionRaw: "1.2.3", | ||||
| 				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/foo"), | ||||
| 				GitURL:        "https://git.coopcloud.tech/coop-cloud/foo.git", | ||||
| 				SSHURL:        "ssh://git@git.coopcloud.tech:2222/coop-cloud/foo.git", | ||||
| @ -61,6 +62,22 @@ func TestGet(t *testing.T) { | ||||
| 			recipe: Recipe{ | ||||
| 				Name:          "mygit.org/myorg/cool-recipe", | ||||
| 				EnvVersion:    "1.2.4", | ||||
| 				EnvVersionRaw: "1.2.4", | ||||
| 				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"), | ||||
| 				GitURL:        "https://mygit.org/myorg/cool-recipe.git", | ||||
| 				SSHURL:        "ssh://git@mygit.org/myorg/cool-recipe.git", | ||||
| 				ComposePath:   path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/compose.yml"), | ||||
| 				ReadmePath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/README.md"), | ||||
| 				SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/.env.sample"), | ||||
| 				AbraShPath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"), | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "mygit.org/myorg/cool-recipe:1e83340e+U", | ||||
| 			recipe: Recipe{ | ||||
| 				Name:          "mygit.org/myorg/cool-recipe", | ||||
| 				EnvVersion:    "1e83340e", | ||||
| 				EnvVersionRaw: "1e83340e+U", | ||||
| 				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"), | ||||
| 				GitURL:        "https://mygit.org/myorg/cool-recipe.git", | ||||
| 				SSHURL:        "ssh://git@mygit.org/myorg/cool-recipe.git", | ||||
| @ -105,16 +122,3 @@ func TestGetVersionLabelLocalDoesNotUseTimeoutLabel(t *testing.T) { | ||||
| 		assert.NotEqual(t, label, defaultTimeoutLabel) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDirtyMarkerRemoved(t *testing.T) { | ||||
| 	r := Get("abra-test-recipe:1e83340e+U") | ||||
| 	assert.Equal(t, "1e83340e", r.EnvVersion) | ||||
| } | ||||
|  | ||||
| func TestGetEnvVersionRaw(t *testing.T) { | ||||
| 	v, err := GetEnvVersionRaw("abra-test-recipe:1e83340e+U") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	assert.Equal(t, "1e83340e+U", v) | ||||
| } | ||||
|  | ||||
| @ -22,6 +22,8 @@ setup(){ | ||||
| teardown(){ | ||||
|   _reset_recipe | ||||
|   _undeploy_app | ||||
|   _undeploy_app2 "gitea.$TEST_SERVER" | ||||
|  | ||||
|   _reset_app | ||||
|   _reset_tags | ||||
|  | ||||
| @ -222,19 +224,6 @@ teardown(){ | ||||
|   run $ABRA app deploy "gitea.$TEST_SERVER" --no-input --no-converge-checks | ||||
|   assert_success | ||||
|   assert_output --partial "$latestVersion" | ||||
|  | ||||
|   run $ABRA app undeploy "gitea.$TEST_SERVER" --no-input | ||||
|   assert_success | ||||
|  | ||||
|   run $ABRA app secret remove "gitea.$TEST_SERVER" --all --no-input | ||||
|   assert_success | ||||
|  | ||||
|   run $ABRA app volume remove "gitea.$TEST_SERVER" --no-input | ||||
|   assert_success | ||||
|  | ||||
|   run $ABRA app remove "gitea.$TEST_SERVER" --no-input | ||||
|   assert_success | ||||
|   assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/gitea.$TEST_SERVER.env" | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
|  | ||||
| @ -54,13 +54,21 @@ teardown(){ | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
| @test "chaos commit written to env" { | ||||
| @test "deploy commit written to env and redeploy keeps that version" { | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" "1e83340e" --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:1e83340e" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_success | ||||
|  | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" \ | ||||
|     --force --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:1e83340e" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_success | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
| @ -98,12 +106,15 @@ teardown(){ | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
| @test "deploy overwrites chaos deploy" { | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" "1e83340e" \ | ||||
|     --no-input --no-converge-checks | ||||
| @test "takes deployed version when no .env version is present " { | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks --ignore-env-version | ||||
|   assert_success | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:1e83340e" \ | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_success | ||||
|  | ||||
|   run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=abra-test-recipe/g' \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_success | ||||
|  | ||||
| @ -111,7 +122,7 @@ teardown(){ | ||||
|     --force --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:1e83340e" \ | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_failure | ||||
|   assert_success | ||||
| } | ||||
|  | ||||
| @ -37,17 +37,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*N/A' | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.* ' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*N/A' | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${latestRelease}" | ||||
|   assert_output --partial 'NEW DEPLOY OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    N/A' | ||||
|   assert_output --partial 'ENV VERSION           N/A' | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${latestRelease}" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -61,17 +54,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*N/A' | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.* ' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${latestRelease}" | ||||
|   assert_output --partial 'NEW DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    N/A" | ||||
|   assert_output --partial "ENV VERSION           ${latestRelease}" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${latestRelease}" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -90,17 +76,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*N/A' | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.1.1+1.20.2" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.1.1+1.20.2" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.1.1+1.20.2" | ||||
|   assert_output --partial 'NEW DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    N/A" | ||||
|   assert_output --partial "ENV VERSION           0.1.1+1.20.2" | ||||
|   assert_output --partial "NEW DEPLOYMENT        0.1.1+1.20.2" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.1.1+1.20.2" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -120,17 +99,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --ignore-env-version | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*N/A' | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.1.1+1.20.2" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${latestRelease}" | ||||
|   assert_output --partial 'NEW DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    N/A" | ||||
|   assert_output --partial "ENV VERSION           0.1.1+1.20.2" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${latestRelease}" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -153,17 +125,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --chaos | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}+U" | ||||
|   assert_output --partial 'CHAOS DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${latestRelease}" | ||||
|   assert_output --partial "ENV VERSION           ${latestRelease}" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}+U" | ||||
|  | ||||
|   run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
|   assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
| @ -173,7 +138,7 @@ teardown(){ | ||||
|   assert_success | ||||
| } | ||||
|  | ||||
| @test "chaos deploy then force deploy" { | ||||
| @test "can not redeploy chaos version without --chaos" { | ||||
|   headHash=$(_get_head_hash) | ||||
|   latestRelease=$(_latest_release) | ||||
|  | ||||
| @ -190,26 +155,11 @@ teardown(){ | ||||
|  | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" \ | ||||
|     --no-input --no-converge-checks --force | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U" | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${headHash:0:8}+U" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${latestRelease}" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_success | ||||
|   assert_failure | ||||
|   assert_output --regexp 'can not redeploy chaos version .*' + "${headHash:0:8}+U" | ||||
| } | ||||
|  | ||||
| @test "deploy then force chaos commit deploy" { | ||||
| @test "deploy then force commit deploy" { | ||||
|   headHash=$(_get_head_hash) | ||||
|   latestRelease=$(_latest_release) | ||||
|  | ||||
| @ -225,17 +175,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --force | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}" | ||||
|   assert_output --partial 'DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${latestRelease}" | ||||
|   assert_output --partial "ENV VERSION           ${latestRelease}" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -250,17 +193,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --chaos | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*N/A' | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}" | ||||
|   assert_output --partial 'NEW DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    N/A" | ||||
|   assert_output --partial "ENV VERSION           ${latestRelease}" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}" | ||||
|  | ||||
|   run bash -c 'echo "unstaged changes" >> "$ABRA_DIR/recipes/$TEST_RECIPE/foo"' | ||||
|   assert_success | ||||
| @ -270,17 +206,28 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --chaos | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}" | ||||
|   assert_output --partial 'CHAOS DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${headHash:0:8}" | ||||
|   assert_output --partial "ENV VERSION           ${headHash:0:8}" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}+U" | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U" | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" \ | ||||
|     --no-input --no-converge-checks --chaos | ||||
|   assert_success | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}+U" | ||||
|   assert_output --partial 'CHAOS DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${headHash:0:8}+U" | ||||
|   assert_output --partial "ENV VERSION           ${headHash:0:8}+U" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}+U" | ||||
|  | ||||
|   run $ABRA app deploy "$TEST_APP_DOMAIN" \ | ||||
|     --no-input --no-converge-checks --chaos | ||||
|   assert_success | ||||
|  | ||||
|   assert_output --partial 'CHAOS DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${headHash:0:8}+U" | ||||
|   assert_output --partial "ENV VERSION           ${headHash:0:8}+U" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}+U" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -302,19 +249,8 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --force | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}" | ||||
|  | ||||
|   # new deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${headHash:0:8}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${latestRelease}" | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_success | ||||
|   assert_output --partial 'CHAOS DEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${headHash:0:8}" | ||||
|   assert_output --partial "ENV VERSION           ${headHash:0:8}" | ||||
|   assert_output --partial "NEW DEPLOYMENT        ${headHash:0:8}" | ||||
| } | ||||
|  | ||||
| @ -56,7 +56,7 @@ teardown(){ | ||||
|   assert_success | ||||
| } | ||||
|  | ||||
| @test "create new app with chaos commit" { | ||||
| @test "create new app with version commit" { | ||||
|   tagHash=$(_get_tag_hash "0.3.0+1.21.0") | ||||
|  | ||||
|   run $ABRA app new "$TEST_RECIPE" "$tagHash" \ | ||||
| @ -129,6 +129,10 @@ teardown(){ | ||||
|   assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
|   assert_equal "$(_git_status)" "?? foo" | ||||
|  | ||||
|   run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status | ||||
|   assert_success | ||||
|   assert_output --partial 'foo' | ||||
|  | ||||
|   run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
|   assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
| } | ||||
| @ -210,7 +214,7 @@ teardown(){ | ||||
|     --chaos | ||||
|   assert_success | ||||
|   assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_output --partial "version: $latestRelease" | ||||
|   assert_output --partial "version: ${currentHash:0:8}" | ||||
|   assert_output --partial "chaos: ${currentHash:0:8}" | ||||
|  | ||||
|   assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
| @ -238,7 +242,7 @@ teardown(){ | ||||
|     --chaos | ||||
|   assert_success | ||||
|   assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|   assert_output --partial "version: unknown" | ||||
|   assert_output --partial "version: ${currentHash:0:8}" | ||||
|   assert_output --partial "chaos: ${currentHash:0:8}" | ||||
|  | ||||
|   assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" | ||||
|  | ||||
| @ -153,7 +153,7 @@ teardown(){ | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
| @test "rollback chaos deployment" { | ||||
| @test "rollback chaos deployment is not possible" { | ||||
|   tagHash=$(_get_tag_hash "0.2.0+1.21.0") | ||||
|   run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash" | ||||
|   assert_success | ||||
| @ -163,17 +163,9 @@ teardown(){ | ||||
|   assert_output --partial "${tagHash:0:8}" | ||||
|  | ||||
|   run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks | ||||
|   assert_success | ||||
|   assert_failure | ||||
|   assert_output --partial "0.1.1+1.20.2" | ||||
|   assert_output --partial "${tagHash:0:8}" | ||||
|  | ||||
|   run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks | ||||
|   assert_success | ||||
|   assert_output --partial "0.1.0+1.20.0" | ||||
|  | ||||
|   tagHash=$(_get_tag_hash "0.1.1+1.20.2") | ||||
|   refute_output --partial "${tagHash:0:8}" | ||||
|   assert_output --partial "false" | ||||
|   assert_output --partial "${tagHash:0:8}" + 'is not a known version' | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
|  | ||||
| @ -33,16 +33,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"  | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # rollback | ||||
|   assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0"  | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.1.0+1.20.0" | ||||
|   assert_output --partial 'DOWNGRADE OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.2.0+1.21.0' | ||||
|   assert_output --partial 'ENV VERSION           0.2.0+1.21.0' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        0.1.0+1.20.0' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -58,16 +52,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --force | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"  | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # rollback | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --partial 'REDEPLOY OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.2.0+1.21.0' | ||||
|   assert_output --partial 'ENV VERSION           0.2.0+1.21.0' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        0.2.0+1.21.0' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -85,16 +73,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # rollback | ||||
|   assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*N/A' | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --partial 'DOWNGRADE OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.2.0+1.21.0' | ||||
|   assert_output --partial 'ENV VERSION           N/A' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        0.1.0+1.20.0' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|  | ||||
| @ -41,6 +41,11 @@ teardown(){ | ||||
|  | ||||
|   run $ABRA app secret generate "$TEST_APP_DOMAIN" | ||||
|   assert_failure | ||||
|   assert_output --partial 'missing arguments' | ||||
|  | ||||
|   run $ABRA app secret generate "$TEST_APP_DOMAIN" test_pass_one | ||||
|   assert_failure | ||||
|   assert_output --partial 'missing arguments' | ||||
|  | ||||
|   run $ABRA app secret generate "$TEST_APP_DOMAIN" testSecret testVersion --all | ||||
|   assert_failure | ||||
|  | ||||
| @ -92,9 +92,6 @@ teardown(){ | ||||
|  | ||||
|   run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input | ||||
|   assert_success | ||||
|  | ||||
|   # NOTE(d1): ensure not chaos undeploy | ||||
|   assert_output --partial 'false' | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
|  | ||||
| @ -33,13 +33,10 @@ teardown(){ | ||||
|   run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0"  | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.1.0+1.20.0" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.1.0+1.20.0" | ||||
|   assert_output --partial 'UNDEPLOY OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.1.0+1.20.0' | ||||
|   assert_output --partial 'ENV VERSION           0.1.0+1.20.0' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        N/A' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -57,13 +54,10 @@ teardown(){ | ||||
|   run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}" | ||||
|   assert_output --partial 'UNDEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${headHash:0:8}" | ||||
|   assert_output --partial "ENV VERSION           ${headHash:0:8}" | ||||
|   assert_output --partial 'NEW DEPLOYMENT        N/A' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -72,7 +66,6 @@ teardown(){ | ||||
|  | ||||
| @test "chaos deploy with unstaged commits and undeploy" { | ||||
|   headHash=$(_get_head_hash) | ||||
|   latestRelease=$(_latest_release) | ||||
|  | ||||
|   run bash -c 'echo "unstaged changes" >> "$ABRA_DIR/recipes/$TEST_RECIPE/foo"' | ||||
|   assert_success | ||||
| @ -85,13 +78,10 @@ teardown(){ | ||||
|   run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U" | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}+U" | ||||
|   assert_output --partial 'UNDEPLOY OVERVIEW' | ||||
|   assert_output --partial "CURRENT DEPLOYMENT    ${headHash:0:8}+U" | ||||
|   assert_output --partial "ENV VERSION           ${headHash:0:8}+U" | ||||
|   assert_output --partial 'NEW DEPLOYMENT        N/A' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|  | ||||
| @ -205,7 +205,7 @@ teardown(){ | ||||
| } | ||||
|  | ||||
| # bats test_tags=slow | ||||
| @test "upgrade chaos deployment" { | ||||
| @test "upgrade commit deployment not possible" { | ||||
|   tagHash=$(_get_tag_hash "0.1.0+1.20.0") | ||||
|   run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash" | ||||
|   assert_success | ||||
| @ -215,17 +215,8 @@ teardown(){ | ||||
|   assert_output --partial "${tagHash:0:8}" | ||||
|  | ||||
|   run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks | ||||
|   assert_success | ||||
|   assert_output --partial "0.1.1+1.20.2" | ||||
|   assert_output --partial "${tagHash:0:8}" | ||||
|  | ||||
|   run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.2.0+1.21.0" --no-input --no-converge-checks | ||||
|   assert_success | ||||
|   assert_output --partial "0.2.0+1.21.0" | ||||
|  | ||||
|   tagHash=$(_get_tag_hash "0.1.1+1.20.2") | ||||
|   refute_output --partial "${tagHash:0:8}" | ||||
|   assert_output --partial "false" | ||||
|   assert_failure | ||||
|   assert_output --partial "not a known version" | ||||
| } | ||||
|  | ||||
| @test "chaos commit upgrade not possible" { | ||||
|  | ||||
| @ -31,17 +31,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # upgrade | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"  | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.1.0+1.20.0" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --partial 'UPGRADE OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.1.0+1.20.0' | ||||
|   assert_output --partial 'ENV VERSION           0.1.0+1.20.0' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        0.2.0+1.21.0' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -57,17 +50,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --force | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"  | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # upgrade | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --partial 'REDEPLOY OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.2.0+1.21.0' | ||||
|   assert_output --partial 'ENV VERSION           0.2.0+1.21.0' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        0.2.0+1.21.0' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
| @ -87,17 +73,10 @@ teardown(){ | ||||
|     --no-input --no-converge-checks --force | ||||
|   assert_success | ||||
|  | ||||
|   # current deployment | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # upgrade | ||||
|   assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --regexp 'CHAOS.*false' | ||||
|  | ||||
|   # env version | ||||
|   assert_output --regexp 'CURRENT VERSION.*N/A' | ||||
|   assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0" | ||||
|   assert_output --partial 'UPGRADE OVERVIEW' | ||||
|   assert_output --partial 'CURRENT DEPLOYMENT    0.2.0+1.21.0' | ||||
|   assert_output --partial 'ENV VERSION           N/A' | ||||
|   assert_output --partial 'NEW DEPLOYMENT        0.3.1+1.21.0' | ||||
|  | ||||
|   run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ | ||||
|     "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" | ||||
|  | ||||
| @ -30,6 +30,15 @@ _undeploy_app() { | ||||
|   assert_output --partial 'unknown' | ||||
| } | ||||
|  | ||||
| _undeploy_app2() { | ||||
|   run $ABRA app undeploy "$1" --no-input | ||||
|  | ||||
|   run $ABRA app ls --server "$TEST_SERVER" --status | ||||
|   assert_success | ||||
|   assert_output --partial "$1" | ||||
|   assert_output --partial 'unknown' | ||||
| } | ||||
|  | ||||
| _rm_app() { | ||||
|   # NOTE(d1): not asserting outcomes on teardown here since some might fail | ||||
|   # depending on what the test created. all commands run through anyway | ||||
|  | ||||
| @ -38,6 +38,8 @@ _set_git_author() { | ||||
| } | ||||
|  | ||||
| _git_commit() { | ||||
|   _set_git_author | ||||
|  | ||||
|   run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" add . | ||||
|   assert_success | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user