Skip to content

Commit

Permalink
update rancher tag release (#378)
Browse files Browse the repository at this point in the history
* update rancher create release

* fix tag name

* add support for debug releases
  • Loading branch information
tashima42 authored Mar 21, 2024
1 parent aa7d3b2 commit 52ce4d5
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 76 deletions.
62 changes: 30 additions & 32 deletions cmd/release/cmd/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,8 @@ type tagRKE2CmdFlags struct {
RPMVersion *int
}

type tagRancherCmdFlags struct {
Tag *string
Branch *string
RepoOwner *string
SkipStatusCheck *bool
DryRun *bool
}

var (
tagRKE2Flags tagRKE2CmdFlags
tagRancherFlags tagRancherCmdFlags
tagRKE2Flags tagRKE2CmdFlags
)

// tagCmd represents the tag command.
Expand All @@ -53,7 +44,7 @@ var k3sTagSubCmd = &cobra.Command{
if len(args) < 2 {
return errors.New("expected at least two arguments: [ga,rc] [version]")
}
rc, err := releaseTypeRC(args[0])
rc, err := releaseTypePreRelease(args[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -139,6 +130,7 @@ var rke2TagSubCmd = &cobra.Command{
Repo: "rke2-packaging",
Branch: "master",
Name: version + rpmTag,
Tag: version + rpmTag,
Prerelease: false,
}
if _, err := repository.CreateRelease(ctx, client, &cro); err != nil {
Expand All @@ -155,12 +147,33 @@ var rke2TagSubCmd = &cobra.Command{
}

var rancherTagSubCmd = &cobra.Command{
Use: "rancher",
Use: "rancher [ga, rc, debug, alpha] [version]",
Short: "Tag Rancher releases",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return errors.New("expected at least two arguments: [ga,rc,debug,alpha] [version]")
}
releaseType := args[0]
preRelease, err := releaseTypePreRelease(releaseType)
if err != nil {
return err
}
tag := args[1]
rancherRelease, found := rootConfig.Rancher.Versions[tag]
if !found {
return errors.New("verify your config file, version not found: " + tag)
}

ctx := context.Background()
ghClient := repository.NewGithub(ctx, rootConfig.Auth.GithubToken)
return rancher.TagRelease(ctx, ghClient, *tagRancherFlags.Tag, *tagRancherFlags.Branch, *tagRancherFlags.RepoOwner, *tagRancherFlags.DryRun, *tagRancherFlags.SkipStatusCheck)

opts := &repository.CreateReleaseOpts{
Tag: tag,
Repo: "rancher",
Owner: rancherRelease.RancherRepoOwner,
Branch: rancherRelease.ReleaseBranch,
}
return rancher.CreateRelease(ctx, ghClient, &rancherRelease, opts, preRelease, releaseType)
},
}

Expand All @@ -171,7 +184,7 @@ var systemAgentInstallerK3sTagSubCmd = &cobra.Command{
if len(args) < 2 {
return errors.New("expected at least two arguments: [ga,rc] [version]")
}
rc, err := releaseTypeRC(args[0])
rc, err := releaseTypePreRelease(args[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -207,29 +220,14 @@ func init() {
tagRKE2Flags.ReleaseVersion = rke2TagSubCmd.Flags().StringP("release-version", "r", "r1", "Release version")
tagRKE2Flags.RCVersion = rke2TagSubCmd.Flags().String("rc", "", "RC version")
tagRKE2Flags.RPMVersion = rke2TagSubCmd.Flags().Int("rpm-version", 0, "RPM version")

// rancher
tagRancherFlags.Tag = rancherTagSubCmd.Flags().StringP("tag", "t", "", "tag to be created. e.g: v2.8.1-rc4")
tagRancherFlags.Branch = rancherTagSubCmd.Flags().StringP("branch", "b", "", "branch to be used as the base to create the tag. e.g: release/v2.8")
tagRancherFlags.RepoOwner = rancherTagSubCmd.Flags().StringP("repo-owner", "o", "rancher", "repository owner to create the tag in, optional")
tagRancherFlags.SkipStatusCheck = rancherTagSubCmd.Flags().BoolP("skip-status-check", "s", false, "skip the github commit status check before creating a tag")
tagRancherFlags.DryRun = dryRun
if err := rancherTagSubCmd.MarkFlagRequired("tag"); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if err := rancherTagSubCmd.MarkFlagRequired("branch"); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}

func releaseTypeRC(releaseType string) (bool, error) {
if releaseType == "rc" {
func releaseTypePreRelease(releaseType string) (bool, error) {
if releaseType == "rc" || releaseType == "debug" || releaseType == "alpha" {
return true, nil
}
if releaseType == "ga" {
return false, nil
}
return false, errors.New("release type must be either 'ga' or 'rc', instead got: " + releaseType)
return false, errors.New("release type must be either 'ga', 'debug', 'alpha' or 'rc', instead got: " + releaseType)
}
69 changes: 51 additions & 18 deletions cmd/release/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ type K3sRelease struct {
K3sUpstreamURL string `json:"k3s_upstream_url"`
}

// RancherRelease
type RancherRelease struct {
ReleaseBranch string `json:"release_branch"`
DryRun bool `json:"dry_run"`
SkipStatusCheck bool `json:"skip_status_check"`
RancherRepoOwner string `json:"rancher_repo_owner"`
IssueNumber string `json:"issue_number"`
}

// RKE2
type RKE2 struct {
Versions []string `json:"versions"`
Expand All @@ -50,6 +59,11 @@ type K3s struct {
Versions map[string]K3sRelease `json:"versions"`
}

// Rancher
type Rancher struct {
Versions map[string]RancherRelease `json:"versions"`
}

// Drone
type Drone struct {
K3sPR string `json:"k3s_pr"`
Expand All @@ -67,10 +81,11 @@ type Auth struct {

// Config
type Config struct {
User *User `json:"user"`
K3s *K3s `json:"k3s"`
RKE2 *RKE2 `json:"rke2"`
Auth *Auth `json:"auth"`
User *User `json:"user"`
K3s *K3s `json:"k3s"`
Rancher *Rancher `json:"rancher"`
RKE2 *RKE2 `json:"rke2"`
Auth *Auth `json:"auth"`
}

func DefaultConfigPath() (string, error) {
Expand Down Expand Up @@ -168,6 +183,16 @@ func exampleConfig() Config {
RKE2: &RKE2{
Versions: []string{"v1.x.y"},
},
Rancher: &Rancher{
Versions: map[string]RancherRelease{
"v2.x.y": {
ReleaseBranch: "release/v2.x",
DryRun: false,
SkipStatusCheck: false,
RancherRepoOwner: "rancher",
},
},
},
Auth: &Auth{
Drone: &Drone{
K3sPR: "YOUR_TOKEN",
Expand Down Expand Up @@ -195,20 +220,28 @@ User
Email: {{ .User.Email }}
Github Username: {{ .User.GithubUsername }}
K3s {{ range $version, $value := .K3s.Versions }}
{{ $version }}:
Old K8s Version: {{ $value.OldK8sVersion}}
New K8s Version: {{ $value.NewK8sVersion}}
Old K8s Client: {{ $value.OldK8sClient}}
New K8s Client: {{ $value.NewK8sClient}}
Old Suffix: {{ $value.OldSuffix}}
New Suffix: {{ $value.NewSuffix}}
Release Branch: {{ $value.ReleaseBranch}}
Dry Run: {{ $value.DryRun}}
K3s Repo Owner: {{ $value.K3sRepoOwner}}
K8s Rancher URL: {{ $value.K8sRancherURL}}
Workspace: {{ $value.Workspace}}
K3s Upstream URL: {{ $value.K3sUpstreamURL}}{{ end }}
K3s {{ range $k3sVersion, $k3sValue := .K3s.Versions }}
{{ $k3sVersion }}:
Old K8s Version: {{ $k3sValue.OldK8sVersion}}
New K8s Version: {{ $k3sValue.NewK8sVersion}}
Old K8s Client: {{ $k3sValue.OldK8sClient}}
New K8s Client: {{ $k3sValue.NewK8sClient}}
Old Suffix: {{ $k3sValue.OldSuffix}}
New Suffix: {{ $k3sValue.NewSuffix}}
Release Branch: {{ $k3sValue.ReleaseBranch}}
Dry Run: {{ $k3sValue.DryRun}}
K3s Repo Owner: {{ $k3sValue.K3sRepoOwner}}
K8s Rancher URL: {{ $k3sValue.K8sRancherURL}}
Workspace: {{ $k3sValue.Workspace}}
K3s Upstream URL: {{ $k3sValue.K3sUpstreamURL}}{{ end }}
Rancher {{ range $rancherVersion, $rancherValue := .Rancher.Versions }}
{{ $rancherVersion }}:
Release Branch: {{ $rancherValue.ReleaseBranch }}
Dry Run: {{ $rancherValue.DryRun }}
Skip Status Check: {{ $rancherValue.SkipStatusCheck }}
Issue Number: {{ $rancherValue.IssueNumber }}
Rancher Repo Owner: {{ $rancherValue.RancherRepoOwner }}{{ end }}
RKE2{{ range .RKE2.Versions }}
{{ . }}{{ end}}
Expand Down
1 change: 1 addition & 0 deletions release/k3s/k3s.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ func CreateRelease(ctx context.Context, client *github.Client, r *ecmConfig.K3sR
}

opts.Name = name
opts.Tag = name
opts.Prerelease = true
opts.Draft = !rc
opts.ReleaseNotes = ""
Expand Down
62 changes: 45 additions & 17 deletions release/rancher/rancher.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import (
"time"

"github.com/google/go-github/v39/github"
ecmConfig "github.com/rancher/ecm-distro-tools/cmd/release/config"
"github.com/rancher/ecm-distro-tools/exec"
ecmHTTP "github.com/rancher/ecm-distro-tools/http"
"github.com/rancher/ecm-distro-tools/release"
"github.com/rancher/ecm-distro-tools/repository"
"github.com/sirupsen/logrus"
"golang.org/x/mod/semver"
Expand Down Expand Up @@ -430,41 +432,67 @@ func SetChartBranchReferences(ctx context.Context, forkPath, rancherBaseBranch,
return nil
}

func TagRelease(ctx context.Context, ghClient *github.Client, tag, remoteBranch, repoOwner string, dryRun, skipStatusCheck bool) error {
func CreateRelease(ctx context.Context, ghClient *github.Client, r *ecmConfig.RancherRelease, opts *repository.CreateReleaseOpts, preRelease bool, releaseType string) error {
fmt.Println("validating tag semver format")
if !semver.IsValid(tag) {
return errors.New("the tag `" + tag + "` isn't a valid semantic versioning string")
if !semver.IsValid(opts.Tag) {
return errors.New("the tag isn't a valid semver: " + opts.Tag)
}
fmt.Println("getting remote branch information from " + repoOwner + "/" + rancherRepo)
branch, _, err := ghClient.Repositories.GetBranch(ctx, repoOwner, rancherRepo, remoteBranch, true)
fmt.Println("getting remote branch information from " + r.RancherRepoOwner + "/" + rancherRepo)
branch, _, err := ghClient.Repositories.GetBranch(ctx, r.RancherRepoOwner, rancherRepo, r.ReleaseBranch, true)
if err != nil {
return err
}
if branch.Commit.SHA == nil {
return errors.New("branch commit sha is nil")
}
fmt.Println("the latest commit on branch " + remoteBranch + " is: " + *branch.Commit.SHA)
if !skipStatusCheck {
fmt.Println("the latest commit on branch " + r.ReleaseBranch + " is: " + *branch.Commit.SHA)
if !r.SkipStatusCheck {
fmt.Println("checking if CI is passing")
if err := commitStateSuccess(ctx, ghClient, repoOwner, rancherRepo, *branch.Commit.SHA); err != nil {
if err := commitStateSuccess(ctx, ghClient, r.RancherRepoOwner, rancherRepo, *branch.Commit.SHA); err != nil {
return err
}
}
fmt.Println("creating tag: " + tag)
if dryRun {

releaseName := opts.Tag
if preRelease {
if releaseType == "debug" {
if r.IssueNumber == "" {
return errors.New("debug releases require an issue number")
}
releaseType = "debug-" + r.IssueNumber + "-"
}
latestVersionNumber := 1
latestVersion, err := release.LatestPreRelease(ctx, ghClient, opts.Owner, opts.Repo, opts.Tag, releaseType)
if err != nil {
return err
}
if latestVersion != nil {
trimmedVersionNumber := strings.TrimPrefix(*latestVersion, opts.Tag+"-"+releaseType)
currentVersionNumber, err := strconv.Atoi(trimmedVersionNumber)
if err != nil {
return errors.New("failed to parse trimmed latest version number: " + err.Error())
}
latestVersionNumber = currentVersionNumber + 1
}
opts.Tag = opts.Tag + "-" + releaseType + strconv.Itoa(latestVersionNumber)
releaseName = "Pre-release " + opts.Tag
}

opts.Name = releaseName
opts.Prerelease = true
opts.Draft = !preRelease
opts.ReleaseNotes = ""

fmt.Printf("creating release with options: %+v\n", opts)
if r.DryRun {
fmt.Println("dry run, skipping tag creation")
return nil
}
ref, _, err := ghClient.Git.CreateRef(ctx, repoOwner, rancherRepo, &github.Reference{
Ref: github.String("refs/tags/" + tag),
Object: &github.GitObject{
SHA: branch.Commit.SHA,
},
})
createdRelease, err := repository.CreateRelease(ctx, ghClient, opts)
if err != nil {
return err
}
fmt.Println("created tag: " + *ref.URL)
fmt.Println("release created: " + *createdRelease.URL)
return nil
}

Expand Down
34 changes: 26 additions & 8 deletions release/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,26 +661,44 @@ func findInURL(url, regex, str string, checkStatusCode bool) []string {
}

// LatestRC will get the latest rc created for the k8s version in either rke2 or k3s
func LatestRC(ctx context.Context, owner, repo, k8sVersion, suffix string, client *github.Client) (*string, error) {
func LatestRC(ctx context.Context, owner, repo, k8sVersion, projectSuffix string, client *github.Client) (*string, error) {
var rcs []*github.RepositoryRelease

allReleases, _, err := client.Repositories.ListReleases(ctx, owner, repo, &github.ListOptions{})
if err != nil {
return nil, err
}
for _, release := range allReleases {
if strings.Contains(*release.Name, k8sVersion+"-rc") && strings.Contains(*release.Name, suffix) {
if strings.Contains(*release.TagName, k8sVersion+"-rc") && strings.Contains(*release.TagName, projectSuffix) {
rcs = append(rcs, release)
}
}
sort.Slice(rcs, func(i, j int) bool {
return rcs[i].PublishedAt.Time.Before(rcs[j].PublishedAt.Time)
})
return latestRelease(rcs), nil
}

func LatestPreRelease(ctx context.Context, client *github.Client, owner, repo, version, preReleaseSuffix string) (*string, error) {
var versions []*github.RepositoryRelease

allReleases, _, err := client.Repositories.ListReleases(ctx, owner, repo, &github.ListOptions{})
if err != nil {
return nil, err
}
for _, release := range allReleases {
if strings.Contains(*release.TagName, version+"-"+preReleaseSuffix) {
versions = append(versions, release)
}
}
return latestRelease(versions), nil
}

if len(rcs) == 0 {
return nil, nil
func latestRelease(versions []*github.RepositoryRelease) *string {
sort.Slice(versions, func(i, j int) bool {
return versions[i].PublishedAt.Time.Before(versions[j].PublishedAt.Time)
})
if len(versions) == 0 {
return nil
}
return rcs[len(rcs)-1].Name, nil
return versions[len(versions)-1].TagName
}

// rke2ChartVersion will return the version of the rke2 chart from the chart versions file
Expand Down
2 changes: 1 addition & 1 deletion repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func CreateRelease(ctx context.Context, client *github.Client, cro *CreateReleas

rr := github.RepositoryRelease{
Name: &cro.Name,
TagName: &cro.Name,
TagName: &cro.Tag,
Prerelease: &cro.Prerelease,
TargetCommitish: &cro.Branch,
Draft: &cro.Draft,
Expand Down

0 comments on commit 52ce4d5

Please sign in to comment.