diff --git a/Makefile b/Makefile index d2af304cc..3e86b5734 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=v0.0.25 +VERSION=v0.0.26 OUT_DIR=dist YEAR?=$(shell date +"%Y") @@ -6,7 +6,7 @@ CLI_NAME?=cf IMAGE_REPOSITORY?=quay.io IMAGE_NAMESPACE?=codefresh -RUNTIME_DEF_URL="https://github.com/codefresh-io/cli-v2/manifests/runtime.yaml" +RUNTIME_DEF_URL="https://github.com/codefresh-io/cli-v2/releases/latest/download/runtime.yaml" DEV_RUNTIME_DEF_URL="manifests/runtime.yaml" diff --git a/build/ci.yml b/build/ci.yml index 1e634afff..59eed328b 100644 --- a/build/ci.yml +++ b/build/ci.yml @@ -27,7 +27,7 @@ steps: - cf_export GOCACHE=/codefresh/volume/gocache # change gopath to codefresh shared volume - cf_export GOPATH=/codefresh/volume/gopath - cf_export PATH=$PATH:/codefresh/volume/gopath/bin - - cf_export LATEST_VERSION=$(curl --silent -H "Authorization:Bearer ${{GITHUB_TOKEN}}" "https://api.github.com/repos/codefresh-io/cli-v2/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') + - cf_export LATEST_VERSION=$(curl --silent -H "Authorization:Bearer ${{GITHUB_TOKEN}}" "https://api.github.com/repos/codefresh-io/cli-v2/releases/latest" | jq -r ".tag_name") - cf_export VERSION=$(make cur-version) when: steps: diff --git a/cmd/commands/runtime.go b/cmd/commands/runtime.go index a28728e57..a071ccbc9 100644 --- a/cmd/commands/runtime.go +++ b/cmd/commands/runtime.go @@ -51,6 +51,7 @@ import ( type ( RuntimeInstallOptions struct { RuntimeName string + Version *semver.Version gsCloneOpts *git.CloneOptions insCloneOpts *git.CloneOptions KubeFactory kube.Factory @@ -91,6 +92,7 @@ func NewRuntimeCommand() *cobra.Command { func NewRuntimeInstallCommand() *cobra.Command { var ( + versionStr string f kube.Factory insCloneOpts *git.CloneOptions gsCloneOpts *git.CloneOptions @@ -127,13 +129,25 @@ func NewRuntimeInstallCommand() *cobra.Command { gsCloneOpts.Parse() }, RunE: func(cmd *cobra.Command, args []string) error { + var ( + version *semver.Version + err error + ) ctx := cmd.Context() if len(args) < 1 { log.G(ctx).Fatal("must enter runtime name") } + if versionStr != "" { + version, err = semver.NewVersion(versionStr) + if err != nil { + return err + } + } + return RunRuntimeInstall(ctx, &RuntimeInstallOptions{ RuntimeName: args[0], + Version: version, gsCloneOpts: gsCloneOpts, insCloneOpts: insCloneOpts, KubeFactory: f, @@ -141,6 +155,7 @@ func NewRuntimeInstallCommand() *cobra.Command { }, } + cmd.Flags().StringVar(&versionStr, "version", "", "The runtime version to install, defaults to latest") insCloneOpts = git.AddFlags(cmd, &git.AddFlagsOptions{ Prefix: "install", CreateIfNotExist: true, @@ -158,13 +173,13 @@ func NewRuntimeInstallCommand() *cobra.Command { } func RunRuntimeInstall(ctx context.Context, opts *RuntimeInstallOptions) error { - rt, err := runtime.Download(nil, opts.RuntimeName) + rt, err := runtime.Download(opts.Version, opts.RuntimeName) if err != nil { return fmt.Errorf("failed to download runtime definition: %w", err) } err = apcmd.RunRepoBootstrap(ctx, &apcmd.RepoBootstrapOptions{ - AppSpecifier: rt.Spec.BootstrapSpecifier, + AppSpecifier: rt.Spec.FullSpecifier(), Namespace: opts.RuntimeName, KubeFactory: opts.KubeFactory, CloneOptions: opts.insCloneOpts, @@ -183,7 +198,7 @@ func RunRuntimeInstall(ctx context.Context, opts *RuntimeInstallOptions) error { for _, component := range rt.Spec.Components { log.G(ctx).Infof("creating component '%s'", component.Name) - if err = component.CreateApp(ctx, opts.KubeFactory, opts.insCloneOpts, opts.RuntimeName); err != nil { + if err = component.CreateApp(ctx, opts.KubeFactory, opts.insCloneOpts, opts.RuntimeName, rt.Spec.Version); err != nil { return fmt.Errorf("failed to create '%s' application: %w", component.Name, err) } } @@ -327,7 +342,8 @@ func RunRuntimeUninstall(ctx context.Context, opts *RuntimeUninstallOptions) err func NewRuntimeUpgradeCommand() *cobra.Command { var ( - cloneOpts *git.CloneOptions + versionStr string + cloneOpts *git.CloneOptions ) cmd := &cobra.Command{ @@ -351,14 +367,20 @@ func NewRuntimeUpgradeCommand() *cobra.Command { cloneOpts.Parse() }, RunE: func(cmd *cobra.Command, args []string) error { - var version *semver.Version + var ( + version *semver.Version + err error + ) ctx := cmd.Context() if len(args) < 1 { log.G(ctx).Fatal("must enter runtime name") } - if len(args) > 1 { - version = semver.MustParse(args[1]) + if versionStr != "" { + version, err = semver.NewVersion(versionStr) + if err != nil { + return err + } } return RunRuntimeUpgrade(ctx, &RuntimeUpgradeOptions{ @@ -369,6 +391,7 @@ func NewRuntimeUpgradeCommand() *cobra.Command { }, } + cmd.Flags().StringVar(&versionStr, "version", "", "The runtime version to upgrade to, defaults to latest") cloneOpts = git.AddFlags(cmd, &git.AddFlagsOptions{ FS: memfs.New(), }) @@ -415,7 +438,7 @@ func RunRuntimeUpgrade(ctx context.Context, opts *RuntimeUpgradeOptions) error { for _, component := range newComponents { log.G(ctx).Infof("Creating app '%s'", component.Name) - if err = component.CreateApp(ctx, nil, opts.CloneOpts, opts.RuntimeName); err != nil { + if err = component.CreateApp(ctx, nil, opts.CloneOpts, opts.RuntimeName, newRt.Spec.Version); err != nil { return fmt.Errorf("failed to create '%s' application: %w", component.Name, err) } } @@ -455,7 +478,7 @@ func createComponentsReporter(ctx context.Context, cloneOpts *git.CloneOptions, Type: application.AppTypeDirectory, URL: cloneOpts.URL() + "/" + resPath, } - if err := appDef.CreateApp(ctx, opts.KubeFactory, cloneOpts, opts.RuntimeName); err != nil { + if err := appDef.CreateApp(ctx, opts.KubeFactory, cloneOpts, opts.RuntimeName, nil); err != nil { return err } @@ -835,7 +858,7 @@ func createGitSource(ctx context.Context, insCloneOpts *git.CloneOptions, gsClon Type: application.AppTypeDirectory, URL: insCloneOpts.URL() + insFs.Join(insFs.Root(), resPath), } - if err = appDef.CreateApp(ctx, nil, insCloneOpts, runtimeName); err != nil { + if err = appDef.CreateApp(ctx, nil, insCloneOpts, runtimeName, nil); err != nil { return fmt.Errorf("failed to create git-source: %w", err) } diff --git a/docs/commands/cli-v2_runtime_install.md b/docs/commands/cli-v2_runtime_install.md index c12cece73..705aec89f 100644 --- a/docs/commands/cli-v2_runtime_install.md +++ b/docs/commands/cli-v2_runtime_install.md @@ -37,6 +37,7 @@ cli-v2 runtime install [runtime_name] [flags] --install-repo string Repository URL [INSTALL_GIT_REPO] --kubeconfig string Path to the kubeconfig file to use for CLI requests. -n, --namespace string If present, the namespace scope for this CLI request + --version string The runtime version to install, defaults to latest ``` ### Options inherited from parent commands diff --git a/docs/commands/cli-v2_runtime_upgrade.md b/docs/commands/cli-v2_runtime_upgrade.md index b1e2b6eb2..37161d579 100644 --- a/docs/commands/cli-v2_runtime_upgrade.md +++ b/docs/commands/cli-v2_runtime_upgrade.md @@ -31,6 +31,7 @@ cli-v2 runtime upgrade [runtime_name] [flags] -t, --git-token string Your git provider api token [GIT_TOKEN] -h, --help help for upgrade --repo string Repository URL [GIT_REPO] + --version string The runtime version to upgrade to, defaults to latest ``` ### Options inherited from parent commands diff --git a/docs/releases/release_notes.md b/docs/releases/release_notes.md index fd060240a..6fc382609 100644 --- a/docs/releases/release_notes.md +++ b/docs/releases/release_notes.md @@ -8,7 +8,7 @@ ### Linux ```bash # download and extract the binary -curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.24/cf-linux-amd64.tar.gz | tar zx +curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.26/cf-linux-amd64.tar.gz | tar zx # move the binary to your $PATH mv ./cf-* /usr/local/bin/cf @@ -20,7 +20,7 @@ cf version ### Mac ```bash # download and extract the binary -curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.24/cf-darwin-amd64.tar.gz | tar zx +curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.26/cf-darwin-amd64.tar.gz | tar zx # move the binary to your $PATH mv ./cf-* /usr/local/bin/cf diff --git a/hack/build.sh b/hack/build.sh index 48da90746..b95d83096 100755 --- a/hack/build.sh +++ b/hack/build.sh @@ -13,8 +13,5 @@ go build -ldflags=" \ -X 'github.com/codefresh-io/cli-v2/pkg/store.version=${VERSION}' \ -X 'github.com/codefresh-io/cli-v2/pkg/store.buildDate=${BUILD_DATE}' \ -X 'github.com/codefresh-io/cli-v2/pkg/store.gitCommit=${GIT_COMMIT}' \ - -X 'github.com/codefresh-io/cli-v2/pkg/store.ArgoCDManifestsURL=${ARGOCD_INSTALLATION_MANIFESTS_URL}' \ - -X 'github.com/codefresh-io/cli-v2/pkg/store.ArgoEventsManifestsURL=${EVENTS_INSTALLATION_MANIFESTS_URL}' \ - -X 'github.com/codefresh-io/cli-v2/pkg/store.ArgoRolloutsManifestsURL=${ROLLOUTS_INSTALLATION_MANIFESTS_URL}' \ - -X 'github.com/codefresh-io/cli-v2/pkg/store.ArgoWorkflowsManifestsURL=${WORKFLOWS_INSTALLATION_MANIFESTS_URL}'" \ + -X 'github.com/codefresh-io/cli-v2/pkg/store.RuntimeDefURL=${RUNTIME_DEF_URL}'" \ -v -o ${OUT_FILE} ${MAIN} \ No newline at end of file diff --git a/hack/release.sh b/hack/release.sh index 0f0bbc3a5..40cba1cf1 100755 --- a/hack/release.sh +++ b/hack/release.sh @@ -38,4 +38,4 @@ if [[ "$DRY_RUN" == "1" ]]; then exit 0 fi -gh release create --repo $GIT_REPO -t $VERSION -F $FILE --prerelease=$PRERELEASE $VERSION ./dist/*.tar.gz ./dist/*.sha256 +gh release create --repo $GIT_REPO -t $VERSION -F $FILE --prerelease=$PRERELEASE $VERSION ./dist/*.tar.gz ./dist/*.sha256 ./manifests/runtime.yaml diff --git a/manifests/runtime.yaml b/manifests/runtime.yaml index e6e62336c..37d2d6342 100644 --- a/manifests/runtime.yaml +++ b/manifests/runtime.yaml @@ -5,7 +5,7 @@ metadata: namespace: "{{ namespace }}" spec: defVersion: 1.0.0 - version: 0.0.25 + version: 0.0.26 bootstrapSpecifier: github.com/codefresh-io/cli-v2/manifests/argo-cd components: - name: events diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index 228d78f8b..f8d3222ff 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -70,16 +70,12 @@ func Download(version *semver.Version, name string) (*Runtime, error) { ) if strings.HasPrefix(store.RuntimeDefURL, "http") { - urlObj, err := url.Parse(store.RuntimeDefURL) - if err != nil { - return nil, fmt.Errorf("failed parsing url: %w", err) - } - - if urlObj.Query().Get("ref") == "" { - urlObj.Query().Set("ref", version.String()) + urlString := store.RuntimeDefURL + if version != nil { + urlString = strings.Replace(urlString, "/releases/latest/download", "/releases/download/v"+version.String(), 1) } - res, err := http.Get(urlObj.String()) + res, err := http.Get(urlString) if err != nil { return nil, fmt.Errorf("failed to download runtime definition: %w", err) } @@ -161,7 +157,7 @@ func (r *Runtime) Upgrade(fs fs.FS, newRt *Runtime) ([]AppDef, error) { func (r *RuntimeSpec) upgrade(fs fs.FS, newRt *RuntimeSpec) ([]AppDef, error) { log.G().Infof("Upgrading bootstrap specifier") argocdFilename := fs.Join(apstore.Default.BootsrtrapDir, apstore.Default.ArgoCDName, "kustomization.yaml") - if err := updateKustomization(fs, argocdFilename, r.fullSpecifier(), newRt.fullSpecifier()); err != nil { + if err := updateKustomization(fs, argocdFilename, r.FullSpecifier(), newRt.FullSpecifier()); err != nil { return nil, fmt.Errorf("failed to upgrade bootstrap specifier: %w", err) } @@ -205,11 +201,11 @@ func (a *RuntimeSpec) component(name string) *AppDef { return nil } -func (r *RuntimeSpec) fullSpecifier() string { +func (r *RuntimeSpec) FullSpecifier() string { return buildFullURL(r.BootstrapSpecifier, r.DefVersion) } -func (a *AppDef) CreateApp(ctx context.Context, f kube.Factory, cloneOpts *git.CloneOptions, projectName string) error { +func (a *AppDef) CreateApp(ctx context.Context, f kube.Factory, cloneOpts *git.CloneOptions, projectName string, version *semver.Version) error { timeout := time.Duration(0) if a.Wait { timeout = store.Get().WaitTimeout @@ -221,7 +217,7 @@ func (a *AppDef) CreateApp(ctx context.Context, f kube.Factory, cloneOpts *git.C ProjectName: projectName, AppOpts: &application.CreateOptions{ AppName: a.Name, - AppSpecifier: a.URL, + AppSpecifier: buildFullURL(a.URL, version), AppType: a.Type, DestNamespace: projectName, }, @@ -260,9 +256,15 @@ func updateKustomization(fs fs.FS, filename, fromURL, toURL string) error { } func buildFullURL(urlString string, version *semver.Version) string { + if version == nil { + return urlString + } + urlObj, _ := url.Parse(urlString) - if urlObj.Query().Get("ref") == "" { - urlObj.Query().Add("ref", version.String()) + v := urlObj.Query() + if v.Get("ref") == "" { + v.Add("ref", version.String()) + urlObj.RawQuery = v.Encode() } return urlObj.String()