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 @@ -30,6 +30,7 @@ func main() {
listImagesRCCommand(),
checkRancherImageCommand(),
setKDMBranchReferencesCommand(),
setChartsBranchReferencesCommand(),
}
app.Flags = rootFlags

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

import (
"context"
"errors"

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

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",
Aliases: []string{"f"},
Usage: "rancher repo fork directory path",
Required: true,
},
&cli.StringFlag{
Name: "base-branch",
Aliases: []string{"b"},
Usage: "rancher branch to use as a base, e.g: release/v2.8",
Required: true,
},
&cli.StringFlag{
Name: "current-charts-branch",
Aliases: []string{"c"},
Usage: "current branch set for charts in the repo",
Required: true,
},
&cli.StringFlag{
Name: "new-charts-branch",
Aliases: []string{"n"},
Usage: "branch to be replaced in charts in the repo",
Required: true,
},
&cli.BoolFlag{
Name: "create-pr",
Aliases: []string{"p"},
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",
},
&cli.StringFlag{
Name: "fork-owner",
Aliases: []string{"o"},
Usage: "github username of the owner of the fork, only required if 'create-pr' is true",
Required: false,
},
&cli.StringFlag{
Name: "github-token",
Aliases: []string{"g"},
Usage: "github token",
EnvVars: []string{"GITHUB_TOKEN"},
Required: false,
},
&cli.BoolFlag{
Name: "dry-run",
Aliases: []string{"r"},
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.Bool("create-pr")
forkOwner := c.String("fork-owner")
githubToken := c.String("github-token")
dryRun := c.Bool("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)
}
29 changes: 29 additions & 0 deletions exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package exec
import (
"bytes"
"errors"
"os"
"os/exec"
"path/filepath"
"text/template"
)

func RunCommand(dir, cmd string, args ...string) (string, error) {
Expand All @@ -19,3 +22,29 @@ func RunCommand(dir, cmd string, args ...string) (string, error) {

return outb.String(), nil
}

func RunTemplatedScript(path, fileName, script string, args interface{}) error {
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 := RunCommand(path, "bash", "./"+fileName); err != nil {
return err
}
return nil
}
145 changes: 92 additions & 53 deletions release/rancher/rancher.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import (
"errors"
"io"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"text/template"
"time"

"github.com/google/go-github/v39/github"
Expand All @@ -27,49 +24,80 @@ const (
rancherImagesFileName = "/rancher-images.txt"
rancherHelmRepositoryURL = "https://releases.rancher.com/server-charts/latest/index.yaml"

setKDMBranchReferencesScriptFile = "set_kdm_branch_references.sh"
setKDMBranchReferencesScript = `#!/bin/bash
set -x
setKDMBranchReferencesScriptFileName = "set_kdm_branch_references.sh"
setChartReferencesScriptFileName = `set_chart_references.sh`
cloneCheckoutRancherScript = `#!/bin/sh
set -e

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

cd {{ .RancherRepoDir }}
git remote add upstream https://github.com/rancher/rancher.git
cd {{ .RancherRepoPath }}
git remote -v | grep -w upstream || 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

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
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
else
>&2 echo "$(uname) not supported yet"
git clean -xfd`
setKDMBranchReferencesScript = `
OS=$(uname -s)
case ${OS} in
Darwin)
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
;;
Linux)
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
;;
*)
>&2 echo "$(OS) not supported yet"
exit 1
;;
esac
fi

git add pkg/settings/setting.go
git add package/Dockerfile
git add Dockerfile.dapper
git commit --all --signoff -m "update kdm branch to {{ .NewBranch }}"`
setChartBranchReferencesScript = `
OS=$(uname -s)
case ${OS} in
Darwin)
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
;;
Linux)
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
;;
*)
>&2 echo "$(OS) not supported yet"
exit 1
;;
esac

git commit --all --signoff -m "update kdm branch to {{ .NewKDMBranch }}"
if [ "${DRY_RUN}" == false ]; then
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
BranchName string
tashima42 marked this conversation as resolved.
Show resolved Hide resolved
DryRun bool
}

Expand Down Expand Up @@ -183,57 +211,68 @@ 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 := exec.RunTemplatedScript(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 := exec.RunTemplatedScript(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)
Expand Down