Skip to content

Commit

Permalink
Merge pull request #504 from NautiluX/appinterface-dir
Browse files Browse the repository at this point in the history
promote: Allow providing app-interface checkout directory
  • Loading branch information
openshift-merge-bot[bot] authored Jan 22, 2024
2 parents b17e73a + 13bcf91 commit 3b47dbd
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 47 deletions.
88 changes: 69 additions & 19 deletions cmd/promote/git/app_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"os"
"os/exec"
"path/filepath"
"strings"

"gopkg.in/yaml.v3"
Expand All @@ -23,21 +24,49 @@ type Service struct {
} `yaml:"resourceTemplates"`
}

func BootstrapOsdCtlForAppInterfaceAndServicePromotions() {
_, err := getBaseDir()
if err != nil {
log.Fatal(err)
type AppInterface struct {
GitDirectory string
}

func DefaultAppInterfaceDirectory() string {
return filepath.Join(os.Getenv("HOME"), "git", "app-interface")
}

func BootstrapOsdCtlForAppInterfaceAndServicePromotions(appInterfaceCheckoutDir string) AppInterface {
a := AppInterface{}
if appInterfaceCheckoutDir != "" {
a.GitDirectory = appInterfaceCheckoutDir
err := checkAppInterfaceCheckout(a.GitDirectory)
if err != nil {
log.Fatalf("Provided directory %s is not an AppInterface directory: %v", a.GitDirectory, err)
}
return a
}
err = checkAppInterfaceCheckout()

dir, err := getBaseDir()
if err == nil {
a.GitDirectory = dir
err = checkAppInterfaceCheckout(a.GitDirectory)
if err == nil {
return a
}
}

log.Printf("Not running in AppInterface directory: %v - Trying %s next\n", err, DefaultAppInterfaceDirectory())
a.GitDirectory = DefaultAppInterfaceDirectory()
err = checkAppInterfaceCheckout(a.GitDirectory)
if err != nil {
log.Fatal(err)
log.Fatalf("%s is not an AppInterface directory: %v", DefaultAppInterfaceDirectory(), err)
}

log.Printf("Found AppInterface in %s.\n", a.GitDirectory)
return a
}

// checkAppInterfaceCheckout checks if the script is running in the checkout of app-interface
func checkAppInterfaceCheckout() error {
func checkAppInterfaceCheckout(directory string) error {
cmd := exec.Command("git", "remote", "-v")
cmd.Dir = BaseDir
cmd.Dir = directory
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error executing 'git remote -v': %v", err)
Expand All @@ -49,7 +78,7 @@ func checkAppInterfaceCheckout() error {
if !strings.Contains(outputString, "gitlab.cee.redhat.com") && !strings.Contains(outputString, "app-interface") {
return fmt.Errorf("not running in checkout of app-interface")
}
fmt.Println("Running in checkout of app-interface.")
//fmt.Println("Running in checkout of app-interface.")

return nil
}
Expand Down Expand Up @@ -149,10 +178,24 @@ func GetCurrentPackageTagFromAppInterface(saasFile string) (string, error) {
return currentPackageTag, nil
}

func UpdateAppInterface(serviceName, saasFile, currentGitHash, promotionGitHash, branchName string) error {
cmd := exec.Command("git", "checkout", "-b", branchName, "master")
cmd.Dir = BaseDir
func (a AppInterface) UpdateAppInterface(serviceName, saasFile, currentGitHash, promotionGitHash, branchName string) error {
cmd := exec.Command("git", "checkout", "master")
cmd.Dir = a.GitDirectory
err := cmd.Run()
if err != nil {
return fmt.Errorf("failed to checkout master branch: %v", err)
}

cmd = exec.Command("git", "branch", "-D", branchName)
cmd.Dir = a.GitDirectory
err = cmd.Run()
if err != nil {
fmt.Printf("failed to cleanup branch %s: %v, continuing to create it.\n", branchName, err)
}

cmd = exec.Command("git", "checkout", "-b", branchName, "master")
cmd.Dir = a.GitDirectory
err = cmd.Run()
if err != nil {
return fmt.Errorf("failed to create branch %s: %v, does it already exist? If so, please delete it with `git branch -D %s` first", branchName, err, branchName)
}
Expand All @@ -174,12 +217,19 @@ func UpdateAppInterface(serviceName, saasFile, currentGitHash, promotionGitHash,
return nil
}

func UpdatePackageTag(saasFile, oldTag, promotionTag, branchName string) error {
cmd := exec.Command("git", "checkout", "-b", branchName, "master")
cmd.Dir = BaseDir
func (a AppInterface) UpdatePackageTag(saasFile, oldTag, promotionTag, branchName string) error {
cmd := exec.Command("git", "checkout", "master")
cmd.Dir = a.GitDirectory
err := cmd.Run()
if err != nil {
return fmt.Errorf("failed to create branch %s: %v, does it already exist? If so, please delete it with `git branch -D %s` first", branchName, err, branchName)
return fmt.Errorf("failed to checkout master branch: %v", err)
}

cmd = exec.Command("git", "branch", "-D", branchName)
cmd.Dir = a.GitDirectory
err = cmd.Run()
if err != nil {
fmt.Printf("failed to cleanup branch %s: %v, continuing to create it.\n", branchName, err)
}

// Update the hash in the SAAS file
Expand All @@ -198,18 +248,18 @@ func UpdatePackageTag(saasFile, oldTag, promotionTag, branchName string) error {
return nil
}

func CommitSaasFile(saasFile, commitMessage string) error {
func (a AppInterface) CommitSaasFile(saasFile, commitMessage string) error {
// Commit the change
cmd := exec.Command("git", "add", saasFile)
cmd.Dir = BaseDir
cmd.Dir = a.GitDirectory
err := cmd.Run()
if err != nil {
return fmt.Errorf("failed to add file %s: %v", saasFile, err)
}

//commitMessage := fmt.Sprintf("Promote %s to %s", serviceName, promotionGitHash)
cmd = exec.Command("git", "commit", "-m", commitMessage)
cmd.Dir = BaseDir
cmd.Dir = a.GitDirectory
err = cmd.Run()
if err != nil {
return fmt.Errorf("failed to commit changes: %v", err)
Expand Down
8 changes: 4 additions & 4 deletions cmd/promote/git/git_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ func getBaseDir() (string, error) {
return BaseDir, baseDirErr
}

func checkBehindMaster() error {
func checkBehindMaster(dir string) error {
fmt.Printf("### Checking 'master' branch is up to date ###\n")

cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
cmd.Dir = BaseDir
cmd.Dir = dir
output, err := cmd.Output()
if err != nil {
return fmt.Errorf("error executing git rev-parse command: %v", err)
Expand All @@ -46,14 +46,14 @@ func checkBehindMaster() error {

// Fetch the latest changes from the upstream repository
cmd = exec.Command("git", "fetch", "upstream")
cmd.Dir = BaseDir
cmd.Dir = dir
err = cmd.Run()
if err != nil {
return fmt.Errorf("error executing git fetch command: %v", err)
}

cmd = exec.Command("git", "rev-list", "--count", "HEAD..upstream/master")
cmd.Dir = BaseDir
cmd.Dir = dir
output, err = cmd.Output()
if err != nil {
return fmt.Errorf("error executing git rev-list command: %v", err)
Expand Down
20 changes: 11 additions & 9 deletions cmd/promote/pko/pko.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,24 @@ func NewCmdPKO() *cobra.Command {
osdctl promote package --serviceName <serviceName> --gitHash <git-hash>`,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(ops.ValidatePKOOptions())
git.BootstrapOsdCtlForAppInterfaceAndServicePromotions()
appInterface := git.BootstrapOsdCtlForAppInterfaceAndServicePromotions(ops.appInterfaceCheckoutDir)

cmdutil.CheckErr(PromotePackage(ops.serviceName, ops.packageTag, ops.hcp))
cmdutil.CheckErr(PromotePackage(appInterface, ops.serviceName, ops.packageTag, ops.hcp))
},
}
pkoCmd.Flags().StringVarP(&ops.serviceName, "serviceName", "n", "", "Service getting promoted")
pkoCmd.Flags().StringVarP(&ops.packageTag, "tag", "t", "", "Package tag being promoted to")
pkoCmd.Flags().StringVarP(&ops.appInterfaceCheckoutDir, "appInterfaceDir", "", "", "location of app-interfache checkout. Falls back to `pwd` and "+git.DefaultAppInterfaceDirectory())
pkoCmd.Flags().BoolVar(&ops.hcp, "hcp", false, "The service being promoted conforms to the HyperShift progressive delivery definition")
return pkoCmd
}

// pkoOptions defines the options provided by this command
type pkoOptions struct {
serviceName string
packageTag string
hcp bool
serviceName string
packageTag string
appInterfaceCheckoutDir string
hcp bool
}

func (p pkoOptions) ValidatePKOOptions() error {
Expand All @@ -49,8 +51,8 @@ func (p pkoOptions) ValidatePKOOptions() error {
return nil
}

func PromotePackage(serviceName string, packageTag string, hcp bool) error {
services, err := saas.GetServiceNames(saas.OSDSaasDir, saas.BPSaasDir, saas.CADSaasDir)
func PromotePackage(appInterface git.AppInterface, serviceName string, packageTag string, hcp bool) error {
services, err := saas.GetServiceNames(appInterface, saas.OSDSaasDir, saas.BPSaasDir, saas.CADSaasDir)
if err != nil {
return err
}
Expand All @@ -75,13 +77,13 @@ func PromotePackage(serviceName string, packageTag string, hcp bool) error {
}

branchName := fmt.Sprintf("promote-%s-package-%s", serviceName, packageTag)
err = git.UpdatePackageTag(saasFile, currentTag, packageTag, branchName)
err = appInterface.UpdatePackageTag(saasFile, currentTag, packageTag, branchName)
if err != nil {
return err
}

commitMessage := fmt.Sprintf("Promote %s package to %s", serviceName, packageTag)
err = git.CommitSaasFile(saasFile, commitMessage)
err = appInterface.CommitSaasFile(saasFile, commitMessage)
if err != nil {
return err
}
Expand Down
16 changes: 9 additions & 7 deletions cmd/promote/saas/saas.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ type saasOptions struct {
osd bool
hcp bool

serviceName string
gitHash string
appInterfaceCheckoutDir string
serviceName string
gitHash string
}

// newCmdSaas implementes the saas command to interact with promoting SaaS services/operators
Expand All @@ -35,15 +36,15 @@ func NewCmdSaas() *cobra.Command {
osdctl promote saas --serviceName <service-name> --gitHash <git-hash> --hcp`,
Run: func(cmd *cobra.Command, args []string) {
ops.validateSaasFlow()
git.BootstrapOsdCtlForAppInterfaceAndServicePromotions()
appInterface := git.BootstrapOsdCtlForAppInterfaceAndServicePromotions(ops.appInterfaceCheckoutDir)

if ops.list {
if ops.serviceName != "" || ops.gitHash != "" || ops.osd || ops.hcp {
fmt.Printf("Error: --list cannot be used with any other flags\n\n")
cmd.Help()
os.Exit(1)
}
listServiceNames()
listServiceNames(appInterface)
os.Exit(0)
}

Expand All @@ -53,7 +54,7 @@ func NewCmdSaas() *cobra.Command {
os.Exit(1)
}

err := servicePromotion(ops.serviceName, ops.gitHash, ops.osd, ops.hcp)
err := servicePromotion(appInterface, ops.serviceName, ops.gitHash, ops.osd, ops.hcp)
if err != nil {
fmt.Printf("Error while promoting service: %v\n", err)
os.Exit(1)
Expand All @@ -69,13 +70,14 @@ func NewCmdSaas() *cobra.Command {
saasCmd.Flags().StringVarP(&ops.gitHash, "gitHash", "g", "", "Git hash of the SaaS service/operator commit getting promoted")
saasCmd.Flags().BoolVarP(&ops.osd, "osd", "", false, "OSD service/operator getting promoted")
saasCmd.Flags().BoolVarP(&ops.hcp, "hcp", "", false, "Git hash of the SaaS service/operator commit getting promoted")
saasCmd.Flags().StringVarP(&ops.appInterfaceCheckoutDir, "appInterfaceDir", "", "", "location of app-interfache checkout. Falls back to `pwd` and "+git.DefaultAppInterfaceDirectory())

return saasCmd
}

func (o *saasOptions) validateSaasFlow() {
if o.serviceName == "" || o.gitHash == "" {
fmt.Printf("Usage: For SaaS services/operators, please provide --serviceName and --gitHash\n")
if o.serviceName == "" && o.gitHash == "" {
fmt.Printf("Usage: For SaaS services/operators, please provide --serviceName and (optional) --gitHash\n")
fmt.Printf("--serviceName is the name of the service, i.e. saas-managed-cluster-config\n")
fmt.Printf("--gitHash is the target git commit in the service, if not specified defaults to HEAD of master\n\n")
return
Expand Down
17 changes: 9 additions & 8 deletions cmd/promote/saas/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ var (
ServicesFilesMap = map[string]string{}
)

func listServiceNames() error {
_, err := GetServiceNames(OSDSaasDir, BPSaasDir, CADSaasDir)
func listServiceNames(appInterface git.AppInterface) error {
_, err := GetServiceNames(appInterface, OSDSaasDir, BPSaasDir, CADSaasDir)
if err != nil {
return err
}
Expand All @@ -36,8 +36,8 @@ func listServiceNames() error {
return nil
}

func servicePromotion(serviceName, gitHash string, osd, hcp bool) error {
_, err := GetServiceNames(OSDSaasDir, BPSaasDir, CADSaasDir)
func servicePromotion(appInterface git.AppInterface, serviceName, gitHash string, osd, hcp bool) error {
_, err := GetServiceNames(appInterface, OSDSaasDir, BPSaasDir, CADSaasDir)
if err != nil {
return err
}
Expand Down Expand Up @@ -74,13 +74,13 @@ func servicePromotion(serviceName, gitHash string, osd, hcp bool) error {
fmt.Printf("Service: %s will be promoted to %s\n", serviceName, promotionGitHash)

branchName := fmt.Sprintf("promote-%s-%s", serviceName, promotionGitHash)
err = git.UpdateAppInterface(serviceName, saasDir, currentGitHash, promotionGitHash, branchName)
err = appInterface.UpdateAppInterface(serviceName, saasDir, currentGitHash, promotionGitHash, branchName)
if err != nil {
fmt.Printf("FAILURE: %v\n", err)
}

commitMessage := fmt.Sprintf("Promote %s to %s\n\nSee %s/compare/%s...%s for contents of the promotion.", serviceName, promotionGitHash, serviceRepo, currentGitHash, promotionGitHash)
err = git.CommitSaasFile(saasDir, commitMessage)
err = appInterface.CommitSaasFile(saasDir, commitMessage)
if err != nil {
return fmt.Errorf("failed to commit changes to app-interface: %w", err)
}
Expand All @@ -94,8 +94,9 @@ func servicePromotion(serviceName, gitHash string, osd, hcp bool) error {
return nil
}

func GetServiceNames(saaDirs ...string) ([]string, error) {
baseDir := git.BaseDir
func GetServiceNames(appInterface git.AppInterface, saaDirs ...string) ([]string, error) {
baseDir := appInterface.GitDirectory

for _, dir := range saaDirs {
dirGlob := filepath.Join(baseDir, dir, "saas-*")
filepaths, err := filepath.Glob(dirGlob)
Expand Down

0 comments on commit 3b47dbd

Please sign in to comment.