├── .codecov.yml ├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ ├── bug.yaml │ └── feature.yaml └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .golangci.yaml ├── .pre-commit-config.yaml ├── .readthedocs.yml ├── CODEOWNERS ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── brew └── template.rb ├── build └── Dockerfile.helper ├── cmd ├── commands │ ├── account.go │ ├── account_test.go │ ├── cluster.go │ ├── cluster_test.go │ ├── common.go │ ├── completion.go │ ├── component.go │ ├── config.go │ ├── config_test.go │ ├── git-source.go │ ├── helm.go │ ├── helm_test.go │ ├── integrations.go │ ├── pipeline.go │ ├── product-release.go │ ├── product-release_mock.json │ ├── product-release_test.go │ ├── root.go │ ├── runtime.go │ ├── upgrade.go │ ├── version.go │ └── workflow.go └── main.go ├── docs ├── assets │ ├── logo.svg │ ├── versions.css │ └── versions.js ├── commands │ ├── .gitkeep │ ├── cli-v2.md │ ├── cli-v2_account.md │ ├── cli-v2_account_validate-usage.md │ ├── cli-v2_cluster.md │ ├── cli-v2_cluster_add.md │ ├── cli-v2_cluster_create-argo-rollouts.md │ ├── cli-v2_cluster_list.md │ ├── cli-v2_cluster_remove.md │ ├── cli-v2_completion.md │ ├── cli-v2_component.md │ ├── cli-v2_component_list.md │ ├── cli-v2_config.md │ ├── cli-v2_config_create-context.md │ ├── cli-v2_config_current-context.md │ ├── cli-v2_config_delete-context.md │ ├── cli-v2_config_get-contexts.md │ ├── cli-v2_config_get-runtime.md │ ├── cli-v2_config_set-runtime.md │ ├── cli-v2_config_update-gitops-settings.md │ ├── cli-v2_config_use-context.md │ ├── cli-v2_git-source.md │ ├── cli-v2_git-source_create.md │ ├── cli-v2_git-source_delete.md │ ├── cli-v2_git-source_edit.md │ ├── cli-v2_git-source_list.md │ ├── cli-v2_helm.md │ ├── cli-v2_helm_validate.md │ ├── cli-v2_integration.md │ ├── cli-v2_integration_git.md │ ├── cli-v2_integration_git_add.md │ ├── cli-v2_integration_git_auth.md │ ├── cli-v2_integration_git_deregister.md │ ├── cli-v2_integration_git_edit.md │ ├── cli-v2_integration_git_get.md │ ├── cli-v2_integration_git_list.md │ ├── cli-v2_integration_git_register.md │ ├── cli-v2_integration_git_remove.md │ ├── cli-v2_pipeline.md │ ├── cli-v2_pipeline_get.md │ ├── cli-v2_pipeline_list.md │ ├── cli-v2_product-release.md │ ├── cli-v2_product-release_list.md │ ├── cli-v2_runtime.md │ ├── cli-v2_runtime_list.md │ ├── cli-v2_runtime_logs.md │ ├── cli-v2_runtime_uninstall.md │ ├── cli-v2_upgrade.md │ ├── cli-v2_version.md │ ├── cli-v2_workflow.md │ ├── cli-v2_workflow_get.md │ └── cli-v2_workflow_list.md ├── index.md ├── releases │ └── release_notes.md └── requirements.txt ├── go.mod ├── go.sum ├── hack ├── boilerplate.txt ├── build.sh ├── check_worktree.sh ├── cmd-docs │ └── main.go ├── license.go ├── release.sh └── test.sh ├── internal ├── config │ ├── config.go │ ├── config_test.go │ └── mocks │ │ └── config.go ├── git │ ├── mocks │ │ └── roundTripper.go │ ├── provider.go │ ├── provider_bitbucket-server.go │ ├── provider_bitbucket-server_test.go │ ├── provider_bitbucket.go │ ├── provider_bitbucket_test.go │ ├── provider_github.go │ ├── provider_github_test.go │ ├── provider_gitlab.go │ ├── provider_gitlab_test.go │ └── provider_test.go ├── kube │ ├── kube.go │ └── mocks │ │ └── kube.go ├── log │ ├── log.go │ └── logrus.go ├── reporter │ └── reporter.go ├── store │ └── store.go └── util │ ├── cli │ └── cli.go │ ├── helm │ ├── helm.go │ └── mocks │ │ └── helm.go │ ├── http │ └── http.go │ ├── kube │ └── kube.go │ ├── kust │ └── util.go │ └── util.go ├── mkdocs.yml ├── overrides └── partials │ └── language │ └── en-custom.html └── util └── assets └── assets.go /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | patch: off 4 | project: 5 | default: 6 | # allow test coverage to drop by 2% 7 | threshold: 2 -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | dist -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yaml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: ["bug", "triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! 10 | - type: textarea 11 | id: what-happened 12 | attributes: 13 | label: What happened? 14 | description: Describe the bug in detail. What did you expect to happen? What actually happened? 15 | value: "A bug happened!" 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: version 20 | attributes: 21 | label: Version 22 | description: What version of the CLI are you running? 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: info 27 | attributes: 28 | label: Additional Information 29 | description: Please copy and paste any additional information we can use to reproduce the bug. 30 | render: shell 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yaml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Submit a feature request 3 | title: "[Feature]: " 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this feature request! 10 | - type: textarea 11 | id: feature 12 | attributes: 13 | label: What would you like to be added? 14 | description: If applicable, add a mock CLI invocation for the new feature. 15 | value: "The following feature would be great!" 16 | validations: 17 | required: true -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## What 2 | 3 | 4 | ## Why 5 | 6 | 7 | ## Notes 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | coverage.txt 8 | .dccache 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # ides 17 | .vscode 18 | __debug_bin 19 | .idea 20 | 21 | # Dependency directories (remove the comment below to include it) 22 | # vendor/ 23 | dist/ 24 | 25 | # General 26 | .DS_Store 27 | .AppleDouble 28 | .LSOverride 29 | 30 | # Icon must end with two \r 31 | Icon 32 | vendor 33 | 34 | 35 | # Thumbnails 36 | ._* 37 | 38 | # Files that might appear in the root of a volume 39 | .DocumentRevisions-V100 40 | .fseventsd 41 | .Spotlight-V100 42 | .TemporaryItems 43 | .Trashes 44 | .VolumeIcon.icns 45 | .com.apple.timemachine.donotpresent 46 | 47 | # Directories potentially created on remote AFP share 48 | .AppleDB 49 | .AppleDesktop 50 | Network Trash Folder 51 | Temporary Items 52 | .apdisk 53 | 54 | # Windows thumbnail cache files 55 | Thumbs.db 56 | Thumbs.db:encryptable 57 | ehthumbs.db 58 | ehthumbs_vista.db 59 | 60 | # Dump file 61 | *.stackdump 62 | 63 | # Folder config file 64 | [Dd]esktop.ini 65 | 66 | # Recycle Bin used on file shares 67 | $RECYCLE.BIN/ 68 | 69 | # Windows Installer files 70 | *.cab 71 | *.msi 72 | *.msix 73 | *.msm 74 | *.msp 75 | 76 | # Windows shortcuts 77 | *.lnk 78 | 79 | *~ 80 | 81 | # temporary files which can be created if a process still has a handle open of a deleted file 82 | .fuse_hidden* 83 | 84 | # KDE directory preferences 85 | .directory 86 | 87 | # Linux trash folder which might appear on any partition or disk 88 | .Trash-* 89 | 90 | # .nfs files are created when an open file is removed but is still being accessed 91 | .nfs* 92 | 93 | # mkdocs 94 | site 95 | 96 | # codecov 97 | codecov* 98 | 99 | values.yaml 100 | -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | # This file contains all available configuration options 2 | # with their default values. 3 | 4 | # options for analysis running 5 | run: 6 | # https://github.com/golangci/golangci-lint/issues/2649 7 | # enable go 1.17 linting, will not allow generics 8 | go: "1.17" 9 | 10 | # default concurrency is a available CPU number 11 | concurrency: 4 12 | 13 | # timeout for analysis, e.g. 30s, 5m, default is 1m 14 | timeout: 1m 15 | 16 | # exit code when at least one issue was found, default is 1 17 | issues-exit-code: 1 18 | 19 | linters: 20 | enable: 21 | - gocyclo 22 | - errcheck 23 | - godox 24 | # all available settings of specific linters 25 | linters-settings: 26 | errcheck: 27 | # report about not checking of errors in type assertions: `a := b.(MyStruct)`; 28 | # default is false: such cases aren't reported by default. 29 | check-type-assertions: false 30 | 31 | # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; 32 | # default is false: such cases aren't reported by default. 33 | check-blank: false 34 | 35 | gocyclo: 36 | # minimal code complexity to report, 30 by default (but we recommend 10-20) 37 | min-complexity: 20 38 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_stages: [commit, push] 2 | repos: 3 | - repo: local 4 | hooks: 5 | - id: pre-comit 6 | name: pre-commit linting 7 | language: system 8 | entry: make pre-commit 9 | verbose: true 10 | stages: [ commit ] 11 | - id: pre-push 12 | name: pre-push testing 13 | language: system 14 | entry: make pre-push 15 | verbose: true 16 | stages: [ push ] 17 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | formats: all 3 | mkdocs: 4 | fail_on_warning: false 5 | python: 6 | install: 7 | - requirements: docs/requirements.txt 8 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # https://github.com/orgs/codefresh-io/teams/r-d/teams 2 | # use teams and github usernames, instead of email addresses 3 | * @codefresh-io/Backend 4 | 5 | # only teamleads can approve CODEOOWNERS rule changes 6 | CODEOWNERS @codefresh-io/teamleads 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.4-alpine3.21 AS base 2 | 3 | WORKDIR /go/src/github.com/codefresh-io/cli-v2 4 | 5 | RUN apk -U add --no-cache git ca-certificates && update-ca-certificates 6 | 7 | RUN adduser \ 8 | --disabled-password \ 9 | --gecos "" \ 10 | --home "/home/codefresh" \ 11 | --shell "/sbin/nologin" \ 12 | --no-create-home \ 13 | --uid 10001 \ 14 | codefresh 15 | 16 | RUN --mount=type=secret,id=GITHUB_TOKEN \ 17 | GITHUB_TOKEN=$(cat /run/secrets/GITHUB_TOKEN) \ 18 | git config \ 19 | --global \ 20 | url."https://github:${GITHUB_TOKEN}@github.com".insteadOf \ 21 | "https://github.com" 22 | COPY go.mod . 23 | COPY go.sum . 24 | 25 | RUN go mod download -x 26 | RUN go mod verify 27 | 28 | ############################### CLI ############################### 29 | ### Compile 30 | FROM golang:1.23.4-alpine3.21 AS codefresh-build 31 | 32 | WORKDIR /go/src/github.com/codefresh-io/cli-v2 33 | 34 | RUN apk -U add --no-cache git make bash 35 | 36 | COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 37 | COPY --from=base /go/pkg/mod /go/pkg/mod 38 | 39 | COPY . . 40 | 41 | ENV GOPATH /go 42 | ENV GOBIN /go/bin 43 | 44 | ARG SEGMENT_WRITE_KEY 45 | RUN make local DEV_MODE=false SEGMENT_WRITE_KEY=${SEGMENT_WRITE_KEY} 46 | 47 | ### Run 48 | FROM alpine:3.21 AS codefresh 49 | 50 | WORKDIR /go/src/github.com/codefresh-io/cli-v2 51 | 52 | RUN apk -U add --no-cache git 53 | 54 | # copy ca-certs and user details 55 | COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 56 | COPY --from=base /etc/passwd /etc/passwd 57 | COPY --from=base /etc/group /etc/group 58 | COPY --chown=codefresh:codefresh --from=codefresh-build /go/src/github.com/codefresh-io/cli-v2/dist/* /usr/local/bin/cf 59 | 60 | USER codefresh:codefresh 61 | 62 | ENTRYPOINT [ "cf" ] 63 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION=v0.2.8 2 | 3 | OUT_DIR=dist 4 | YEAR?=$(shell date +"%Y") 5 | 6 | CLI_NAME?=cf 7 | IMAGE_REPOSITORY?=quay.io 8 | IMAGE_NAMESPACE?=codefresh 9 | 10 | RUNTIME_DEF_URL="https://raw.githubusercontent.com/codefresh-io/csdp-official/stable/csdp/hybrid/basic/runtime.yaml" 11 | ADD_CLUSTER_DEF_URL="https://github.com/codefresh-io/csdp-official/add-cluster/kustomize" 12 | 13 | # when developing, point this to your local clone of csdp-official 14 | DEV_RUNTIME_DEF_URL="https://raw.githubusercontent.com/codefresh-io/csdp-official/stable/csdp/hybrid/basic/runtime.yaml" 15 | DEV_ADD_CLUSTER_DEF_URL="https://github.com/codefresh-io/csdp-official/add-cluster/kustomize" # specify dev branch using ?ref= here if you want to test a change 16 | 17 | CLI_SRCS := $(shell find . -name '*.go') 18 | 19 | MKDOCS_DOCKER_IMAGE?=squidfunk/mkdocs-material:4.1.1 20 | 21 | GIT_COMMIT=$(shell git rev-parse HEAD) 22 | BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') 23 | 24 | DEV_MODE?=true 25 | SEGMENT_WRITE_KEY?="" 26 | 27 | ifeq (${DEV_MODE},true) 28 | RUNTIME_DEF_URL=${DEV_RUNTIME_DEF_URL} 29 | ADD_CLUSTER_DEF_URL=${DEV_ADD_CLUSTER_DEF_URL} 30 | endif 31 | 32 | ifdef LOCAL_MANIFESTS 33 | RUNTIME_DEF_URL=${LOCAL_MANIFESTS} 34 | endif 35 | 36 | ifndef GOBIN 37 | ifndef GOPATH 38 | $(error GOPATH is not set, please make sure you set your GOPATH correctly!) 39 | endif 40 | GOBIN=$(GOPATH)/bin 41 | ifndef GOBIN 42 | $(error GOBIN is not set, please make sure you set your GOBIN correctly!) 43 | endif 44 | endif 45 | 46 | define docker_build 47 | docker buildx build -t $(IMAGE_REPOSITORY)/$(IMAGE_NAMESPACE)/$(1):dev-$(VERSION) . 48 | endef 49 | 50 | .PHONY: all 51 | all: bin image 52 | 53 | .PHONY: local 54 | local: bin-local 55 | 56 | .PHONY: bin 57 | bin: cli 58 | 59 | .PHONY: bin-local 60 | bin-local: cli-local 61 | 62 | .PHONY: image 63 | image: cli-image 64 | 65 | .PHONY: cur-version 66 | cur-version: 67 | @echo -n $(VERSION) 68 | 69 | .PHONY: cli 70 | cli: $(OUT_DIR)/$(CLI_NAME)-linux-amd64.sha256 $(OUT_DIR)/$(CLI_NAME)-linux-arm64.sha256 $(OUT_DIR)/$(CLI_NAME)-linux-ppc64le.sha256 $(OUT_DIR)/$(CLI_NAME)-linux-s390x.sha256 $(OUT_DIR)/$(CLI_NAME)-darwin-amd64.sha256 $(OUT_DIR)/$(CLI_NAME)-darwin-arm64.sha256 $(OUT_DIR)/$(CLI_NAME)-windows-amd64.sha256 71 | 72 | .PHONY: cli-local 73 | cli-local: $(OUT_DIR)/$(CLI_NAME)-$(shell go env GOOS)-$(shell go env GOARCH) 74 | @rm /usr/local/bin/$(CLI_NAME)-dev 2>/dev/null || true 75 | @ln $(OUT_DIR)/$(CLI_NAME)-$(shell go env GOOS)-$(shell go env GOARCH) /usr/local/bin/$(CLI_NAME)-dev 76 | 77 | .PHONY: cli-e2e 78 | cli-e2e: cli-package 79 | 80 | .PHONY: cli-package 81 | cli-package: $(OUT_DIR)/$(CLI_NAME)-$(shell go env GOOS)-$(shell go env GOARCH) 82 | @cp $(OUT_DIR)/$(CLI_NAME)-$(shell go env GOOS)-$(shell go env GOARCH) $(OUT_DIR)/$(CLI_NAME) 83 | 84 | $(OUT_DIR)/$(CLI_NAME)-linux-amd64: GO_FLAGS='GOOS=linux GOARCH=amd64 CGO_ENABLED=0' 85 | $(OUT_DIR)/$(CLI_NAME)-darwin-amd64: GO_FLAGS='GOOS=darwin GOARCH=amd64 CGO_ENABLED=0' 86 | $(OUT_DIR)/$(CLI_NAME)-darwin-arm64: GO_FLAGS='GOOS=darwin GOARCH=arm64 CGO_ENABLED=0' 87 | $(OUT_DIR)/$(CLI_NAME)-windows-amd64.exe: GO_FLAGS='GOOS=windows GOARCH=amd64 CGO_ENABLED=0' 88 | $(OUT_DIR)/$(CLI_NAME)-linux-arm64: GO_FLAGS='GOOS=linux GOARCH=arm64 CGO_ENABLED=0' 89 | $(OUT_DIR)/$(CLI_NAME)-linux-ppc64le: GO_FLAGS='GOOS=linux GOARCH=ppc64le CGO_ENABLED=0' 90 | $(OUT_DIR)/$(CLI_NAME)-linux-s390x: GO_FLAGS='GOOS=linux GOARCH=s390x CGO_ENABLED=0' 91 | 92 | $(OUT_DIR)/$(CLI_NAME)-windows-amd64.tar.gz: 93 | @make $(OUT_DIR)/$(CLI_NAME)-windows-amd64.exe 94 | cd $(OUT_DIR) && tar -czvf $(CLI_NAME)-windows-amd64.tar.gz $(CLI_NAME)-windows-amd64.exe && cd .. 95 | 96 | $(OUT_DIR)/$(CLI_NAME)-%.tar.gz: 97 | @make $(OUT_DIR)/$(CLI_NAME)-$* 98 | cd $(OUT_DIR) && tar -czvf $(CLI_NAME)-$*.tar.gz $(CLI_NAME)-$* && cd .. 99 | 100 | $(OUT_DIR)/$(CLI_NAME)-%.sha256: 101 | @make $(OUT_DIR)/$(CLI_NAME)-$*.tar.gz 102 | openssl dgst -sha256 "$(OUT_DIR)/$(CLI_NAME)-$*.tar.gz" | awk '{ print $$2 }' > "$(OUT_DIR)/$(CLI_NAME)-$*".sha256 103 | 104 | $(OUT_DIR)/$(CLI_NAME)-%: $(CLI_SRCS) 105 | @GO_FLAGS=$(GO_FLAGS) \ 106 | BINARY_NAME=$(CLI_NAME) \ 107 | VERSION=$(VERSION) \ 108 | BUILD_DATE=$(BUILD_DATE) \ 109 | GIT_COMMIT=$(GIT_COMMIT) \ 110 | RUNTIME_DEF_URL=$(RUNTIME_DEF_URL) \ 111 | ADD_CLUSTER_DEF_URL=$(ADD_CLUSTER_DEF_URL) \ 112 | SEGMENT_WRITE_KEY=$(SEGMENT_WRITE_KEY) \ 113 | DEV_MODE=$(DEV_MODE) \ 114 | OUT_FILE=$(OUT_DIR)/$(CLI_NAME)-$* \ 115 | MAIN=./cmd \ 116 | ./hack/build.sh 117 | 118 | .PHONY: cli-image 119 | cli-image: tidy $(OUT_DIR)/$(CLI_NAME).image 120 | 121 | $(OUT_DIR)/$(CLI_NAME).image: $(CLI_SRCS) 122 | $(call docker_build,$(CLI_NAME)) 123 | @mkdir -p $(OUT_DIR) 124 | @touch $(OUT_DIR)/$(CLI_NAME).image 125 | 126 | .PHONY: lint 127 | lint: $(GOBIN)/golangci-lint tidy 128 | @echo linting go code... 129 | @golangci-lint run --fix --timeout 10m 130 | 131 | .PHONY: test 132 | test: 133 | @./hack/test.sh 134 | 135 | .PHONY: codegen 136 | codegen: $(GOBIN)/mockgen 137 | rm -f ./docs/commands/* 138 | go generate ./... 139 | go run ./hack/license.go --license ./hack/boilerplate.txt --year $(YEAR) . 140 | 141 | .PHONY: pre-commit 142 | pre-commit: lint 143 | 144 | .PHONY: pre-push 145 | pre-push: tidy lint test codegen check-worktree 146 | 147 | .PHONY: build-docs 148 | build-docs: 149 | docker run ${MKDOCS_RUN_ARGS} --rm -it -p 8000:8000 -v $(shell pwd):/docs ${MKDOCS_DOCKER_IMAGE} build 150 | 151 | .PHONY: serve-docs 152 | serve-docs: 153 | docker run ${MKDOCS_RUN_ARGS} --rm -it -p 8000:8000 -v $(shell pwd):/docs ${MKDOCS_DOCKER_IMAGE} serve -a 0.0.0.0:8000 154 | 155 | .PHONY: release 156 | release: tidy check-worktree 157 | @./hack/release.sh 158 | 159 | .PHONY: clean 160 | clean: 161 | @rm -rf dist 162 | 163 | .PHONY: tidy 164 | tidy: 165 | @echo running go mod tidy... 166 | @go mod tidy 167 | 168 | .PHONY: check-worktree 169 | check-worktree: 170 | @./hack/check_worktree.sh 171 | 172 | $(GOBIN)/mockgen: 173 | @go install github.com/golang/mock/mockgen@v1.6.0 174 | @mockgen -version 175 | 176 | $(GOBIN)/golangci-lint: 177 | @mkdir dist || true 178 | @echo installing: golangci-lint 179 | @curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) v1.62.2 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Argo Logo

2 | 3 | # Codefresh CLI V2 4 | 5 | [![Codefresh build status]( https://g.codefresh.io/api/badges/pipeline/codefresh-inc/golang%2Fci?type=cf-1)]( https://g.codefresh.io/public/accounts/codefresh-inc/pipelines/new/60ae2ae330acb8f9c9bace7f) 6 | [![codecov](https://codecov.io/gh/codefresh-io/cli-v2/branch/main/graph/badge.svg?token=IDyZNfRUfY)](https://codecov.io/gh/codefresh-io/cli-v2) 7 | [![Go Report Card](https://goreportcard.com/badge/github.com/codefresh-io/cli-v2)](https://goreportcard.com/report/github.com/codefresh-io/cli-v2) 8 | 9 | ## Introduction 10 | 11 | The new Codefresh CLI tool. 12 | 13 | ## Installation 14 | ### Using brew: 15 | ```bash 16 | # tap Codefresh homebrew repo 17 | brew tap codefresh-io/cli 18 | 19 | # install cf2 CLI 20 | brew install cf2 21 | 22 | # check the installation 23 | cf version 24 | ``` 25 | 26 | ### Mac 27 | 28 | ```bash 29 | # get the latest version or change to a specific version 30 | VERSION=$(curl --silent "https://api.github.com/repos/codefresh-io/cli-v2/releases/latest" | jq -r ".tag_name") 31 | 32 | # download and extract the binary 33 | curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/$VERSION/cf-darwin-amd64.tar.gz | tar zx 34 | 35 | # move the binary to your $PATH 36 | mv ./cf-* /usr/local/bin/cf 37 | 38 | # check the installation 39 | cf version 40 | ``` 41 | 42 | ### Linux 43 | ```bash 44 | # get the latest version or change to a specific version 45 | VERSION=$(curl --silent "https://api.github.com/repos/codefresh-io/cli-v2/releases/latest" | jq -r ".tag_name") 46 | 47 | # download and extract the binary 48 | curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/$VERSION/cf-linux-amd64.tar.gz | tar zx 49 | 50 | # move the binary to your $PATH 51 | mv ./cf-* /usr/local/bin/cf 52 | 53 | # check the installation 54 | cf version 55 | ``` 56 | -------------------------------------------------------------------------------- /brew/template.rb: -------------------------------------------------------------------------------- 1 | class Cf2 < Formula 2 | desc "Codefresh CLI tool, V2" 3 | homepage "https://codefresh.io/" 4 | url "https://github.com/codefresh-io/cli-v2.git", 5 | tag: "{{ version }}", 6 | revision: "{{ revision }}" 7 | license "Apache-2.0" 8 | 9 | depends_on "go" => :build 10 | 11 | def install 12 | system "make", "cli-package", "DEV_MODE=false" 13 | bin.install "dist/cf" => "cf" 14 | end 15 | 16 | test do 17 | assert_match version.to_s, shell_output("#{bin}/cf version") 18 | 19 | assert_match "must provide context name to use\"", 20 | shell_output("#{bin}/cf config use-context 2>&1", 1) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /build/Dockerfile.helper: -------------------------------------------------------------------------------- 1 | # docker buildx build --platform linux/amd64,linux/arm64 --build-arg GO_VERSION -t quay.io/codefresh/golang-ci-helper:${GO_VERSION} -f Dockerfile.helper . 2 | ARG GO_VERSION=1.23.4 3 | FROM golang:${GO_VERSION}-alpine3.20 4 | 5 | RUN apk -U add --no-cache \ 6 | bash \ 7 | @@ -13,14 +14,14 @@ RUN apk -U add --no-cache \ 8 | openssl \ 9 | && update-ca-certificates 10 | 11 | ARG GH_VERSION=2.64.0 12 | RUN curl -L https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_amd64.tar.gz --output gh.tar.gz \ 13 | && tar -xzf gh.tar.gz \ 14 | && mv gh_${GH_VERSION}_linux_amd64/bin/gh /usr/local/bin \ 15 | && rm gh.tar.gz \ 16 | && rm -rf gh_${GH_VERSION}_linux_amd64 17 | 18 | ARG KUSTOMIZE_VERSION=5.5.0 19 | RUN curl -Ls https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv${KUSTOMIZE_VERSION}/kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz --output kustomize.tar.gz \ 20 | && tar -xzf kustomize.tar.gz \ 21 | && mv ./kustomize /usr/bin \ 22 | && rm kustomize.tar.gz 23 | ENTRYPOINT [ "/bin/bash" ] 24 | -------------------------------------------------------------------------------- /cmd/commands/cluster_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "testing" 19 | 20 | platmodel "github.com/codefresh-io/go-sdk/pkg/model/platform" 21 | ) 22 | 23 | func Test_getSuffixToClusterName(t *testing.T) { 24 | cluster1 := getEmptyClusterEntity() 25 | cluster2 := getEmptyClusterEntity() 26 | cluster3 := getEmptyClusterEntity() 27 | 28 | cluster1.Metadata.Name = "test-cluster" 29 | cluster2.Metadata.Name = "test-cluster-1" 30 | cluster3.Metadata.Name = "test-cluster-2" 31 | 32 | clusters := []platmodel.Cluster{ 33 | cluster1, 34 | cluster2, 35 | cluster3, 36 | } 37 | 38 | type args struct { 39 | clusters []platmodel.Cluster 40 | name string 41 | tempName string 42 | counter int 43 | } 44 | tests := []struct { 45 | name string 46 | args args 47 | want int 48 | }{ 49 | { 50 | name: "should return 3", 51 | args: args{ 52 | clusters: clusters, 53 | name: "test-cluster", 54 | tempName: "test-cluster", 55 | counter: 0, 56 | }, 57 | want: 3, 58 | }, 59 | } 60 | for _, tt := range tests { 61 | t.Run(tt.name, func(t *testing.T) { 62 | if got := getSuffixToClusterName(tt.args.clusters, tt.args.name, tt.args.tempName, tt.args.counter); got != tt.want { 63 | t.Errorf("getSuffixToClusterName() = %v, want %v", got, tt.want) 64 | } 65 | }) 66 | } 67 | } 68 | 69 | func Test_sanitizeClusterName(t *testing.T) { 70 | tests := map[string]struct { 71 | name string 72 | want string 73 | wantErr bool 74 | }{ 75 | "should return sanitized string": { 76 | name: "^-.123test!@-:cluster&*`;')test.cluster(-12_3=+::±§.", 77 | want: "test----cluster------test-cluster--12-3", 78 | wantErr: false, 79 | }, 80 | "should return error of sanitization failed": { 81 | name: "12345", 82 | want: "", 83 | wantErr: true, 84 | }, 85 | } 86 | for name, tt := range tests { 87 | t.Run(name, func(t *testing.T) { 88 | got, err := sanitizeClusterName(tt.name) 89 | 90 | if (err != nil) != tt.wantErr { 91 | t.Errorf("sanitizeClusterName() error = %v, wantErr %v", err, tt.wantErr) 92 | } 93 | if got != tt.want { 94 | t.Errorf("sanitizeClusterName() = %v, want %v", got, tt.want) 95 | } 96 | }) 97 | } 98 | } 99 | 100 | func Test_validateClusterName(t *testing.T) { 101 | tests := map[string]struct { 102 | name string 103 | wantErr bool 104 | }{ 105 | "name should be valid": { 106 | name: "test-cluster-123", 107 | wantErr: false, 108 | }, 109 | "name should not be valid (contains uppercase)": { 110 | name: "Test-cluster", 111 | wantErr: true, 112 | }, 113 | "name should not be valid (contains invalid chars)": { 114 | name: "test-cluster:test/cluster.123#", 115 | wantErr: true, 116 | }, 117 | "name should not be valid (begins with numeric char)": { 118 | name: "2test-cluster", 119 | wantErr: true, 120 | }, 121 | "name should not be valid (too long)": { 122 | name: "this-cluster-name-is-too-long-1-this-cluster-name-is-too-long-1-this-cluster-name-is-too-long-1-123", 123 | wantErr: true, 124 | }, 125 | } 126 | for name, tt := range tests { 127 | t.Run(name, func(t *testing.T) { 128 | if err := validateClusterName(tt.name); (err != nil) != tt.wantErr { 129 | t.Errorf("validateClusterName() error = %v, wantErr %v", err, tt.wantErr) 130 | } 131 | }) 132 | } 133 | } 134 | 135 | func getEmptyClusterEntity() platmodel.Cluster { 136 | empty := "" 137 | return platmodel.Cluster{ 138 | Metadata: &platmodel.ObjectMeta{ 139 | Group: "", 140 | Version: "", 141 | Kind: "", 142 | Name: "", 143 | Description: &empty, 144 | Namespace: &empty, 145 | Runtime: "", 146 | Cluster: &empty, 147 | Account: "", 148 | Labels: nil, 149 | Annotations: nil, 150 | LastUpdated: &empty, 151 | Created: &empty, 152 | UID: &empty, 153 | }, 154 | Errors: []platmodel.Error{}, 155 | ReferencedBy: []platmodel.BaseEntity{}, 156 | References: []platmodel.BaseEntity{}, 157 | Server: "", 158 | Namespaces: []string{}, 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /cmd/commands/completion.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "os" 19 | 20 | "github.com/codefresh-io/cli-v2/internal/util" 21 | 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | func NewCompletionCommand() *cobra.Command { 26 | cmd := &cobra.Command{ 27 | Use: "completion [bash|zsh|fish|powershell]", 28 | Short: "Generates shell completion script.", 29 | Args: cobra.ExactArgs(1), 30 | Long: util.Doc(`Generates shell completion script for your shell environment 31 | 32 | Example: 33 | 34 | source <( completion bash) 35 | `), 36 | RunE: func(cmd *cobra.Command, args []string) error { 37 | switch args[0] { 38 | case "bash": 39 | return cmd.Root().GenBashCompletion(os.Stdout) 40 | case "zsh": 41 | return cmd.Root().GenZshCompletion(os.Stdout) 42 | case "fish": 43 | return cmd.Root().GenFishCompletion(os.Stdout, true) 44 | case "powershell": 45 | return cmd.Root().GenPowerShellCompletion(os.Stdout) 46 | default: 47 | return cmd.Help() 48 | } 49 | }, 50 | } 51 | 52 | return cmd 53 | } 54 | -------------------------------------------------------------------------------- /cmd/commands/component.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | "io" 21 | "os" 22 | 23 | "github.com/codefresh-io/cli-v2/internal/log" 24 | "github.com/codefresh-io/cli-v2/internal/util" 25 | 26 | platmodel "github.com/codefresh-io/go-sdk/pkg/model/platform" 27 | "github.com/juju/ansiterm" 28 | "github.com/spf13/cobra" 29 | ) 30 | 31 | type () 32 | 33 | func newComponentCommand() *cobra.Command { 34 | cmd := &cobra.Command{ 35 | Use: "component", 36 | Short: "Manage components of Codefresh runtimes", 37 | PersistentPreRunE: cfConfig.RequireAuthentication, 38 | Args: cobra.NoArgs, // Workaround for subcommand usage errors. See: https://github.com/spf13/cobra/issues/706 39 | Run: func(cmd *cobra.Command, args []string) { 40 | cmd.HelpFunc()(cmd, args) 41 | exit(1) 42 | }, 43 | } 44 | 45 | cmd.AddCommand(newComponentListCommand()) 46 | 47 | return cmd 48 | } 49 | 50 | func newComponentListCommand() *cobra.Command { 51 | var runtimeName string 52 | 53 | cmd := &cobra.Command{ 54 | Use: "list RUNTIME_NAME", 55 | Short: "List all the components under a specific runtime", 56 | Args: cobra.MaximumNArgs(1), 57 | Example: util.Doc(` 58 | component list runtime_name 59 | `), 60 | PreRunE: func(cmd *cobra.Command, args []string) error { 61 | var err error 62 | 63 | runtimeName, err = ensureRuntimeName(cmd.Context(), args, nil) 64 | if err != nil { 65 | return err 66 | } 67 | 68 | return nil 69 | }, 70 | RunE: func(cmd *cobra.Command, args []string) error { 71 | return runComponentList(cmd.Context(), runtimeName) 72 | }, 73 | } 74 | 75 | return cmd 76 | } 77 | 78 | func runComponentList(ctx context.Context, runtimeName string) error { 79 | components, err := cfConfig.NewClient().GraphQL().Component().List(ctx, runtimeName) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | if len(components) == 0 { 85 | log.G(ctx).WithField("runtime", runtimeName).Warn("no components were found in runtime") 86 | return nil 87 | } 88 | 89 | tb := ansiterm.NewTabWriter(os.Stdout, 0, 0, 4, ' ', 0) 90 | 91 | if err := printComponents(tb, components); err != nil { 92 | return err 93 | } 94 | 95 | return tb.Flush() 96 | } 97 | 98 | func printComponents(w io.Writer, components []platmodel.Component) error { 99 | _, err := fmt.Fprintln(w, "NAME\tHEALTH STATUS\tSYNC STATUS\tVERSION") 100 | if err != nil { 101 | return err 102 | } 103 | 104 | for _, c := range components { 105 | if err := printComponent(w, c); err != nil { 106 | return err 107 | } 108 | } 109 | 110 | return nil 111 | } 112 | 113 | func printComponent(w io.Writer, c platmodel.Component) error { 114 | name := c.Metadata.Name 115 | healthStatus := "N/A" 116 | syncStatus := "N/A" 117 | version := c.Version 118 | 119 | if c.Self != nil { 120 | if c.Self.Status != nil { 121 | syncStatus = c.Self.Status.SyncStatus.String() 122 | } 123 | 124 | if c.Self.Status.HealthStatus != nil { 125 | healthStatus = c.Self.Status.HealthStatus.String() 126 | } 127 | } 128 | 129 | _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", 130 | name, 131 | healthStatus, 132 | syncStatus, 133 | version, 134 | ) 135 | 136 | return err 137 | } 138 | -------------------------------------------------------------------------------- /cmd/commands/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/codefresh-io/cli-v2/internal/git" 21 | "github.com/codefresh-io/cli-v2/internal/store" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func Test_updateCsdpSettingsPreRunHandler(t *testing.T) { 27 | store.Get().Silent = true 28 | tests := map[string]struct { 29 | opts *updateGitOpsSettingsOpts 30 | wantGitProvider git.ProviderType 31 | wantGitApiURL string 32 | wantInferred bool 33 | wantErr string 34 | }{ 35 | "should succeed when all values are available and matching": { 36 | opts: &updateGitOpsSettingsOpts{ 37 | gitProvider: git.GITHUB, 38 | gitApiURL: "https://api.github.com", 39 | sharedConfigRepo: "https://github.com/org/repo.git", 40 | }, 41 | wantGitProvider: git.GITHUB, 42 | wantGitApiURL: "https://api.github.com", 43 | wantInferred: false, 44 | }, 45 | "should succeed when shared-config-repo has cloud values": { 46 | opts: &updateGitOpsSettingsOpts{ 47 | sharedConfigRepo: "https://github.com/org/repo.git", 48 | }, 49 | wantGitProvider: git.GITHUB, 50 | wantGitApiURL: "https://api.github.com", 51 | wantInferred: true, 52 | }, 53 | "should succeed when shared-config-repo is on-prem and all values are supplied": { 54 | opts: &updateGitOpsSettingsOpts{ 55 | gitProvider: git.GITHUB, 56 | gitApiURL: "https://some.ghe.server/api/v3", 57 | sharedConfigRepo: "https://some.ghe.server/org/repo.git", 58 | }, 59 | wantGitProvider: git.GITHUB, 60 | wantGitApiURL: "https://some.ghe.server/api/v3", 61 | wantInferred: false, 62 | }, 63 | "should fail when user supplies wrong git-provider": { 64 | opts: &updateGitOpsSettingsOpts{ 65 | gitProvider: git.GITLAB, 66 | sharedConfigRepo: "https://github.com/org/repo.git", 67 | }, 68 | wantErr: "supplied provider \"gitlab\" does not match inferred cloud provider \"github\" for url \"https://github.com/org/repo.git\"", 69 | }, 70 | "should fail when user supplies wrong git-api-url on cloud provider": { 71 | opts: &updateGitOpsSettingsOpts{ 72 | gitApiURL: "https://github.com/wrong/api", 73 | sharedConfigRepo: "https://github.com/org/repo.git", 74 | }, 75 | wantErr: "supplied git-api-url \"https://github.com/wrong/api\" does not match inferred git-api-url \"https://api.github.com\" from github cloud", 76 | }, 77 | } 78 | for name, tt := range tests { 79 | t.Run(name, func(t *testing.T) { 80 | err := updateGitOpsSettingsPreRunHandler(tt.opts) 81 | if err != nil || tt.wantErr != "" { 82 | assert.EqualError(t, err, tt.wantErr) 83 | return 84 | } 85 | 86 | assert.Equal(t, tt.wantGitProvider, tt.opts.gitProvider) 87 | assert.Equal(t, tt.wantGitApiURL, tt.opts.gitApiURL) 88 | }) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /cmd/commands/pipeline.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | "os" 21 | 22 | "github.com/codefresh-io/cli-v2/internal/log" 23 | "github.com/codefresh-io/cli-v2/internal/util" 24 | 25 | platmodel "github.com/codefresh-io/go-sdk/pkg/model/platform" 26 | "github.com/juju/ansiterm" 27 | "github.com/spf13/cobra" 28 | ) 29 | 30 | func newPipelineCommand() *cobra.Command { 31 | cmd := &cobra.Command{ 32 | Use: "pipeline", 33 | Short: "Manage pipelines of Codefresh runtimes", 34 | PersistentPreRunE: cfConfig.RequireAuthentication, 35 | Args: cobra.NoArgs, // Workaround for subcommand usage errors. See: https://github.com/spf13/cobra/issues/706 36 | Run: func(cmd *cobra.Command, args []string) { 37 | cmd.HelpFunc()(cmd, args) 38 | exit(1) 39 | }, 40 | } 41 | 42 | cmd.AddCommand(newPipelineGetCommand()) 43 | cmd.AddCommand(newPipelineListCommand()) 44 | 45 | return cmd 46 | } 47 | 48 | func newPipelineGetCommand() *cobra.Command { 49 | var ( 50 | name string 51 | namespace string 52 | runtime string 53 | ) 54 | 55 | cmd := &cobra.Command{ 56 | Use: "get --runtime --namespace --name ", 57 | Short: "Get a pipeline under a specific runtime and namespace", 58 | Args: cobra.NoArgs, 59 | Example: util.Doc(` 60 | pipeline --runtime runtime_name --namespace namespace --name pipeline_name 61 | 62 | pipeline -r runtime_name -N namespace -n pipeline_name 63 | `), 64 | RunE: func(cmd *cobra.Command, _ []string) error { 65 | ctx := cmd.Context() 66 | 67 | return runPipelineGet(ctx, name, namespace, runtime) 68 | }, 69 | } 70 | 71 | cmd.Flags().StringVarP(&name, "name", "n", "", "Name of target pipeline") 72 | util.Die(cmd.MarkFlagRequired("name")) 73 | cmd.Flags().StringVarP(&namespace, "namespace", "N", "", "Namespace of target pipeline") 74 | util.Die(cmd.MarkFlagRequired("namespace")) 75 | cmd.Flags().StringVarP(&runtime, "runtime", "r", "", "Runtime name of target pipeline") 76 | util.Die(cmd.MarkFlagRequired("runtime")) 77 | 78 | return cmd 79 | } 80 | 81 | func newPipelineListCommand() *cobra.Command { 82 | var ( 83 | name string 84 | namespace string 85 | runtime string 86 | project string 87 | ) 88 | 89 | cmd := &cobra.Command{ 90 | Use: "list", 91 | Short: "List all the pipelines", 92 | Args: cobra.NoArgs, 93 | Example: util.Doc(` 94 | pipelines list 95 | 96 | pipelines list --runtime 97 | 98 | pipelines list -r 99 | `), 100 | RunE: func(cmd *cobra.Command, _ []string) error { 101 | ctx := cmd.Context() 102 | 103 | filterArgs := platmodel.PipelinesFilterArgs{ 104 | Name: &name, 105 | Namespace: &namespace, 106 | Runtime: &runtime, 107 | Project: &project, 108 | } 109 | return runPipelineList(ctx, filterArgs) 110 | }, 111 | } 112 | 113 | cmd.Flags().StringVarP(&name, "name", "n", "", "Filter by pipeline name") 114 | cmd.Flags().StringVarP(&namespace, "namespace", "N", "", "Filter by pipeline namespace") 115 | cmd.Flags().StringVarP(&runtime, "runtime", "r", "", "Filter by pipeline runtime") 116 | cmd.Flags().StringVarP(&project, "project", "p", "", "Filter by pipeline project") 117 | 118 | return cmd 119 | } 120 | 121 | func runPipelineGet(ctx context.Context, name, namespace, runtime string) error { 122 | pipeline, err := cfConfig.NewClient().GraphQL().Pipeline().Get(ctx, name, namespace, runtime) 123 | if err != nil { 124 | return err 125 | } 126 | 127 | if pipeline == nil { 128 | fields := log.Fields{ 129 | "name": name, 130 | "namespace": namespace, 131 | "runtime": runtime, 132 | } 133 | log.G(ctx).WithFields(fields).Warn("pipeline was not found") 134 | return nil 135 | } 136 | 137 | tb := ansiterm.NewTabWriter(os.Stdout, 0, 0, 4, ' ', 0) 138 | _, err = fmt.Fprintln(tb, "NAME\tNAMESPACE\tRUNTIME\tHEALTH STATUS\tSYNC STATUS") 139 | if err != nil { 140 | return err 141 | } 142 | 143 | healthStatus := "N/A" 144 | if pipeline.Self.HealthStatus != nil { 145 | healthStatus = pipeline.Self.HealthStatus.String() 146 | } 147 | _, err = fmt.Fprintf(tb, "%s\t%s\t%s\t%s\t%s\n", 148 | pipeline.Metadata.Name, 149 | *pipeline.Metadata.Namespace, 150 | pipeline.Metadata.Runtime, 151 | healthStatus, 152 | pipeline.Self.SyncStatus, 153 | ) 154 | if err != nil { 155 | return err 156 | } 157 | 158 | return tb.Flush() 159 | } 160 | 161 | func runPipelineList(ctx context.Context, filterArgs platmodel.PipelinesFilterArgs) error { 162 | pipelines, err := cfConfig.NewClient().GraphQL().Pipeline().List(ctx, filterArgs) 163 | if err != nil { 164 | return err 165 | } 166 | 167 | if len(pipelines) == 0 { 168 | log.G(ctx).Warn("no pipelines were found") 169 | return nil 170 | } 171 | 172 | tb := ansiterm.NewTabWriter(os.Stdout, 0, 0, 4, ' ', 0) 173 | _, err = fmt.Fprintln(tb, "NAME\tNAMESPACE\tRUNTIME\tHEALTH STATUS\tSYNC STATUS") 174 | if err != nil { 175 | return err 176 | } 177 | 178 | for _, p := range pipelines { 179 | healthStatus := "N/A" 180 | if p.Self.HealthStatus != nil { 181 | healthStatus = p.Self.HealthStatus.String() 182 | } 183 | _, err = fmt.Fprintf(tb, "%s\t%s\t%s\t%s\t%s\n", 184 | p.Metadata.Name, 185 | *p.Metadata.Namespace, 186 | p.Metadata.Runtime, 187 | healthStatus, 188 | p.Self.SyncStatus, 189 | ) 190 | if err != nil { 191 | return err 192 | } 193 | } 194 | 195 | return tb.Flush() 196 | } 197 | -------------------------------------------------------------------------------- /cmd/commands/product-release_mock.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "releaseId": "669fac7668fc487b38c2ad19", 4 | "status": "FAILED", 5 | "steps": [ 6 | { 7 | "environmentName": "my-env", 8 | "status": "SUCCEEDED" 9 | }, 10 | { 11 | "environmentName": "staging", 12 | "status": "SUCCEEDED" 13 | }, 14 | { 15 | "environmentName": "prod", 16 | "status": "FAILED" 17 | } 18 | ] 19 | }, 20 | { 21 | "releaseId": "669fac7668fc487b38c2ad18", 22 | "status": "FAILED", 23 | "steps": [ 24 | { 25 | "environmentName": "my-env", 26 | "status": "SUCCEEDED" 27 | }, 28 | { 29 | "environmentName": "staging", 30 | "status": "SUCCEEDED" 31 | }, 32 | { 33 | "environmentName": "prod", 34 | "status": "FAILED" 35 | } 36 | ] 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /cmd/commands/root.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "github.com/codefresh-io/cli-v2/internal/config" 19 | "github.com/codefresh-io/cli-v2/internal/store" 20 | "github.com/codefresh-io/cli-v2/internal/util" 21 | 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | func NewRoot() *cobra.Command { 26 | s := store.Get() 27 | 28 | cmd := &cobra.Command{ 29 | Use: s.BinaryName, 30 | Short: util.Doc(` is used for installing and managing codefresh installations using gitops`), 31 | Long: util.Doc(` is used for installing and managing codefresh installations using gitops. 32 | 33 | Most of the commands in this CLI require you to specify a personal access token 34 | for your git provider. This token is used to authenticate with your git provider 35 | when performing operations on the gitops repository, such as cloning it and 36 | pushing changes to it. 37 | 38 | It is recommended that you export the $GIT_TOKEN and $GIT_REPO environment 39 | variables in advanced to simplify the use of those commands. 40 | `), 41 | RunE: func(cmd *cobra.Command, args []string) error { 42 | return cmd.Help() 43 | }, 44 | SilenceUsage: true, // will not display usage when RunE returns an error 45 | SilenceErrors: true, // will not use fmt to print errors 46 | DisableAutoGenTag: true, // disable the date in the command docs 47 | } 48 | 49 | cfConfig = config.AddFlags(cmd.PersistentFlags()) 50 | 51 | cmd.AddCommand(newVersionCommand()) 52 | cmd.AddCommand(newUpgradeCommand()) 53 | cmd.AddCommand(newConfigCommand()) 54 | cmd.AddCommand(newRuntimeCommand()) 55 | cmd.AddCommand(newGitSourceCommand()) 56 | cmd.AddCommand(newClusterCommand()) 57 | cmd.AddCommand(newComponentCommand()) 58 | cmd.AddCommand(newHelmCommand()) 59 | cmd.AddCommand(newWorkflowCommand()) 60 | cmd.AddCommand(newPipelineCommand()) 61 | cmd.AddCommand(newIntegrationCommand()) 62 | cmd.AddCommand(NewCompletionCommand()) 63 | cmd.AddCommand(NewProductReleaseCommand()) 64 | cmd.AddCommand(NewAccountCommand()) 65 | 66 | cobra.OnInitialize(func() { postInitCommands(cmd.Commands()) }) 67 | 68 | return cmd 69 | } 70 | -------------------------------------------------------------------------------- /cmd/commands/upgrade.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | cliutil "github.com/codefresh-io/cli-v2/internal/util/cli" 19 | 20 | "github.com/spf13/cobra" 21 | ) 22 | 23 | func newUpgradeCommand() *cobra.Command { 24 | var opts struct { 25 | version string 26 | output string 27 | } 28 | 29 | cmd := &cobra.Command{ 30 | Use: "upgrade", 31 | Short: "Upgrades the cli", 32 | Annotations: map[string]string{ 33 | cliutil.SkipVersionCheck: "true", 34 | }, 35 | Args: cobra.NoArgs, 36 | RunE: func(cmd *cobra.Command, args []string) error { 37 | return cliutil.UpgradeCLIToVersion(cmd.Context(), opts.version, opts.output) 38 | }, 39 | } 40 | 41 | cmd.Flags().StringVar(&opts.version, "version", "", "Specify a cli version to upgrade to") 42 | cmd.Flags().StringVarP(&opts.output, "ouput", "o", "", "Where to save the new binary (default: replace the old binary)") 43 | 44 | return cmd 45 | } 46 | -------------------------------------------------------------------------------- /cmd/commands/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/codefresh-io/cli-v2/internal/store" 21 | 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | func newVersionCommand() *cobra.Command { 26 | var opts struct { 27 | long bool 28 | } 29 | 30 | cmd := &cobra.Command{ 31 | Use: "version", 32 | Short: "Show cli version", 33 | Args: cobra.NoArgs, 34 | RunE: func(cmd *cobra.Command, args []string) error { 35 | s := store.Get() 36 | 37 | if opts.long { 38 | fmt.Printf("CLI:\n") 39 | fmt.Printf(" Version: %s\n", s.Version.Version) 40 | fmt.Printf(" BuildDate: %s\n", s.Version.BuildDate) 41 | fmt.Printf(" GitCommit: %s\n", s.Version.GitCommit) 42 | fmt.Printf(" GoVersion: %s\n", s.Version.GoVersion) 43 | fmt.Printf(" GoCompiler: %s\n", s.Version.GoCompiler) 44 | fmt.Printf(" Platform: %s\n", s.Version.Platform) 45 | } else { 46 | fmt.Printf("%+s\n", s.Version.Version) 47 | } 48 | 49 | return nil 50 | }, 51 | } 52 | 53 | cmd.Flags().BoolVar(&opts.long, "long", false, "display full version information") 54 | 55 | return cmd 56 | } 57 | -------------------------------------------------------------------------------- /cmd/commands/workflow.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package commands 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | "os" 21 | 22 | "github.com/codefresh-io/cli-v2/internal/log" 23 | "github.com/codefresh-io/cli-v2/internal/util" 24 | 25 | platmodel "github.com/codefresh-io/go-sdk/pkg/model/platform" 26 | "github.com/juju/ansiterm" 27 | "github.com/spf13/cobra" 28 | ) 29 | 30 | func newWorkflowCommand() *cobra.Command { 31 | cmd := &cobra.Command{ 32 | Use: "workflow", 33 | Short: "Manage workflows of Codefresh runtimes", 34 | PersistentPreRunE: cfConfig.RequireAuthentication, 35 | Args: cobra.NoArgs, // Workaround for subcommand usage errors. See: https://github.com/spf13/cobra/issues/706 36 | Run: func(cmd *cobra.Command, args []string) { 37 | cmd.HelpFunc()(cmd, args) 38 | exit(1) 39 | }, 40 | } 41 | 42 | cmd.AddCommand(newWorkflowGetCommand()) 43 | cmd.AddCommand(newWorkflowListCommand()) 44 | 45 | return cmd 46 | } 47 | 48 | func newWorkflowGetCommand() *cobra.Command { 49 | cmd := &cobra.Command{ 50 | Use: "get UID", 51 | Args: cobra.MaximumNArgs(1), 52 | Short: "Get a workflow under a specific uid", 53 | Example: util.Doc(` 54 | workflow get 0732b138-b74c-4a5e-b065-e23e6da0803d 55 | `), 56 | RunE: func(cmd *cobra.Command, args []string) error { 57 | ctx := cmd.Context() 58 | if len(args) < 1 { 59 | return fmt.Errorf("must enter uid") 60 | } 61 | 62 | return runWorkflowGet(ctx, args[0]) 63 | }, 64 | } 65 | 66 | return cmd 67 | } 68 | 69 | func newWorkflowListCommand() *cobra.Command { 70 | var ( 71 | namespace string 72 | runtime string 73 | project string 74 | ) 75 | 76 | cmd := &cobra.Command{ 77 | Use: "list", 78 | Short: "List all the workflows", 79 | Args: cobra.NoArgs, 80 | Example: util.Doc(` 81 | workflows list 82 | 83 | workflows list --runtime 84 | 85 | workflows list -r 86 | `), 87 | RunE: func(cmd *cobra.Command, _ []string) error { 88 | ctx := cmd.Context() 89 | 90 | filterArgs := platmodel.WorkflowsFilterArgs{ 91 | Namespace: &namespace, 92 | Runtime: &runtime, 93 | Project: &project, 94 | } 95 | return runWorkflowList(ctx, filterArgs) 96 | }, 97 | } 98 | 99 | cmd.Flags().StringVarP(&namespace, "namespace", "N", "", "Filter by workflow namespace") 100 | cmd.Flags().StringVarP(&runtime, "runtime", "r", "", "Filter by workflow runtime") 101 | cmd.Flags().StringVarP(&project, "project", "p", "", "Filter by workflow project") 102 | 103 | return cmd 104 | } 105 | 106 | func runWorkflowGet(ctx context.Context, uid string) error { 107 | workflow, err := cfConfig.NewClient().GraphQL().Workflow().Get(ctx, uid) 108 | if err != nil { 109 | return err 110 | } 111 | 112 | if workflow == nil { 113 | log.G(ctx).WithField("uid", uid).Warn("workflow was not found") 114 | return nil 115 | } 116 | 117 | tb := ansiterm.NewTabWriter(os.Stdout, 0, 0, 4, ' ', 0) 118 | _, err = fmt.Fprintln(tb, "NAME\tNAMESPACE\tRUNTIME\tPHASE\tUID") 119 | if err != nil { 120 | return err 121 | } 122 | 123 | _, err = fmt.Fprintf(tb, "%s\t%s\t%s\t%s\t%s\n", 124 | workflow.Metadata.Name, 125 | *workflow.Metadata.Namespace, 126 | workflow.Metadata.Runtime, 127 | workflow.Status.Phase, 128 | *workflow.Metadata.UID, 129 | ) 130 | if err != nil { 131 | return err 132 | } 133 | 134 | return tb.Flush() 135 | } 136 | 137 | func runWorkflowList(ctx context.Context, filterArgs platmodel.WorkflowsFilterArgs) error { 138 | workflows, err := cfConfig.NewClient().GraphQL().Workflow().List(ctx, filterArgs) 139 | if err != nil { 140 | return err 141 | } 142 | 143 | if len(workflows) == 0 { 144 | log.G(ctx).Warn("no workflows were found") 145 | return nil 146 | } 147 | 148 | tb := ansiterm.NewTabWriter(os.Stdout, 0, 0, 4, ' ', 0) 149 | _, err = fmt.Fprintln(tb, "NAME\tNAMESPACE\tRUNTIME\tPHASE\tUID") 150 | if err != nil { 151 | return err 152 | } 153 | 154 | for _, w := range workflows { 155 | _, err = fmt.Fprintf(tb, "%s\t%s\t%s\t%s\t%s\n", 156 | w.Metadata.Name, 157 | *w.Metadata.Namespace, 158 | w.Metadata.Runtime, 159 | w.Status.Phase, 160 | *w.Metadata.UID, 161 | ) 162 | if err != nil { 163 | return err 164 | } 165 | } 166 | 167 | return tb.Flush() 168 | } 169 | -------------------------------------------------------------------------------- /cmd/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "context" 19 | "syscall" 20 | 21 | "github.com/codefresh-io/cli-v2/cmd/commands" 22 | "github.com/codefresh-io/cli-v2/internal/log" 23 | "github.com/codefresh-io/cli-v2/internal/reporter" 24 | "github.com/codefresh-io/cli-v2/internal/util" 25 | cliutil "github.com/codefresh-io/cli-v2/internal/util/cli" 26 | 27 | "github.com/sirupsen/logrus" 28 | ) 29 | 30 | //go:generate sh -c "echo generating command docs... && cd .. && go run ./hack/cmd-docs/main.go" 31 | 32 | func main() { 33 | ctx := context.Background() 34 | lgr := log.FromLogrus(logrus.NewEntry(logrus.New()), &log.LogrusConfig{Level: "info"}) 35 | ctx = log.WithLogger(ctx, lgr) 36 | ctx = util.ContextWithCancelOnSignals(ctx, syscall.SIGINT, syscall.SIGTERM) 37 | 38 | c := commands.NewRoot() 39 | 40 | cliutil.AddCLIVersionCheck(c) 41 | 42 | lgr.AddPFlags(c) 43 | 44 | err := c.ExecuteContext(ctx) 45 | reporter.G().Close("", err) 46 | if err != nil { 47 | log.G(ctx).Fatal(err) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/assets/versions.css: -------------------------------------------------------------------------------- 1 | .md-header__title { 2 | display: flex; 3 | } 4 | 5 | .dropdown-caret { 6 | display: inline-block !important; 7 | position: absolute; 8 | right: 4px; 9 | } 10 | 11 | .fa .fa-caret-down { 12 | display: none !important; 13 | } 14 | 15 | .rst-other-versions { 16 | text-align: right; 17 | } 18 | 19 | .rst-other-versions > dl, .rst-other-versions dt, .rst-other-versions small { 20 | display: none; 21 | } 22 | 23 | .rst-other-versions > dl:first-child { 24 | display: flex !important; 25 | flex-direction: column; 26 | line-height: 0px !important; 27 | } 28 | 29 | .rst-versions.shift-up .rst-other-versions { 30 | display: flex !important; 31 | } 32 | 33 | .rst-versions .rst-other-versions { 34 | display: none; 35 | } 36 | 37 | /* Version Warning */ 38 | div[data-md-component=announce] { 39 | background-color: rgba(255,145,0,.1); 40 | } 41 | div[data-md-component=announce]>div#announce-msg{ 42 | color: var(--md-admonition-fg-color); 43 | font-size: .8rem; 44 | text-align: center; 45 | margin: 15px; 46 | } 47 | div[data-md-component=announce]>div#announce-msg>a{ 48 | color: var(--md-typeset-a-color); 49 | text-decoration: underline; 50 | } 51 | 52 | /* from https://assets.readthedocs.org/static/css/badge_only.css, 53 | most styles have to be overriden here */ 54 | .rst-versions{ 55 | position: relative !important; 56 | bottom: 0; 57 | left: 0; 58 | width: 100px !important; 59 | background: hsla(173, 100%, 24%, 1) !important; 60 | font-family: inherit !important; 61 | z-index: 0 !important; 62 | } 63 | .rst-versions a{ 64 | color:#2980B9; 65 | text-decoration:none 66 | } 67 | .rst-versions .rst-badge-small{ 68 | display:none 69 | } 70 | .rst-versions .rst-current-version{ 71 | padding:12px; 72 | background: hsla(173, 100%, 24%, 1) !important; 73 | display:block; 74 | text-align:right; 75 | font-size:90%; 76 | cursor:pointer; 77 | color: white !important; 78 | *zoom:1 79 | } 80 | .rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{ 81 | display:table;content:"" 82 | } 83 | .rst-versions .rst-current-version:after{ 84 | clear:both 85 | } 86 | .rst-versions .rst-current-version .fa{ 87 | color:#fcfcfc 88 | } 89 | .rst-versions .rst-current-version .fa-caret-down{ 90 | display: none; 91 | } 92 | .rst-versions.shift-up .rst-other-versions{ 93 | display:block 94 | } 95 | .rst-versions .rst-other-versions{ 96 | font-size:90%; 97 | padding:12px; 98 | color:gray; 99 | display:none 100 | } 101 | .rst-versions .rst-other-versions hr{ 102 | display: none !important; 103 | height: 0px !important; 104 | border: 0px; 105 | margin: 0px !important; 106 | padding: 0px; 107 | border-top: none !important; 108 | } 109 | .rst-versions .rst-other-versions dd{ 110 | display:inline-block; 111 | margin:0 112 | } 113 | .rst-versions .rst-other-versions dd a{ 114 | display:inline-block; 115 | padding: 1em 0em !important; 116 | color:#fcfcfc; 117 | font-size: .6rem !important; 118 | white-space: nowrap; 119 | text-overflow: ellipsis; 120 | overflow: hidden; 121 | width: 80px; 122 | } 123 | .rst-versions .rst-other-versions dd a:hover{ 124 | font-size: .7rem !important; 125 | font-weight: bold; 126 | } 127 | .rst-versions.rst-badge{ 128 | display: block !important; 129 | width: 100px !important; 130 | bottom: 0px !important; 131 | right: 0px !important; 132 | left:auto; 133 | border:none; 134 | text-align: center !important; 135 | line-height: 0; 136 | } 137 | .rst-versions.rst-badge .icon-book{ 138 | display: none; 139 | } 140 | .rst-versions.rst-badge .fa-book{ 141 | display: none !important; 142 | } 143 | .rst-versions.rst-badge.shift-up .rst-current-version{ 144 | text-align: left !important; 145 | } 146 | .rst-versions.rst-badge.shift-up .rst-current-version .fa-book{ 147 | display: none !important; 148 | } 149 | .rst-versions.rst-badge.shift-up .rst-current-version .icon-book{ 150 | display: none !important; 151 | } 152 | .rst-versions.rst-badge .rst-current-version{ 153 | width: 70px !important; 154 | height: 2.4rem !important; 155 | line-height:2.4rem !important; 156 | padding: 0px 5px !important; 157 | display: inline-block !important; 158 | font-size: .6rem !important; 159 | overflow: hidden !important; 160 | text-overflow: ellipsis !important; 161 | white-space: nowrap !important; 162 | text-align: left !important; 163 | } 164 | @media screen and (max-width: 768px){ 165 | .rst-versions{ 166 | width:85%; 167 | display:none 168 | } 169 | .rst-versions.shift{ 170 | display:block 171 | } 172 | } -------------------------------------------------------------------------------- /docs/assets/versions.js: -------------------------------------------------------------------------------- 1 | setTimeout(function() { 2 | const callbackName = 'callback_' + new Date().getTime(); 3 | window[callbackName] = function (response) { 4 | const div = document.createElement('div'); 5 | div.innerHTML = response.html; 6 | document.querySelector(".md-header__inner > .md-header__title").appendChild(div); 7 | const container = div.querySelector('.rst-versions'); 8 | var caret = document.createElement('div'); 9 | caret.innerHTML = "" 10 | caret.classList.add('dropdown-caret') 11 | div.querySelector('.rst-current-version').appendChild(caret); 12 | div.querySelector('.rst-current-version').addEventListener('click', function() { 13 | const classes = container.className.split(' '); 14 | const index = classes.indexOf('shift-up'); 15 | if (index === -1) { 16 | classes.push('shift-up'); 17 | } else { 18 | classes.splice(index, 1); 19 | } 20 | container.className = classes.join(' '); 21 | }); 22 | } 23 | 24 | var CSSLink = document.createElement('link'); 25 | CSSLink.rel='stylesheet'; 26 | CSSLink.src = '/assets/versions.css'; 27 | document.getElementsByTagName('head')[0].appendChild(CSSLink); 28 | 29 | var script = document.createElement('script'); 30 | script.src = 'https://cli-v2.readthedocs.io/_/api/v2/footer_html/?'+ 31 | 'callback=' + callbackName + '&project=cli-v2&page=&theme=mkdocs&format=jsonp&docroot=docs&source_suffix=.md&version=' + (window['READTHEDOCS_DATA'] || { version: 'latest' }).version; 32 | document.getElementsByTagName('head')[0].appendChild(script); 33 | }, 0); 34 | 35 | // VERSION WARNINGS 36 | window.addEventListener("DOMContentLoaded", function() { 37 | var rtdData = window['READTHEDOCS_DATA'] || { version: 'latest' }; 38 | if (rtdData.version === "latest") { 39 | document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for an unreleased version of Codefresh cli, click here to go to the latest stable version.
" 40 | } 41 | else if (rtdData.version !== "stable") { 42 | document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for a previous version of Codefresh cli, click here to go to the latest stable version.
" 43 | } 44 | }); -------------------------------------------------------------------------------- /docs/commands/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefresh-io/cli-v2/49a49fdf5b007bd7404cbc6592d4b9f14ad47ff2/docs/commands/.gitkeep -------------------------------------------------------------------------------- /docs/commands/cli-v2.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 2 | 3 | cli-v2 is used for installing and managing codefresh installations using gitops 4 | 5 | ### Synopsis 6 | 7 | cli-v2 is used for installing and managing codefresh installations using gitops. 8 | 9 | Most of the commands in this CLI require you to specify a personal access token 10 | for your git provider. This token is used to authenticate with your git provider 11 | when performing operations on the gitops repository, such as cloning it and 12 | pushing changes to it. 13 | 14 | It is recommended that you export the $GIT_TOKEN and $GIT_REPO environment 15 | variables in advanced to simplify the use of those commands. 16 | 17 | 18 | ``` 19 | cli-v2 [flags] 20 | ``` 21 | 22 | ### Options 23 | 24 | ``` 25 | --auth-context string Run the next command using a specific authentication context 26 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 27 | -h, --help help for cli-v2 28 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 29 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 30 | --request-timeout duration Request timeout (default 30s) 31 | ``` 32 | 33 | ### SEE ALSO 34 | 35 | * [cli-v2 account](cli-v2_account.md) - Account related commands 36 | * [cli-v2 cluster](cli-v2_cluster.md) - Manage clusters of Codefresh runtimes 37 | * [cli-v2 completion](cli-v2_completion.md) - Generates shell completion script. 38 | * [cli-v2 component](cli-v2_component.md) - Manage components of Codefresh runtimes 39 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 40 | * [cli-v2 git-source](cli-v2_git-source.md) - Manage git-sources of Codefresh runtimes 41 | * [cli-v2 helm](cli-v2_helm.md) - Helm related commands 42 | * [cli-v2 integration](cli-v2_integration.md) - Manage integrations with git providers, container registries and more 43 | * [cli-v2 pipeline](cli-v2_pipeline.md) - Manage pipelines of Codefresh runtimes 44 | * [cli-v2 product-release](cli-v2_product-release.md) - Manage product releases of Codefresh account 45 | * [cli-v2 runtime](cli-v2_runtime.md) - Manage Codefresh runtimes 46 | * [cli-v2 upgrade](cli-v2_upgrade.md) - Upgrades the cli 47 | * [cli-v2 version](cli-v2_version.md) - Show cli version 48 | * [cli-v2 workflow](cli-v2_workflow.md) - Manage workflows of Codefresh runtimes 49 | 50 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_account.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 account 2 | 3 | Account related commands 4 | 5 | ``` 6 | cli-v2 account [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for account 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 account validate-usage](cli-v2_account_validate-usage.md) - Validate usage of account resources 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_account_validate-usage.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 account validate-usage 2 | 3 | Validate usage of account resources 4 | 5 | ``` 6 | cli-v2 account validate-usage [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 account validate-usage 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | --context string The name of the kubeconfig context to use 19 | --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored 20 | --fail-condition string condition to validate [reached | exceeded] (default "exceeded") 21 | -h, --help help for validate-usage 22 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 23 | -n, --namespace string If present, the namespace scope for this CLI request 24 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 25 | --subject string subject to validate [clusters | applications]. All subjects when omitted 26 | -f, --values string specify values in a YAML file or a URL 27 | --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used 28 | ``` 29 | 30 | ### Options inherited from parent commands 31 | 32 | ``` 33 | --auth-context string Run the next command using a specific authentication context 34 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 35 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 36 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 37 | ``` 38 | 39 | ### SEE ALSO 40 | 41 | * [cli-v2 account](cli-v2_account.md) - Account related commands 42 | 43 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_cluster.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 cluster 2 | 3 | Manage clusters of Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 cluster [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for cluster 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 cluster add](cli-v2_cluster_add.md) - Add a cluster to a given runtime 29 | * [cli-v2 cluster create-argo-rollouts](cli-v2_cluster_create-argo-rollouts.md) - creates argo-rollouts component on the target cluster 30 | * [cli-v2 cluster list](cli-v2_cluster_list.md) - List all the clusters of a given runtime 31 | * [cli-v2 cluster remove](cli-v2_cluster_remove.md) - Removes a cluster from a given runtime 32 | 33 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_cluster_add.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 cluster add 2 | 3 | Add a cluster to a given runtime 4 | 5 | ``` 6 | cli-v2 cluster add [RUNTIME_NAME] [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 cluster add my-runtime --context my-context 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | --annotations stringToString Set metadata annotations (e.g. --annotation key=value) (default []) 19 | --context string The name of the kubeconfig context to use 20 | --dry-run 21 | -h, --help help for add 22 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 23 | --labels stringToString Set metadata labels (e.g. --label key=value) (default []) 24 | --name string Name of the cluster. If omitted, will use the context name 25 | -n, --namespace string If present, the namespace scope for this CLI request 26 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 27 | --skip-tls-validation Set true to skip TLS validation for cluster domain 28 | --system-namespace string Use different system namespace (default "kube-system") (default "kube-system") 29 | ``` 30 | 31 | ### Options inherited from parent commands 32 | 33 | ``` 34 | --auth-context string Run the next command using a specific authentication context 35 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 36 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 37 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 38 | ``` 39 | 40 | ### SEE ALSO 41 | 42 | * [cli-v2 cluster](cli-v2_cluster.md) - Manage clusters of Codefresh runtimes 43 | 44 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_cluster_create-argo-rollouts.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 cluster create-argo-rollouts 2 | 3 | creates argo-rollouts component on the target cluster 4 | 5 | ``` 6 | cli-v2 cluster create-argo-rollouts [RUNTIME_NAME] [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 cluster create-argo-rollouts my-runtime --server-url https://.gr7.us-east-1.eks.amazonaws.com --namespace managed-ns 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for create-argo-rollouts 19 | --namespace string Path to the kubeconfig file 20 | --server-url string The cluster's server url 21 | ``` 22 | 23 | ### Options inherited from parent commands 24 | 25 | ``` 26 | --auth-context string Run the next command using a specific authentication context 27 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 28 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 29 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 30 | --request-timeout duration Request timeout (default 30s) 31 | ``` 32 | 33 | ### SEE ALSO 34 | 35 | * [cli-v2 cluster](cli-v2_cluster.md) - Manage clusters of Codefresh runtimes 36 | 37 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_cluster_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 cluster list 2 | 3 | List all the clusters of a given runtime 4 | 5 | ``` 6 | cli-v2 cluster list [RUNTIME_NAME] [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 cluster list my-runtime 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for list 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --auth-context string Run the next command using a specific authentication context 25 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 26 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 27 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 28 | --request-timeout duration Request timeout (default 30s) 29 | ``` 30 | 31 | ### SEE ALSO 32 | 33 | * [cli-v2 cluster](cli-v2_cluster.md) - Manage clusters of Codefresh runtimes 34 | 35 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_cluster_remove.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 cluster remove 2 | 3 | Removes a cluster from a given runtime 4 | 5 | ``` 6 | cli-v2 cluster remove [RUNTIME_NAME] [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 cluster remove my-runtime --server-url https://.gr7.us-east-1.eks.amazonaws.com 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for remove 19 | --server-url string The cluster's server url 20 | ``` 21 | 22 | ### Options inherited from parent commands 23 | 24 | ``` 25 | --auth-context string Run the next command using a specific authentication context 26 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 27 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 28 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 29 | --request-timeout duration Request timeout (default 30s) 30 | ``` 31 | 32 | ### SEE ALSO 33 | 34 | * [cli-v2 cluster](cli-v2_cluster.md) - Manage clusters of Codefresh runtimes 35 | 36 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_completion.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 completion 2 | 3 | Generates shell completion script. 4 | 5 | ### Synopsis 6 | 7 | Generates shell completion script for your shell environment 8 | 9 | Example: 10 | 11 | source <(cli-v2 completion bash) 12 | 13 | 14 | ``` 15 | cli-v2 completion [bash|zsh|fish|powershell] [flags] 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for completion 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_component.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 component 2 | 3 | Manage components of Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 component [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for component 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 component list](cli-v2_component_list.md) - List all the components under a specific runtime 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_component_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 component list 2 | 3 | List all the components under a specific runtime 4 | 5 | ``` 6 | cli-v2 component list RUNTIME_NAME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 component list runtime_name 14 | 15 | ``` 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for list 21 | ``` 22 | 23 | ### Options inherited from parent commands 24 | 25 | ``` 26 | --auth-context string Run the next command using a specific authentication context 27 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 28 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 29 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 30 | --request-timeout duration Request timeout (default 30s) 31 | ``` 32 | 33 | ### SEE ALSO 34 | 35 | * [cli-v2 component](cli-v2_component.md) - Manage components of Codefresh runtimes 36 | 37 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config 2 | 3 | Manage Codefresh authentication contexts 4 | 5 | ### Synopsis 6 | 7 | By default, Codefresh authentication contexts are persisted at $HOME/.cfconfig. 8 | You can create, delete and list authentication contexts using the following 9 | commands, respectively: 10 | 11 | cli-v2 config create-context --api-key 12 | 13 | cli-v2 config delete-context 14 | 15 | cli-v2 config get-contexts 16 | 17 | 18 | ``` 19 | cli-v2 config [flags] 20 | ``` 21 | 22 | ### Options 23 | 24 | ``` 25 | -h, --help help for config 26 | ``` 27 | 28 | ### Options inherited from parent commands 29 | 30 | ``` 31 | --auth-context string Run the next command using a specific authentication context 32 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 33 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 34 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 35 | --request-timeout duration Request timeout (default 30s) 36 | ``` 37 | 38 | ### SEE ALSO 39 | 40 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 41 | * [cli-v2 config create-context](cli-v2_config_create-context.md) - Create a new Codefresh authentication context 42 | * [cli-v2 config current-context](cli-v2_config_current-context.md) - Shows the currently selected Codefresh authentication context 43 | * [cli-v2 config delete-context](cli-v2_config_delete-context.md) - Delete the specified authentication context 44 | * [cli-v2 config get-contexts](cli-v2_config_get-contexts.md) - Lists all Codefresh authentication contexts 45 | * [cli-v2 config get-runtime](cli-v2_config_get-runtime.md) - Gets the default runtime for the current authentication context 46 | * [cli-v2 config set-runtime](cli-v2_config_set-runtime.md) - Sets the default runtime name to use for the current authentication context 47 | * [cli-v2 config update-gitops-settings](cli-v2_config_update-gitops-settings.md) - Updates the account's GitOps settings (gitProvider|gitApiUrl|sharedConfigRepo) if possible 48 | * [cli-v2 config use-context](cli-v2_config_use-context.md) - Switch the current authentication context 49 | 50 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_create-context.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config create-context 2 | 3 | Create a new Codefresh authentication context 4 | 5 | ``` 6 | cli-v2 config create-context NAME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # Create a new context named 'test': 14 | 15 | cli-v2 config create-context test --api-key TOKEN 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | --api-key string API key 22 | --ca-cert string Codefresh Platform certificate file (for on-prem) 23 | -h, --help help for create-context 24 | --url string Codefresh system custom url (default "https://g.codefresh.io") 25 | ``` 26 | 27 | ### Options inherited from parent commands 28 | 29 | ``` 30 | --auth-context string Run the next command using a specific authentication context 31 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 32 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 33 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 34 | --request-timeout duration Request timeout (default 30s) 35 | ``` 36 | 37 | ### SEE ALSO 38 | 39 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 40 | 41 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_current-context.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config current-context 2 | 3 | Shows the currently selected Codefresh authentication context 4 | 5 | ``` 6 | cli-v2 config current-context [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # Shows the current context: 14 | 15 | cli-v2 config current-context 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for current-context 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_delete-context.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config delete-context 2 | 3 | Delete the specified authentication context 4 | 5 | ``` 6 | cli-v2 config delete-context CONTEXT [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # Deleting an authentication context name 'test': 14 | 15 | cli-v2 config delete-context test 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for delete-context 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_get-contexts.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config get-contexts 2 | 3 | Lists all Codefresh authentication contexts 4 | 5 | ``` 6 | cli-v2 config get-contexts [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # List all authentication contexts: 14 | 15 | cli-v2 config get-contexts 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for get-contexts 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_get-runtime.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config get-runtime 2 | 3 | Gets the default runtime for the current authentication context 4 | 5 | ``` 6 | cli-v2 config get-runtime [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # Prints the default runtime: 14 | 15 | cli-v2 config get-runtime 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for get-runtime 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_set-runtime.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config set-runtime 2 | 3 | Sets the default runtime name to use for the current authentication context 4 | 5 | ``` 6 | cli-v2 config set-runtime RUNTIME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # Sets the default runtime to 'runtime-2': 14 | 15 | cli-v2 config set-runtime runtime-2 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for set-runtime 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_update-gitops-settings.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config update-gitops-settings 2 | 3 | Updates the account's GitOps settings (gitProvider|gitApiUrl|sharedConfigRepo) if possible 4 | 5 | ``` 6 | cli-v2 config update-gitops-settings [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | --git-api-url string Your git server's API URL 13 | --git-provider ProviderType The git provider, one of: bitbucket|bitbucket-server|github|gitlab 14 | -h, --help help for update-gitops-settings 15 | --shared-config-repo string URL to the shared configurations repo 16 | --silent Disables the command wizard 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --auth-context string Run the next command using a specific authentication context 23 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 24 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 25 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 26 | --request-timeout duration Request timeout (default 30s) 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 32 | 33 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_config_use-context.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 config use-context 2 | 3 | Switch the current authentication context 4 | 5 | ``` 6 | cli-v2 config use-context CONTEXT [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # Switch to another authentication context: 14 | 15 | cli-v2 config use-context test 16 | ``` 17 | 18 | ### Options 19 | 20 | ``` 21 | -h, --help help for use-context 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --auth-context string Run the next command using a specific authentication context 28 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 29 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 30 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 31 | --request-timeout duration Request timeout (default 30s) 32 | ``` 33 | 34 | ### SEE ALSO 35 | 36 | * [cli-v2 config](cli-v2_config.md) - Manage Codefresh authentication contexts 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_git-source.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 git-source 2 | 3 | Manage git-sources of Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 git-source [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for git-source 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 git-source create](cli-v2_git-source_create.md) - Adds a new git-source to an existing runtime 29 | * [cli-v2 git-source delete](cli-v2_git-source_delete.md) - delete a git-source from a runtime 30 | * [cli-v2 git-source edit](cli-v2_git-source_edit.md) - edit a git-source of a runtime 31 | * [cli-v2 git-source list](cli-v2_git-source_list.md) - List all Codefresh git-sources of a given runtime 32 | 33 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_git-source_create.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 git-source create 2 | 3 | Adds a new git-source to an existing runtime 4 | 5 | ``` 6 | cli-v2 git-source create RUNTIME_NAME GITSOURCE_NAME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 git-source create runtime_name git-source-name --git-src-repo https://github.com/owner/repo-name/my-workflow 14 | 15 | ``` 16 | 17 | ### Options 18 | 19 | ``` 20 | --create-repo If true, will create the specified git-source repo in case it doesn't already exist 21 | --exclude string files to exclude. can be either filenames or a glob 22 | --git-src-repo string Repository URL [%sGIT_SOURCE_GIT_REPO] 23 | -h, --help help for create 24 | --include string files to include. can be either filenames or a glob 25 | ``` 26 | 27 | ### Options inherited from parent commands 28 | 29 | ``` 30 | --auth-context string Run the next command using a specific authentication context 31 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 32 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 33 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 34 | --request-timeout duration Request timeout (default 30s) 35 | ``` 36 | 37 | ### SEE ALSO 38 | 39 | * [cli-v2 git-source](cli-v2_git-source.md) - Manage git-sources of Codefresh runtimes 40 | 41 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_git-source_delete.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 git-source delete 2 | 3 | delete a git-source from a runtime 4 | 5 | ``` 6 | cli-v2 git-source delete RUNTIME_NAME GITSOURCE_NAME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 git-source delete runtime_name git-source_name 14 | 15 | ``` 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for delete 21 | ``` 22 | 23 | ### Options inherited from parent commands 24 | 25 | ``` 26 | --auth-context string Run the next command using a specific authentication context 27 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 28 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 29 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 30 | --request-timeout duration Request timeout (default 30s) 31 | ``` 32 | 33 | ### SEE ALSO 34 | 35 | * [cli-v2 git-source](cli-v2_git-source.md) - Manage git-sources of Codefresh runtimes 36 | 37 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_git-source_edit.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 git-source edit 2 | 3 | edit a git-source of a runtime 4 | 5 | ``` 6 | cli-v2 git-source edit RUNTIME_NAME GITSOURCE_NAME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 git-source edit runtime_name git-source_name --git-src-repo https://github.com/owner/repo-name.git/path/to/dir 14 | 15 | ``` 16 | 17 | ### Options 18 | 19 | ``` 20 | --exclude string files to exclude. can be either filenames or a glob 21 | --git-src-repo string Repository URL [%sGIT_SOURCE_GIT_REPO] 22 | -h, --help help for edit 23 | --include string files to include. can be either filenames or a glob 24 | ``` 25 | 26 | ### Options inherited from parent commands 27 | 28 | ``` 29 | --auth-context string Run the next command using a specific authentication context 30 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 31 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 32 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 33 | --request-timeout duration Request timeout (default 30s) 34 | ``` 35 | 36 | ### SEE ALSO 37 | 38 | * [cli-v2 git-source](cli-v2_git-source.md) - Manage git-sources of Codefresh runtimes 39 | 40 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_git-source_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 git-source list 2 | 3 | List all Codefresh git-sources of a given runtime 4 | 5 | ``` 6 | cli-v2 git-source list RUNTIME_NAME [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 git-source list my-runtime 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for list 19 | --include-internal If true, will include the Codefresh internal git-sources 20 | ``` 21 | 22 | ### Options inherited from parent commands 23 | 24 | ``` 25 | --auth-context string Run the next command using a specific authentication context 26 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 27 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 28 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 29 | --request-timeout duration Request timeout (default 30s) 30 | ``` 31 | 32 | ### SEE ALSO 33 | 34 | * [cli-v2 git-source](cli-v2_git-source.md) - Manage git-sources of Codefresh runtimes 35 | 36 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_helm.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 helm 2 | 3 | Helm related commands 4 | 5 | ``` 6 | cli-v2 helm [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for helm 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 helm validate](cli-v2_helm_validate.md) - Validate helm installation values file 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_helm_validate.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 helm validate 2 | 3 | Validate helm installation values file 4 | 5 | ``` 6 | cli-v2 helm validate [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 helm validate --values [--namespace ] [--version ] 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | --context string The name of the kubeconfig context to use 19 | --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored 20 | -h, --help help for validate 21 | --kubeconfig string Path to the kubeconfig file to use for CLI requests. 22 | -n, --namespace string If present, the namespace scope for this CLI request 23 | --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") 24 | -f, --values string specify values in a YAML file or a URL 25 | --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used 26 | ``` 27 | 28 | ### Options inherited from parent commands 29 | 30 | ``` 31 | --auth-context string Run the next command using a specific authentication context 32 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 33 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 34 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 35 | ``` 36 | 37 | ### SEE ALSO 38 | 39 | * [cli-v2 helm](cli-v2_helm.md) - Helm related commands 40 | 41 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration 2 | 3 | Manage integrations with git providers, container registries and more 4 | 5 | ``` 6 | cli-v2 integration [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for integration 13 | --runtime string Name of runtime to use 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --auth-context string Run the next command using a specific authentication context 20 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 21 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 22 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 23 | --request-timeout duration Request timeout (default 30s) 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 29 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 30 | 31 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git 2 | 3 | Manage your git integrations 4 | 5 | ``` 6 | cli-v2 integration git [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for git 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | --runtime string Name of runtime to use 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2 integration](cli-v2_integration.md) - Manage integrations with git providers, container registries and more 29 | * [cli-v2 integration git add](cli-v2_integration_git_add.md) - Add a new git integration 30 | * [cli-v2 integration git auth](cli-v2_integration_git_auth.md) - Authenticate user 31 | * [cli-v2 integration git deregister](cli-v2_integration_git_deregister.md) - Deregister user from a git integrations 32 | * [cli-v2 integration git edit](cli-v2_integration_git_edit.md) - Edit a git integration 33 | * [cli-v2 integration git get](cli-v2_integration_git_get.md) - Retrieve a git integration 34 | * [cli-v2 integration git list](cli-v2_integration_git_list.md) - List your git integrations 35 | * [cli-v2 integration git register](cli-v2_integration_git_register.md) - Register to a git integrations 36 | * [cli-v2 integration git remove](cli-v2_integration_git_remove.md) - Remove a git integration 37 | 38 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_add.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git add 2 | 3 | Add a new git integration 4 | 5 | ``` 6 | cli-v2 integration git add [NAME] [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | --account-admins-only If true, this integration would only be visible to account admins (default: false) 13 | --api-url string Git provider API Url 14 | -h, --help help for add 15 | --provider string One of bitbucket|bitbucket-server|github|gitlab (default "github") 16 | ``` 17 | 18 | ### Options inherited from parent commands 19 | 20 | ``` 21 | --auth-context string Run the next command using a specific authentication context 22 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 23 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 24 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 25 | --request-timeout duration Request timeout (default 30s) 26 | --runtime string Name of runtime to use 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 32 | 33 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_auth.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git auth 2 | 3 | Authenticate user 4 | 5 | ``` 6 | cli-v2 integration git auth [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for auth 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | --runtime string Name of runtime to use 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_deregister.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git deregister 2 | 3 | Deregister user from a git integrations 4 | 5 | ``` 6 | cli-v2 integration git deregister [NAME] [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for deregister 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | --runtime string Name of runtime to use 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_edit.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git edit 2 | 3 | Edit a git integration 4 | 5 | ``` 6 | cli-v2 integration git edit [NAME] [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | --account-admins-only If true, this integration would only be visible to account admins (default: false) 13 | --api-url string Git provider API Url 14 | -h, --help help for edit 15 | ``` 16 | 17 | ### Options inherited from parent commands 18 | 19 | ``` 20 | --auth-context string Run the next command using a specific authentication context 21 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 22 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 23 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 24 | --request-timeout duration Request timeout (default 30s) 25 | --runtime string Name of runtime to use 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 31 | 32 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_get.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git get 2 | 3 | Retrieve a git integration 4 | 5 | ``` 6 | cli-v2 integration git get [NAME] [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for get 13 | -o, --output string Output format, one of: yaml|yml|json (default "yaml") 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --auth-context string Run the next command using a specific authentication context 20 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 21 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 22 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 23 | --request-timeout duration Request timeout (default 30s) 24 | --runtime string Name of runtime to use 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 30 | 31 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git list 2 | 3 | List your git integrations 4 | 5 | ``` 6 | cli-v2 integration git list [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for list 13 | -o, --output string Output format, one of: list|yaml|yml|json (default "list") 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --auth-context string Run the next command using a specific authentication context 20 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 21 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 22 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 23 | --request-timeout duration Request timeout (default 30s) 24 | --runtime string Name of runtime to use 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 30 | 31 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_register.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git register 2 | 3 | Register to a git integrations 4 | 5 | ``` 6 | cli-v2 integration git register [NAME] [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for register 13 | --token string Authentication token 14 | --username string Authentication user name 15 | ``` 16 | 17 | ### Options inherited from parent commands 18 | 19 | ``` 20 | --auth-context string Run the next command using a specific authentication context 21 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 22 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 23 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 24 | --request-timeout duration Request timeout (default 30s) 25 | --runtime string Name of runtime to use 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 31 | 32 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_integration_git_remove.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 integration git remove 2 | 3 | Remove a git integration 4 | 5 | ``` 6 | cli-v2 integration git remove NAME [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for remove 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | --runtime string Name of runtime to use 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2 integration git](cli-v2_integration_git.md) - Manage your git integrations 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_pipeline.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 pipeline 2 | 3 | Manage pipelines of Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 pipeline [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for pipeline 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 pipeline get](cli-v2_pipeline_get.md) - Get a pipeline under a specific runtime and namespace 29 | * [cli-v2 pipeline list](cli-v2_pipeline_list.md) - List all the pipelines 30 | 31 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_pipeline_get.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 pipeline get 2 | 3 | Get a pipeline under a specific runtime and namespace 4 | 5 | ``` 6 | cli-v2 pipeline get --runtime --namespace --name [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 pipeline --runtime runtime_name --namespace namespace --name pipeline_name 14 | 15 | cli-v2 pipeline -r runtime_name -N namespace -n pipeline_name 16 | 17 | ``` 18 | 19 | ### Options 20 | 21 | ``` 22 | -h, --help help for get 23 | -n, --name string Name of target pipeline 24 | -N, --namespace string Namespace of target pipeline 25 | -r, --runtime string Runtime name of target pipeline 26 | ``` 27 | 28 | ### Options inherited from parent commands 29 | 30 | ``` 31 | --auth-context string Run the next command using a specific authentication context 32 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 33 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 34 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 35 | --request-timeout duration Request timeout (default 30s) 36 | ``` 37 | 38 | ### SEE ALSO 39 | 40 | * [cli-v2 pipeline](cli-v2_pipeline.md) - Manage pipelines of Codefresh runtimes 41 | 42 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_pipeline_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 pipeline list 2 | 3 | List all the pipelines 4 | 5 | ``` 6 | cli-v2 pipeline list [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 pipelines list 14 | 15 | cli-v2 pipelines list --runtime 16 | 17 | cli-v2 pipelines list -r 18 | 19 | ``` 20 | 21 | ### Options 22 | 23 | ``` 24 | -h, --help help for list 25 | -n, --name string Filter by pipeline name 26 | -N, --namespace string Filter by pipeline namespace 27 | -p, --project string Filter by pipeline project 28 | -r, --runtime string Filter by pipeline runtime 29 | ``` 30 | 31 | ### Options inherited from parent commands 32 | 33 | ``` 34 | --auth-context string Run the next command using a specific authentication context 35 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 36 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 37 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 38 | --request-timeout duration Request timeout (default 30s) 39 | ``` 40 | 41 | ### SEE ALSO 42 | 43 | * [cli-v2 pipeline](cli-v2_pipeline.md) - Manage pipelines of Codefresh runtimes 44 | 45 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_product-release.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 product-release 2 | 3 | Manage product releases of Codefresh account 4 | 5 | ``` 6 | cli-v2 product-release [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for product-release 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 product-release list](cli-v2_product-release_list.md) - List all product releases 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_product-release_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 product-release list 2 | 3 | List all product releases 4 | 5 | ``` 6 | cli-v2 product-release list [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 product-release list 14 | cli-v2 product-release list --page-limit 3 15 | cli-v2 product-release list --status RUNNING,FAILED --promotion-flows base-flow,flow-2 16 | 17 | ``` 18 | 19 | ### Options 20 | 21 | ``` 22 | -h, --help help for list 23 | --page-limit int page limit number, limited to 50 (default 20) 24 | --promotion-flows strings Filter by promotion flows, comma seperated array 25 | -s, --status strings Filter by statuses, comma seperated array RUNNING|SUCCEEDED|SUSPENDED|FAILED 26 | ``` 27 | 28 | ### Options inherited from parent commands 29 | 30 | ``` 31 | --auth-context string Run the next command using a specific authentication context 32 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 33 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 34 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 35 | --request-timeout duration Request timeout (default 30s) 36 | ``` 37 | 38 | ### SEE ALSO 39 | 40 | * [cli-v2 product-release](cli-v2_product-release.md) - Manage product releases of Codefresh account 41 | 42 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_runtime.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 runtime 2 | 3 | Manage Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 runtime [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for runtime 13 | --silent Disables the command wizard 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --auth-context string Run the next command using a specific authentication context 20 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 21 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 22 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 23 | --request-timeout duration Request timeout (default 30s) 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 29 | * [cli-v2 runtime list](cli-v2_runtime_list.md) - List all Codefresh runtimes 30 | * [cli-v2 runtime logs](cli-v2_runtime_logs.md) - Work with current runtime logs 31 | * [cli-v2 runtime uninstall](cli-v2_runtime_uninstall.md) - Uninstall a Codefresh runtime 32 | 33 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_runtime_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 runtime list 2 | 3 | List all Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 runtime list [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | cli-v2 runtime list 13 | ``` 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for list 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --auth-context string Run the next command using a specific authentication context 25 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 26 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 27 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 28 | --request-timeout duration Request timeout (default 30s) 29 | --silent Disables the command wizard 30 | ``` 31 | 32 | ### SEE ALSO 33 | 34 | * [cli-v2 runtime](cli-v2_runtime.md) - Manage Codefresh runtimes 35 | 36 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_runtime_logs.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 runtime logs 2 | 3 | Work with current runtime logs 4 | 5 | ``` 6 | cli-v2 runtime logs [--ingress-host ] [--download] [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | --download If true, will download logs from all componnents that consist of current runtime 13 | -h, --help help for logs 14 | --ingress-host string Set runtime ingress host 15 | ``` 16 | 17 | ### Options inherited from parent commands 18 | 19 | ``` 20 | --auth-context string Run the next command using a specific authentication context 21 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 22 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 23 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 24 | --request-timeout duration Request timeout (default 30s) 25 | --silent Disables the command wizard 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [cli-v2 runtime](cli-v2_runtime.md) - Manage Codefresh runtimes 31 | 32 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_runtime_uninstall.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 runtime uninstall 2 | 3 | Uninstall a Codefresh runtime 4 | 5 | ``` 6 | cli-v2 runtime uninstall [RUNTIME_NAME] [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | # To run this command you need to create a personal access token for your git provider 14 | # and provide it using: 15 | 16 | export GIT_TOKEN= 17 | 18 | # or with the flag: 19 | 20 | --git-token 21 | 22 | # Deletes a runtime 23 | 24 | cli-v2 runtime uninstall runtime-name --repo gitops_repo 25 | 26 | ``` 27 | 28 | ### Options 29 | 30 | ``` 31 | --disable-telemetry If true, will disable the analytics reporting for the uninstall process 32 | --force If true, will guarantee the runtime is removed from the platform, even in case of errors while cleaning the repo and the cluster 33 | -h, --help help for uninstall 34 | --wait-timeout duration How long to wait for the runtime components to be deleted (default 8m0s) 35 | ``` 36 | 37 | ### Options inherited from parent commands 38 | 39 | ``` 40 | --auth-context string Run the next command using a specific authentication context 41 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 42 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 43 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 44 | --request-timeout duration Request timeout (default 30s) 45 | --silent Disables the command wizard 46 | ``` 47 | 48 | ### SEE ALSO 49 | 50 | * [cli-v2 runtime](cli-v2_runtime.md) - Manage Codefresh runtimes 51 | 52 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_upgrade.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 upgrade 2 | 3 | Upgrades the cli 4 | 5 | ``` 6 | cli-v2 upgrade [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for upgrade 13 | -o, --ouput string Where to save the new binary (default: replace the old binary) 14 | --version string Specify a cli version to upgrade to 15 | ``` 16 | 17 | ### Options inherited from parent commands 18 | 19 | ``` 20 | --auth-context string Run the next command using a specific authentication context 21 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 22 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 23 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 24 | --request-timeout duration Request timeout (default 30s) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 30 | 31 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_version.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 version 2 | 3 | Show cli version 4 | 5 | ``` 6 | cli-v2 version [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for version 13 | --long display full version information 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --auth-context string Run the next command using a specific authentication context 20 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 21 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 22 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 23 | --request-timeout duration Request timeout (default 30s) 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 29 | 30 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_workflow.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 workflow 2 | 3 | Manage workflows of Codefresh runtimes 4 | 5 | ``` 6 | cli-v2 workflow [flags] 7 | ``` 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for workflow 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --auth-context string Run the next command using a specific authentication context 19 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 20 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 21 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 22 | --request-timeout duration Request timeout (default 30s) 23 | ``` 24 | 25 | ### SEE ALSO 26 | 27 | * [cli-v2](cli-v2.md) - cli-v2 is used for installing and managing codefresh installations using gitops 28 | * [cli-v2 workflow get](cli-v2_workflow_get.md) - Get a workflow under a specific uid 29 | * [cli-v2 workflow list](cli-v2_workflow_list.md) - List all the workflows 30 | 31 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_workflow_get.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 workflow get 2 | 3 | Get a workflow under a specific uid 4 | 5 | ``` 6 | cli-v2 workflow get UID [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 workflow get 0732b138-b74c-4a5e-b065-e23e6da0803d 14 | 15 | ``` 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for get 21 | ``` 22 | 23 | ### Options inherited from parent commands 24 | 25 | ``` 26 | --auth-context string Run the next command using a specific authentication context 27 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 28 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 29 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 30 | --request-timeout duration Request timeout (default 30s) 31 | ``` 32 | 33 | ### SEE ALSO 34 | 35 | * [cli-v2 workflow](cli-v2_workflow.md) - Manage workflows of Codefresh runtimes 36 | 37 | -------------------------------------------------------------------------------- /docs/commands/cli-v2_workflow_list.md: -------------------------------------------------------------------------------- 1 | ## cli-v2 workflow list 2 | 3 | List all the workflows 4 | 5 | ``` 6 | cli-v2 workflow list [flags] 7 | ``` 8 | 9 | ### Examples 10 | 11 | ``` 12 | 13 | cli-v2 workflows list 14 | 15 | cli-v2 workflows list --runtime 16 | 17 | cli-v2 workflows list -r 18 | 19 | ``` 20 | 21 | ### Options 22 | 23 | ``` 24 | -h, --help help for list 25 | -N, --namespace string Filter by workflow namespace 26 | -p, --project string Filter by workflow project 27 | -r, --runtime string Filter by workflow runtime 28 | ``` 29 | 30 | ### Options inherited from parent commands 31 | 32 | ``` 33 | --auth-context string Run the next command using a specific authentication context 34 | --cfconfig string Custom path for authentication contexts config file (default "/home/user") 35 | --insecure Disable certificate validation for TLS connections (e.g. to g.codefresh.io) 36 | --insecure-ingress-host Disable certificate validation of ingress host (default: false) 37 | --request-timeout duration Request timeout (default 30s) 38 | ``` 39 | 40 | ### SEE ALSO 41 | 42 | * [cli-v2 workflow](cli-v2_workflow.md) - Manage workflows of Codefresh runtimes 43 | 44 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 |

Argo Logo

2 | 3 | [![Codefresh build status]( https://g.codefresh.io/api/badges/pipeline/codefresh-inc/cli-v2%2Frelease?type=cf-1)]( https://g.codefresh.io/public/accounts/codefresh-inc/pipelines/new/60881f8199c9564ef31aac61) 4 | [![codecov](https://codecov.io/gh/codefresh-io/cli-v2/branch/main/graph/badge.svg?token=IDyZNfRUfY)](https://codecov.io/gh/codefresh-io/cli-v2) 5 | [![Documentation Status](https://readthedocs.org/projects/cli-v2/badge/?version=latest)](https://cli-v2.readthedocs.io/en/latest/?badge=latest) 6 | [![slack](https://img.shields.io/badge/slack-codefresh-brightgreen.svg?logo=slack)](https://codefresh.slack.com/archives/C01FG6M5KDY/) 7 | 8 | Codefresh cli got gitops-runtime management 9 | -------------------------------------------------------------------------------- /docs/releases/release_notes.md: -------------------------------------------------------------------------------- 1 | ### Using brew: 2 | 3 | ```bash 4 | # tap Codefresh homebrew repo 5 | brew tap codefresh-io/cli 6 | 7 | # install cf2 CLI 8 | brew install cf2 9 | 10 | # check the installation 11 | cf version 12 | ``` 13 | 14 | ### Linux 15 | 16 | ```bash 17 | # download and extract the binary 18 | curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.2.8/cf-linux-amd64.tar.gz | tar zx 19 | 20 | # move the binary to your $PATH 21 | mv ./cf-linux-amd64 /usr/local/bin/cf 22 | 23 | # check the installation 24 | cf version 25 | ``` 26 | 27 | ### Mac 28 | 29 | ```bash 30 | # download and extract the binary 31 | curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.2.8/cf-darwin-amd64.tar.gz | tar zx 32 | 33 | # move the binary to your $PATH 34 | mv ./cf-darwin-amd64 /usr/local/bin/cf 35 | 36 | # check the installation 37 | cf version 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs-material 2 | markdown_include 3 | pygments==2.15.0 -------------------------------------------------------------------------------- /hack/boilerplate.txt: -------------------------------------------------------------------------------- 1 | // Copyright YEAR The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | -------------------------------------------------------------------------------- /hack/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! -z "${GO_FLAGS}" ]]; then 4 | echo Building \"${OUT_FILE}\" with flags: \"${GO_FLAGS}\" starting at: \"${MAIN}\" 5 | for d in ${GO_FLAGS}; do 6 | export $d 7 | done 8 | fi 9 | 10 | go build -ldflags=" \ 11 | -extldflags '-static' \ 12 | -X 'github.com/codefresh-io/cli-v2/internal/store.binaryName=${BINARY_NAME}' \ 13 | -X 'github.com/codefresh-io/cli-v2/internal/store.version=${VERSION}' \ 14 | -X 'github.com/codefresh-io/cli-v2/internal/store.buildDate=${BUILD_DATE}' \ 15 | -X 'github.com/codefresh-io/cli-v2/internal/store.gitCommit=${GIT_COMMIT}' \ 16 | -X 'github.com/codefresh-io/cli-v2/internal/store.AddClusterDefURL=${ADD_CLUSTER_DEF_URL}' \ 17 | -X 'github.com/codefresh-io/cli-v2/internal/store.SegmentWriteKey=${SEGMENT_WRITE_KEY}'" \ 18 | -v -o ${OUT_FILE} ${MAIN} 19 | -------------------------------------------------------------------------------- /hack/check_worktree.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "checking worktree..." 4 | res=$(git status -s) 5 | if [[ -z "$res" ]]; then 6 | echo worktree is clean! 7 | else 8 | echo error: working tree is not clean! make sure you run 'make pre-push' and commit the changes. 9 | GIT_PAGER=cat git diff --minimal 10 | exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /hack/cmd-docs/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "fmt" 19 | "io/fs" 20 | "log" 21 | "os" 22 | "path/filepath" 23 | "strings" 24 | 25 | "github.com/codefresh-io/cli-v2/cmd/commands" 26 | 27 | "github.com/spf13/cobra/doc" 28 | ) 29 | 30 | const ( 31 | outputDir = "./docs/commands" 32 | home = "/home/user" 33 | ) 34 | 35 | var orgHome = os.Getenv("HOME") 36 | 37 | func main() { 38 | log.Printf("org home: %s", orgHome) 39 | log.Printf("new home: %s", home) 40 | 41 | if err := doc.GenMarkdownTree(commands.NewRoot(), outputDir); err != nil { 42 | log.Fatal(fmt.Errorf("failed generating markdown tree: %w", err)) 43 | } 44 | 45 | if err := replaceHome(); err != nil { 46 | log.Fatal(fmt.Errorf("failed replacing home: %w", err)) 47 | } 48 | } 49 | 50 | func replaceHome() error { 51 | files, err := fs.Glob(os.DirFS(outputDir), "*.md") 52 | if err != nil { 53 | return fmt.Errorf("failed globbing files: %w", err) 54 | } 55 | 56 | for _, fname := range files { 57 | fname = filepath.Join(outputDir, fname) 58 | data, err := os.ReadFile(fname) 59 | if err != nil { 60 | return fmt.Errorf("failed reading file: %w", err) 61 | } 62 | 63 | datastr := string(data) 64 | newstr := strings.ReplaceAll(datastr, orgHome, home) 65 | 66 | if datastr == newstr { 67 | continue 68 | } 69 | 70 | log.Printf("replaced home at: %s", fname) 71 | 72 | err = os.WriteFile(fname, []byte(newstr), 0422) 73 | if err != nil { 74 | return fmt.Errorf("failed writing file: %w", err) 75 | } 76 | } 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /hack/license.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "flag" 19 | "fmt" 20 | "io" 21 | "log" 22 | "os" 23 | "path/filepath" 24 | "strings" 25 | ) 26 | 27 | func main() { 28 | var ( 29 | licenseFile string 30 | year int 31 | ) 32 | 33 | flag.StringVar(&licenseFile, "license", "", "license file path") 34 | flag.IntVar(&year, "year", 0, "year") 35 | flag.Parse() 36 | 37 | if licenseFile == "" { 38 | panic("--license required") 39 | } 40 | 41 | if year <= 0 { 42 | panic("--year positive int required") 43 | } 44 | 45 | d, err := os.ReadFile(licenseFile) 46 | die(err) 47 | 48 | license := string(d) 49 | 50 | license = strings.ReplaceAll(license, "YEAR", fmt.Sprintf("%d", year)) 51 | 52 | die(filepath.Walk(flag.Arg(0), func(path string, info os.FileInfo, err error) error { 53 | die(err) 54 | if info.IsDir() { 55 | return nil 56 | } 57 | if filepath.Ext(path) != ".go" { 58 | return nil 59 | } 60 | f, err := os.OpenFile(path, os.O_RDWR, info.Mode()) 61 | die(err) 62 | defer f.Close() 63 | 64 | data, err := io.ReadAll(f) 65 | die(err) 66 | 67 | s := string(data) 68 | 69 | if strings.HasPrefix(strings.TrimSpace(s), strings.TrimSpace(license)) { 70 | return nil 71 | } 72 | 73 | log.Print(path) 74 | 75 | s = license + s 76 | _, err = f.WriteAt([]byte(s), 0) 77 | die(err) 78 | return nil 79 | })) 80 | } 81 | 82 | func die(err error) { 83 | if err != nil { 84 | log.Fatal(err) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /hack/release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | if [[ -z "$GIT_REPO" ]]; then 3 | echo "error: git repo not defined" 4 | exit 1 5 | fi 6 | 7 | if [[ -z "$VERSION" ]]; then 8 | echo "error: missing VERSION" 9 | exit 1 10 | fi 11 | 12 | echo "$VERSION" > ./dist/version.txt 13 | 14 | if [[ -z "$GITHUB_TOKEN" ]]; then 15 | echo "error: GITHUB_TOKEN token not defined" 16 | exit 1 17 | fi 18 | 19 | if [[ -z "$PRERELEASE" ]]; then 20 | PRERELEASE=false 21 | fi 22 | 23 | echo "uploading files:" 24 | ls -1a ./dist/version.txt ./dist/*.tar.gz ./dist/*.sha256 25 | echo "" 26 | 27 | FILE="./docs/releases/release_notes.md" 28 | echo "using release notes file: ./docs/releases/release_notes.md" 29 | cat $FILE | head -n 5 && echo ... 30 | echo "" 31 | 32 | if [[ "$DRY_RUN" == "1" ]]; then 33 | echo "gh release create --repo $GIT_REPO -t $VERSION -F $FILE --prerelease=$PRERELEASE $VERSION ./dist/version.txt ./dist/*.tar.gz ./dist/*.sha256" 34 | exit 0 35 | fi 36 | 37 | gh release create --repo $GIT_REPO -t $VERSION -F $FILE --prerelease=$PRERELEASE $VERSION ./dist/version.txt ./dist/*.tar.gz ./dist/*.sha256 38 | -------------------------------------------------------------------------------- /hack/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | echo "" > coverage.txt 5 | 6 | for d in $(go list ./... | grep -v vendor); do 7 | go test -v -race -coverprofile=profile.out -covermode=atomic $d 8 | if [ -f profile.out ]; then 9 | cat profile.out >> coverage.txt 10 | rm profile.out 11 | fi 12 | done 13 | -------------------------------------------------------------------------------- /internal/config/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // // Copyright 2025 The Codefresh Authors. 16 | // // 17 | // // Licensed under the Apache License, Version 2.0 (the "License"); 18 | // // you may not use this file except in compliance with the License. 19 | // // You may obtain a copy of the License at 20 | // // 21 | // // http://www.apache.org/licenses/LICENSE-2.0 22 | // // 23 | // // Unless required by applicable law or agreed to in writing, software 24 | // // distributed under the License is distributed on an "AS IS" BASIS, 25 | // // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 | // // See the License for the specific language governing permissions and 27 | // // limitations under the License. 28 | 29 | package config 30 | 31 | // import ( 32 | // "bytes" 33 | // "context" 34 | // "testing" 35 | 36 | // "github.com/codefresh-io/go-sdk/pkg/codefresh" 37 | // "github.com/stretchr/testify/assert" 38 | // "github.com/stretchr/testify/mock" 39 | // ) 40 | 41 | // func TestConfig_Write(t *testing.T) { 42 | // tests := map[string]struct { 43 | // config ConfigImpl 44 | // beforeFn func(usersMock *mocks.UsersAPI) 45 | // assertFn func(t *testing.T, usersMock *mocks.UsersAPI, out string, err error) 46 | // }{ 47 | // "Basic": { 48 | // config: ConfigImpl{ 49 | // Contexts: map[string]*AuthContext{ 50 | // "foo": { 51 | // Type: "APIKey", 52 | // Name: "foo", 53 | // Token: "123qwe", 54 | // URL: "https://g.codefresh.io", 55 | // }, 56 | // }, 57 | // CurrentContext: "foo", 58 | // }, 59 | // beforeFn: func(usersMock *mocks.UsersAPI) { 60 | // usersMock.On("GetCurrent", mock.Anything).Return(&codefresh.User{ 61 | // Name: "foo", 62 | // Accounts: []codefresh.Account{ 63 | // { 64 | // Name: "bar", 65 | // }, 66 | // }, 67 | // ActiveAccountName: "bar", 68 | // }, nil) 69 | // }, 70 | // assertFn: func(t *testing.T, usersMock *mocks.UsersAPI, out string, _ error) { 71 | // usersMock.AssertCalled(t, "GetCurrent", mock.Anything) 72 | // assert.Contains(t, out, "foo") 73 | // assert.Contains(t, out, "VALID") 74 | // assert.Contains(t, out, "bar") 75 | // assert.Contains(t, out, "*") 76 | // }, 77 | // }, 78 | // } 79 | 80 | // orgCf := NewCodefresh 81 | // defer func() { NewCodefresh = orgCf }() 82 | 83 | // for tname, tt := range tests { 84 | // t.Run(tname, func(t *testing.T) { 85 | // usersMock := &mocks.UsersAPI{} 86 | // cfMock := &mocks.Codefresh{} 87 | // cfMock.On("Users").Return(usersMock) 88 | // NewCodefresh = func(opts *codefresh.ClientOptions) codefresh.Codefresh { return cfMock } 89 | 90 | // tt.beforeFn(usersMock) 91 | // w := &bytes.Buffer{} 92 | // err := tt.config.Write(context.Background(), w) 93 | 94 | // tt.assertFn(t, usersMock, w.String(), err) 95 | // }) 96 | // } 97 | // } 98 | 99 | // func TestConfig_GetUser(t *testing.T) { 100 | // tests := map[string]struct { 101 | // config ConfigImpl 102 | // beforeFn func(usersMock *mocks.UsersAPI) 103 | // assertFn func(t *testing.T, user *codefresh.User, usersMock *mocks.UsersAPI, err error) 104 | // }{ 105 | // "Basic": { 106 | // config: ConfigImpl{ 107 | // Contexts: map[string]*AuthContext{ 108 | // "foo": { 109 | // Type: "APIKey", 110 | // Name: "foo", 111 | // Token: "123qwe", 112 | // URL: "https://g.codefresh.io", 113 | // }, 114 | // }, 115 | // CurrentContext: "foo", 116 | // }, 117 | // beforeFn: func(usersMock *mocks.UsersAPI) { 118 | // usersMock.On("GetCurrent", mock.Anything).Return(&codefresh.User{ 119 | // Name: "foo", 120 | // Accounts: []codefresh.Account{ 121 | // { 122 | // Name: "bar", 123 | // ID: "1234", 124 | // }, 125 | // }, 126 | // ActiveAccountName: "bar", 127 | // }, nil) 128 | // }, 129 | // assertFn: func(t *testing.T, user *codefresh.User, usersMock *mocks.UsersAPI, _ error) { 130 | // usersMock.AssertCalled(t, "GetCurrent", mock.Anything) 131 | // assert.Equal(t, "bar", user.GetActiveAccount().Name) 132 | // assert.Equal(t, "1234", user.GetActiveAccount().ID) 133 | // }, 134 | // }, 135 | // } 136 | 137 | // orgCf := NewCodefresh 138 | // defer func() { NewCodefresh = orgCf }() 139 | 140 | // for tname, tt := range tests { 141 | // t.Run(tname, func(t *testing.T) { 142 | // usersMock := &mocks.UsersAPI{} 143 | // cfMock := &mocks.Codefresh{} 144 | // cfMock.On("Users").Return(usersMock) 145 | // NewCodefresh = func(opts *codefresh.ClientOptions) codefresh.Codefresh { return cfMock } 146 | 147 | // tt.beforeFn(usersMock) 148 | // user, err := tt.config.GetUser(context.Background()) 149 | 150 | // tt.assertFn(t, user, usersMock, err) 151 | // }) 152 | // } 153 | // } 154 | -------------------------------------------------------------------------------- /internal/git/mocks/roundTripper.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: net/http (interfaces: RoundTripper) 17 | 18 | // Package mocks is a generated GoMock package. 19 | package mocks 20 | 21 | import ( 22 | http "net/http" 23 | reflect "reflect" 24 | 25 | gomock "github.com/golang/mock/gomock" 26 | ) 27 | 28 | // MockRoundTripper is a mock of RoundTripper interface. 29 | type MockRoundTripper struct { 30 | ctrl *gomock.Controller 31 | recorder *MockRoundTripperMockRecorder 32 | } 33 | 34 | // MockRoundTripperMockRecorder is the mock recorder for MockRoundTripper. 35 | type MockRoundTripperMockRecorder struct { 36 | mock *MockRoundTripper 37 | } 38 | 39 | // NewMockRoundTripper creates a new mock instance. 40 | func NewMockRoundTripper(ctrl *gomock.Controller) *MockRoundTripper { 41 | mock := &MockRoundTripper{ctrl: ctrl} 42 | mock.recorder = &MockRoundTripperMockRecorder{mock} 43 | return mock 44 | } 45 | 46 | // EXPECT returns an object that allows the caller to indicate expected use. 47 | func (m *MockRoundTripper) EXPECT() *MockRoundTripperMockRecorder { 48 | return m.recorder 49 | } 50 | 51 | // RoundTrip mocks base method. 52 | func (m *MockRoundTripper) RoundTrip(arg0 *http.Request) (*http.Response, error) { 53 | m.ctrl.T.Helper() 54 | ret := m.ctrl.Call(m, "RoundTrip", arg0) 55 | ret0, _ := ret[0].(*http.Response) 56 | ret1, _ := ret[1].(error) 57 | return ret0, ret1 58 | } 59 | 60 | // RoundTrip indicates an expected call of RoundTrip. 61 | func (mr *MockRoundTripperMockRecorder) RoundTrip(arg0 interface{}) *gomock.Call { 62 | mr.mock.ctrl.T.Helper() 63 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoundTrip", reflect.TypeOf((*MockRoundTripper)(nil).RoundTrip), arg0) 64 | } 65 | -------------------------------------------------------------------------------- /internal/git/provider.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "crypto/tls" 20 | "crypto/x509" 21 | "fmt" 22 | "net/http" 23 | "net/url" 24 | "os" 25 | "slices" 26 | 27 | "github.com/codefresh-io/cli-v2/internal/store" 28 | 29 | "github.com/manifoldco/promptui" 30 | "golang.org/x/exp/maps" 31 | ) 32 | 33 | //go:generate mockgen -destination=./mocks/roundTripper.go -package=mocks net/http RoundTripper 34 | 35 | type ( 36 | ProviderType string 37 | 38 | // Provider represents a git provider 39 | Provider interface { 40 | ApiURL() string 41 | IsCloud() bool 42 | Type() ProviderType 43 | VerifyRuntimeToken(ctx context.Context, auth Auth) error 44 | } 45 | 46 | Auth struct { 47 | Username string 48 | Password string 49 | CertFile string 50 | } 51 | ) 52 | 53 | var ( 54 | CYAN = "\033[36m" 55 | COLOR_RESET = "\033[0m" 56 | 57 | cloudProvidersByDomain = map[string]ProviderType{ 58 | BITBUCKET_CLOUD_DOMAIN: BITBUCKET, 59 | GITHUB_CLOUD_DOMAIN: GITHUB, 60 | GITLAB_CLOUD_DOMAIN: GITLAB, 61 | } 62 | 63 | providersByType = map[ProviderType]func(string, *http.Client) (Provider, error){ 64 | BITBUCKET: NewBitbucketProvider, 65 | BITBUCKET_SERVER: NewBitbucketServerProvider, 66 | GITHUB: NewGithubProvider, 67 | GITHUB_ENT: NewGithubProvider, // for backward compatability 68 | GITLAB: NewGitlabProvider, 69 | } 70 | 71 | legalProviders = maps.Keys(providersByType) 72 | GetProvider = getProvider 73 | ) 74 | 75 | func (pt *ProviderType) String() string { 76 | if pt == nil { 77 | return "" 78 | } 79 | 80 | return string(*pt) 81 | } 82 | 83 | func (pt *ProviderType) Set(s string) error { 84 | *pt = ProviderType(s) 85 | if !slices.Contains(legalProviders, *pt) { 86 | return fmt.Errorf("value \"%s\" does not match ProviderType", s) 87 | } 88 | 89 | return nil 90 | } 91 | 92 | func (pt *ProviderType) Type() string { 93 | return "ProviderType" 94 | } 95 | 96 | func (a *Auth) GetCertificate() ([]byte, error) { 97 | if a.CertFile == "" { 98 | return nil, nil 99 | } 100 | 101 | return os.ReadFile(a.CertFile) 102 | } 103 | 104 | func DefaultTransportWithCa(certFile string) (*http.Transport, error) { 105 | rootCAs, err := getRootCas(certFile) 106 | if err != nil { 107 | return nil, err 108 | } 109 | 110 | transport := http.DefaultTransport.(*http.Transport).Clone() 111 | transport.TLSClientConfig = &tls.Config{RootCAs: rootCAs} 112 | return transport, nil 113 | } 114 | 115 | func getRootCas(certFile string) (*x509.CertPool, error) { 116 | rootCAs, err := x509.SystemCertPool() 117 | if err != nil { 118 | return nil, fmt.Errorf("failed getting system certificates: %w", err) 119 | } 120 | 121 | if rootCAs == nil { 122 | rootCAs = x509.NewCertPool() 123 | } 124 | 125 | if certFile == "" { 126 | return rootCAs, nil 127 | } 128 | 129 | certs, err := os.ReadFile(certFile) 130 | if err != nil { 131 | return nil, fmt.Errorf("failed reading certificate from %s: %w", certFile, err) 132 | } 133 | 134 | // Append our cert to the system pool 135 | if ok := rootCAs.AppendCertsFromPEM(certs); !ok { 136 | return nil, fmt.Errorf("failed adding certificate to rootCAs") 137 | } 138 | 139 | return rootCAs, nil 140 | } 141 | 142 | func getProvider(providerType ProviderType, cloneURL, certFile string) (Provider, error) { 143 | transport, err := DefaultTransportWithCa(certFile) 144 | if err != nil { 145 | return nil, err 146 | } 147 | 148 | client := &http.Client{ 149 | Transport: transport, 150 | } 151 | 152 | u, err := url.Parse(cloneURL) 153 | if err != nil { 154 | return nil, err 155 | } 156 | 157 | inferredType, ok := cloudProvidersByDomain[u.Hostname()] 158 | if ok { 159 | if providerType != "" && providerType != inferredType { 160 | return nil, fmt.Errorf("supplied provider \"%s\" does not match inferred cloud provider \"%s\" for url \"%s\"", providerType, inferredType, cloneURL) 161 | } 162 | 163 | providerType = inferredType 164 | } 165 | 166 | if providerType != "" { 167 | fn, ok := providersByType[providerType] 168 | if !ok { 169 | return nil, fmt.Errorf("invalid git provider %s", providerType) 170 | } 171 | 172 | return fn(cloneURL, client) 173 | } 174 | 175 | if !store.Get().Silent { 176 | provider := getGitProviderFromUserSelect(cloneURL, client) 177 | if provider != nil { 178 | return provider, nil 179 | } 180 | } 181 | 182 | return nil, fmt.Errorf("failed getting git provider for url %s", cloneURL) 183 | } 184 | 185 | func getGitProviderFromUserSelect(baseURL string, client *http.Client) Provider { 186 | var providers = map[string]func(string, *http.Client) (Provider, error){ 187 | "Bitbucket": NewBitbucketServerProvider, 188 | "GitHub": NewGithubProvider, 189 | "GitLab": NewGitlabProvider, 190 | } 191 | 192 | templates := &promptui.SelectTemplates{ 193 | Selected: "{{ .Name | yellow }}", 194 | } 195 | 196 | labelStr := fmt.Sprintf("%vSelect git provider%v", CYAN, COLOR_RESET) 197 | 198 | prompt := promptui.Select{ 199 | Label: labelStr, 200 | Items: maps.Keys(providers), 201 | Templates: templates, 202 | } 203 | 204 | _, label, err := prompt.Run() 205 | if err != nil { 206 | return nil 207 | } 208 | 209 | if fn, ok := providers[label]; ok { 210 | provider, _ := fn(baseURL, client) 211 | return provider 212 | } 213 | 214 | return nil 215 | } 216 | -------------------------------------------------------------------------------- /internal/git/provider_bitbucket-server.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "errors" 20 | "fmt" 21 | "net/http" 22 | "net/url" 23 | "path" 24 | 25 | httputil "github.com/codefresh-io/cli-v2/internal/util/http" 26 | ) 27 | 28 | type ( 29 | bitbucketServer struct { 30 | providerType ProviderType 31 | apiURL *url.URL 32 | c *http.Client 33 | } 34 | 35 | createRepoBody struct { 36 | Name string `json:"name"` 37 | } 38 | ) 39 | 40 | const ( 41 | BITBUCKET_SERVER_REST_ENDPOINT = "/rest/api/1.0" 42 | BITBUCKET_SERVER ProviderType = "bitbucket-server" 43 | ) 44 | 45 | func NewBitbucketServerProvider(baseURL string, client *http.Client) (Provider, error) { 46 | u, err := url.Parse(baseURL) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | if u.Host == BITBUCKET_CLOUD_DOMAIN { 52 | return nil, fmt.Errorf("wrong domain for bitbucket-server provider: \"%s\"\n maybe you meant to use \"bitbucket\" for the cloud git provider?", baseURL) 53 | } 54 | 55 | if u.Path == "" { 56 | u.Path = BITBUCKET_SERVER_REST_ENDPOINT 57 | } 58 | 59 | return &bitbucketServer{ 60 | providerType: BITBUCKET_SERVER, 61 | apiURL: u, 62 | c: client, 63 | }, nil 64 | } 65 | 66 | func (bbs *bitbucketServer) ApiURL() string { 67 | return bbs.apiURL.String() 68 | } 69 | 70 | func (_ *bitbucketServer) IsCloud() bool { 71 | return false 72 | } 73 | 74 | func (bbs *bitbucketServer) Type() ProviderType { 75 | return bbs.providerType 76 | } 77 | 78 | func (bbs *bitbucketServer) VerifyRuntimeToken(ctx context.Context, auth Auth) error { 79 | return bbs.checkProjectAdminPermission(ctx, auth.Password) 80 | } 81 | 82 | // POST to users//repos with an invalid repo name (starts with "!"). 83 | // if it returns 400 - the token has "Project admin" permission 84 | // otherwise - the token does not have the permission 85 | func (bbs *bitbucketServer) checkProjectAdminPermission(ctx context.Context, token string) error { 86 | username, err := bbs.getCurrentUsername(ctx, token) 87 | if err != nil { 88 | return fmt.Errorf("failed checking Project admin permission: %w", err) 89 | } 90 | 91 | urlPath := fmt.Sprintf("users/%s/repos", username) 92 | body := &createRepoBody{ 93 | Name: "!invalid", 94 | } 95 | res, err := bbs.request(ctx, token, http.MethodPost, urlPath, body) 96 | if err != nil { 97 | return fmt.Errorf("failed checking Project admin permission: %w", err) 98 | } 99 | defer res.Body.Close() 100 | 101 | if res.StatusCode != http.StatusBadRequest { 102 | return errors.New("git-token is invalid or missing required \"Project admin\" scope") 103 | } 104 | 105 | return nil 106 | } 107 | 108 | // HEAD to application-properties - this endpoint does not require any permission (or auth header). 109 | // but any request with a valid token has the X-AUSERNAME response header with the user name in it. 110 | func (bbs *bitbucketServer) getCurrentUsername(ctx context.Context, token string) (string, error) { 111 | res, err := bbs.request(ctx, token, http.MethodHead, "application-properties", nil) 112 | if err != nil { 113 | return "", fmt.Errorf("failed getting current user: %w", err) 114 | } 115 | defer res.Body.Close() 116 | 117 | username := res.Header.Get("X-AUSERNAME") 118 | if username == "" { 119 | return "", errors.New("invalid token") 120 | } 121 | 122 | return username, nil 123 | } 124 | 125 | func (bbs *bitbucketServer) request(ctx context.Context, token, method, urlPath string, body interface{}) (*http.Response, error) { 126 | urlClone := *bbs.apiURL 127 | urlClone.Path = path.Join(urlClone.Path, urlPath) 128 | headers := map[string]string{ 129 | "Authorization": "Bearer " + token, 130 | "Accept": "application/json", 131 | "Content-Type": "application/json", 132 | } 133 | req, err := httputil.NewRequest(ctx, method, urlClone.String(), headers, body) 134 | if err != nil { 135 | return nil, err 136 | } 137 | 138 | return bbs.c.Do(req) 139 | } 140 | -------------------------------------------------------------------------------- /internal/git/provider_bitbucket.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "encoding/base64" 20 | "errors" 21 | "fmt" 22 | "net/http" 23 | "net/url" 24 | "path" 25 | "strings" 26 | 27 | httputil "github.com/codefresh-io/cli-v2/internal/util/http" 28 | ) 29 | 30 | type ( 31 | bitbucket struct { 32 | providerType ProviderType 33 | apiURL *url.URL 34 | c *http.Client 35 | } 36 | ) 37 | 38 | const ( 39 | BITBUCKET_CLOUD_DOMAIN = "bitbucket.org" 40 | BITBUCKET_REST_ENDPOINT = "/api/2.0" 41 | BITBUCKET ProviderType = "bitbucket" 42 | ) 43 | 44 | var ( 45 | runtimeScopes = [][]string{ 46 | {"repository:admin"}, 47 | {"account:read", "account:write"}, 48 | {"team", "team:write"}, 49 | {"webhook"}, 50 | } 51 | 52 | scopesApiMap = map[string]string{ 53 | "account:read account:write": "account:read", 54 | "repository:admin repository:write": "repository:write", 55 | "repository:admin": "repository:admin", 56 | "team team:write": "workspace membership:write (team:write)", 57 | "webhook": "webhook:read and write", 58 | } 59 | ) 60 | 61 | func NewBitbucketProvider(baseURL string, client *http.Client) (Provider, error) { 62 | u, err := url.Parse(baseURL) 63 | if err != nil { 64 | return nil, err 65 | } 66 | 67 | if u.Host != BITBUCKET_CLOUD_DOMAIN { 68 | return nil, fmt.Errorf("wrong domain for bitbucket provider: \"%s\", expected \"%s\"\n maybe you meant to use \"bitbucket-server\" for on-prem git provider?", baseURL, BITBUCKET_CLOUD_DOMAIN) 69 | } 70 | 71 | u.Path = BITBUCKET_REST_ENDPOINT 72 | return &bitbucket{ 73 | providerType: BITBUCKET, 74 | apiURL: u, 75 | c: client, 76 | }, nil 77 | } 78 | 79 | func (bb *bitbucket) ApiURL() string { 80 | return bb.apiURL.String() 81 | } 82 | 83 | func (_ *bitbucket) IsCloud() bool { 84 | return true 85 | } 86 | 87 | func (bb *bitbucket) Type() ProviderType { 88 | return bb.providerType 89 | } 90 | 91 | func (bb *bitbucket) VerifyRuntimeToken(ctx context.Context, auth Auth) error { 92 | if auth.Password == "" { 93 | return fmt.Errorf("user name is require for bitbucket cloud request") 94 | } 95 | 96 | return bb.verifyToken(ctx, auth.Password, auth.Username, runtimeScopes) 97 | } 98 | 99 | func (bb *bitbucket) verifyToken(ctx context.Context, token string, username string, requiredScopes [][]string) error { 100 | scopes, err := bb.getCurrentUserScopes(ctx, token, username) 101 | if err != nil { 102 | return fmt.Errorf("failed checking token scope permission: %w", err) 103 | } 104 | 105 | for _, requiredScope := range requiredScopes { 106 | isScopeIncluded := false 107 | for _, scopeOpt := range requiredScope { 108 | if strings.Contains(scopes, scopeOpt) { 109 | isScopeIncluded = true 110 | } 111 | } 112 | if !isScopeIncluded { 113 | var requestedScopes = bb.getRequestedScopes(requiredScopes) 114 | return fmt.Errorf("the provided token is missing required token scopes, got: %s \nrequired: %v", scopes, requestedScopes) 115 | } 116 | } 117 | 118 | return nil 119 | } 120 | 121 | func (bb *bitbucket) getCurrentUserScopes(ctx context.Context, token, username string) (string, error) { 122 | res, err := bb.request(ctx, username, token, http.MethodHead, "user", nil) 123 | if err != nil { 124 | return "", fmt.Errorf("failed getting current user: %w", err) 125 | } 126 | defer res.Body.Close() 127 | 128 | scopes := res.Header.Get("x-oauth-scopes") 129 | 130 | if scopes == "" { 131 | return "", errors.New("invalid token") 132 | } 133 | 134 | return scopes, nil 135 | } 136 | 137 | func (bb *bitbucket) request(ctx context.Context, username, token, method, urlPath string, body interface{}) (*http.Response, error) { 138 | urlClone := *bb.apiURL 139 | urlClone.Path = path.Join(urlClone.Path, urlPath) 140 | auth := base64.StdEncoding.EncodeToString([]byte(username + ":" + token)) 141 | headers := map[string]string{ 142 | "Authorization": "Basic " + auth, 143 | "Accept": "application/json", 144 | "Content-Type": "application/json", 145 | } 146 | req, err := httputil.NewRequest(ctx, method, urlClone.String(), headers, body) 147 | if err != nil { 148 | return nil, err 149 | } 150 | 151 | return bb.c.Do(req) 152 | } 153 | 154 | func (bb *bitbucket) getRequestedScopes(requiredScopes [][]string) string { 155 | var requestedScopes string = "" 156 | 157 | for _, requiredScopeOpts := range requiredScopes { 158 | var scopeOpts = "" 159 | for _, requiredScope := range requiredScopeOpts { 160 | if len(scopeOpts) > 0 { 161 | scopeOpts += " " 162 | } 163 | scopeOpts += requiredScope 164 | } 165 | 166 | if len(requestedScopes) > 0 { 167 | requestedScopes += ", " 168 | } 169 | 170 | if len(scopesApiMap[scopeOpts]) > 0 { 171 | requestedScopes += scopesApiMap[scopeOpts] 172 | } else { 173 | requestedScopes += scopeOpts 174 | } 175 | } 176 | 177 | return requestedScopes 178 | } 179 | -------------------------------------------------------------------------------- /internal/git/provider_bitbucket_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "errors" 20 | "net/http" 21 | "testing" 22 | 23 | "github.com/codefresh-io/cli-v2/internal/git/mocks" 24 | 25 | "github.com/golang/mock/gomock" 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func newBitbucket(transport http.RoundTripper) *bitbucket { 30 | client := &http.Client{ 31 | Transport: transport, 32 | } 33 | g, _ := NewBitbucketProvider("https://bitbucket.org", client) 34 | return g.(*bitbucket) 35 | } 36 | 37 | func TestNewBitbucketProvider(t *testing.T) { 38 | tests := map[string]struct { 39 | baseURL string 40 | wantApiURL string 41 | wantErr string 42 | }{ 43 | "should use standard api path when base is host only": { 44 | baseURL: "https://bitbucket.org", 45 | wantApiURL: "https://bitbucket.org/api/2.0", 46 | }, 47 | "should ignore baseUrl path if it contains it": { 48 | baseURL: "https://bitbucket.org/some/api/v-whatever", 49 | wantApiURL: "https://bitbucket.org/api/2.0", 50 | }, 51 | "should fail when base is not a valid url": { 52 | baseURL: "https://bitbucket.org/\x7f", 53 | wantErr: "parse \"https://bitbucket.org/\\x7f\": net/url: invalid control character in URL", 54 | }, 55 | "should fail if base is not in bitbucket-cloud": { 56 | baseURL: "https://some-server", 57 | wantErr: "wrong domain for bitbucket provider: \"https://some-server\", expected \"bitbucket.org\"\n maybe you meant to use \"bitbucket-server\" for on-prem git provider?", 58 | }, 59 | } 60 | for name, tt := range tests { 61 | t.Run(name, func(t *testing.T) { 62 | got, err := NewBitbucketProvider(tt.baseURL, &http.Client{}) 63 | if err != nil || tt.wantErr != "" { 64 | assert.EqualError(t, err, tt.wantErr) 65 | return 66 | } 67 | 68 | assert.Equal(t, tt.wantApiURL, got.ApiURL()) 69 | assert.True(t, got.IsCloud()) 70 | }) 71 | } 72 | } 73 | 74 | func Test_bitbucket_verifyToken(t *testing.T) { 75 | tests := map[string]struct { 76 | requiredScopes [][]string 77 | wantErr string 78 | beforeFn func(c *mocks.MockRoundTripper) 79 | }{ 80 | "Should fail if HEAD fails": { 81 | wantErr: "failed checking token scope permission: failed getting current user: Head \"https://bitbucket.org/api/2.0/user\": some error", 82 | beforeFn: func(c *mocks.MockRoundTripper) { 83 | c.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Return(nil, errors.New("some error")) 84 | }, 85 | }, 86 | "Should fail if no x-oauth-Scopes in res headers": { 87 | wantErr: "failed checking token scope permission: invalid token", 88 | beforeFn: func(c *mocks.MockRoundTripper) { 89 | header := http.Header{} 90 | c.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Return(&http.Response{ 91 | StatusCode: 200, 92 | Header: header, 93 | }, nil) 94 | }, 95 | }, 96 | "Should fail if required scope is not in res header": { 97 | requiredScopes: [][]string{{"scope 3"}}, 98 | wantErr: "the provided token is missing required token scopes, got: scope 1, scope 2 \nrequired: scope 3", 99 | beforeFn: func(c *mocks.MockRoundTripper) { 100 | c.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Times(1).DoAndReturn(func(_ *http.Request) (*http.Response, error) { 101 | header := http.Header{} 102 | header.Add("X-Oauth-Scopes", "scope 1, scope 2") 103 | res := &http.Response{ 104 | StatusCode: 200, 105 | Header: header, 106 | } 107 | return res, nil 108 | }) 109 | }, 110 | }, 111 | "Should succeed if all required scopes or higher are in the res header": { 112 | requiredScopes: [][]string{ 113 | {"scope 3:write", "scope 3:admin"}, 114 | {"scope 4"}, 115 | }, 116 | beforeFn: func(c *mocks.MockRoundTripper) { 117 | c.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Times(1).DoAndReturn(func(_ *http.Request) (*http.Response, error) { 118 | header := http.Header{} 119 | header.Add("X-Oauth-Scopes", "scope 1, scope 2, scope 3:write, scope 4") 120 | res := &http.Response{ 121 | StatusCode: 200, 122 | Header: header, 123 | } 124 | return res, nil 125 | }) 126 | }, 127 | }, 128 | } 129 | for name, tt := range tests { 130 | t.Run(name, func(t *testing.T) { 131 | ctrl := gomock.NewController(t) 132 | mockTransport := mocks.NewMockRoundTripper(ctrl) 133 | tt.beforeFn(mockTransport) 134 | g := newBitbucket(mockTransport) 135 | err := g.verifyToken(context.Background(), "token", "username", tt.requiredScopes) 136 | if err != nil || tt.wantErr != "" { 137 | assert.EqualError(t, err, tt.wantErr) 138 | } 139 | }) 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /internal/git/provider_github.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "errors" 20 | "fmt" 21 | "net/http" 22 | "net/url" 23 | "strings" 24 | 25 | httputil "github.com/codefresh-io/cli-v2/internal/util/http" 26 | ) 27 | 28 | type ( 29 | github struct { 30 | providerType ProviderType 31 | apiURL *url.URL 32 | c *http.Client 33 | } 34 | ) 35 | 36 | const ( 37 | GITHUB_CLOUD_DOMAIN = "github.com" 38 | GITHUB_CLOUD_API_URL = "https://api.github.com" 39 | GITHUB_REST_ENDPOINT = "/api/v3" 40 | GITHUB ProviderType = "github" 41 | GITHUB_ENT ProviderType = "github-enterpeise" // for backward compatability 42 | ) 43 | 44 | var runtime_token_scopes = []string{"repo", "admin:repo_hook"} 45 | 46 | func NewGithubProvider(baseURL string, client *http.Client) (Provider, error) { 47 | u, err := url.Parse(baseURL) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | if u.Host == GITHUB_CLOUD_DOMAIN { 53 | u, _ = url.Parse(GITHUB_CLOUD_API_URL) 54 | } else if u.Path == "" { 55 | u.Path = GITHUB_REST_ENDPOINT 56 | } 57 | 58 | return &github{ 59 | providerType: GITHUB, 60 | apiURL: u, 61 | c: client, 62 | }, nil 63 | } 64 | 65 | func (g *github) ApiURL() string { 66 | return g.apiURL.String() 67 | } 68 | 69 | func (g *github) IsCloud() bool { 70 | return g.ApiURL() == GITHUB_CLOUD_API_URL 71 | } 72 | 73 | func (g *github) Type() ProviderType { 74 | return g.providerType 75 | } 76 | 77 | func (g *github) VerifyRuntimeToken(ctx context.Context, auth Auth) error { 78 | tokenType, err := g.getTokenType(auth.Password) 79 | if err != nil { 80 | return fmt.Errorf("failed getting token type: %w", err) 81 | } 82 | 83 | if tokenType == "fine-grained" { 84 | return fmt.Errorf("validation for github fine-grained PAT is not supported yet, please retry with --skip-permissions-validation or use a classic token") 85 | } 86 | 87 | err = g.verifyToken(ctx, auth.Password, runtime_token_scopes) 88 | if err != nil { 89 | return fmt.Errorf("invalid git-token: %w", err) 90 | } 91 | 92 | return nil 93 | } 94 | 95 | func (g *github) getTokenType(token string) (string, error) { 96 | if token == "" { 97 | return "", errors.New("missing token") 98 | } 99 | if strings.HasPrefix(token, "github_pat") { 100 | return "fine-grained", nil 101 | } 102 | return "classic", nil 103 | } 104 | 105 | func (g *github) verifyToken(ctx context.Context, token string, requiredScopes []string) error { 106 | reqHeaders := map[string]string{ 107 | "Authorization": "token " + token, 108 | } 109 | req, err := httputil.NewRequest(ctx, http.MethodHead, g.apiURL.String(), reqHeaders, nil) 110 | if err != nil { 111 | return err 112 | } 113 | 114 | res, err := g.c.Do(req) 115 | if err != nil { 116 | return err 117 | } 118 | defer res.Body.Close() 119 | 120 | rawScopes := res.Header.Get("X-Oauth-Scopes") 121 | if rawScopes == "" { 122 | return errors.New("missing scopes header on response") 123 | } 124 | 125 | var scopes []string 126 | if len(rawScopes) > 0 { 127 | scopes = strings.Split(rawScopes, ", ") 128 | } 129 | 130 | for _, rs := range requiredScopes { 131 | var contained bool 132 | for _, scope := range scopes { 133 | if scope == rs { 134 | contained = true 135 | break 136 | } 137 | } 138 | 139 | if !contained { 140 | return fmt.Errorf("the provided token is missing one or more of the required scopes: %s", strings.Join(requiredScopes, ", ")) 141 | } 142 | } 143 | 144 | return nil 145 | } 146 | -------------------------------------------------------------------------------- /internal/git/provider_github_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "errors" 20 | "net/http" 21 | "testing" 22 | 23 | "github.com/codefresh-io/cli-v2/internal/git/mocks" 24 | 25 | "github.com/golang/mock/gomock" 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func newGithub(transport http.RoundTripper) *github { 30 | client := &http.Client{ 31 | Transport: transport, 32 | } 33 | g, _ := NewGithubProvider("https://some.server", client) 34 | return g.(*github) 35 | } 36 | 37 | func TestNewGithubProvider(t *testing.T) { 38 | tests := map[string]struct { 39 | baseURL string 40 | wantApiURL string 41 | wantCloud bool 42 | wantErr string 43 | }{ 44 | "should use cloud api path when base is cloud host": { 45 | baseURL: "https://github.com", 46 | wantApiURL: "https://api.github.com", 47 | wantCloud: true, 48 | }, 49 | "should use cloud api path when base is cloud host with path": { 50 | baseURL: "https://github.com/org/repo", 51 | wantApiURL: "https://api.github.com", 52 | wantCloud: true, 53 | }, 54 | "should use standard api path when base is host only": { 55 | baseURL: "https://some.server", 56 | wantApiURL: "https://some.server/api/v3", 57 | wantCloud: false, 58 | }, 59 | "should use baseUrl as apiUrl if it on-prem and has path": { 60 | baseURL: "https://some.server/some/api/v-whatever", 61 | wantApiURL: "https://some.server/some/api/v-whatever", 62 | wantCloud: false, 63 | }, 64 | "should fail when base is not a valid url": { 65 | baseURL: "https://contains-bad-\x7f", 66 | wantErr: "parse \"https://contains-bad-\\x7f\": net/url: invalid control character in URL", 67 | }, 68 | } 69 | for name, tt := range tests { 70 | t.Run(name, func(t *testing.T) { 71 | got, err := NewGithubProvider(tt.baseURL, &http.Client{}) 72 | if err != nil || tt.wantErr != "" { 73 | assert.EqualError(t, err, tt.wantErr) 74 | return 75 | } 76 | 77 | assert.Equal(t, tt.wantApiURL, got.ApiURL()) 78 | assert.Equal(t, tt.wantCloud, got.IsCloud()) 79 | }) 80 | } 81 | } 82 | 83 | func Test_github_verifyToken(t *testing.T) { 84 | tests := map[string]struct { 85 | requiredScopes []string 86 | wantErr string 87 | beforeFn func(rt *mocks.MockRoundTripper) 88 | }{ 89 | "Should fail if HEAD fails": { 90 | wantErr: "Head \"https://some.server/api/v3\": some error", 91 | beforeFn: func(rt *mocks.MockRoundTripper) { 92 | rt.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Return(nil, errors.New("some error")) 93 | }, 94 | }, 95 | "Should fail if no X-Oauth-Scopes in res headers": { 96 | wantErr: "missing scopes header on response", 97 | beforeFn: func(rt *mocks.MockRoundTripper) { 98 | rt.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Return(&http.Response{ 99 | StatusCode: 200, 100 | }, nil) 101 | }, 102 | }, 103 | "Should fail if required scope is not in res header": { 104 | requiredScopes: []string{"scope 3"}, 105 | wantErr: "the provided token is missing one or more of the required scopes: scope 3", 106 | beforeFn: func(rt *mocks.MockRoundTripper) { 107 | rt.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Times(1).DoAndReturn(func(_ *http.Request) (*http.Response, error) { 108 | header := http.Header{} 109 | header.Add("X-Oauth-Scopes", "scope 1, scope 2") 110 | res := &http.Response{ 111 | StatusCode: 200, 112 | Header: header, 113 | } 114 | return res, nil 115 | }) 116 | }, 117 | }, 118 | "Should succeed if all required scopes are in the res header": { 119 | requiredScopes: []string{"scope 3", "scope 4"}, 120 | beforeFn: func(rt *mocks.MockRoundTripper) { 121 | rt.EXPECT().RoundTrip(gomock.AssignableToTypeOf(&http.Request{})).Times(1).DoAndReturn(func(_ *http.Request) (*http.Response, error) { 122 | header := http.Header{} 123 | header.Add("X-Oauth-Scopes", "scope 1, scope 2, scope 3, scope 4") 124 | res := &http.Response{ 125 | StatusCode: 200, 126 | Header: header, 127 | } 128 | return res, nil 129 | }) 130 | }, 131 | }, 132 | } 133 | for name, tt := range tests { 134 | t.Run(name, func(t *testing.T) { 135 | ctrl := gomock.NewController(t) 136 | mockTransport := mocks.NewMockRoundTripper(ctrl) 137 | tt.beforeFn(mockTransport) 138 | g := newGithub(mockTransport) 139 | err := g.verifyToken(context.Background(), "token", tt.requiredScopes) 140 | if err != nil || tt.wantErr != "" { 141 | assert.EqualError(t, err, tt.wantErr) 142 | } 143 | }) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /internal/git/provider_gitlab.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "context" 19 | "encoding/json" 20 | "errors" 21 | "fmt" 22 | "io" 23 | "net/http" 24 | "net/url" 25 | "path" 26 | "strings" 27 | 28 | httputil "github.com/codefresh-io/cli-v2/internal/util/http" 29 | ) 30 | 31 | type ( 32 | gitlab struct { 33 | providerType ProviderType 34 | apiURL *url.URL 35 | c *http.Client 36 | } 37 | 38 | gitlabUserResponse struct { 39 | Username string `json:"username"` 40 | Bot bool `json:"bot"` 41 | } 42 | ) 43 | 44 | const ( 45 | GITLAB_CLOUD_DOMAIN = "gitlab.com" 46 | GITLAB_REST_ENDPOINT = "/api/v4" 47 | GITLAB ProviderType = "gitlab" 48 | ) 49 | 50 | func NewGitlabProvider(baseURL string, client *http.Client) (Provider, error) { 51 | u, err := url.Parse(baseURL) 52 | if err != nil { 53 | return nil, err 54 | } 55 | 56 | if u.Host == GITLAB_CLOUD_DOMAIN || u.Path == "" { 57 | u.Path = GITLAB_REST_ENDPOINT 58 | } 59 | 60 | return &gitlab{ 61 | providerType: GITLAB, 62 | apiURL: u, 63 | c: client, 64 | }, nil 65 | } 66 | 67 | func (g *gitlab) ApiURL() string { 68 | return g.apiURL.String() 69 | } 70 | 71 | func (g *gitlab) IsCloud() bool { 72 | return g.apiURL.Host == GITLAB_CLOUD_DOMAIN 73 | } 74 | 75 | func (g *gitlab) Type() ProviderType { 76 | return g.providerType 77 | } 78 | 79 | func (g *gitlab) VerifyRuntimeToken(ctx context.Context, auth Auth) error { 80 | return g.checkApiScope(ctx, auth.Password) 81 | } 82 | 83 | // POST to projects without a body. 84 | // if it returns 400 - the token has "api" scope 85 | // otherwise - the token does not have the scope 86 | func (g *gitlab) checkApiScope(ctx context.Context, token string) error { 87 | 88 | tokenType, err := g.checkTokenType(token, ctx) 89 | if err != nil { 90 | return fmt.Errorf("failed checking api scope: %w", err) 91 | } 92 | 93 | if tokenType == "project" { 94 | return errors.New("runtime git-token is invalid, project token is not exceptable") 95 | } 96 | 97 | res, err := g.request(ctx, token, http.MethodPost, "projects") 98 | if err != nil { 99 | return fmt.Errorf("failed checking api scope: %w", err) 100 | } 101 | defer res.Body.Close() 102 | 103 | if res.StatusCode != http.StatusBadRequest { 104 | return errors.New("git-token is invalid or missing required \"api\" scope") 105 | } 106 | 107 | return nil 108 | } 109 | 110 | func (g *gitlab) checkTokenType(token string, ctx context.Context) (string, error) { 111 | userRes, err := g.request(ctx, token, http.MethodGet, "user") 112 | 113 | if err != nil { 114 | return "", fmt.Errorf("failed getting user: %w", err) 115 | } 116 | 117 | defer userRes.Body.Close() 118 | 119 | bodyBytes, err := io.ReadAll(userRes.Body) 120 | if err != nil { 121 | return "", fmt.Errorf("failed reading user body: %w", err) 122 | } 123 | 124 | var user gitlabUserResponse 125 | err = json.Unmarshal(bodyBytes, &user) 126 | if err != nil { 127 | return "", fmt.Errorf("failed parse user body: %w", err) 128 | } 129 | if user.Bot { 130 | if strings.HasPrefix(user.Username, "project") { 131 | return "project", nil 132 | } 133 | return "group", nil 134 | } 135 | 136 | return "personal", nil 137 | } 138 | 139 | func (g *gitlab) request(ctx context.Context, token, method, urlPath string) (*http.Response, error) { 140 | urlClone := *g.apiURL 141 | urlClone.Path = path.Join(urlClone.Path, urlPath) 142 | headers := map[string]string{ 143 | "Authorization": "Bearer " + token, 144 | "Accept": "application/json", 145 | "Content-Type": "application/json", 146 | } 147 | req, err := httputil.NewRequest(ctx, method, urlClone.String(), headers, nil) 148 | if err != nil { 149 | return nil, err 150 | } 151 | 152 | return g.c.Do(req) 153 | } 154 | -------------------------------------------------------------------------------- /internal/git/provider_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package git 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestGetProvider(t *testing.T) { 24 | tests := map[string]struct { 25 | providerType ProviderType 26 | baseURL string 27 | wantType ProviderType 28 | wantApiURL string 29 | wantErr string 30 | }{ 31 | "should return github when url is in github.com": { 32 | baseURL: "https://github.com/org/repo", 33 | wantType: GITHUB, 34 | wantApiURL: "https://api.github.com", 35 | }, 36 | "should return gitlab when url is in gitlab.com": { 37 | baseURL: "https://gitlab.com/org/repo", 38 | wantType: GITLAB, 39 | wantApiURL: "https://gitlab.com/api/v4", 40 | }, 41 | "should return bitbucket when url is in bitbucket.org": { 42 | baseURL: "https://bitbucket.org/org/repo", 43 | wantType: BITBUCKET, 44 | wantApiURL: "https://bitbucket.org/api/2.0", 45 | }, 46 | "should use providedType when domain doesn't match known cloud providers": { 47 | providerType: BITBUCKET_SERVER, 48 | baseURL: "https://some.on-prem-provider.com/org/repo", 49 | wantType: BITBUCKET_SERVER, 50 | wantApiURL: "https://some.on-prem-provider.com/org/repo", 51 | }, 52 | "should fail if provider does not match known cloud url, and no providerType was supplied": { 53 | providerType: GITLAB, 54 | baseURL: "https://github.com/org/repo", 55 | wantErr: "supplied provider \"gitlab\" does not match inferred cloud provider \"github\" for url \"https://github.com/org/repo\"", 56 | }, 57 | "should fail if using bitbucket with an on-prem url": { 58 | providerType: BITBUCKET, 59 | baseURL: "https://some.on-prem-provider.com", 60 | wantErr: "wrong domain for bitbucket provider: \"https://some.on-prem-provider.com\", expected \"bitbucket.org\"\n maybe you meant to use \"bitbucket-server\" for on-prem git provider?", 61 | }, 62 | } 63 | for name, tt := range tests { 64 | t.Run(name, func(t *testing.T) { 65 | got, err := GetProvider(tt.providerType, tt.baseURL, "") 66 | if err != nil || tt.wantErr != "" { 67 | assert.EqualError(t, err, tt.wantErr) 68 | return 69 | } 70 | 71 | assert.Equal(t, tt.wantType, got.Type()) 72 | assert.Equal(t, tt.wantApiURL, got.ApiURL()) 73 | }) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /internal/kube/mocks/kube.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: ./kube.go 17 | 18 | // Package mocks is a generated GoMock package. 19 | package mocks 20 | 21 | import ( 22 | context "context" 23 | reflect "reflect" 24 | 25 | kube "github.com/codefresh-io/cli-v2/internal/kube" 26 | gomock "github.com/golang/mock/gomock" 27 | kubernetes "k8s.io/client-go/kubernetes" 28 | rest "k8s.io/client-go/rest" 29 | ) 30 | 31 | // MockFactory is a mock of Factory interface. 32 | type MockFactory struct { 33 | ctrl *gomock.Controller 34 | recorder *MockFactoryMockRecorder 35 | } 36 | 37 | // MockFactoryMockRecorder is the mock recorder for MockFactory. 38 | type MockFactoryMockRecorder struct { 39 | mock *MockFactory 40 | } 41 | 42 | // NewMockFactory creates a new mock instance. 43 | func NewMockFactory(ctrl *gomock.Controller) *MockFactory { 44 | mock := &MockFactory{ctrl: ctrl} 45 | mock.recorder = &MockFactoryMockRecorder{mock} 46 | return mock 47 | } 48 | 49 | // EXPECT returns an object that allows the caller to indicate expected use. 50 | func (m *MockFactory) EXPECT() *MockFactoryMockRecorder { 51 | return m.recorder 52 | } 53 | 54 | // Apply mocks base method. 55 | func (m *MockFactory) Apply(ctx context.Context, manifests []byte) error { 56 | m.ctrl.T.Helper() 57 | ret := m.ctrl.Call(m, "Apply", ctx, manifests) 58 | ret0, _ := ret[0].(error) 59 | return ret0 60 | } 61 | 62 | // Apply indicates an expected call of Apply. 63 | func (mr *MockFactoryMockRecorder) Apply(ctx, manifests interface{}) *gomock.Call { 64 | mr.mock.ctrl.T.Helper() 65 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockFactory)(nil).Apply), ctx, manifests) 66 | } 67 | 68 | // KubernetesClientSet mocks base method. 69 | func (m *MockFactory) KubernetesClientSet() (kubernetes.Interface, error) { 70 | m.ctrl.T.Helper() 71 | ret := m.ctrl.Call(m, "KubernetesClientSet") 72 | ret0, _ := ret[0].(kubernetes.Interface) 73 | ret1, _ := ret[1].(error) 74 | return ret0, ret1 75 | } 76 | 77 | // KubernetesClientSet indicates an expected call of KubernetesClientSet. 78 | func (mr *MockFactoryMockRecorder) KubernetesClientSet() *gomock.Call { 79 | mr.mock.ctrl.T.Helper() 80 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KubernetesClientSet", reflect.TypeOf((*MockFactory)(nil).KubernetesClientSet)) 81 | } 82 | 83 | // ToRESTConfig mocks base method. 84 | func (m *MockFactory) ToRESTConfig() (*rest.Config, error) { 85 | m.ctrl.T.Helper() 86 | ret := m.ctrl.Call(m, "ToRESTConfig") 87 | ret0, _ := ret[0].(*rest.Config) 88 | ret1, _ := ret[1].(error) 89 | return ret0, ret1 90 | } 91 | 92 | // ToRESTConfig indicates an expected call of ToRESTConfig. 93 | func (mr *MockFactoryMockRecorder) ToRESTConfig() *gomock.Call { 94 | mr.mock.ctrl.T.Helper() 95 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToRESTConfig", reflect.TypeOf((*MockFactory)(nil).ToRESTConfig)) 96 | } 97 | 98 | // Wait mocks base method. 99 | func (m *MockFactory) Wait(arg0 context.Context, arg1 *kube.WaitOptions) error { 100 | m.ctrl.T.Helper() 101 | ret := m.ctrl.Call(m, "Wait", arg0, arg1) 102 | ret0, _ := ret[0].(error) 103 | return ret0 104 | } 105 | 106 | // Wait indicates an expected call of Wait. 107 | func (mr *MockFactoryMockRecorder) Wait(arg0, arg1 interface{}) *gomock.Call { 108 | mr.mock.ctrl.T.Helper() 109 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Wait", reflect.TypeOf((*MockFactory)(nil).Wait), arg0, arg1) 110 | } 111 | -------------------------------------------------------------------------------- /internal/log/log.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package log 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/spf13/cobra" 21 | ) 22 | 23 | var ( 24 | G = GetLogger 25 | 26 | L Logger = NopLogger{} 27 | ) 28 | 29 | type ( 30 | loggerKey struct{} 31 | NopLogger struct{} 32 | ) 33 | 34 | type Fields map[string]interface{} 35 | 36 | type Logger interface { 37 | Printf(string, ...interface{}) 38 | Debug(...interface{}) 39 | Info(...interface{}) 40 | Warn(...interface{}) 41 | Fatal(...interface{}) 42 | Error(...interface{}) 43 | Debugf(string, ...interface{}) 44 | Infof(string, ...interface{}) 45 | Warnf(string, ...interface{}) 46 | Fatalf(string, ...interface{}) 47 | Errorf(string, ...interface{}) 48 | 49 | WithField(string, interface{}) Logger 50 | WithFields(Fields) Logger 51 | WithError(error) Logger 52 | 53 | // AddPFlags adds persistent logger flags to cmd 54 | AddPFlags(*cobra.Command) 55 | } 56 | 57 | func WithLogger(ctx context.Context, logger Logger) context.Context { 58 | if L != nil { 59 | L = logger 60 | } 61 | 62 | return context.WithValue(ctx, loggerKey{}, logger) 63 | } 64 | 65 | func SetDefault(logger Logger) { 66 | L = logger 67 | } 68 | 69 | func GetLogger(ctx ...context.Context) Logger { 70 | if len(ctx) == 0 { 71 | if L == nil { 72 | panic("default logger not initialized") 73 | } 74 | 75 | return L 76 | } 77 | 78 | logger := ctx[0].Value(loggerKey{}) 79 | if logger == nil { 80 | if L == nil { 81 | panic("default logger not initialized") 82 | } 83 | 84 | return L 85 | } 86 | 87 | return logger.(Logger) 88 | } 89 | 90 | func (NopLogger) AddPFlags(*cobra.Command) {} 91 | func (NopLogger) Printf(string, ...interface{}) {} 92 | func (NopLogger) Debug(...interface{}) {} 93 | func (NopLogger) Info(...interface{}) {} 94 | func (NopLogger) Warn(...interface{}) {} 95 | func (NopLogger) Fatal(...interface{}) {} 96 | func (NopLogger) Error(...interface{}) {} 97 | func (NopLogger) Debugf(string, ...interface{}) {} 98 | func (NopLogger) Infof(string, ...interface{}) {} 99 | func (NopLogger) Warnf(string, ...interface{}) {} 100 | func (NopLogger) Fatalf(string, ...interface{}) {} 101 | func (NopLogger) Errorf(string, ...interface{}) {} 102 | func (l NopLogger) WithField(string, interface{}) Logger { return l } 103 | func (l NopLogger) WithFields(Fields) Logger { return l } 104 | func (l NopLogger) WithError(error) Logger { return l } 105 | -------------------------------------------------------------------------------- /internal/log/logrus.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package log 16 | 17 | import ( 18 | "fmt" 19 | 20 | cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" 21 | "github.com/sirupsen/logrus" 22 | "github.com/spf13/cobra" 23 | "github.com/spf13/pflag" 24 | ) 25 | 26 | const ( 27 | defaultLvl = logrus.InfoLevel 28 | defaultFormatter = "text" 29 | ) 30 | 31 | type LogrusFormatter string 32 | 33 | type LogrusConfig struct { 34 | Level string 35 | Format LogrusFormatter 36 | } 37 | 38 | type logrusAdapter struct { 39 | *logrus.Entry 40 | c *LogrusConfig 41 | } 42 | 43 | const ( 44 | FormatterText LogrusFormatter = defaultFormatter 45 | FormatterJSON LogrusFormatter = "json" 46 | ) 47 | 48 | func FromLogrus(l *logrus.Entry, c *LogrusConfig) Logger { 49 | if c == nil { 50 | c = &LogrusConfig{} 51 | } 52 | 53 | return &logrusAdapter{l, c} 54 | } 55 | 56 | func GetLogrusEntry(l Logger) (*logrus.Entry, error) { 57 | adpt, ok := l.(*logrusAdapter) 58 | if !ok { 59 | return nil, fmt.Errorf("not a logrus logger") 60 | } 61 | 62 | return adpt.Entry, nil 63 | } 64 | 65 | func initCommands(cmd *cobra.Command, initFunc func(*cobra.Command)) { 66 | initFunc(cmd) 67 | 68 | for _, subCmd := range cmd.Commands() { 69 | if subCmd.HasSubCommands() { 70 | initCommands(subCmd, initFunc) 71 | } else { 72 | initFunc(subCmd) 73 | } 74 | } 75 | } 76 | 77 | func (l *logrusAdapter) AddPFlags(cmd *cobra.Command) { 78 | flags := pflag.NewFlagSet("logrus", pflag.ContinueOnError) 79 | flags.StringVar(&l.c.Level, "log-level", l.c.Level, `set the log level, e.g. "debug", "info", "warn", "error"`) 80 | format := flags.String("log-format", defaultFormatter, `set the log format: "text", "json"`) 81 | 82 | cmd.PersistentFlags().AddFlagSet(flags) 83 | 84 | initFunc := func(cmd *cobra.Command) { 85 | orgPreRunE := cmd.PreRunE 86 | 87 | cmd.PreRunE = func(cmd *cobra.Command, args []string) error { 88 | switch *format { 89 | case string(FormatterJSON), string(FormatterText): 90 | l.c.Format = LogrusFormatter(*format) 91 | default: 92 | return fmt.Errorf("invalid log format: %s", *format) 93 | } 94 | 95 | if err := l.configure(flags); err != nil { 96 | return err 97 | } 98 | 99 | if orgPreRunE != nil { 100 | return orgPreRunE(cmd, args) 101 | } 102 | if cmd.PreRun != nil { 103 | cmd.PreRun(cmd, args) 104 | } 105 | 106 | return nil 107 | } 108 | } 109 | 110 | cobra.OnInitialize(func() { initCommands(cmd, initFunc) }) 111 | 112 | cmdutil.LogFormat = *format 113 | cmdutil.LogLevel = l.c.Level 114 | } 115 | 116 | func (l *logrusAdapter) Printf(format string, args ...interface{}) { 117 | if len(args) > 0 { 118 | fmt.Printf(fmt.Sprintf("%s\n", format), args...) 119 | } else { 120 | fmt.Println(format) 121 | } 122 | } 123 | 124 | func (l *logrusAdapter) WithField(key string, val interface{}) Logger { 125 | return FromLogrus(l.Entry.WithField(key, val), l.c) 126 | } 127 | 128 | func (l *logrusAdapter) WithFields(fields Fields) Logger { 129 | return FromLogrus(l.Entry.WithFields(logrus.Fields(fields)), l.c) 130 | } 131 | 132 | func (l *logrusAdapter) WithError(err error) Logger { 133 | return FromLogrus(l.Entry.WithError(err), l.c) 134 | } 135 | 136 | func (l *logrusAdapter) configure(f *pflag.FlagSet) error { 137 | var ( 138 | err error 139 | fmtr logrus.Formatter 140 | lvl = defaultLvl 141 | ) 142 | 143 | if l.c.Level != "" { 144 | lvl, err = logrus.ParseLevel(l.c.Level) 145 | if err != nil { 146 | return err 147 | } 148 | } 149 | 150 | if lvl < logrus.DebugLevel { 151 | fmtr = &logrus.TextFormatter{ 152 | DisableTimestamp: true, 153 | DisableLevelTruncation: true, 154 | } 155 | } else { 156 | fmtr = &logrus.TextFormatter{ 157 | FullTimestamp: true, 158 | } 159 | } 160 | 161 | if l.c.Format == FormatterJSON { 162 | fmtr = &logrus.JSONFormatter{} 163 | } 164 | 165 | l.Logger.SetLevel(lvl) 166 | l.Logger.SetFormatter(fmtr) 167 | 168 | return nil 169 | } 170 | -------------------------------------------------------------------------------- /internal/store/store.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package store 16 | 17 | import ( 18 | "fmt" 19 | "runtime" 20 | "time" 21 | 22 | "github.com/Masterminds/semver/v3" 23 | ) 24 | 25 | var s Store 26 | 27 | var ( 28 | binaryName = "cli-v2" 29 | version = "v99.99.99" 30 | buildDate = "" 31 | gitCommit = "" 32 | SegmentWriteKey = "" 33 | AddClusterDefURL = "https://github.com/codefresh-io/csdp-official/add-cluster/kustomize" 34 | ) 35 | 36 | type Version struct { 37 | Version *semver.Version 38 | BuildDate string 39 | GitCommit string 40 | GoVersion string 41 | GoCompiler string 42 | Platform string 43 | } 44 | type Store struct { 45 | AddClusterJobName string 46 | AppProxyIngressPath string 47 | BinaryName string 48 | CFInternalGitSources []string 49 | CFTokenSecret string 50 | CLIDownloadTemplate string 51 | CLILatestVersionFileLink string 52 | DefaultAPI string 53 | InClusterName string 54 | InClusterServerURL string 55 | IngressHost string 56 | InsecureIngressHost bool 57 | IsDownloadRuntimeLogs bool 58 | MarketplaceGitSourceName string //asd 59 | Silent bool 60 | Version Version 61 | WaitTimeout time.Duration 62 | } 63 | 64 | // Get returns the global store 65 | func Get() *Store { 66 | return &s 67 | } 68 | 69 | func init() { 70 | s.AddClusterJobName = "csdp-add-cluster-job-" 71 | s.AppProxyIngressPath = "/app-proxy" 72 | s.BinaryName = binaryName 73 | s.CFInternalGitSources = []string{s.MarketplaceGitSourceName} 74 | s.CFTokenSecret = "codefresh-token" 75 | s.CLIDownloadTemplate = "https://github.com/codefresh-io/cli-v2/releases/download/%s/cf-%s-%s.tar.gz" 76 | s.CLILatestVersionFileLink = "https://github.com/codefresh-io/cli-v2/releases/latest/download/version.txt" 77 | s.DefaultAPI = "https://g.codefresh.io" 78 | s.InClusterName = "in-cluster" 79 | s.InClusterServerURL = "https://kubernetes.default.svc" 80 | s.MarketplaceGitSourceName = "marketplace-git-source" 81 | s.WaitTimeout = 8 * time.Minute 82 | 83 | initVersion() 84 | } 85 | 86 | func initVersion() { 87 | s.Version.Version = semver.MustParse(version) 88 | s.Version.BuildDate = buildDate 89 | s.Version.GitCommit = gitCommit 90 | s.Version.GoVersion = runtime.Version() 91 | s.Version.GoCompiler = runtime.Compiler 92 | s.Version.Platform = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) 93 | } 94 | -------------------------------------------------------------------------------- /internal/util/helm/helm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package helm 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/codefresh-io/cli-v2/internal/util" 21 | 22 | "github.com/spf13/pflag" 23 | "helm.sh/helm/v3/pkg/action" 24 | "helm.sh/helm/v3/pkg/chart" 25 | "helm.sh/helm/v3/pkg/chart/loader" 26 | "helm.sh/helm/v3/pkg/chartutil" 27 | "helm.sh/helm/v3/pkg/cli" 28 | "helm.sh/helm/v3/pkg/registry" 29 | ) 30 | 31 | //go:generate mockgen -destination=./mocks/helm.go -package=helm -source=./helm.go Helm 32 | 33 | type ( 34 | Helm interface { 35 | GetValues(valuesFile string, loadFromChart bool) (chartutil.Values, error) 36 | GetDependency(name string) (string, string, error) 37 | } 38 | 39 | helmImpl struct { 40 | chart string 41 | devel bool 42 | install *action.Install 43 | } 44 | ) 45 | 46 | func AddFlags(flags *pflag.FlagSet) (Helm, error) { 47 | client, err := registry.NewClient() 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | helm := &helmImpl{ 53 | install: action.NewInstall(&action.Configuration{ 54 | RegistryClient: client, 55 | }), 56 | } 57 | 58 | flags.BoolVar(&helm.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") 59 | flags.StringVar(&helm.install.ChartPathOptions.Version, "version", "", "specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used") 60 | flags.StringVar(&helm.chart, "chart", "oci://quay.io/codefresh/gitops-runtime", "chart oci url [oci://quay.io/codefresh/gitops-runtime]") 61 | 62 | util.Die(flags.MarkHidden("chart")) 63 | 64 | return helm, nil 65 | } 66 | 67 | func (h *helmImpl) GetValues(valuesFile string, loadFromChart bool) (chartutil.Values, error) { 68 | values, err := chartutil.ReadValuesFile(valuesFile) 69 | if err != nil { 70 | return nil, err 71 | } 72 | 73 | if !loadFromChart { 74 | return values, nil 75 | } 76 | 77 | chart, err := h.loadHelmChart() 78 | if err != nil { 79 | return nil, err 80 | } 81 | 82 | return chartutil.CoalesceValues(chart, values) 83 | } 84 | 85 | func (h *helmImpl) GetDependency(name string) (string, string, error) { 86 | chart, err := h.loadHelmChart() 87 | if err != nil { 88 | return "", "", err 89 | } 90 | 91 | for _, dep := range chart.Metadata.Dependencies { 92 | if dep.Name == name { 93 | return dep.Repository, dep.Version, nil 94 | } 95 | } 96 | 97 | return "", "", fmt.Errorf("dependency %q not found", name) 98 | } 99 | 100 | func (h *helmImpl) loadHelmChart() (*chart.Chart, error) { 101 | if h.install.ChartPathOptions.Version == "" && h.devel { 102 | h.install.ChartPathOptions.Version = ">0.0.0-0" 103 | } 104 | 105 | settings := cli.New() 106 | cp, err := h.install.LocateChart(h.chart, settings) 107 | if err != nil { 108 | return nil, err 109 | } 110 | 111 | return loader.Load(cp) 112 | } 113 | 114 | func PathValue[V any](values chartutil.Values, path string) (V, error) { 115 | var v V 116 | 117 | value, err := values.PathValue(path) 118 | if err != nil { 119 | return v, err 120 | } 121 | 122 | v, ok := value.(V) 123 | if !ok { 124 | return v, fmt.Errorf("\"%s\" must be a %T value", path, v) 125 | } 126 | 127 | return v, nil 128 | } 129 | -------------------------------------------------------------------------------- /internal/util/helm/mocks/helm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: ./helm.go 17 | 18 | // Package helm is a generated GoMock package. 19 | package helm 20 | 21 | import ( 22 | reflect "reflect" 23 | 24 | gomock "github.com/golang/mock/gomock" 25 | chartutil "helm.sh/helm/v3/pkg/chartutil" 26 | ) 27 | 28 | // MockHelm is a mock of Helm interface. 29 | type MockHelm struct { 30 | ctrl *gomock.Controller 31 | recorder *MockHelmMockRecorder 32 | } 33 | 34 | // MockHelmMockRecorder is the mock recorder for MockHelm. 35 | type MockHelmMockRecorder struct { 36 | mock *MockHelm 37 | } 38 | 39 | // NewMockHelm creates a new mock instance. 40 | func NewMockHelm(ctrl *gomock.Controller) *MockHelm { 41 | mock := &MockHelm{ctrl: ctrl} 42 | mock.recorder = &MockHelmMockRecorder{mock} 43 | return mock 44 | } 45 | 46 | // EXPECT returns an object that allows the caller to indicate expected use. 47 | func (m *MockHelm) EXPECT() *MockHelmMockRecorder { 48 | return m.recorder 49 | } 50 | 51 | // GetDependency mocks base method. 52 | func (m *MockHelm) GetDependency(name string) (string, string, error) { 53 | m.ctrl.T.Helper() 54 | ret := m.ctrl.Call(m, "GetDependency", name) 55 | ret0, _ := ret[0].(string) 56 | ret1, _ := ret[1].(string) 57 | ret2, _ := ret[2].(error) 58 | return ret0, ret1, ret2 59 | } 60 | 61 | // GetDependency indicates an expected call of GetDependency. 62 | func (mr *MockHelmMockRecorder) GetDependency(name interface{}) *gomock.Call { 63 | mr.mock.ctrl.T.Helper() 64 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDependency", reflect.TypeOf((*MockHelm)(nil).GetDependency), name) 65 | } 66 | 67 | // GetValues mocks base method. 68 | func (m *MockHelm) GetValues(valuesFile string, loadFromChart bool) (chartutil.Values, error) { 69 | m.ctrl.T.Helper() 70 | ret := m.ctrl.Call(m, "GetValues", valuesFile, loadFromChart) 71 | ret0, _ := ret[0].(chartutil.Values) 72 | ret1, _ := ret[1].(error) 73 | return ret0, ret1 74 | } 75 | 76 | // GetValues indicates an expected call of GetValues. 77 | func (mr *MockHelmMockRecorder) GetValues(valuesFile, loadFromChart interface{}) *gomock.Call { 78 | mr.mock.ctrl.T.Helper() 79 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockHelm)(nil).GetValues), valuesFile, loadFromChart) 80 | } 81 | -------------------------------------------------------------------------------- /internal/util/http/http.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package http 16 | 17 | import ( 18 | "bytes" 19 | "context" 20 | "encoding/json" 21 | "net/http" 22 | ) 23 | 24 | func NewRequest(ctx context.Context, method, url string, headers map[string]string, body interface{}) (*http.Request, error) { 25 | var err error 26 | 27 | bodyStr := []byte{} 28 | if body != nil { 29 | bodyStr, err = json.Marshal(body) 30 | if err != nil { 31 | return nil, err 32 | } 33 | } 34 | 35 | req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewBuffer(bodyStr)) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | for key, value := range headers { 41 | req.Header.Set(key, value) 42 | } 43 | 44 | return req, nil 45 | } 46 | -------------------------------------------------------------------------------- /internal/util/kube/kube.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package kube 16 | 17 | import ( 18 | "bytes" 19 | "context" 20 | "errors" 21 | "fmt" 22 | "io" 23 | "strings" 24 | "time" 25 | 26 | "github.com/codefresh-io/cli-v2/internal/kube" 27 | "github.com/codefresh-io/cli-v2/internal/log" 28 | "github.com/codefresh-io/cli-v2/internal/util" 29 | 30 | batchv1 "k8s.io/api/batch/v1" 31 | v1 "k8s.io/api/core/v1" 32 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 | "k8s.io/client-go/kubernetes" 34 | ) 35 | 36 | func WaitForJob(ctx context.Context, kubeFactory kube.Factory, ns, jobName string) error { 37 | var attempt int32 38 | var jobErr error 39 | _ = kubeFactory.Wait(ctx, &kube.WaitOptions{ 40 | Interval: time.Second * 5, 41 | Timeout: time.Minute, 42 | Resources: []kube.Resource{ 43 | { 44 | Name: jobName, 45 | Namespace: ns, 46 | WaitFunc: func(ctx context.Context, kubeFactory kube.Factory, ns, name string) (bool, error) { 47 | cs, err := GetClientSet(kubeFactory) 48 | if err != nil { 49 | return false, err 50 | } 51 | 52 | j, err := cs.BatchV1().Jobs(ns).Get(ctx, name, metav1.GetOptions{}) 53 | if err != nil { 54 | return false, err 55 | } 56 | 57 | totalRetries := *j.Spec.BackoffLimit + 1 58 | if j.Status.Failed > attempt { 59 | attempt = j.Status.Failed 60 | log.G(ctx).Warnf("Attempt #%d/%d failed:", attempt, totalRetries) 61 | printJobLogs(ctx, cs, j) 62 | } else if j.Status.Succeeded == 1 { 63 | attempt += 1 64 | log.G(ctx).Infof("Attempt #%d/%d succeeded:", attempt, totalRetries) 65 | printJobLogs(ctx, cs, j) 66 | } 67 | 68 | for _, cond := range j.Status.Conditions { 69 | if cond.Type == batchv1.JobFailed { 70 | jobErr = fmt.Errorf("add-cluster-job failed after %d attempt(s)", j.Status.Failed) 71 | break 72 | } 73 | } 74 | 75 | return j.Status.Succeeded == 1 || j.Status.Failed == totalRetries, jobErr 76 | }, 77 | }, 78 | }, 79 | }) 80 | return jobErr 81 | } 82 | 83 | func printJobLogs(ctx context.Context, client kubernetes.Interface, job *batchv1.Job) { 84 | p, err := getPodByJob(ctx, client, job) 85 | if err != nil { 86 | log.G(ctx).Errorf("Failed getting pod for job: $s", err.Error()) 87 | return 88 | } 89 | 90 | logs, err := getPodLogs(ctx, client, p.GetNamespace(), p.GetName()) 91 | if err != nil { 92 | log.G(ctx).Errorf("Failed getting logs for pod: $s", err.Error()) 93 | return 94 | } 95 | 96 | fmt.Printf("=====\n%s\n=====\n\n", logs) 97 | } 98 | 99 | func getPodByJob(ctx context.Context, client kubernetes.Interface, job *batchv1.Job) (*v1.Pod, error) { 100 | pods, err := client.CoreV1().Pods(job.GetNamespace()).List(ctx, metav1.ListOptions{ 101 | LabelSelector: "controller-uid=" + job.Labels["controller-uid"], 102 | }) 103 | if err != nil { 104 | return nil, err 105 | } 106 | 107 | if len(pods.Items) == 0 { 108 | return nil, nil 109 | } 110 | 111 | return &pods.Items[0], nil 112 | } 113 | 114 | func getPodLogs(ctx context.Context, client kubernetes.Interface, namespace, name string) (string, error) { 115 | req := client.CoreV1().Pods(namespace).GetLogs(name, &v1.PodLogOptions{}) 116 | podLogs, err := req.Stream(ctx) 117 | if err != nil { 118 | return "", fmt.Errorf("failed to get network-tester pod logs: %w", err) 119 | } 120 | defer podLogs.Close() 121 | 122 | logsBuf := new(bytes.Buffer) 123 | _, err = io.Copy(logsBuf, podLogs) 124 | if err != nil { 125 | return "", fmt.Errorf("failed to read network-tester pod logs: %w", err) 126 | } 127 | 128 | return strings.Trim(logsBuf.String(), "\n"), nil 129 | } 130 | 131 | func GetClientSet(kubeFactory kube.Factory) (kubernetes.Interface, error) { 132 | cs, err := kubeFactory.KubernetesClientSet() 133 | if err != nil { 134 | if strings.Contains(err.Error(), "exec plugin: invalid apiVersion") { 135 | return nil, errors.New("Kubeconfig user entry is using an invalid API version client.authentication.k8s.io/v1alpha1.\nSee details at https://support.codefresh.io/hc/en-us/articles/6947789386652-Failure-to-perform-actions-on-your-selected-Kubernetes-context") 136 | } 137 | 138 | return nil, fmt.Errorf("failed to build kubernetes clientset: %w", err) 139 | } 140 | 141 | return cs, nil 142 | } 143 | 144 | func GetClientSetOrDie(kubeFactory kube.Factory) kubernetes.Interface { 145 | cs, err := GetClientSet(kubeFactory) 146 | util.Die(err) 147 | return cs 148 | } 149 | 150 | func GetValueFromSecret(ctx context.Context, kubeFactory kube.Factory, namespace, name, key string) (string, error) { 151 | cs := GetClientSetOrDie(kubeFactory) 152 | secret, err := cs.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) 153 | if err != nil { 154 | return "", fmt.Errorf("failed reading secret \"%s\": %w", name, err) 155 | } 156 | 157 | data, ok := secret.Data[key] 158 | if !ok { 159 | return "", fmt.Errorf("secret \"%s\" does not contain key \"%s\"", name, key) 160 | } 161 | 162 | value := string(data) 163 | if value == "" { 164 | return "", fmt.Errorf("secret \"%s\" key \"%s\" is an empty string", name, key) 165 | } 166 | 167 | return value, nil 168 | } 169 | -------------------------------------------------------------------------------- /internal/util/kust/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package util 16 | 17 | import ( 18 | "os" 19 | "path/filepath" 20 | 21 | "sigs.k8s.io/kustomize/api/krusty" 22 | kusttypes "sigs.k8s.io/kustomize/api/types" 23 | "sigs.k8s.io/kustomize/kyaml/filesys" 24 | "sigs.k8s.io/yaml" 25 | ) 26 | 27 | func BuildKustomization(k *kusttypes.Kustomization) ([]byte, error) { 28 | td, err := os.MkdirTemp("", "csdp-add-cluster") 29 | if err != nil { 30 | return nil, err 31 | } 32 | defer os.RemoveAll(td) 33 | 34 | kyaml, err := yaml.Marshal(k) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | kustomizationPath := filepath.Join(td, "kustomization.yaml") 40 | if err = os.WriteFile(kustomizationPath, kyaml, 0400); err != nil { 41 | return nil, err 42 | } 43 | 44 | opts := krusty.MakeDefaultOptions() 45 | kust := krusty.MakeKustomizer(opts) 46 | fs := filesys.MakeFsOnDisk() 47 | res, err := kust.Run(fs, td) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | return res.AsYaml() 53 | } 54 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Codefresh 2 | repo_url: https://github.com/codefresh-io/cli-v2 3 | strict: true 4 | theme: 5 | name: material 6 | palette: 7 | primary: teal 8 | font: 9 | text: 'Work Sans' 10 | logo: 'assets/logo.png' 11 | favicon: 'assets/favicon.png' 12 | custom_dir: 'overrides' 13 | extra_javascript: 14 | - assets/versions.js 15 | extra_css: 16 | - assets/versions.css 17 | markdown_extensions: 18 | - codehilite 19 | - admonition 20 | - toc: 21 | permalink: true 22 | nav: 23 | - Introduction: index.md 24 | - Releases ⧉: https://github.com/codefresh-io/cli-v2/releases 25 | - Issues ⧉: https://github.com/codefresh-io/cli-v2/issues 26 | - Slack ⧉: https://cloud-native.slack.com/archives/C0207C47D0X 27 | -------------------------------------------------------------------------------- /overrides/partials/language/en-custom.html: -------------------------------------------------------------------------------- 1 | {% macro t(key) %}{{ { 2 | "toc.title": "Table of Contents" 3 | }[key] }}{% endmacro %} -------------------------------------------------------------------------------- /util/assets/assets.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Codefresh Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package assets 16 | 17 | import "github.com/gobuffalo/packr" 18 | 19 | // You can use the "packr clean" command to clean up this, 20 | // and any other packr generated files. 21 | func init() { 22 | _ = packr.PackJSONBytes("../../assets", "README.md", "\"dGhpcyBpcyBoZXJlIGp1c3QgdG8gZml4IHRoaXMgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9hcmdvcHJvai9hcmdvLWNkL2lzc3Vlcy8yOTA3\"") 23 | _ = packr.PackJSONBytes("../../assets", "badge.svg", "\"bW9jaw==\"") 24 | _ = packr.PackJSONBytes("../../assets", "builtin-policy.csv", "\"bW9jaw==\"") 25 | _ = packr.PackJSONBytes("../../assets", "model.conf", "\"bW9jaw==\"") 26 | _ = packr.PackJSONBytes("../../assets", "swagger.json", "\"Im1vY2si\"") 27 | } 28 | --------------------------------------------------------------------------------