vault/tools/pipeline/internal/cmd/github_sync_branch.go
Ryan Cragun 3611b8b709
[VAULT-32028] pipeline(github): add sync branches sub-command (#31252)
Add a new `pipeline github sync branches` command that can synchronize
two branches. We'll use this to synchronize the
`hashicorp/vault-enterprise/ce/*` branches with `hashicorp/vault/*`.

As the community repository is effectively a mirror of what is hosted in
Enterprise, a scheduled sync cadence is probably fine. Eventually we'll
hook the workflow and sync into the release pipeline to ensure that
`hashicorp/vault` branches are up-to-date when cutting community
releases.

As part of this I also fixed a few static analysis issues that popped up
when running `golangci-lint` and fixed a few smaller bugs.

Signed-off-by: Ryan Cragun <me@ryan.ec>
2025-07-11 14:08:14 -06:00

65 lines
2.5 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package cmd
import (
"context"
"errors"
"fmt"
"github.com/hashicorp/vault/tools/pipeline/internal/pkg/github"
"github.com/spf13/cobra"
)
var syncGithubBranchReq = github.SyncBranchReq{}
func newSyncGithubBranchCmd() *cobra.Command {
syncBranchCmd := &cobra.Command{
Use: "branch",
Short: "Sync a branch between two repositories",
Long: "Sync a branch between two repositories by merging the --from branch into the --to branch and pushing the result on success",
RunE: runSyncGithubBranchCmd,
}
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.FromOrigin, "from-origin", "from", "The origin name to use for the from-branch")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.FromOwner, "from-owner", "hashicorp", "The Github organization hosting the from branch")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.FromRepo, "from-repo", "vault-enterprise", "The Github repository to sync from")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.FromBranch, "from-branch", "", "The name of the branch we want to sync from")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.ToOrigin, "to-origin", "to", "The origin name to use for the to-branch")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.ToOwner, "to-owner", "hashicorp", "The Github organization hosting the to branch")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.ToRepo, "to-repo", "vault-enterprise", "The Github repository to sync to")
syncBranchCmd.PersistentFlags().StringVar(&syncGithubBranchReq.ToBranch, "to-branch", "", "The name of the branch we want to sync to")
syncBranchCmd.PersistentFlags().StringVarP(&syncGithubBranchReq.RepoDir, "repo-dir", "d", "", "The path to the vault repository dir. If not set a temporary directory will be used")
err := syncBranchCmd.MarkPersistentFlagRequired("from-branch")
if err != nil {
panic(err)
}
err = syncBranchCmd.MarkPersistentFlagRequired("to-branch")
if err != nil {
panic(err)
}
return syncBranchCmd
}
func runSyncGithubBranchCmd(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true // Don't spam the usage on failure
res, err := syncGithubBranchReq.Run(context.TODO(), githubCmdState.Github, githubCmdState.Git)
switch rootCfg.format {
case "json":
b, err1 := res.ToJSON()
if err1 != nil {
return errors.Join(err, err1)
}
fmt.Println(string(b))
default:
fmt.Println(res.ToTable(err).Render())
}
return err
}