diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f0d99114..53b1f081 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,6 +38,7 @@ jobs: ${{ github.workspace }}/cmd/gen_release_notes/bin/* ${{ github.workspace }}/cmd/k3s_release/bin/* ${{ github.workspace }}/cmd/rancher_release/bin/* + ${{ github.workspace }}/cmd/rke2_release/bin/* ${{ github.workspace }}/cmd/standup/bin/* ${{ github.workspace }}/cmd/test_coverage/bin/* ${{ github.workspace }}/cmd/upstream_go_version/bin/* diff --git a/.gitignore b/.gitignore index 0b34b236..0d3728ae 100644 --- a/.gitignore +++ b/.gitignore @@ -28,14 +28,7 @@ _testmain.go .idea *.iml -cmd/gen_release_report/bin -cmd/gen_release_notes/bin -cmd/backport/bin -cmd/standup/bin -cmd/k3s_release/bin -cmd/test_coverage/bin -cmd/upstream_go_version/bin -cmd/rancher_release/bin +cmd/*/bin data/* diff --git a/Makefile b/Makefile index a24bc513..9e321eb2 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,10 @@ k3s_release: rancher_release: cd cmd/$@ && $(MAKE) +.PHONY: rke2_release +rke2_release: + cd cmd/$@ && $(MAKE) + .PHONY: backport backport: cd cmd/$@ && $(MAKE) diff --git a/cmd/Makefile b/cmd/Makefile index e6944667..a4593923 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -1,4 +1,4 @@ -BINARIES = gen_release_notes gen_release_report backport standup k3s_release rancher_release test_coverage upstream_go_version +BINARIES = gen_release_notes gen_release_report backport standup k3s_release rancher_release test_coverage upstream_go_version rke2_release ARCHS = amd64 arm64 OSs = linux darwin freebsd diff --git a/cmd/rke2_release/Makefile b/cmd/rke2_release/Makefile new file mode 100644 index 00000000..4453ae74 --- /dev/null +++ b/cmd/rke2_release/Makefile @@ -0,0 +1,23 @@ +include ../Makefile + +GO = go + +BINDIR := bin +BINARY := rke2_release + +VERSION = v0.1.0 +GIT_SHA = $(shell git rev-parse HEAD) +override LDFLAGS += -X main.gitSHA=$(GIT_SHA) -X main.version=$(VERSION) -X main.name=$(BINARY) -extldflags '-static -Wl,--fatal-warnings' +TAGS = "netgo osusergo no_stage static_build" + +$(BINDIR)/$(BINARY): clean + for arch in $(ARCHS); do \ + for os in $(OSs); do \ + $(GO_COMPILE) ; \ + done; \ + done + +.PHONY: clean +clean: + $(GO) clean + rm -f $(BINDIR)/$(BINARY) diff --git a/cmd/rke2_release/README.md b/cmd/rke2_release/README.md new file mode 100644 index 00000000..75df5f52 --- /dev/null +++ b/cmd/rke2_release/README.md @@ -0,0 +1,28 @@ +# rke2_release + +rke2_release is a utility that performs the bulk of the actions to complete a rke2 release. + +Please reference the help menu from the binary. + +## Commands + +### image-build-base-release + +Checks if new Golang versions are available and creates new releases in `rancher/image-build-base` + +| **Flag** | **Description** | **Required** | +| ----------------------------------- | --------------- | ------------ | +| `github-token`, `g`, `GITHUB_TOKEN` | Github Token | TRUE | + +**Examples** + +``` +export GITHUB_TOKEN={YOUR_GITHUB_TOKEN} + +rke2_release image-build-base-release +``` + +## Contributions + +- File Issue with details of the problem, feature request, etc. +- Submit a pull request and include details of what problem or feature the code is solving or implementing. diff --git a/cmd/rke2_release/main.go b/cmd/rke2_release/main.go new file mode 100644 index 00000000..1dccd6e5 --- /dev/null +++ b/cmd/rke2_release/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "os" + + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" +) + +var rootFlags = []cli.Flag{ + &cli.StringFlag{ + Name: "config", + Aliases: []string{"c"}, + Usage: "Specify release config file", + EnvVars: []string{"RELEASE_CONFIG"}, + }, + &cli.BoolFlag{ + Name: "debug", + Aliases: []string{"d"}, + Usage: "Debug mode", + }, +} + +func main() { + app := cli.NewApp() + app.Name = "rke2-release" + app.Usage = "Perform a rke2 release" + app.UseShortOptionHandling = true + app.Commands = []*cli.Command{ + imageBuildBaseReleaseCommand(), + } + app.Flags = rootFlags + + if err := app.Run(os.Args); err != nil { + logrus.Fatal(err) + } +} diff --git a/cmd/rke2_release/update_image_build_base.go b/cmd/rke2_release/update_image_build_base.go new file mode 100644 index 00000000..bc1c1f90 --- /dev/null +++ b/cmd/rke2_release/update_image_build_base.go @@ -0,0 +1,36 @@ +package main + +import ( + "context" + "errors" + + "github.com/rancher/ecm-distro-tools/release/rke2" + "github.com/rancher/ecm-distro-tools/repository" + "github.com/urfave/cli/v2" +) + +func imageBuildBaseReleaseCommand() *cli.Command { + return &cli.Command{ + Name: "image-build-base-release", + Usage: "checks if new golang versions are available and creates new releases for rancher/image-build-base", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "github-token", + Aliases: []string{"g"}, + EnvVars: []string{"GITHUB_TOKEN"}, + Required: true, + }, + }, + Action: imageBuildBaseRelease, + } +} + +func imageBuildBaseRelease(c *cli.Context) error { + token := c.String("github-token") + if token == "" { + return errors.New("env var GITHUB_TOKEN is required") + } + ctx := context.Background() + ghClient := repository.NewGithub(ctx, token) + return rke2.ImageBuildBaseRelease(ctx, ghClient) +} diff --git a/release/rke2/rke2.go b/release/rke2/rke2.go new file mode 100644 index 00000000..aa82bf29 --- /dev/null +++ b/release/rke2/rke2.go @@ -0,0 +1,80 @@ +package rke2 + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "strings" + "time" + + "github.com/google/go-github/v39/github" + ecmHTTP "github.com/rancher/ecm-distro-tools/http" + "github.com/rancher/ecm-distro-tools/repository" + "github.com/sirupsen/logrus" +) + +const ( + goDevURL = "https://go.dev/dl/?mode=json" + imageBuildBaseRepo = "image-build-base" +) + +type goVersionRecord struct { + Version string `json:"version"` + Stable bool `json:"stable"` +} + +func ImageBuildBaseRelease(ctx context.Context, ghClient *github.Client) error { + versions, err := goVersions(goDevURL) + if err != nil { + return err + } + imageBuildBaseOrg, err := repository.OrgFromRepo(imageBuildBaseRepo) + if err != nil { + return err + } + for _, version := range versions { + logrus.Info("version: " + version.Version) + if !version.Stable { + logrus.Info("version " + version.Version + " is not stable") + continue + } + v := "v" + strings.Split(version.Version, "go")[1] + "b1" + logrus.Info("stripped version: " + v) + _, _, err := ghClient.Repositories.GetReleaseByTag(ctx, imageBuildBaseOrg, imageBuildBaseRepo, v) + if err == nil { + logrus.Info("release " + v + " already exists") + continue + } + logrus.Info("release " + v + " doesn't exists, creating release") + _, _, err = ghClient.Repositories.CreateRelease(ctx, imageBuildBaseOrg, imageBuildBaseRepo, &github.RepositoryRelease{ + TagName: github.String(v), + Name: github.String(v), + Prerelease: github.Bool(false), + }) + if err != nil { + return err + } + logrus.Info("created release for version: " + v) + } + return nil +} + +func goVersions(goDevURL string) ([]goVersionRecord, error) { + httpClient := ecmHTTP.NewClient(time.Second * 15) + res, err := httpClient.Get(goDevURL) + if err != nil { + return nil, err + } + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + return nil, errors.New("failed to get stable go versions") + } + + var versions []goVersionRecord + if err := json.NewDecoder(res.Body).Decode(&versions); err != nil { + return nil, err + } + return versions, nil +} diff --git a/release/rke2/rke2_test.go b/release/rke2/rke2_test.go new file mode 100644 index 00000000..431bcb21 --- /dev/null +++ b/release/rke2/rke2_test.go @@ -0,0 +1,26 @@ +package rke2 + +import ( + "net/http" + "net/http/httptest" + "reflect" + "testing" +) + +func TestGoVersions(t *testing.T) { + path := "/dl/?mode=json" + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte(`[{"version": "go1.21.3", "stable": true}, {"version": "go1.20.10", "stable": true}]`)) + })) + defer server.Close() + + versions, err := goVersions(server.URL + path) + if err != nil { + t.Error(err) + } + expectedVersions := []goVersionRecord{{Version: "go1.21.3", Stable: true}, {Version: "go1.20.10", Stable: true}} + if !reflect.DeepEqual(expectedVersions, versions) { + t.Errorf("expected %v, got %v", expectedVersions, versions) + } +} diff --git a/repository/repository.go b/repository/repository.go index 60fd4e2a..bb623e60 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -25,9 +25,10 @@ const ( // repoToOrg associates repo to org. var repoToOrg = map[string]string{ - "rke2": "rancher", - "k3s": "k3s-io", - "rancher": "rancher", + "rke2": "rancher", + "k3s": "k3s-io", + "rancher": "rancher", + "image-build-base": "rancher", } // stripBackportTag returns a string with a prefix backport tag removed