Ryan Cragun 3e9f84e666
[VAULT-36202] pipeline(releases): add releases list active-versions command (#30658)
While working on VAULT-34829 it became apparent that if our new backporter
could know which branches are active and which CE counterparts are active
then we could completely omit the need for `ce` backport labels and instead
automatically backport to corresponding CE branches that are active.

To facilitate that we can re-use our `.release/versions.hcl` file as it is
the current source of truth for our present backport assistant workflow.

Here we add a new `pipeline releases list versions` command that is capable
of decoding that file and optionally displaying it. It will be used in the
next PR that fully implements VAULT-34829.

As part of this work we refactors `pipeline releases` to include a new `list`
sub-command and moved both `list-active-versions` and `versions` to it.

We also include a few small fixes that were noticed:
  - `.release/verions.hcl` was not up-to-date
  - Our cached dynamic config was not getting recreated when the pipeline
    tool changed. That has been fixed so now dynamic config should always
    get recreated when the pipeline binary changes
  - We now initialize a git client when using the `github` sub-command.
    This will be used in more forthcoming work
  - Update our changed file detection to resolve some incorrect groupings
  - Add some additional changed file helpers that we be used in forthcoming
    work

Signed-off-by: Ryan Cragun <me@ryan.ec>
2025-05-20 11:10:24 -06:00

75 lines
1.7 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package cmd
import (
"fmt"
"log/slog"
"os"
"github.com/spf13/cobra"
slogctx "github.com/veqryn/slog-context"
)
type rootCmdCfg struct {
logLevel string
format string
}
var rootCfg = &rootCmdCfg{}
func newRootCmd() *cobra.Command {
rootCmd := &cobra.Command{
Use: "pipeline",
Short: "Execute pipeline tasks",
Long: "Pipeline automation tasks",
}
rootCmd.PersistentFlags().StringVar(&rootCfg.logLevel, "log", "warn", "Set the log level. One of 'debug', 'info', 'warn', 'error'")
rootCmd.PersistentFlags().StringVarP(&rootCfg.format, "format", "f", "table", "The output format. Can be 'json' or 'table'")
rootCmd.AddCommand(newGenerateCmd())
rootCmd.AddCommand(newGithubCmd())
rootCmd.AddCommand(newReleasesCmd())
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
var ll slog.Level
switch rootCfg.logLevel {
case "debug":
ll = slog.LevelDebug
case "info":
ll = slog.LevelInfo
case "warn":
ll = slog.LevelWarn
case "error":
ll = slog.LevelError
default:
return fmt.Errorf("unsupported log level: %s", rootCfg.logLevel)
}
h := slogctx.NewHandler(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: ll}), nil)
slog.SetDefault(slog.New(h))
switch rootCfg.format {
case "json", "table":
default:
return fmt.Errorf("unsupported format: %s", rootCfg.format)
}
return nil
}
return rootCmd
}
// Execute executes the root pipeline command.
func Execute() {
rootCmd := newRootCmd()
rootCmd.SilenceErrors = true // We handle this below
if err := rootCmd.Execute(); err != nil {
slog.Default().Error(err.Error())
os.Exit(1)
}
}