Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#252: Add set charts branch refs command #271

Merged
merged 11 commits into from
Oct 13, 2023
1 change: 1 addition & 0 deletions cmd/rancher_release/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func main() {
listImagesRCCommand(),
checkRancherImageCommand(),
setKDMBranchReferencesCommand(),
setChartsBranchReferencesCommand(),
}
app.Flags = rootFlags

Expand Down
75 changes: 75 additions & 0 deletions cmd/rancher_release/set_chart_branch_references.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package main

import (
"context"
"errors"
"os"

"github.com/rancher/ecm-distro-tools/release/rancher"
"github.com/urfave/cli"
)

func setChartsBranchReferencesCommand() cli.Command {
return cli.Command{
Name: "set-charts-branch-refs",
Usage: "set charts branch references in files",
Flags: []cli.Flag{
cli.StringFlag{
Name: "fork-path",
Usage: "rancher repo fork directory path",
Required: true,
},
cli.StringFlag{
Name: "base-branch",
Usage: "rancher branch to use as a base, e.g: release/v2.8",
Required: true,
},
cli.StringFlag{
Name: "current-charts-branch",
Usage: "current branch set for charts in the repo",
Required: true,
},
cli.StringFlag{
Name: "new-charts-branch",
Usage: "branch to be replaced in charts in the repo",
Required: true,
},
cli.BoolFlag{
Name: "create-pr",
Usage: "if true, a PR will be created from your fork to the rancher repo base branch and a variable 'GITHUB_TOKEN' must be exported",
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
},
cli.StringFlag{
Name: "fork-owner",
Usage: "github username of the owner of the fork, only required if 'create-pr' is true",
Required: false,
},
cli.BoolFlag{
Name: "dry-run",
Usage: "the newly created branch won't be pushed to remote and the PR won't be created",
Required: false,
},
},
Action: setChartBranchReferences,
}
}

func setChartBranchReferences(c *cli.Context) error {
forkPath := c.String("fork-path")
baseBranch := c.String("base-branch")
currentBranch := c.String("current-charts-branch")
newBranch := c.String("new-charts-branch")
createPR := c.BoolT("create-pr")
forkOwner := c.String("fork-owner")
githubToken := os.Getenv("GITHUB_TOKEN")
dryRun := c.BoolT("dry-run")
if createPR {
if forkOwner == "" {
return errors.New("'create-pr' requires 'fork-owner'")
}
if githubToken == "" {
return errors.New("'create-pr' requires the 'GITHUB_TOKEN' env var")
}
}

return rancher.SetChartBranchReferences(context.Background(), forkPath, baseBranch, currentBranch, newBranch, forkOwner, githubToken, createPR, dryRun)
}
144 changes: 100 additions & 44 deletions release/rancher/rancher.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,69 @@ const (
rancherImagesFileName = "/rancher-images.txt"
rancherHelmRepositoryURL = "https://releases.rancher.com/server-charts/latest/index.yaml"

setKDMBranchReferencesScriptFile = "set_kdm_branch_references.sh"
setKDMBranchReferencesScript = `#!/bin/bash
setKDMBranchReferencesScriptFileName = "set_kdm_branch_references.sh"
setChartReferencesScriptFileName = `set_chart_references_script.sh`
cloneCheckoutRancherScript = `#!/bin/bash
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
set -x

BRANCH_NAME=kdm-set-{{ .NewKDMBranch }}
BRANCH_NAME={{ .BranchName }}
DRY_RUN={{ .DryRun }}

cd {{ .RancherRepoDir }}
cd {{ .RancherRepoPath }}
git remote add upstream https://github.com/rancher/rancher.git
git fetch upstream
git stash
git branch -D ${BRANCH_NAME}
git checkout -B ${BRANCH_NAME} upstream/{{.RancherBaseBranch}}
git clean -xfd

git clean -xfd`
setKDMBranchReferencesScript = `
if [ "$(uname)" == "Darwin" ];then
sed -i '' 's/NewSetting(\"kdm-branch\", \"{{ .CurrentKDMBranch }}\")/NewSetting(\"kdm-branch\", \"{{ .NewKDMBranch }}\")/' pkg/settings/setting.go
sed -i '' 's/CATTLE_KDM_BRANCH={{ .CurrentKDMBranch }}/CATTLE_KDM_BRANCH={{ .NewKDMBranch }}/' package/Dockerfile
sed -i '' 's/CATTLE_KDM_BRANCH={{ .CurrentKDMBranch }}/CATTLE_KDM_BRANCH={{ .NewKDMBranch }}/' Dockerfile.dapper
sed -i '' 's/NewSetting(\"kdm-branch\", \"{{ .CurrentBranch }}\")/NewSetting(\"kdm-branch\", \"{{ .NewBranch }}\")/' pkg/settings/setting.go
sed -i '' 's/CATTLE_KDM_BRANCH={{ .CurrentBranch }}/CATTLE_KDM_BRANCH={{ .NewBranch }}/' package/Dockerfile
sed -i '' 's/CATTLE_KDM_BRANCH={{ .CurrentBranch }}/CATTLE_KDM_BRANCH={{ .NewBranch }}/' Dockerfile.dapper
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
sed -i 's/NewSetting("kdm-branch", "{{ .CurrentKDMBranch }}")/NewSetting("kdm-branch", "{{ .NewKDMBranch }}")/' pkg/settings/setting.go
sed -i 's/CATTLE_KDM_BRANCH={{ .CurrentKDMBranch }}/CATTLE_KDM_BRANCH={{ .NewKDMBranch }}/' package/Dockerfile
sed -i 's/CATTLE_KDM_BRANCH={{ .CurrentKDMBranch }}/CATTLE_KDM_BRANCH={{ .NewKDMBranch }}/' Dockerfile.dapper
sed -i 's/NewSetting("kdm-branch", "{{ .CurrentBranch }}")/NewSetting("kdm-branch", "{{ .NewBranch }}")/' pkg/settings/setting.go
sed -i 's/CATTLE_KDM_BRANCH={{ .CurrentBranch }}/CATTLE_KDM_BRANCH={{ .NewBranch }}/' package/Dockerfile
sed -i 's/CATTLE_KDM_BRANCH={{ .CurrentBranch }}/CATTLE_KDM_BRANCH={{ .NewBranch }}/' Dockerfile.dapper
else
>&2 echo "$(uname) not supported yet"
exit 1
fi

git add pkg/settings/setting.go
git add package/Dockerfile
git add Dockerfile.dapper

git commit --all --signoff -m "update kdm branch to {{ .NewKDMBranch }}"
git commit --all --signoff -m "update kdm branch to {{ .NewBranch }}"`
setChartBranchReferencesScript = `
if [ "$(uname)" == "Darwin" ];then
sed -i '' 's/NewSetting(\"chart-default-branch\", \"{{ .CurrentBranch }}\")/NewSetting(\"chart-default-branch\", \"{{ .NewBranch }}\")/' pkg/settings/setting.go
sed -i '' 's/SYSTEM_CHART_DEFAULT_BRANCH={{ .CurrentBranch }}/SYSTEM_CHART_DEFAULT_BRANCH={{ .NewBranch }}/' package/Dockerfile
sed -i '' 's/CHART_DEFAULT_BRANCH={{ .CurrentBranch }}/CHART_DEFAULT_BRANCH={{ .NewBranch }}/' package/Dockerfile
sed -i '' 's/{SYSTEM_CHART_DEFAULT_BRANCH:-"{{ .CurrentBranch }}"}/{SYSTEM_CHART_DEFAULT_BRANCH:-"{{ .NewBranch }}"}/' scripts/package-env
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
sed -i 's/NewSetting("chart-default-branch", "{{ .CurrentBranch }}")/NewSetting("chart-default-branch", "{{ .NewBranch }}")/' pkg/settings/setting.go
sed -i 's/SYSTEM_CHART_DEFAULT_BRANCH={{ .CurrentBranch }}/SYSTEM_CHART_DEFAULT_BRANCH={{ .NewBranch }}/' package/Dockerfile
sed -i 's/CHART_DEFAULT_BRANCH={{ .CurrentBranch }}/CHART_DEFAULT_BRANCH={{ .NewBranch }}/' package/Dockerfile
sed -i 's/{SYSTEM_CHART_DEFAULT_BRANCH:-"{{ .CurrentBranch }}"}/{SYSTEM_CHART_DEFAULT_BRANCH:-"{{ .NewBranch }}"}/' scripts/package-env
else
>&2 echo "$(uname) not supported yet"
exit 1
fi
git add pkg/settings/setting.go
git add package/Dockerfile
git add scripts/package-env
git commit --all --signoff -m "update chart branch references to {{ .NewBranch }}"`
pushChangesScript = `
if [ "${DRY_RUN}" == false ]; then
git push --set-upstream origin ${BRANCH_NAME}
fi`
)

type SetKDMBranchReferencesArgs struct {
RancherRepoDir string
CurrentKDMBranch string
NewKDMBranch string
type SetBranchReferencesArgs struct {
RancherRepoPath string
CurrentBranch string
NewBranch string
RancherBaseBranch string
DryRun bool
BranchName string
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
}

type HelmIndex struct {
Expand Down Expand Up @@ -183,60 +202,97 @@ func rancherHelmChartVersions(repoURL string) ([]string, error) {
}

func SetKDMBranchReferences(ctx context.Context, forkPath, rancherBaseBranch, currentKDMBranch, newKDMBranch, forkOwner, githubToken string, createPR, dryRun bool) error {
if _, err := os.Stat(forkPath); err != nil {
return err
}
scriptPath := filepath.Join(forkPath, setKDMBranchReferencesScriptFile)
f, err := os.Create(scriptPath)
if err != nil {
return err
branchName := "kdm-set-" + newKDMBranch
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
data := SetBranchReferencesArgs{
RancherRepoPath: forkPath,
CurrentBranch: currentKDMBranch,
NewBranch: newKDMBranch,
RancherBaseBranch: rancherBaseBranch,
DryRun: dryRun,
BranchName: branchName,
}
defer f.Close()
if err := os.Chmod(scriptPath, 0755); err != nil {
script := cloneCheckoutRancherScript + setKDMBranchReferencesScript + pushChangesScript

if err := executeTemplateAndRunScript(forkPath, setKDMBranchReferencesScriptFileName, script, data); err != nil {
return err
}
tmpl, err := template.New(setKDMBranchReferencesScriptFile).Parse(setKDMBranchReferencesScript)
if err != nil {
return err

if createPR && !dryRun {
ghClient := repository.NewGithub(ctx, githubToken)

if err := createPRFromRancher(ctx, rancherBaseBranch, "Update KDM to "+newKDMBranch, branchName, forkOwner, ghClient); err != nil {
return err
}
}
data := SetKDMBranchReferencesArgs{
RancherRepoDir: forkPath,
CurrentKDMBranch: currentKDMBranch,
NewKDMBranch: newKDMBranch,

return nil
}

func SetChartBranchReferences(ctx context.Context, forkPath, rancherBaseBranch, currentBranch, newBranch, forkOwner, githubToken string, createPR, dryRun bool) error {
branchName := "charts-set-" + newBranch
data := SetBranchReferencesArgs{
RancherRepoPath: forkPath,
CurrentBranch: currentBranch,
NewBranch: newBranch,
RancherBaseBranch: rancherBaseBranch,
DryRun: dryRun,
BranchName: branchName,
}
if err := tmpl.Execute(f, data); err != nil {
return err
}
if _, err := exec.RunCommand(forkPath, "bash", "./"+setKDMBranchReferencesScriptFile); err != nil {
script := cloneCheckoutRancherScript + setChartBranchReferencesScript + pushChangesScript
if err := executeTemplateAndRunScript(forkPath, setChartReferencesScriptFileName, script, data); err != nil {
return err
}

if createPR && !dryRun {
ghClient := repository.NewGithub(ctx, githubToken)

if err := createPRFromRancher(ctx, rancherBaseBranch, newKDMBranch, forkOwner, ghClient); err != nil {
if err := createPRFromRancher(ctx, rancherBaseBranch, "Update charts branch references to "+newBranch, branchName, forkOwner, ghClient); err != nil {
return err
}
}

return nil
}

func createPRFromRancher(ctx context.Context, rancherBaseBranch, newKDMBranch, forkOwner string, ghClient *github.Client) error {
func createPRFromRancher(ctx context.Context, rancherBaseBranch, title, branchName, forkOwner string, ghClient *github.Client) error {
const repo = "rancher"
org, err := repository.OrgFromRepo(repo)
if err != nil {
return err
}
pull := &github.NewPullRequest{
Title: github.String("Update KDM Branch to " + newKDMBranch),
Title: github.String(title),
Base: github.String(rancherBaseBranch),
Head: github.String(forkOwner + ":" + "kdm-set-" + newKDMBranch),
Head: github.String(forkOwner + ":" + branchName),
MaintainerCanModify: github.Bool(true),
}
_, _, err = ghClient.PullRequests.Create(ctx, org, repo, pull)

return err
}

func executeTemplateAndRunScript(path, fileName, script string, args SetBranchReferencesArgs) error {
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
if _, err := os.Stat(path); err != nil {
return err
}
scriptPath := filepath.Join(path, fileName)
f, err := os.Create(scriptPath)
if err != nil {
return err
}
defer f.Close()
if err := os.Chmod(scriptPath, 0755); err != nil {
return err
}
tmpl, err := template.New(script).Parse(script)
if err != nil {
return err
}
if err := tmpl.Execute(f, args); err != nil {
return err
}
if _, err := exec.RunCommand(path, "bash", "./"+fileName); err != nil {
return err
}
return nil
}