├── .dockerignore ├── .github ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ ├── jenkins-x-release.yaml │ ├── jenkins-x │ ├── changelog.sh │ ├── release-chart.sh │ └── upload-binaries.sh │ └── plugins-pr.yaml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .helmignore ├── .jx ├── settings.yaml └── updatebot.yaml ├── .lighthouse └── jenkins-x │ ├── lint.yaml │ ├── pullrequest.yaml │ └── triggers.yaml ├── CONTRIBUTING.MD ├── DCO ├── Dockerfile ├── Dockerfile-boot ├── Dockerfile-go ├── Dockerfile-go-maven ├── Dockerfile-kubectl ├── Dockerfile-tfo-aws ├── Dockerfile-tfo-gcp ├── LICENSE ├── Makefile ├── OWNERS ├── OWNERS_ALIASES ├── README.md ├── SECURITY.md ├── build.sh ├── charts └── jx-cli │ ├── .helmignore │ ├── Chart.yaml │ ├── Makefile │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── clusterrole.yaml │ ├── clusterrolebinding.yaml │ ├── cronjob.yaml │ ├── daemonset.yaml │ ├── deployment.yaml │ ├── job.yaml │ ├── role.yaml │ ├── rolebinding.yaml │ ├── service.yaml │ └── serviceaccount.yaml │ └── values.yaml ├── cmd ├── app │ ├── main-win.go │ └── main.go ├── docs │ ├── main.go │ ├── man_docs.go │ └── md_docs.go └── main.go ├── custom-boilerplate.go.txt ├── dependency-matrix ├── matrix.md └── matrix.yaml ├── docs ├── cmd │ ├── jx.md │ ├── jx_add.md │ ├── jx_add_app.md │ ├── jx_create.md │ ├── jx_create_project.md │ ├── jx_create_pullrequest.md │ ├── jx_create_quickstart.md │ ├── jx_create_spring.md │ ├── jx_ctx.md │ ├── jx_dashboard.md │ ├── jx_get.md │ ├── jx_get_activities.md │ ├── jx_get_application.md │ ├── jx_get_build.md │ ├── jx_get_build_logs.md │ ├── jx_get_build_pods.md │ ├── jx_get_pipelines.md │ ├── jx_get_previews.md │ ├── jx_import.md │ ├── jx_namespace.md │ ├── jx_start.md │ ├── jx_start_pipeline.md │ ├── jx_stop.md │ ├── jx_stop_pipeline.md │ ├── jx_ui.md │ ├── jx_upgrade.md │ ├── jx_upgrade_cli.md │ ├── jx_upgrade_plugins.md │ └── jx_version.md └── man │ └── man1 │ ├── jx-add-app.1 │ ├── jx-add.1 │ ├── jx-create-project.1 │ ├── jx-create-pullrequest.1 │ ├── jx-create-quickstart.1 │ ├── jx-create-spring.1 │ ├── jx-create.1 │ ├── jx-ctx.1 │ ├── jx-dashboard.1 │ ├── jx-get-activities.1 │ ├── jx-get-application.1 │ ├── jx-get-build-logs.1 │ ├── jx-get-build-pods.1 │ ├── jx-get-build.1 │ ├── jx-get-pipelines.1 │ ├── jx-get-previews.1 │ ├── jx-get.1 │ ├── jx-import.1 │ ├── jx-namespace.1 │ ├── jx-start-pipeline.1 │ ├── jx-start.1 │ ├── jx-stop-pipeline.1 │ ├── jx-stop.1 │ ├── jx-ui.1 │ ├── jx-upgrade-cli.1 │ ├── jx-upgrade-plugins.1 │ ├── jx-upgrade.1 │ ├── jx-version.1 │ └── jx.1 ├── go.mod ├── go.sum ├── hack ├── changelog-header.md ├── ensure-test-classification.sh ├── generate.sh ├── gofmt.sh ├── linter.sh └── upload_plugin.sh ├── jx.pub ├── pkg ├── cmd │ ├── dashboard │ │ ├── dashboard.go │ │ ├── dashboard_test.go │ │ └── testdata │ │ │ └── kubeconfig │ ├── namespace │ │ ├── namespace.go │ │ ├── namespace_test.go │ │ └── testdata │ │ │ └── kubeconfig │ ├── root.go │ ├── root_test.go │ ├── ui │ │ └── ui.go │ ├── upgrade │ │ ├── testdata │ │ │ └── kubeconfig │ │ ├── upgrade.go │ │ ├── upgrade_cli.go │ │ ├── upgrade_cli_test.go │ │ ├── upgrade_plugins.go │ │ ├── upgrade_plugins_test.go │ │ └── upgrade_test.go │ └── version │ │ ├── version.go │ │ └── version_test.go ├── common │ └── constants.go ├── plugins │ ├── helpers.go │ ├── helpers_test.go │ └── versions.go └── version │ ├── info.go │ └── info_test.go └── run.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | draft.toml 2 | target/classes 3 | target/generated-sources 4 | target/generated-test-sources 5 | target/maven-archiver 6 | target/maven-status 7 | target/surefire-reports 8 | target/test-classes 9 | target/*.original 10 | charts/ 11 | NOTICE 12 | LICENSE 13 | README.md -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | schedule: 9 | # At 23:30 on Sunday 10 | - cron: '30 23 * * 0' 11 | 12 | jobs: 13 | analyze: 14 | if: github.repository_owner == 'jenkins-x' 15 | name: Analyze 16 | runs-on: ubuntu-latest 17 | permissions: 18 | actions: read 19 | contents: read 20 | security-events: write 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | language: [ 'go' ] 26 | 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v4 30 | 31 | # Initializes the CodeQL tools for scanning. 32 | - name: Initialize CodeQL 33 | uses: github/codeql-action/init@v3 34 | with: 35 | languages: ${{ matrix.language }} 36 | 37 | - run: | 38 | make linux 39 | 40 | - name: Perform CodeQL Analysis 41 | uses: github/codeql-action/analyze@v3 42 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-x-release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | permissions: 3 | contents: read # to fetch code (actions/checkout) 4 | jobs: 5 | release: 6 | if: github.repository_owner == 'jenkins-x' 7 | runs-on: ubuntu-latest 8 | # Only this job needs id-token: write for cosign to push signatures using keyless signing 9 | permissions: 10 | id-token: write 11 | packages: write 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | with: 16 | # Only fetch last 10 commits, before we were fetching everything including v2 commits! 17 | fetch-depth: "0" 18 | token: ${{ secrets.GIT_BOT_TOKEN }} 19 | - uses: fusion-engineering/setup-git-credentials@v2 20 | with: 21 | credentials: ${{ format('https://x-access-token:{0}@github.com/', secrets.GIT_BOT_TOKEN) }} 22 | - name: Run coverage 23 | run: make test-coverage 24 | - name: Upload coverage to Codecov 25 | uses: codecov/codecov-action@v5 26 | with: 27 | files: ./build/reports/cover.txt 28 | token: ${{ secrets.CODECOV_TOKEN }} 29 | - id: prep 30 | name: next release version 31 | uses: jenkins-x-plugins/jx-release-version@v2.7.10 32 | - env: 33 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 34 | REPO_NAME: ${{ github.event.repository.name }} 35 | VERSION: ${{ steps.prep.outputs.version }} 36 | name: changelog 37 | uses: docker://ghcr.io/jenkins-x/jx-boot:latest 38 | with: 39 | entrypoint: .github/workflows/jenkins-x/changelog.sh 40 | - env: 41 | VERSION: ${{ steps.prep.outputs.version }} 42 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 43 | REPOSITORY: ${{ github.repository }} 44 | COSIGN_EXPERIMENTAL: "true" 45 | name: upload-binaries 46 | uses: docker://ghcr.io/jenkins-x/jx-goreleaser-image:1.0.0@sha256:35070795367fea9a789c1c3a138b5e32262e4253d38e47406ba9ab7833ff15b2 47 | with: 48 | entrypoint: .github/workflows/jenkins-x/upload-binaries.sh 49 | - name: Set up QEMU 50 | uses: docker/setup-qemu-action@v3 51 | - name: Set up Docker Buildx 52 | uses: docker/setup-buildx-action@v3 53 | - name: Login to GitHub Container Registry 54 | uses: docker/login-action@v3 55 | with: 56 | registry: ghcr.io 57 | username: jenkins-x 58 | password: ${{ secrets.GITHUB_TOKEN }} 59 | - name: syft-installer 60 | uses: anchore/sbom-action/download-syft@v0.19.0 61 | - name: cosign-installer 62 | uses: sigstore/cosign-installer@v3.8.2 63 | with: 64 | cosign-release: 'v2.2.3' 65 | - name: Build and push jx-boot 66 | uses: docker/build-push-action@v6 67 | id: push-jx-boot 68 | with: 69 | context: . 70 | file: ./Dockerfile-boot 71 | platforms: linux/amd64,linux/arm64 72 | push: true 73 | build-args: | 74 | VERSION=${{ steps.prep.outputs.version }} 75 | tags: | 76 | ghcr.io/jenkins-x/jx-boot:latest 77 | ghcr.io/jenkins-x/jx-boot:${{ steps.prep.outputs.version }} 78 | - name: Sign the published Docker image for jx boot 79 | # ToDo(ankitm123): Remove this when this step works, for now we want this to unblock other releases 80 | continue-on-error: true 81 | env: 82 | COSIGN_EXPERIMENTAL: "true" 83 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 84 | # ToDo: We should change this to some other user, a test account pushing images and artifacts for jx org sounds wrong! 85 | GIT_USERNAME: jenkins-x-bot-test 86 | DOCKER_REGISTRY_ORG: jenkins-x 87 | run: | 88 | cosign sign ghcr.io/"${DOCKER_REGISTRY_ORG}"/jx-boot@"${{ steps.push-jx-boot.outputs.digest }}" 89 | - name: Generate and Push signed SBOM for jx-boot 90 | # ToDo(ankitm123): Remove this when this step works, for now we want this to unblock other releases 91 | continue-on-error: true 92 | env: 93 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 94 | GIT_USERNAME: jenkins-x-bot-test 95 | DOCKER_REGISTRY_ORG: jenkins-x 96 | VERSION: ${{ steps.prep.outputs.version }} 97 | COSIGN_EXPERIMENTAL: "true" 98 | run: | 99 | syft ghcr.io/$DOCKER_REGISTRY_ORG/jx-boot:$VERSION --scope all-layers -o spdx-json > sbom.json 100 | # This uploads the sbom 101 | cosign attach sbom --sbom sbom.json ghcr.io/${DOCKER_REGISTRY_ORG}/jx-boot@${{ steps.push-jx-boot.outputs.digest }} 102 | # This signs the sbom 103 | cosign sign --attachment sbom ghcr.io/${DOCKER_REGISTRY_ORG}/jx-boot@${{ steps.push-jx-boot.outputs.digest }} 104 | rm -f sbom.json 105 | - name: Build and push jx 106 | uses: docker/build-push-action@v6 107 | id: push-jx 108 | with: 109 | context: . 110 | file: ./Dockerfile 111 | platforms: linux/amd64 112 | push: true 113 | build-args: | 114 | VERSION=${{ steps.prep.outputs.version }} 115 | tags: | 116 | ghcr.io/jenkins-x/jx:latest 117 | ghcr.io/jenkins-x/jx:${{ steps.prep.outputs.version }} 118 | - name: Sign the published Docker image for jx 119 | # ToDo(ankitm123): Remove this when this step works, for now we want this to unblock other releases 120 | continue-on-error: true 121 | env: 122 | COSIGN_EXPERIMENTAL: "true" 123 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 124 | # ToDo: We should change this to some other user, a test account pushing images and artifacts for jx org sounds wrong! 125 | GIT_USERNAME: jenkins-x-bot-test 126 | DOCKER_REGISTRY_ORG: jenkins-x 127 | REPO_NAME: ${{ github.event.repository.name }} 128 | run: | 129 | cosign sign ghcr.io/$DOCKER_REGISTRY_ORG/$REPO_NAME@${{ steps.push-jx.outputs.digest }} 130 | - name: Generate and Push signed SBOM for jx 131 | # ToDo(ankitm123): Remove this when this step works, for now we want this to unblock other releases 132 | continue-on-error: true 133 | env: 134 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 135 | GIT_USERNAME: jenkins-x-bot-test 136 | DOCKER_REGISTRY_ORG: jenkins-x 137 | VERSION: ${{ steps.prep.outputs.version }} 138 | REPO_NAME: ${{ github.event.repository.name }} 139 | COSIGN_EXPERIMENTAL: "true" 140 | run: | 141 | syft ghcr.io/$DOCKER_REGISTRY_ORG/$REPO_NAME:$VERSION --scope all-layers -o spdx-json > sbom.json 142 | # This uploads the sbom 143 | cosign attach sbom --sbom sbom.json ghcr.io/${DOCKER_REGISTRY_ORG}/${REPO_NAME}@${{ steps.push-jx.outputs.digest }} 144 | # This signs the sbom 145 | cosign sign --attachment sbom ghcr.io/${DOCKER_REGISTRY_ORG}/${REPO_NAME}@${{ steps.push-jx.outputs.digest }} 146 | release2: 147 | if: github.repository_owner == 'jenkins-x' 148 | permissions: 149 | id-token: write 150 | packages: write 151 | runs-on: ubuntu-latest 152 | needs: release 153 | steps: 154 | - name: Checkout 155 | uses: actions/checkout@v4 156 | with: 157 | fetch-depth: "0" 158 | token: ${{ secrets.GIT_BOT_TOKEN }} 159 | - id: getrelease 160 | name: getrelease 161 | uses: pozetroninc/github-action-get-latest-release@master 162 | with: 163 | repository: jenkins-x/jx 164 | - id: prep 165 | name: prep 166 | env: 167 | VERSION: ${{ steps.getrelease.outputs.release }} 168 | run: | 169 | echo "::set-output name=version::${VERSION#v}" 170 | - uses: fusion-engineering/setup-git-credentials@v2 171 | with: 172 | credentials: ${{ format('https://x-access-token:{0}@github.com/', secrets.GIT_BOT_TOKEN) }} 173 | - name: Set up QEMU 174 | uses: docker/setup-qemu-action@v3 175 | - name: Set up Docker Buildx 176 | uses: docker/setup-buildx-action@v3 177 | - name: Login to GitHub Container Registry 178 | uses: docker/login-action@v3 179 | with: 180 | registry: ghcr.io 181 | username: jenkins-x 182 | password: ${{ secrets.GITHUB_TOKEN }} 183 | - name: Build and push jx-go 184 | uses: docker/build-push-action@v6 185 | with: 186 | context: . 187 | file: ./Dockerfile-go 188 | platforms: linux/amd64 189 | push: true 190 | build-args: | 191 | VERSION=${{ steps.prep.outputs.version }} 192 | tags: | 193 | ghcr.io/jenkins-x/jx-go:latest 194 | ghcr.io/jenkins-x/jx-go:${{ steps.prep.outputs.version }} 195 | - name: Build and push jx-go-maven 196 | uses: docker/build-push-action@v6 197 | with: 198 | context: . 199 | file: ./Dockerfile-go-maven 200 | platforms: linux/amd64 201 | push: true 202 | build-args: | 203 | VERSION=${{ steps.prep.outputs.version }} 204 | tags: | 205 | ghcr.io/jenkins-x/jx-go-maven:latest 206 | ghcr.io/jenkins-x/jx-go-maven:${{ steps.prep.outputs.version }} 207 | - env: 208 | GIT_USERNAME: jenkins-x-bot-test 209 | GITHUB_TOKEN: ${{ secrets.GIT_BOT_TOKEN }} 210 | VERSION: ${{ steps.prep.outputs.version}} 211 | XDG_CONFIG_HOME: /github/home/.config 212 | name: promote-release 213 | uses: docker://ghcr.io/jenkins-x/jx-updatebot:0.1.3 214 | with: 215 | args: pr --git-credentials 216 | "on": 217 | push: 218 | branches: 219 | - main 220 | - master 221 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-x/changelog.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | echo "HOME is $HOME" 4 | echo current git configuration 5 | 6 | # See https://github.com/actions/checkout/issues/766 7 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 8 | git config --global --get user.name 9 | git config --global --get user.email 10 | 11 | echo "setting git user" 12 | 13 | git config --global user.name jenkins-x-bot-test 14 | git config --global user.email "jenkins-x@googlegroups.com" 15 | 16 | git clean -f 17 | git tag -fa v$VERSION -m "chore: release version $VERSION" 18 | git push origin v$VERSION 19 | 20 | jx changelog create --verbose --header-file=hack/changelog-header.md --version=v$VERSION --prerelease 21 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-x/release-chart.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | echo "HOME is $HOME" 3 | echo current git configuration 4 | 5 | # See https://github.com/actions/checkout/issues/766 6 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 7 | 8 | git config --global --get user.name 9 | git config --global --get user.email 10 | 11 | echo "setting git user" 12 | 13 | git config --global user.name jenkins-x-bot-test 14 | git config --global user.email "jenkins-x@googlegroups.com" 15 | 16 | jx gitops helm release 17 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-x/upload-binaries.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # See https://github.com/actions/checkout/issues/766 4 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 5 | git config --global --get user.name 6 | git config --global --get user.email 7 | 8 | echo "setting git user" 9 | 10 | git config --global user.name jenkins-x-bot-test 11 | git config --global user.email "jenkins-x@googlegroups.com" 12 | 13 | export BRANCH=$(git rev-parse --abbrev-ref HEAD) 14 | export BUILDDATE=$(date) 15 | export REV=$(git rev-parse HEAD) 16 | export GOVERSION="$(go version | sed -e 's/^[^0-9.]*\([0-9.]*\).*/\1/')" 17 | export ROOTPACKAGE="github.com/$REPOSITORY" 18 | 19 | goreleaser release 20 | -------------------------------------------------------------------------------- /.github/workflows/plugins-pr.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | plugins: 3 | if: github.repository_owner == 'jenkins-x' 4 | runs-on: ${{ matrix.os }} 5 | strategy: 6 | matrix: 7 | os: [ubuntu-latest, macos-latest, windows-latest] 8 | include: 9 | - os: ubuntu-latest 10 | TARGET: linux 11 | BINARY: jx 12 | - os: macos-latest 13 | TARGET: darwin 14 | BINARY: jx 15 | - os: windows-latest 16 | TARGET: win 17 | BINARY: jx-windows-amd64.exe 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: actions/setup-go@v5 22 | with: 23 | go-version: '1.23' 24 | - run: make ${{ matrix.target }} 25 | - run: | 26 | ./build/${{ matrix.target }}/${{ matrix.binary }} version 27 | ./build/${{ matrix.target }}/${{ matrix.binary }} upgrade plugins 28 | ./build/${{ matrix.target }}/${{ matrix.binary }} gitops --help 29 | ./build/${{ matrix.target }}/${{ matrix.binary }} secret --help 30 | on: 31 | pull_request: 32 | branches: 33 | - main 34 | - master 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | debug 14 | 15 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 16 | .glide/ 17 | 18 | .idea/ 19 | *.iml 20 | 21 | .vscode/ 22 | 23 | #Various temporary created while building/running jx. 24 | /build/ 25 | /release/ 26 | dist/ 27 | scanning/ 28 | .updatebot-repos/ 29 | .terraform/ 30 | myvalues.yaml 31 | myvalues.yml 32 | **/extraValues.yaml 33 | 34 | # vim swap files 35 | *.swp 36 | 37 | #OSX system files. 38 | **/.DS_Store 39 | 40 | vendor/** 41 | 42 | # if you run `jx install --gitops` locally 43 | jenkins-x-dev-environment 44 | 45 | # generated apidocs 46 | docs/apidocs/build 47 | docs/apidocs/includes 48 | docs/apidocs/site 49 | 50 | # ignore these files 1 by 1 so we can not ignore the stylesheet override 51 | docs/apidocs/static/FontAwesome.otf 52 | docs/apidocs/static/bootstrap-3.3.7.min.js 53 | docs/apidocs/static/bootstrap.min.css 54 | docs/apidocs/static/font-awesome.min.css 55 | docs/apidocs/static/fontawesome-webfont.eot 56 | docs/apidocs/static/fontawesome-webfont.svg 57 | docs/apidocs/static/fontawesome-webfont.ttf 58 | docs/apidocs/static/fontawesome-webfont.woff 59 | docs/apidocs/static/fontawesome-webfont.woff2 60 | docs/apidocs/static/jquery-3.2.1.min.js 61 | docs/apidocs/static/jquery.scrollTo.min.js 62 | docs/apidocs/static/scroll.js 63 | pkg/jx/cmd/verify-pod.log 64 | 65 | plugin.gz 66 | 67 | # syft 68 | /usr/local/bin/syft 69 | 70 | # docker credential binaries 71 | docker-credential-* 72 | 73 | # sbom json created by syft 74 | sbom.json 75 | 76 | 77 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters-settings: 2 | depguard: 3 | rules: 4 | main: 5 | list-mode: original 6 | deny: 7 | - pkg: github.com/jenkins-x/jx/v2/pkg/log 8 | desc: "use jenkins-x/jx-logging instead" 9 | - pkg: github.com/satori/go.uuid 10 | desc: "use github.com/google/uuid instead" 11 | - pkg: github.com/pborman/uuid 12 | desc: "use github.com/google/uuid instead" 13 | dupl: 14 | threshold: 100 15 | exhaustive: 16 | default-signifies-exhaustive: false 17 | funlen: 18 | lines: 200 19 | statements: 150 20 | goconst: 21 | min-len: 3 22 | min-occurrences: 3 23 | gocritic: 24 | enabled-tags: 25 | - diagnostic 26 | - experimental 27 | - opinionated 28 | - performance 29 | - style 30 | disabled-checks: 31 | - dupImport # https://github.com/go-critic/go-critic/issues/845 32 | - ifElseChain 33 | - octalLiteral 34 | - whyNoLint 35 | - wrapperFunc 36 | - importShadow # not important for now 37 | - unnamedResult # not important 38 | gocyclo: 39 | min-complexity: 15 40 | goimports: {} 41 | revive: 42 | confidence: 0 43 | gofmt: 44 | simplify: true 45 | mnd: 46 | # don't include the "operation" and "assign" 47 | checks: [argument, case, condition, return] 48 | govet: 49 | settings: 50 | printf: 51 | funcs: 52 | - (github.com/jenkins-x/jx-logging/v3/pkg/log/Logger()).Debugf 53 | - (github.com/jenkins-x/jx-logging/v3/pkg/log/Logger()).Infof 54 | - (github.com/jenkins-x/jx-logging/v3/pkg/log/Logger()).Warnf 55 | - (github.com/jenkins-x/jx-logging/v3/pkg/log/Logger()).Errorf 56 | - (github.com/jenkins-x/jx-logging/v3/pkg/log/Logger()).Fatalf 57 | lll: 58 | line-length: 140 59 | misspell: {} 60 | nolintlint: 61 | allow-unused: false # report any unused nolint directives 62 | require-explanation: false # don't require an explanation for nolint directives 63 | require-specific: false # don't require nolint directives to be specific about which linter is being skipped 64 | linters: 65 | # please, do not use `enable-all`: it's deprecated and will be removed soon. 66 | # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint 67 | disable-all: true 68 | enable: 69 | - asciicheck 70 | - bodyclose 71 | - depguard 72 | - errcheck 73 | - gofmt 74 | - goimports 75 | - goprintffuncname 76 | - gosec 77 | - gosimple 78 | - ineffassign 79 | - misspell 80 | - mnd 81 | - nakedret 82 | - rowserrcheck 83 | - staticcheck 84 | - typecheck 85 | - unconvert 86 | - unparam 87 | - unused 88 | - revive 89 | - gocritic 90 | - govet 91 | - dupl 92 | issues: 93 | exclude-dirs: 94 | - cmd/docs 95 | # Excluding configuration per-path, per-linter, per-text and per-source 96 | exclude-rules: 97 | # - path: _test\.go 98 | # linters: 99 | # - gomnd 100 | # https://github.com/go-critic/go-critic/issues/926 101 | - linters: 102 | - gocritic 103 | text: "unnecessaryDefer:" 104 | exclude: 105 | - 'shadow: declaration of "err" shadows declaration at' 106 | max-same-issues: 0 107 | 108 | run: 109 | timeout: 1h30m 110 | # golangci.com configuration 111 | # https://github.com/golangci/golangci/wiki/Configuration 112 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | env: 3 | - GO111MODULE=on 4 | - CGO_ENABLED=0 5 | - COSIGN_EXPERIMENTAL=true 6 | before: 7 | hooks: 8 | - go mod download 9 | builds: 10 | - id: jx 11 | # Path to main.go file or main package. 12 | # Default is `.`. 13 | main: ./cmd/main.go 14 | # Binary name. 15 | # Can be a path (e.g. `bin/app`) to wrap the binary in a directory. 16 | # Default is the name of the project directory. 17 | binary: jx 18 | # Custom ldflags templates. 19 | # Default is `-s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}} -X main.date={{.Date}} -X main.builtBy=goreleaser`. 20 | ldflags: 21 | - -X "{{.Env.ROOTPACKAGE}}/pkg/cmd/version.Version={{.Env.VERSION}}" -X "{{.Env.ROOTPACKAGE}}/pkg/cmd/version.Revision={{.Env.REV}}" -X "{{.Env.ROOTPACKAGE}}/pkg/cmd/version.Branch={{.Env.BRANCH}}" -X "{{.Env.ROOTPACKAGE}}/pkg/cmd/version.BuildDate={{.Env.BUILDDATE}}" -X "{{.Env.ROOTPACKAGE}}/pkg/cmd/version.GoVersion={{.Env.GOVERSION}}" 22 | # GOOS list to build for. 23 | # For more info refer to: https://golang.org/doc/install/source#environment 24 | # Defaults are darwin and linux. 25 | goos: 26 | - windows 27 | - darwin 28 | - linux 29 | # GOARCH to build for. 30 | # For more info refer to: https://golang.org/doc/install/source#environment 31 | # Defaults are 386 and amd64. 32 | goarch: 33 | - amd64 34 | - arm64 35 | ignore: 36 | - goos: windows 37 | goarch: arm64 38 | archives: 39 | - name_template: "jx-{{ .Os }}-{{ .Arch }}" 40 | format_overrides: 41 | - goos: windows 42 | format: zip 43 | checksum: 44 | # You can change the name of the checksums file. 45 | # Default is `jx_{{ .Version }}_checksums.txt`. 46 | name_template: "jx-checksums.txt" 47 | # Algorithm to be used. 48 | # Accepted options are sha256, sha512, sha1, crc32, md5, sha224 and sha384. 49 | # Default is sha256. 50 | algorithm: sha256 51 | changelog: 52 | # set it to true if you wish to skip the changelog generation 53 | disable: true 54 | release: 55 | # If set to true, will not auto-publish the release. 56 | # Default is false. 57 | draft: false 58 | # If set to auto, will mark the release as not ready for production 59 | # in case there is an indicator for this in the tag e.g. v1.0.0-rc1 60 | # If set to true, will mark the release as not ready for production. 61 | # Default is false. 62 | prerelease: true 63 | # You can change the name of the GitHub release. 64 | # Default is `{{.Tag}}` 65 | name_template: "{{.Env.VERSION}}" 66 | sboms: 67 | - artifacts: archive 68 | signs: 69 | - cmd: cosign 70 | env: 71 | - COSIGN_EXPERIMENTAL=1 72 | certificate: '${artifact}.pem' 73 | output: true 74 | artifacts: all 75 | args: 76 | - sign-blob 77 | - --yes=true 78 | - '--output-certificate=${certificate}' 79 | - '--output-signature=${signature}' 80 | - '${artifact}' 81 | -------------------------------------------------------------------------------- /.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | *.png 23 | 24 | # known compile time folders 25 | target/ 26 | node_modules/ 27 | vendor/ -------------------------------------------------------------------------------- /.jx/settings.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.jenkins-x.io/v4beta1 2 | kind: Settings 3 | spec: 4 | gitUrl: "https://github.com/jx3-gitops-repositories/jx3-github.git" 5 | destination: 6 | chartRepository: https://github.com/jenkins-x-charts/repo.git 7 | chartKind: pages -------------------------------------------------------------------------------- /.jx/updatebot.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: updatebot.jenkins-x.io/v1alpha1 2 | kind: UpdateConfig 3 | spec: 4 | rules: 5 | - urls: 6 | - https://github.com/jenkins-x/jx3-pipeline-catalog 7 | changes: 8 | - regex: 9 | pattern: "jenkins-x/jx:(.*)" 10 | files: 11 | - "**/*.yaml" 12 | - regex: 13 | pattern: "jenkins-x/jx-boot:(.*)" 14 | files: 15 | - "**/*.yaml" 16 | - urls: 17 | - https://github.com/jenkins-x/jx3-versions 18 | changes: 19 | - versionTemplate: | 20 | {{ pullRequestSha "jenkins-x/jx3-pipeline-catalog" }} 21 | regex: 22 | pattern: "version: (.*)" 23 | files: 24 | - git/github.com/jenkins-x/jx3-pipeline-catalog.yml 25 | - regex: 26 | pattern: "\\s+image: ghcr.io/jenkins-x/jx:(.*)" 27 | files: 28 | - ".lighthouse/jenkins-x/release.yaml" 29 | - ".lighthouse/jenkins-x/pullrequest*.yaml" 30 | - "jenkins-x-*.yml" 31 | - "git-operator/job.yaml" 32 | - regex: 33 | pattern: "\\s+image: ghcr.io/jenkins-x/jx-boot:(.*)" 34 | files: 35 | - ".lighthouse/jenkins-x/release.yaml" 36 | - ".lighthouse/jenkins-x/pullrequest*.yaml" 37 | - "jenkins-x-*.yml" 38 | - "git-operator/job*.yaml" 39 | - regex: 40 | pattern: "version: (.*)" 41 | files: 42 | - "docker/ghcr.io/jenkins-x/jx.yml" 43 | - "packages/jx.yml" 44 | - "packages/jx-cli.yml" 45 | # - regex: 46 | # pattern: "terraformVersion: (.*)" 47 | # files: 48 | # - ".lighthouse/jenkins-x/bdd/*.yaml*" 49 | - regex: 50 | pattern: "JX_DEFAULT_IMAGE: ghcr.io/jenkins-x/jx:(.*)" 51 | files: 52 | - "apps/jenkins-x/lighthouse/values.yaml.gotmpl" 53 | - "charts/jenkins-x/lighthouse/values.yaml.gotmpl" 54 | - urls: 55 | - https://github.com/jenkins-x-charts/jxboot-helmfile-resources 56 | changes: 57 | - regex: 58 | pattern: "jx: (.*)" 59 | files: 60 | - "charts/jxboot-helmfile-resources/values.yaml" 61 | -------------------------------------------------------------------------------- /.lighthouse/jenkins-x/lint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | creationTimestamp: null 5 | name: lint 6 | spec: 7 | pipelineSpec: 8 | tasks: 9 | - name: jx-lint 10 | resources: {} 11 | timeout: 1h30m0s 12 | taskSpec: 13 | metadata: {} 14 | stepTemplate: 15 | image: uses:jenkins-x/jx3-pipeline-catalog/tasks/go/pullrequest.yaml@versionStream 16 | name: "" 17 | resources: {} 18 | workingDir: /workspace/source 19 | steps: 20 | - image: uses:jenkins-x/jx3-pipeline-catalog/tasks/git-clone/git-clone-pr.yaml@versionStream 21 | name: "" 22 | resources: {} 23 | - name: make-lint 24 | resources: {} 25 | podTemplate: {} 26 | serviceAccountName: tekton-bot 27 | timeout: 1h30m0s 28 | status: {} 29 | -------------------------------------------------------------------------------- /.lighthouse/jenkins-x/pullrequest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | creationTimestamp: null 5 | name: pullrequest 6 | spec: 7 | pipelineSpec: 8 | tasks: 9 | - name: from-build-pack 10 | resources: {} 11 | taskSpec: 12 | metadata: {} 13 | stepTemplate: 14 | image: uses:jenkins-x/jx3-pipeline-catalog/tasks/go-plugin/pullrequest.yaml@versionStream 15 | name: "" 16 | resources: {} 17 | workingDir: /workspace/source 18 | steps: 19 | - image: uses:jenkins-x/jx3-pipeline-catalog/tasks/git-clone/git-clone-pr.yaml@versionStream 20 | name: "" 21 | resources: {} 22 | - name: jx-variables 23 | resources: {} 24 | - name: build-make-linux 25 | resources: {} 26 | # Move to catalog 27 | - image: golang:1.23.2-alpine3.19@sha256:f6392ffebb028fed5ffe743ddb9716e38402c978779edd66474bb5d05f5e65e4 28 | name: coverage-report 29 | resources: {} 30 | script: | 31 | #!/bin/sh 32 | source .jx/variables.sh 33 | apk add --update make bash curl gnupg coreutils 34 | make test-coverage 35 | curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import 36 | # Pin it to 0.2.4, seeing an error with slug in 0.2.5 37 | curl -Os https://uploader.codecov.io/v0.2.4/alpine/codecov 38 | curl -Os https://uploader.codecov.io/0.2.4/alpine/codecov.SHA256SUM 39 | curl -Os https://uploader.codecov.io/0.2.4/alpine/codecov.SHA256SUM.sig 40 | gpgv codecov.SHA256SUM.sig codecov.SHA256SUM 41 | sha256sum -c codecov.SHA256SUM 42 | chmod +x codecov 43 | ./codecov -Z -B ${PR_HEAD_REF} -r jenkins-x/jx -C ${PULL_PULL_SHA} -t ${CODECOV_TOKEN} -R . -f ./build/reports/cover.txt 44 | env: 45 | - name: CODECOV_TOKEN 46 | valueFrom: 47 | secretKeyRef: 48 | name: codecov 49 | key: token 50 | optional: true 51 | podTemplate: {} 52 | serviceAccountName: tekton-bot 53 | timeout: 1h0m 54 | status: {} 55 | -------------------------------------------------------------------------------- /.lighthouse/jenkins-x/triggers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.lighthouse.jenkins-x.io/v1alpha1 2 | kind: TriggerConfig 3 | spec: 4 | presubmits: 5 | - name: pr 6 | context: "pr" 7 | always_run: true 8 | optional: false 9 | trigger: (?m)^/test( all| pr),?(s+|$) 10 | rerun_command: /test pr 11 | source: "pullrequest.yaml" 12 | - name: lint 13 | context: "lint" 14 | always_run: true 15 | optional: false 16 | trigger: (?m)^/test( all| lint),?(s+|$) 17 | rerun_command: /test lint 18 | source: "lint.yaml" 19 | -------------------------------------------------------------------------------- /DCO: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 660 York Street, Suite 102, 6 | San Francisco, CA 94110 USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this 9 | license document, but changing it is not allowed. 10 | 11 | 12 | Developer's Certificate of Origin 1.1 13 | 14 | By making a contribution to this project, I certify that: 15 | 16 | (a) The contribution was created in whole or in part by me and I 17 | have the right to submit it under the open source license 18 | indicated in the file; or 19 | 20 | (b) The contribution is based upon previous work that, to the best 21 | of my knowledge, is covered under an appropriate open source 22 | license and I have the right under that license to submit that 23 | work with modifications, whether created in whole or in part 24 | by me, under the same open source license (unless I am 25 | permitted to submit under a different license), as indicated 26 | in the file; or 27 | 28 | (c) The contribution was provided directly to me by some other 29 | person who certified (a), (b) or (c) and I have not modified 30 | it. 31 | 32 | (d) I understand and agree that this project and the contribution 33 | are public and that a record of the contribution (including all 34 | personal information I submit with it, including my sign-off) is 35 | maintained indefinitely and may be redistributed consistent with 36 | this project or the open source license(s) involved. 37 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/jenkins-x/jx-cli-base-image:0.1.1 2 | 3 | ARG VERSION 4 | ARG TARGETARCH 5 | ARG TARGETOS 6 | 7 | ENV HOME /home 8 | ENV JX3_HOME /home/.jx3 9 | 10 | RUN echo using jx version ${VERSION} and OS ${TARGETOS} arch ${TARGETARCH} && \ 11 | mkdir -p /home/.jx3 && \ 12 | curl -L https://github.com/jenkins-x/jx/releases/download/v${VERSION}/jx-${TARGETOS}-${TARGETARCH}.tar.gz | tar xzv && \ 13 | mv jx /usr/bin 14 | 15 | RUN jx upgrade plugins --mandatory 16 | -------------------------------------------------------------------------------- /Dockerfile-boot: -------------------------------------------------------------------------------- 1 | FROM alpine:3.16.2 2 | 3 | ARG BUILD_DATE 4 | ARG VERSION 5 | ARG REVISION 6 | ARG TARGETARCH 7 | ARG TARGETOS 8 | 9 | LABEL maintainer="jenkins-x" 10 | 11 | RUN addgroup -S app \ 12 | && adduser -S -g app app \ 13 | && apk --no-cache add \ 14 | ca-certificates curl git git-lfs make netcat-openbsd bash yq 15 | 16 | ENV JX_HOME /root/.jx 17 | ENV JX3_HOME /root/.jx 18 | ENV HELM_DATA_HOME /root/.local/share/helm 19 | 20 | RUN echo using jx version ${VERSION} and OS ${TARGETOS} arch ${TARGETARCH} && \ 21 | mkdir -p /home/.jx3 && \ 22 | curl -L https://github.com/jenkins-x/jx/releases/download/v${VERSION}/jx-${TARGETOS}-${TARGETARCH}.tar.gz | tar xzv && \ 23 | mv jx /usr/bin 24 | 25 | RUN jx upgrade plugins --boot --path /usr/bin && \ 26 | jx secret plugins upgrade 27 | 28 | #RUN chown -R app:app /usr/bin/jx /home 29 | #USER app 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Dockerfile-go: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.2-alpine3.19@sha256:f6392ffebb028fed5ffe743ddb9716e38402c978779edd66474bb5d05f5e65e4 2 | 3 | ARG VERSION 4 | ARG TARGETARCH 5 | ARG TARGETOS 6 | 7 | #ENV HOME /home 8 | ENV JX3_HOME /home/.jx3 9 | 10 | RUN apk add --no-cache curl && \ 11 | echo using jx version ${VERSION} and OS ${TARGETOS} arch ${TARGETARCH} && \ 12 | mkdir -p /home/.jx3 && \ 13 | curl -L https://github.com/jenkins-x/jx/releases/download/v${VERSION}/jx-${TARGETOS}-${TARGETARCH}.tar.gz | tar xzv && \ 14 | mv jx /usr/bin 15 | 16 | RUN jx upgrade plugins --mandatory 17 | -------------------------------------------------------------------------------- /Dockerfile-go-maven: -------------------------------------------------------------------------------- 1 | # ToDo: Make it work with alpine, not sure why alpine images complain about java not found 2 | FROM golang:1.23.2@sha256:a7f2fc9834049c1f5df787690026a53738e55fc097cd8a4a93faa3e06c67ee32 3 | 4 | # Maven 5 | ENV MAVEN_VERSION 3.6.3 6 | ENV M2_HOME /opt/apache-maven-$MAVEN_VERSION 7 | ENV maven.home $M2_HOME 8 | ENV M2 $M2_HOME/bin 9 | ENV PATH $M2:$PATH 10 | ENV JAVA_HOME=/opt/jdk-15.0.1 11 | ENV PATH=$JAVA_HOME/bin:$PATH 12 | ENV JX3_HOME /home/.jx3 13 | 14 | ARG VERSION 15 | ARG TARGETARCH 16 | ARG TARGETOS 17 | 18 | RUN curl -f -L https://repo1.maven.org/maven2/org/apache/maven/apache-maven/$MAVEN_VERSION/apache-maven-$MAVEN_VERSION-bin.tar.gz | tar -C /opt -xzv 19 | 20 | RUN curl -f -L https://download.java.net/java/GA/jdk15.0.1/51f4f36ad4ef43e39d0dfdbaf6549e32/9/GPL/openjdk-15.0.1_linux-x64_bin.tar.gz | tar -C /opt -xzv 21 | 22 | RUN echo using jx version ${VERSION} and OS ${TARGETOS} arch ${TARGETARCH} && \ 23 | mkdir -p /home/.jx3 && \ 24 | curl -L https://github.com/jenkins-x/jx/releases/download/v${VERSION}/jx-${TARGETOS}-${TARGETARCH}.tar.gz | tar xzv && \ 25 | mv jx /usr/bin 26 | 27 | RUN jx upgrade plugins --mandatory 28 | -------------------------------------------------------------------------------- /Dockerfile-kubectl: -------------------------------------------------------------------------------- 1 | FROM alpine:3.16.2 2 | 3 | ARG VERSION 4 | ARG TARGETARCH 5 | ARG TARGETOS 6 | 7 | LABEL org.opencontainers.image.authors="Linux Foundation" \ 8 | org.opencontainers.image.description="Kubectl docker image used by Jenkins X" \ 9 | org.opencontainers.image.ref.name="alpine:3.16.2" \ 10 | org.opencontainers.image.source="https://github.com/jenkins-x/jx/blob/main/Dockerfile-kubectl" \ 11 | org.opencontainers.image.title="kubectl" 12 | 13 | RUN apk add --update --no-cache curl &&\ 14 | adduser -D -u 1001 jx 15 | 16 | RUN curl -LO "https://dl.k8s.io/release/v${VERSION}/bin/${TARGETOS}/${TARGETARCH}/kubectl" &&\ 17 | chmod +x kubectl && \ 18 | mv kubectl /usr/local/bin 19 | 20 | USER 1001 21 | ENTRYPOINT [ "kubectl" ] 22 | CMD [ "--help" ] 23 | -------------------------------------------------------------------------------- /Dockerfile-tfo-aws: -------------------------------------------------------------------------------- 1 | FROM amazon/aws-cli 2 | 3 | ARG TARGETARCH 4 | ARG TARGETOS 5 | ARG VERSION 6 | 7 | # install packages 8 | RUN yum -y update \ 9 | && yum install -y git tar gzip unzip jq which\ 10 | && yum clean all && rm -rf /var/cache/yum 11 | 12 | RUN curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.15.10/2020-02-22/bin/linux/amd64/aws-iam-authenticator && \ 13 | chmod +x aws-iam-authenticator && \ 14 | mv aws-iam-authenticator /usr/bin/aws-iam-authenticator 15 | 16 | # terraform 17 | ENV TERRAFORM 1.1.2 18 | RUN curl -LO https://releases.hashicorp.com/terraform/${TERRAFORM}/terraform_${TERRAFORM}_linux_amd64.zip && \ 19 | unzip terraform_${TERRAFORM}_linux_amd64.zip && \ 20 | chmod +x terraform && mv terraform /usr/bin && rm terraform_${TERRAFORM}_linux_amd64.zip 21 | 22 | # jx 23 | RUN echo using jx version ${VERSION} and OS ${TARGETOS} arch ${TARGETARCH} && \ 24 | mkdir -p /home/.jx3 && \ 25 | curl -L https://github.com/jenkins-x/jx/releases/download/v${VERSION}/jx-${TARGETOS}-${TARGETARCH}.tar.gz | tar xzv && \ 26 | mv jx /usr/bin 27 | 28 | # lets install the boot plugins 29 | RUN jx upgrade plugins --boot --path /usr/bin 30 | 31 | # lets install the admin plugin 32 | RUN jx admin help 33 | 34 | COPY run.sh /run.sh 35 | ENTRYPOINT ["/bin/bash"] 36 | CMD ["/run.sh"] 37 | 38 | LABEL org.opencontainers.image.source https://github.com/jenkins-x/jx 39 | -------------------------------------------------------------------------------- /Dockerfile-tfo-gcp: -------------------------------------------------------------------------------- 1 | FROM google/cloud-sdk:slim 2 | USER root 3 | 4 | ARG TARGETARCH 5 | ARG TARGETOS 6 | ARG VERSION 7 | 8 | LABEL org.opencontainers.image.source https://github.com/jenkins-x/jx 9 | 10 | # unzip 11 | RUN apt-get install -y unzip bash jq && \ 12 | rm -rf /var/lib/apt/lists/* 13 | 14 | # terraform 15 | ENV TERRAFORM 1.1.2 16 | RUN curl -LO https://releases.hashicorp.com/terraform/${TERRAFORM}/terraform_${TERRAFORM}_linux_amd64.zip && \ 17 | unzip terraform_${TERRAFORM}_linux_amd64.zip && \ 18 | chmod +x terraform && mv terraform /usr/bin && rm terraform_${TERRAFORM}_linux_amd64.zip 19 | 20 | # jx 21 | RUN echo using jx version ${VERSION} and OS ${TARGETOS} arch ${TARGETARCH} && \ 22 | mkdir -p /home/.jx3 && \ 23 | curl -L https://github.com/jenkins-x/jx/releases/download/v${VERSION}/jx-${TARGETOS}-${TARGETARCH}.tar.gz | tar xzv && \ 24 | mv jx /usr/bin 25 | 26 | # lets install the boot plugins 27 | RUN jx upgrade plugins --boot --path /usr/bin 28 | 29 | # lets install the admin plugin 30 | RUN jx admin help 31 | 32 | COPY run.sh /run.sh 33 | ENTRYPOINT ["/bin/bash"] 34 | CMD ["run.sh"] 35 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Make does not offer a recursive wildcard function, so here's one: 2 | rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)) 3 | 4 | SHELL := /bin/sh 5 | NAME := jx 6 | BINARY_NAME := jx 7 | BUILD_TARGET = build 8 | MAIN_SRC_FILE=cmd/main.go 9 | GO := GO111MODULE=on go 10 | GO_NOMOD :=GO111MODULE=off go 11 | REV := $(shell git rev-parse --short HEAD 2> /dev/null || echo 'unknown') 12 | ORG := jenkins-x 13 | ORG_REPO := $(ORG)/$(NAME) 14 | RELEASE_ORG_REPO := $(ORG_REPO) 15 | ROOT_PACKAGE := github.com/$(ORG_REPO) 16 | 17 | # The go version is derived from the image built by this repo: https://github.com/jenkins-x/jx-goreleaser-image 18 | GO_VERSION := $(shell $(GO) version | sed -e 's/^[^0-9.]*\([0-9.]*\).*/\1/') 19 | GO_DEPENDENCIES := $(call rwildcard,pkg/,*.go) $(call rwildcard,cmd/,*.go) 20 | 21 | GIT_TREE_STATE := $(shell test -z "`git status --porcelain`" && echo "clean" || echo "dirty") 22 | BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2> /dev/null || echo 'unknown') 23 | BUILD_DATE := $(shell date -u +%Y-%m-%dT%H:%M:%S) 24 | CGO_ENABLED = 0 25 | 26 | REPORTS_DIR=$(BUILD_TARGET)/reports 27 | 28 | GOTEST := $(GO) test 29 | 30 | # set dev version unless VERSION is explicitly set via environment 31 | VERSION ?= $(shell echo "$$(git for-each-ref refs/tags/ --count=1 --sort=-version:refname --format='%(refname:short)' 2>/dev/null)-dev+$(REV)" | sed 's/^v//') 32 | 33 | # Build flags for setting build-specific configuration at build time - defaults to empty 34 | #BUILD_TIME_CONFIG_FLAGS ?= "" 35 | 36 | # Full build flags used when building binaries. Not used for test compilation/execution. 37 | BUILDFLAGS := -ldflags \ 38 | " -X $(ROOT_PACKAGE)/pkg/cmd/version.Version=$(VERSION)\ 39 | -X $(ROOT_PACKAGE)/pkg/cmd/version.Revision=$(REV)\ 40 | -X $(ROOT_PACKAGE)/pkg/cmd/version.Branch=$(BRANCH)\ 41 | -X $(ROOT_PACKAGE)/pkg/cmd/version.GitTreeState=$(GIT_TREE_STATE)\ 42 | -X $(ROOT_PACKAGE)/pkg/cmd/version.BuildDate=$(BUILD_DATE)\ 43 | -X $(ROOT_PACKAGE)/pkg/cmd/version.GoVersion=$(GO_VERSION)\ 44 | $(BUILD_TIME_CONFIG_FLAGS)" 45 | 46 | # Some tests expect default values for version.*, so just use the config package values there. 47 | TEST_BUILDFLAGS := -ldflags "$(BUILD_TIME_CONFIG_FLAGS)" 48 | 49 | ifdef DEBUG 50 | BUILDFLAGS := -gcflags "all=-N -l" $(BUILDFLAGS) 51 | endif 52 | 53 | ifdef PARALLEL_BUILDS 54 | BUILDFLAGS += -p $(PARALLEL_BUILDS) 55 | GOTEST += -p $(PARALLEL_BUILDS) 56 | else 57 | # -p 4 seems to work well for people 58 | GOTEST += -p 4 59 | endif 60 | 61 | ifdef DISABLE_TEST_CACHING 62 | GOTEST += -count=1 63 | endif 64 | 65 | TEST_PACKAGE ?= ./... 66 | COVER_OUT:=$(REPORTS_DIR)/cover.txt 67 | COVERFLAGS=-coverprofile=$(COVER_OUT) --covermode=atomic --coverpkg=./pkg/... 68 | 69 | .PHONY: list 70 | list: ## List all make targets 71 | @$(MAKE) -pRrn : -f $(MAKEFILE_LIST) 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | sort 72 | 73 | .PHONY: help 74 | .DEFAULT_GOAL := help 75 | help: 76 | @grep -h -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 77 | 78 | full: check ## Build and run the tests 79 | check: build test ## Build and run the tests 80 | 81 | print-version: ## Print version 82 | @echo $(VERSION) 83 | 84 | build: $(GO_DEPENDENCIES) clean ## Build jx binary for current OS 85 | go mod download 86 | CGO_ENABLED=$(CGO_ENABLED) $(GO) $(BUILD_TARGET) $(BUILDFLAGS) -o build/$(BINARY_NAME) $(MAIN_SRC_FILE) 87 | 88 | build-all: $(GO_DEPENDENCIES) build make-reports-dir ## Build all files - runtime, all tests etc. 89 | CGO_ENABLED=$(CGO_ENABLED) $(GOTEST) -run=nope -tags=integration -failfast -short ./... $(BUILDFLAGS) 90 | 91 | tidy-deps: ## Cleans up dependencies 92 | $(GO) mod tidy 93 | # mod tidy only takes compile dependencies into account, let's make sure we capture tooling dependencies as well 94 | @$(MAKE) install-generate-deps 95 | 96 | .PHONY: make-reports-dir 97 | make-reports-dir: 98 | mkdir -p $(REPORTS_DIR) 99 | 100 | test: ## Run tests with the "unit" build tag 101 | KUBECONFIG=/cluster/connections/not/allowed JX3_HOME=/tmp/jx3 CGO_ENABLED=$(CGO_ENABLED) $(GOTEST) --tags=unit -failfast -short ./... $(TEST_BUILDFLAGS) 102 | 103 | test-coverage : make-reports-dir ## Run tests and coverage for all tests with the "unit" build tag 104 | CGO_ENABLED=$(CGO_ENABLED) $(GOTEST) --tags=unit $(COVERFLAGS) -failfast -short ./... $(TEST_BUILDFLAGS) 105 | 106 | test-report-html: make-reports-dir test-coverage 107 | $(GO) tool cover -html=$(COVER_OUT) 108 | 109 | test-total-cov: make-reports-dir test-coverage 110 | $(GO) tool cover -func=$(COVER_OUT) 111 | 112 | install: $(GO_DEPENDENCIES) ## Install the binary 113 | GOBIN=${GOPATH}/bin $(GO) install $(BUILDFLAGS) $(MAIN_SRC_FILE) 114 | 115 | linux: ## Build for Linux 116 | CGO_ENABLED=$(CGO_ENABLED) GOOS=linux GOARCH=amd64 $(GO) $(BUILD_TARGET) $(BUILDFLAGS) -o build/linux/$(BINARY_NAME) $(MAIN_SRC_FILE) 117 | chmod +x build/linux/$(BINARY_NAME) 118 | 119 | arm: ## Build for ARM 120 | CGO_ENABLED=$(CGO_ENABLED) GOOS=linux GOARCH=arm $(GO) $(BUILD_TARGET) $(BUILDFLAGS) -o build/arm/$(BINARY_NAME) $(MAIN_SRC_FILE) 121 | chmod +x build/arm/$(BINARY_NAME) 122 | 123 | win: ## Build for Windows 124 | CGO_ENABLED=$(CGO_ENABLED) GOOS=windows GOARCH=amd64 $(GO) $(BUILD_TARGET) $(BUILDFLAGS) -o build/win/$(BINARY_NAME)-windows-amd64.exe $(MAIN_SRC_FILE) 125 | 126 | darwin: ## Build for OSX 127 | CGO_ENABLED=$(CGO_ENABLED) GOOS=darwin GOARCH=amd64 $(GO) $(BUILD_TARGET) $(BUILDFLAGS) -o build/darwin/$(BINARY_NAME) $(MAIN_SRC_FILE) 128 | chmod +x build/darwin/$(BINARY_NAME) 129 | 130 | .PHONY: release 131 | release: clean linux test 132 | 133 | release-all: release linux win darwin 134 | 135 | .PHONY: goreleaser 136 | goreleaser: 137 | step-go-releaser --organisation=$(ORG) --revision=$(REV) --branch=$(BRANCH) --build-date=$(BUILD_DATE) --go-version=$(GO_VERSION) --root-package=$(ROOT_PACKAGE) --version=$(VERSION) 138 | 139 | .PHONY: clean 140 | clean: ## Clean the generated artifacts 141 | rm -rf build release dist 142 | 143 | get-fmt-deps: ## Install test dependencies 144 | $(GO_NOMOD) install golang.org/x/tools/cmd/goimports 145 | 146 | .PHONY: fmt 147 | fmt: importfmt ## Format the code 148 | $(eval FORMATTED = $(shell $(GO) fmt ./...)) 149 | @if [ "$(FORMATTED)" == "" ]; \ 150 | then \ 151 | echo "All Go files properly formatted"; \ 152 | else \ 153 | echo "Fixed formatting for: $(FORMATTED)"; \ 154 | fi 155 | 156 | .PHONY: importfmt 157 | importfmt: get-fmt-deps 158 | @echo "Formatting the imports..." 159 | goimports -w $(GO_DEPENDENCIES) 160 | 161 | .PHONY: lint 162 | lint: ## Lint the code 163 | ./hack/gofmt.sh 164 | ./hack/linter.sh 165 | ./hack/generate.sh 166 | 167 | .PHONY: all 168 | all: fmt build test lint 169 | 170 | bin/docs: 171 | go build $(LDFLAGS) -v -o bin/docs cmd/docs/*.go 172 | 173 | .PHONY: docs 174 | docs: bin/docs ## update docs 175 | @echo "Generating docs" 176 | @./bin/docs --target=./docs/cmd 177 | @./bin/docs --target=./docs/man/man1 --kind=man 178 | @rm -f ./bin/docs -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - rawlingsj 3 | - jstrachan 4 | - rajdavies 5 | - ankitm123 6 | - maintainers 7 | reviewers: 8 | - rawlingsj 9 | - jstrachan 10 | - rajdavies 11 | - ankitm123 12 | - maintainers 13 | -------------------------------------------------------------------------------- /OWNERS_ALIASES: -------------------------------------------------------------------------------- 1 | foreignAliases: 2 | - name: jx-community 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jenkins X CLI 2 | 3 | [![Documentation](https://godoc.org/github.com/jenkins-x/jx?status.svg)](https://pkg.go.dev/mod/github.com/jenkins-x/jx) 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/jenkins-x/jx)](https://goreportcard.com/report/github.com/jenkins-x/jx) 5 | [![Releases](https://img.shields.io/github/release-pre/jenkins-x/jx.svg)](https://github.com/jenkins-x/jx/releases) 6 | [![LICENSE](https://img.shields.io/github/license/jenkins-x/jx.svg)](https://github.com/jenkins-x/jx/blob/master/LICENSE) 7 | [![Slack Status](https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social)](https://slack.k8s.io/) 8 | [![codecov](https://codecov.io/gh/jenkins-x/jx/branch/main/graph/badge.svg?token=aBT7eQHx37)](https://codecov.io/gh/jenkins-x/jx) 9 | 10 | `jx` is the modular command line CLI for [Jenkins X 3.x](https://jenkins-x.io/v3/about/) 11 | 12 | ## Commands 13 | 14 | See the [jx command reference](https://jenkins-x.io/v3/develop/reference/jx/) 15 | 16 | ## Issues 17 | 18 | To track [issues in this repository](https://github.com/jenkins-x/jx/issues) and all the related [Plugins](#plugins) use these links: 19 | 20 | * [view open issues in jenkins-x-plugins](https://github.com/issues?q=is%3Aopen+is%3Aissue+author%3Ajstrachan+archived%3Afalse+user%3Ajenkins-x-plugins) 21 | * [view open pull requests in jenkins-x-plugins](https://github.com/pulls?q=is%3Aopen+is%3Apr+archived%3Afalse+user%3Ajenkins-x-plugins+-label%3Adependencies) 22 | 23 | ## Plugins 24 | 25 | You can browse the documentation for all of the `jx` plugins at: 26 | 27 | * [Plugin CLI Reference](https://jenkins-x.io/v3/develop/reference/jx/) 28 | * [Plugin Source](https://github.com/jenkins-x-plugins) 29 | 30 | 31 | ## Components 32 | 33 | * [jx-git-operator](https://github.com/jenkins-x/jx-git-operator) is an operator for triggering jobs when git commits are made 34 | * [octant-jx](https://github.com/jenkins-x/octant-jx) an open source Jenkins X UI for [vmware-tanzu/octant](https://github.com/vmware-tanzu/octant) 35 | 36 | ## Libraries 37 | 38 | These are the modular libraries which have been refactored out of the main [jenkins-x/jx](https://github.com/jenkins-x/jx) repository as part of the [modularisation enhancement process](https://github.com/jenkins-x/enhancements/tree/master/proposals/5#1-overview) 39 | 40 | * [go-scm](https://github.com/jenkins-x/go-scm) API for working with SCM providers 41 | * [jx-api](https://github.com/jenkins-x/jx-api) the core JX APIs 42 | * [jx-helpers](https://github.com/jenkins-x/jx-helpers) a bunch of utilities (mostly from the `util` package) refactored + no longer dependent on [jenkins-x/jx](https://github.com/jenkins-x/jx/) 43 | * [jx-kube-client](https://github.com/jenkins-x/jx-kube-client) the core library for working with kube/jx/tekton clients 44 | * [jx-logging](https://github.com/jenkins-x/jx-logging) logging APIs 45 | * [lighthouse-client](https://github.com/jenkins-x/lighthouse-client) client library for working with [lighthouse](https://github.com/jenkins-x/lighthouse) 46 | 47 | 48 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | The Jenkins X project takes security seriously. We make every possible effort to ensure users can adequately secure their automation infrastructure. To that end, we work with Jenkins X platform and app developers, as well as security researchers, to fix security vulnerabilities in Jenkins X in a timely manner, and to improve the security of Jenkins X in general. 4 | 5 | ## Supported Versions 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | 2.0.x | :white_check_mark: | 10 | 11 | 12 | ## Reporting a Vulnerability 13 | 14 | If you find a vulnerability in Jenkins X, please report it in the Jenkins CI issue tracker under the [SECURITY](https://issues.jenkins-ci.org/browse/SECURITY) project. **Please do not report security issues in the github tracker.** 15 | This project is configured in such a way that only the reporter and the security team can see the details. By restricting access to this potentially sensitive information, we can work on a fix and deliver it before the method of attack becomes well-known. 16 | 17 | If you are unable to report using the above issue tracker, you can also send your report to the private Jenkins Security Team mailing list: jenkinsci-cert@googlegroups.com 18 | 19 | ## Vulnerabilities in Apps 20 | 21 | Whilst the Jenkins X team is not responsible for the quality of third party apps, please still use the above reporting mechanism and we will co-ordinate with the app developer to ensure a fix in a secure maner. 22 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -z "$GCP_SA" ] 4 | then 5 | echo "no GCP SA specified" 6 | else 7 | echo "enabling GCP Service Account from $GCP_SA" 8 | gcloud auth activate-service-account --key-file $GCP_SA 9 | fi 10 | 11 | 12 | echo "building container image version: $VERSION" 13 | 14 | gcloud builds submit --config cloudbuild.yaml --project jenkinsxio --substitutions=_VERSION="$VERSION" 15 | 16 | -------------------------------------------------------------------------------- /charts/jx-cli/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | *.png 23 | Makefile -------------------------------------------------------------------------------- /charts/jx-cli/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: jx 3 | description: Jenkins X next gen cloud CI / CD platform for Kubernetes 4 | home: https://jenkins-x.io/ 5 | version: 0.0.1 6 | appVersion: 3.0.0 7 | icon: https://jenkins-x.github.io/jenkins-x-website/img/profile.png 8 | sources: 9 | - https://github.com/jenkins-x/jx 10 | maintainers: 11 | - name: Jenkins X Team 12 | email: jenkins-x@googlegroups.com -------------------------------------------------------------------------------- /charts/jx-cli/Makefile: -------------------------------------------------------------------------------- 1 | CHART_REPO := gs://jenkinsxio/charts 2 | NAME := jx 3 | 4 | build: clean 5 | rm -rf Chart.lock 6 | helm dependency build 7 | helm lint 8 | 9 | install: clean build 10 | helm install . --name ${NAME} 11 | 12 | upgrade: clean build 13 | helm upgrade ${NAME} . 14 | 15 | delete: 16 | helm delete --purge ${NAME} 17 | 18 | clean: 19 | rm -rf charts 20 | rm -rf ${NAME}*.tgz 21 | 22 | release: clean 23 | sed -i -e "s/version:.*/version: $(VERSION)/" Chart.yaml 24 | 25 | helm dependency build 26 | helm lint 27 | helm package . 28 | helm repo add jx-labs $(CHART_REPO) 29 | helm gcs push ${NAME}*.tgz jx-labs --public 30 | rm -rf ${NAME}*.tgz% -------------------------------------------------------------------------------- /charts/jx-cli/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | 6 | {{/* 7 | Create a default fully qualified app name. 8 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 9 | If release name contains chart name it will be used as a full name. 10 | */}} 11 | {{- define "jx.fullname" -}} 12 | {{- if .Values.fullnameOverride -}} 13 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 14 | {{- else -}} 15 | {{- $name := default .Chart.Name .Values.nameOverride -}} 16 | {{- if contains $name .Release.Name -}} 17 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 18 | {{- else -}} 19 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 20 | {{- end -}} 21 | {{- end -}} 22 | {{- end -}} 23 | 24 | {{/* 25 | Create chart name and version as used by the chart label. 26 | */}} 27 | {{- define "jx.chart" -}} 28 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 29 | {{- end -}} 30 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.clusterrole.enabled -}} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: {{ template "jx.fullname" . }}-{{ .Release.Namespace }} 6 | {{ if .Values.clusterrole.rules -}} 7 | rules: 8 | {{ toYaml .Values.clusterrole.rules | indent 0 }} 9 | {{- end }} 10 | {{- end }} 11 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.clusterrole.enabled -}} 2 | {{- if .Values.serviceaccount.enabled -}} 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRoleBinding 5 | metadata: 6 | name: {{ template "jx.fullname" . }}-{{ .Release.Namespace }} 7 | namespace: {{ .Release.Namespace }} 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: {{ template "jx.fullname" . }}-{{ .Release.Namespace }} 12 | subjects: 13 | - kind: ServiceAccount 14 | {{- if .Values.serviceaccount.customName }} 15 | name: {{ .Values.serviceaccount.customName }} 16 | {{- else }} 17 | name: {{ template "jx.fullname" . }} 18 | {{- end }} 19 | namespace: {{ .Release.Namespace }} 20 | {{- end }} 21 | {{- end }} -------------------------------------------------------------------------------- /charts/jx-cli/templates/cronjob.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cronjob.enabled -}} 2 | apiVersion: batch/v1 3 | kind: CronJob 4 | metadata: 5 | name: {{ template "jx.fullname" . }} 6 | labels: 7 | app: {{ template "jx.fullname" . }} 8 | chart: {{ template "jx.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | spec: 12 | concurrencyPolicy: {{ .Values.cronjob.concurrencyPolicy }} 13 | failedJobsHistoryLimit: {{ .Values.cronjob.failedJobsHistoryLimit }} 14 | successfulJobsHistoryLimit: {{ .Values.cronjob.successfulJobsHistoryLimit }} 15 | schedule: {{ .Values.cronjob.schedule | quote }} 16 | jobTemplate: 17 | spec: 18 | template: 19 | metadata: 20 | labels: 21 | app: {{ template "jx.fullname" . }} 22 | release: {{ .Release.Name }} 23 | {{- if .Values.podAnnotations }} 24 | annotations: 25 | {{ toYaml .Values.podAnnotations | indent 12 }} 26 | {{- end }} 27 | spec: 28 | {{- if .Values.restartPolicy }} 29 | restartPolicy: {{ .Values.restartPolicy }} 30 | {{- end }} 31 | {{- if .Values.serviceaccount.customName }} 32 | serviceAccountName: {{ .Values.serviceaccount.customName }} 33 | {{- else if .Values.serviceaccount.enabled }} 34 | serviceAccountName: {{ template "jx.fullname" . }} 35 | {{- end }} 36 | containers: 37 | - name: {{ .Chart.Name }} 38 | {{ if .Values.command -}} 39 | command: {{ .Values.command }} 40 | {{- end }} 41 | {{ if .Values.args -}} 42 | args: 43 | {{ toYaml .Values.args | indent 14 }} 44 | {{- end }} 45 | imagePullPolicy: {{ .Values.image.pullPolicy }} 46 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 47 | {{- if .Values.env }} 48 | env: 49 | {{- range $pkey, $pval := .Values.env }} 50 | - name: {{ $pkey }} 51 | value: {{ $pval }} 52 | {{- end }} 53 | {{- end }} 54 | resources: 55 | {{ toYaml .Values.resources | indent 12 }} 56 | {{- with .Values.nodeSelector }} 57 | nodeSelector: 58 | {{ toYaml . | indent 8 }} 59 | {{- end }} 60 | {{- with .Values.affinity }} 61 | affinity: 62 | {{ toYaml . | indent 8 }} 63 | {{- end }} 64 | {{- with .Values.tolerations }} 65 | tolerations: 66 | {{ toYaml . | indent 8 }} 67 | {{- end }} 68 | {{- end }} 69 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/daemonset.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.daemonset.enabled -}} 2 | apiVersion: apps/v1 3 | kind: DaemonSet 4 | metadata: 5 | name: {{ template "jx.fullname" . }} 6 | labels: 7 | app: {{ template "jx.fullname" . }} 8 | chart: {{ template "jx.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | spec: 12 | backoffLimit: {{ .Values.backoffLimit }} 13 | activeDeadlineSeconds: {{ .Values.activeDeadlineSeconds }} 14 | selector: 15 | matchLabels: 16 | app: {{ template "jx.fullname" . }} 17 | release: {{ .Release.Name }} 18 | template: 19 | metadata: 20 | labels: 21 | app: {{ template "jx.fullname" . }} 22 | release: {{ .Release.Name }} 23 | {{- if .Values.podAnnotations }} 24 | annotations: 25 | {{ toYaml .Values.podAnnotations | indent 8 }} 26 | {{- end }} 27 | spec: 28 | {{- if .Values.restartPolicy }} 29 | restartPolicy: {{ .Values.restartPolicy }} 30 | {{- end }} 31 | containers: 32 | - name: {{ .Chart.Name }} 33 | {{ if .Values.command -}} 34 | command: {{ .Values.command }} 35 | {{- end }} 36 | {{ if .Values.args -}} 37 | args: 38 | {{ toYaml .Values.args | indent 10 }} 39 | {{- end }} 40 | imagePullPolicy: {{ .Values.image.pullPolicy }} 41 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 42 | ports: 43 | - name: http 44 | containerPort: {{ .Values.internalPort }} 45 | protocol: TCP 46 | livenessProbe: 47 | httpGet: 48 | path: {{ .Values.probe.path }} 49 | port: http 50 | readinessProbe: 51 | httpGet: 52 | path: {{ .Values.probe.path }} 53 | port: http 54 | {{- if .Values.env }} 55 | env: 56 | {{- range $pkey, $pval := .Values.env }} 57 | - name: {{ $pkey }} 58 | value: {{ $pval }} 59 | {{- end }} 60 | {{- end }} 61 | resources: 62 | {{ toYaml .Values.resources | indent 12 }} 63 | {{- with .Values.nodeSelector }} 64 | nodeSelector: 65 | {{ toYaml . | indent 8 }} 66 | {{- end }} 67 | {{- with .Values.affinity }} 68 | affinity: 69 | {{ toYaml . | indent 8 }} 70 | {{- end }} 71 | {{- with .Values.tolerations }} 72 | tolerations: 73 | {{ toYaml . | indent 8 }} 74 | {{- end }} 75 | {{- end }} -------------------------------------------------------------------------------- /charts/jx-cli/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.deployment.enabled -}} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ template "jx.fullname" . }} 6 | labels: 7 | app: {{ template "jx.fullname" . }} 8 | chart: {{ template "jx.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | spec: 12 | selector: 13 | matchLabels: 14 | app: {{ template "jx.fullname" . }} 15 | release: {{ .Release.Name }} 16 | template: 17 | metadata: 18 | labels: 19 | app: {{ template "jx.fullname" . }} 20 | release: {{ .Release.Name }} 21 | {{- if .Values.podAnnotations }} 22 | annotations: 23 | {{ toYaml .Values.podAnnotations | indent 8 }} 24 | {{- end }} 25 | spec: 26 | {{- if .Values.restartPolicy }} 27 | restartPolicy: {{ .Values.restartPolicy }} 28 | {{- end }} 29 | {{- if .Values.serviceaccount.customName }} 30 | serviceAccountName: {{ .Values.serviceaccount.customName }} 31 | {{- else if .Values.serviceaccount.enabled }} 32 | serviceAccountName: {{ template "jx.fullname" . }} 33 | {{- end }} 34 | containers: 35 | - name: {{ .Chart.Name }} 36 | {{ if .Values.command -}} 37 | command: {{ .Values.command }} 38 | {{- end }} 39 | {{ if .Values.args -}} 40 | args: 41 | {{ toYaml .Values.args | indent 10 }} 42 | {{- end }} 43 | imagePullPolicy: {{ .Values.image.pullPolicy }} 44 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 45 | ports: 46 | - name: http 47 | containerPort: {{ .Values.internalPort }} 48 | protocol: TCP 49 | {{- if .Values.probe.path }} 50 | livenessProbe: 51 | httpGet: 52 | path: {{ .Values.probe.path }} 53 | port: http 54 | readinessProbe: 55 | httpGet: 56 | path: {{ .Values.probe.path }} 57 | port: http 58 | {{- end }} 59 | {{- if .Values.env }} 60 | env: 61 | {{- range $pkey, $pval := .Values.env }} 62 | - name: {{ $pkey }} 63 | value: {{ $pval }} 64 | {{- end }} 65 | {{- end }} 66 | resources: 67 | {{ toYaml .Values.resources | indent 12 }} 68 | {{- with .Values.nodeSelector }} 69 | nodeSelector: 70 | {{ toYaml . | indent 8 }} 71 | {{- end }} 72 | {{- with .Values.affinity }} 73 | affinity: 74 | {{ toYaml . | indent 8 }} 75 | {{- end }} 76 | {{- with .Values.tolerations }} 77 | tolerations: 78 | {{ toYaml . | indent 8 }} 79 | {{- end }} 80 | {{- end }} 81 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/job.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.job.enabled -}} 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: {{ template "jx.fullname" . }} 6 | labels: 7 | app: {{ template "jx.fullname" . }} 8 | chart: {{ template "jx.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.job.annotations }} 12 | annotations: 13 | {{ toYaml .Values.job.annotations | indent 4 }} 14 | {{- end }} 15 | spec: 16 | backoffLimit: {{ .Values.backoffLimit }} 17 | activeDeadlineSeconds: {{ .Values.activeDeadlineSeconds }} 18 | template: 19 | metadata: 20 | labels: 21 | app: {{ template "jx.fullname" . }} 22 | release: {{ .Release.Name }} 23 | {{- if .Values.podAnnotations }} 24 | annotations: 25 | {{ toYaml .Values.podAnnotations | indent 8 }} 26 | {{- end }} 27 | spec: 28 | {{- if .Values.restartPolicy }} 29 | restartPolicy: {{ .Values.restartPolicy }} 30 | {{- end }} 31 | {{- if .Values.serviceaccount.customName }} 32 | serviceAccountName: {{ .Values.serviceaccount.customName }} 33 | {{- else if .Values.serviceaccount.enabled }} 34 | serviceAccountName: {{ template "jx.fullname" . }} 35 | {{- end }} 36 | containers: 37 | - name: {{ .Chart.Name }} 38 | {{ if .Values.command -}} 39 | command: {{ .Values.command }} 40 | {{- end }} 41 | {{ if .Values.args -}} 42 | args: 43 | {{ toYaml .Values.args | indent 10 }} 44 | {{- end }} 45 | imagePullPolicy: {{ .Values.image.pullPolicy }} 46 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 47 | ports: 48 | - name: http 49 | containerPort: {{ .Values.internalPort }} 50 | protocol: TCP 51 | {{- if .Values.probe.path }} 52 | livenessProbe: 53 | httpGet: 54 | path: {{ .Values.probe.path }} 55 | port: http 56 | readinessProbe: 57 | httpGet: 58 | path: {{ .Values.probe.path }} 59 | port: http 60 | {{- end }} 61 | {{- if .Values.env }} 62 | env: 63 | {{- range $pkey, $pval := .Values.env }} 64 | - name: {{ $pkey }} 65 | value: {{ $pval }} 66 | {{- end }} 67 | {{- end }} 68 | resources: 69 | {{ toYaml .Values.resources | indent 12 }} 70 | {{- with .Values.nodeSelector }} 71 | nodeSelector: 72 | {{ toYaml . | indent 8 }} 73 | {{- end }} 74 | {{- with .Values.affinity }} 75 | affinity: 76 | {{ toYaml . | indent 8 }} 77 | {{- end }} 78 | {{- with .Values.tolerations }} 79 | tolerations: 80 | {{ toYaml . | indent 8 }} 81 | {{- end }} 82 | {{- end }} -------------------------------------------------------------------------------- /charts/jx-cli/templates/role.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.role.enabled -}} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: {{ template "jx.fullname" . }} 6 | {{ if .Values.role.rules -}} 7 | rules: 8 | {{ toYaml .Values.role.rules | indent 0 }} 9 | {{- end }} 10 | 11 | {{- if .Values.role.additionalNamespaces }} 12 | {{- $ctx := . -}} 13 | {{- range .Values.role.additionalNamespaces }} 14 | --- 15 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: Role 17 | metadata: 18 | name: {{ template "jx.fullname" $ctx }} 19 | namespace: {{ . }} 20 | {{ if $.Values.role.rules -}} 21 | rules: 22 | {{ toYaml $.Values.role.rules | indent 0 }} 23 | {{- end }} 24 | {{- end }} 25 | {{- end }} 26 | {{- end }} 27 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.role.enabled -}} 2 | {{- if .Values.serviceaccount.enabled -}} 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: RoleBinding 5 | metadata: 6 | name: {{ template "jx.fullname" . }} 7 | namespace: {{ .Release.Namespace }} 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: Role 11 | name: {{ template "jx.fullname" . }} 12 | subjects: 13 | - kind: ServiceAccount 14 | {{- if .Values.serviceaccount.customName }} 15 | name: {{ .Values.serviceaccount.customName }} 16 | {{- else }} 17 | name: {{ template "jx.fullname" . }} 18 | {{- end }} 19 | namespace: {{ .Release.Namespace }} 20 | 21 | {{- if .Values.role.additionalNamespaces }} 22 | {{- $ctx := . -}} 23 | {{- range .Values.role.additionalNamespaces }} 24 | --- 25 | apiVersion: rbac.authorization.k8s.io/v1 26 | kind: RoleBinding 27 | metadata: 28 | name: {{ template "jx.fullname" $ctx }} 29 | namespace: {{ . }} 30 | roleRef: 31 | apiGroup: rbac.authorization.k8s.io 32 | kind: Role 33 | name: {{ template "jx.fullname" $ctx }} 34 | subjects: 35 | - kind: ServiceAccount 36 | {{- if $.Values.serviceaccount.customName }} 37 | name: {{ $.Values.serviceaccount.customName }} 38 | {{- else }} 39 | name: {{ template "jx.fullname" $ctx }} 40 | {{- end }} 41 | namespace: {{ $.Release.Namespace }} 42 | {{- end }} 43 | {{- end }} 44 | {{- end }} 45 | {{- end }} 46 | 47 | -------------------------------------------------------------------------------- /charts/jx-cli/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.service.enabled -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "jx.fullname" . }} 6 | labels: 7 | app: {{ template "jx.fullname" . }} 8 | chart: {{ template "jx.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.service.serviceAnnotations }} 12 | annotations: 13 | {{ toYaml .Values.service.serviceAnnotations | indent 4 }} 14 | {{- end }} 15 | spec: 16 | type: {{ .Values.service.type }} 17 | ports: 18 | - port: {{ .Values.service.port }} 19 | targetPort: http 20 | protocol: TCP 21 | name: http 22 | selector: 23 | app: {{ template "jx.fullname" . }} 24 | release: {{ .Release.Name }} 25 | {{- end }} -------------------------------------------------------------------------------- /charts/jx-cli/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceaccount.enabled -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | {{- if .Values.serviceaccount.customName }} 6 | name: {{ .Values.serviceaccount.customName }} 7 | {{- else }} 8 | name: {{ template "jx.fullname" . }} 9 | {{- end }} 10 | labels: 11 | app: {{ template "jx.fullname" . }} 12 | chart: {{ template "jx.chart" . }} 13 | release: {{ .Release.Name }} 14 | heritage: {{ .Release.Service }} 15 | annotations: 16 | {{- range $key, $value := .Values.serviceaccount.annotations }} 17 | {{ $key }}: {{ $value }} 18 | {{- end }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /charts/jx-cli/values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: gcr.io/jenkinsxio/jx 3 | tag: 3.0.354 4 | pullPolicy: IfNotPresent 5 | 6 | replicaCount: 1 7 | 8 | deployment: 9 | enabled: false 10 | 11 | service: 12 | enabled: false 13 | 14 | daemonset: 15 | enabled: false 16 | 17 | job: 18 | enabled: false 19 | 20 | podAnnotations: {} 21 | 22 | cronjob: 23 | enabled: false 24 | schedule: "* * * * *" 25 | failedJobsHistoryLimit: 1 26 | successfulJobsHistoryLimit: 3 27 | concurrencyPolicy: Forbid 28 | 29 | serviceaccount: 30 | enabled: false 31 | customName: "" 32 | 33 | role: 34 | enabled: false 35 | # example: 36 | # rules: 37 | # - apiGroups: 38 | # - jenkins.io 39 | # resources: 40 | # - pipelineactivities 41 | # verbs: 42 | # - list 43 | # - delete 44 | # - apiGroups: 45 | # - "" 46 | # resources: 47 | # - secrets 48 | # - services 49 | # verbs: 50 | # - get 51 | # rules: 52 | # - apiGroups: 53 | # - jenkins.io 54 | # resources: 55 | # - environments 56 | # verbs: 57 | # - list 58 | # - delete 59 | # - apiGroups: 60 | # - "" 61 | # resources: 62 | # - secrets 63 | # verbs: 64 | # - get 65 | # - list 66 | # - apiGroups: 67 | # - apiextensions.k8s.io 68 | # resources: 69 | # - customresourcedefinitions 70 | # verbs: 71 | # - create 72 | 73 | clusterrole: 74 | enabled: false 75 | # rules: 76 | # - apiGroups: 77 | # - apiextensions.k8s.io 78 | # resources: 79 | # - customresourcedefinitions 80 | # verbs: 81 | # - get 82 | # - apiGroups: 83 | # - "" 84 | # resources: 85 | # - namespace 86 | # verbs: 87 | # - get 88 | # - delete 89 | # - list 90 | # - apiGroups: 91 | # - "" 92 | # resources: 93 | # - deployments 94 | # verbs: 95 | # - get 96 | 97 | activeDeadlineSeconds: 300 98 | backoffLimit: 5 99 | 100 | # default is Always but for Jobs use Never or OnFailure 101 | restartPolicy: Never 102 | 103 | command: ["jx"] 104 | args: 105 | - "version" 106 | 107 | env: 108 | # lets use JSON output in logs 109 | JX_LOG_FORMAT: json 110 | 111 | # lets set the logging level 112 | JX_LOG_LEVEL: info 113 | 114 | # lets mark this pod as being a CI/CD pipeline job so reuse the pipeline git user 115 | PIPELINE_KIND: dummy 116 | 117 | internalPort: 80 118 | 119 | probe: 120 | path: / 121 | 122 | service: 123 | type: ClusterIP 124 | port: 80 125 | 126 | resources: {} 127 | # We usually recommend not to specify default resources and to leave this as a conscious 128 | # choice for the user. This also increases chances charts run on environments with little 129 | # resources. If you do want to specify resources, uncomment the following 130 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 131 | # limits: 132 | # cpu: 100m 133 | # memory: 128Mi 134 | # requests: 135 | # cpu: 100m 136 | # memory: 128Mi 137 | 138 | nodeSelector: {} 139 | 140 | tolerations: [] 141 | 142 | affinity: {} 143 | -------------------------------------------------------------------------------- /cmd/app/main-win.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package app 4 | 5 | import ( 6 | "os" 7 | "syscall" 8 | 9 | "github.com/jenkins-x/jx/pkg/cmd" 10 | ) 11 | 12 | // Run runs the command, if args are not nil they will be set on the command 13 | func Run(args []string) error { 14 | configureTerminalForAnsiEscapes() 15 | cmd := cmd.Main(args) 16 | if len(args) > 0 { 17 | args = args[1:] 18 | cmd.SetArgs(args) 19 | } 20 | return cmd.Execute() 21 | } 22 | 23 | const ( 24 | // https://docs.microsoft.com/en-us/windows/console/setconsolemode 25 | enableProcessedOutput = 0x1 26 | enableWrapAtEOLOutput = 0x2 27 | enableVirtualTerminalProcessing = 0x4 28 | ) 29 | 30 | // configureTerminalForAnsiEscapes enables the windows 10 console to translate ansi escape sequences 31 | // requires windows 10 1511 or higher and fails gracefully on older versions (and prior releases like windows 7) 32 | // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences 33 | func configureTerminalForAnsiEscapes() { 34 | 35 | kernel32 := syscall.NewLazyDLL("kernel32.dll") 36 | kern32SetConsoleMode := kernel32.NewProc("SetConsoleMode") 37 | 38 | // stderr 39 | handle := syscall.Handle(os.Stderr.Fd()) 40 | kern32SetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEOLOutput|enableVirtualTerminalProcessing) 41 | 42 | // stdout 43 | handle = syscall.Handle(os.Stdout.Fd()) 44 | kern32SetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEOLOutput|enableVirtualTerminalProcessing) 45 | } 46 | -------------------------------------------------------------------------------- /cmd/app/main.go: -------------------------------------------------------------------------------- 1 | //nolint:gofmt,goimports 2 | //go:build !windows 3 | 4 | package app 5 | 6 | import ( 7 | "github.com/jenkins-x/jx/pkg/cmd" 8 | ) 9 | 10 | // Run runs the command, if args are not nil they will be set on the command 11 | func Run(args []string) error { 12 | c := cmd.Main(args) 13 | if args != nil { 14 | args = args[1:] 15 | c.SetArgs(args) 16 | } 17 | return c.Execute() 18 | } 19 | -------------------------------------------------------------------------------- /cmd/docs/main.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 The Tekton 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 | package main 15 | 16 | import ( 17 | "fmt" 18 | "log" 19 | "os" 20 | "path/filepath" 21 | "strings" 22 | 23 | "github.com/jenkins-x/jx/pkg/cmd" 24 | "github.com/spf13/cobra" 25 | "github.com/spf13/pflag" 26 | ) 27 | 28 | const descriptionSourcePath = "docs/reference/cmd/" 29 | 30 | func generateCliYaml(opts *options) error { 31 | root := cmd.Main(nil) 32 | disableFlagsInUseLine(root) 33 | source := filepath.Join(opts.source, descriptionSourcePath) 34 | if err := loadLongDescription(root, source); err != nil { 35 | return err 36 | } 37 | 38 | switch opts.kind { 39 | case "markdown": 40 | return GenMarkdownTree(root, opts.target) 41 | case "man": 42 | header := &GenManHeader{ 43 | Section: "1", 44 | } 45 | return GenManTree(root, header, opts.target) 46 | default: 47 | return fmt.Errorf("invalid docs kind : %s", opts.kind) 48 | } 49 | } 50 | 51 | func disableFlagsInUseLine(cmd *cobra.Command) { 52 | visitAll(cmd, func(ccmd *cobra.Command) { 53 | // do not add a `[flags]` to the end of the usage line. 54 | ccmd.DisableFlagsInUseLine = true 55 | }) 56 | } 57 | 58 | // visitAll will traverse all commands from the root. 59 | // This is different from the VisitAll of cobra.Command where only parents 60 | // are checked. 61 | func visitAll(root *cobra.Command, fn func(*cobra.Command)) { 62 | for _, c := range root.Commands() { 63 | visitAll(c, fn) 64 | } 65 | fn(root) 66 | } 67 | 68 | func loadLongDescription(cmd *cobra.Command, path ...string) error { 69 | for _, c := range cmd.Commands() { 70 | if c.Name() == "" { 71 | continue 72 | } 73 | fullpath := filepath.Join(path[0], strings.Join(append(path[1:], c.Name()), "_")+".md") 74 | if c.HasSubCommands() { 75 | if err := loadLongDescription(c, path[0], c.Name()); err != nil { 76 | return err 77 | } 78 | } 79 | 80 | if _, err := os.Stat(fullpath); err != nil { 81 | log.Printf("WARN: %s does not exist, skipping\n", fullpath) 82 | continue 83 | } 84 | 85 | content, err := os.ReadFile(fullpath) 86 | if err != nil { 87 | return err 88 | } 89 | description, examples := parseMDContent(string(content)) 90 | c.Long = description 91 | c.Example = examples 92 | } 93 | return nil 94 | } 95 | 96 | type options struct { 97 | source string 98 | target string 99 | kind string 100 | } 101 | 102 | func parseArgs() (*options, error) { 103 | opts := &options{} 104 | cwd, _ := os.Getwd() 105 | flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) 106 | flags.StringVar(&opts.source, "root", cwd, "Path to project root") 107 | flags.StringVar(&opts.target, "target", "/tmp", "Target path for generated yaml files") 108 | flags.StringVar(&opts.kind, "kind", "markdown", "Kind of docs to generate (supported: man, markdown)") 109 | err := flags.Parse(os.Args[1:]) 110 | return opts, err 111 | } 112 | 113 | func parseMDContent(mdString string) (description, examples string) { 114 | parsedContent := strings.Split(mdString, "\n## ") 115 | for _, s := range parsedContent { 116 | if strings.Index(s, "Description") == 0 { 117 | description = strings.TrimSpace(strings.TrimPrefix(s, "Description")) 118 | } 119 | if strings.Index(s, "Examples") == 0 { 120 | examples = strings.TrimSpace(strings.TrimPrefix(s, "Examples")) 121 | } 122 | } 123 | return description, examples 124 | } 125 | 126 | func main() { 127 | opts, err := parseArgs() 128 | if err != nil { 129 | fmt.Fprintln(os.Stderr, err.Error()) 130 | } 131 | if opts != nil { 132 | fmt.Printf("Project root: %s\n", opts.source) 133 | fmt.Printf("Generating yaml files into %s\n", opts.target) 134 | 135 | if err := generateCliYaml(opts); err != nil { 136 | fmt.Fprintf(os.Stderr, "Failed to generate yaml files: %s\n", err.Error()) 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /cmd/docs/man_docs.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 The Tekton 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 | "bytes" 19 | "fmt" 20 | "io" 21 | "os" 22 | "path/filepath" 23 | "sort" 24 | "strings" 25 | 26 | "github.com/cpuguy83/go-md2man/md2man" 27 | "github.com/spf13/cobra" 28 | "github.com/spf13/pflag" 29 | ) 30 | 31 | // GenManTree will generate a man page for this command and all descendants 32 | // in the directory given. The header may be nil. This function may not work 33 | // correctly if your command names have `-` in them. If you have `cmd` with two 34 | // subcmds, `sub` and `sub-third`, and `sub` has a subcommand called `third` 35 | // it is undefined which help output will be in the file `cmd-sub-third.1`. 36 | func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error { 37 | return GenManTreeFromOpts(cmd, GenManTreeOptions{ 38 | Header: header, 39 | Path: dir, 40 | CommandSeparator: "-", 41 | }) 42 | } 43 | 44 | // GenManTreeFromOpts generates a man page for the command and all descendants. 45 | // The pages are written to the opts.Path directory. 46 | func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error { 47 | header := opts.Header 48 | if header == nil { 49 | header = &GenManHeader{} 50 | } 51 | for _, c := range cmd.Commands() { 52 | if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { 53 | continue 54 | } 55 | if err := GenManTreeFromOpts(c, opts); err != nil { 56 | return err 57 | } 58 | } 59 | section := "1" 60 | if header.Section != "" { 61 | section = header.Section 62 | } 63 | 64 | separator := "_" 65 | if opts.CommandSeparator != "" { 66 | separator = opts.CommandSeparator 67 | } 68 | basename := strings.ReplaceAll(cmd.CommandPath(), " ", separator) 69 | filename := filepath.Join(opts.Path, basename+"."+section) 70 | f, err := os.Create(filename) 71 | if err != nil { 72 | return err 73 | } 74 | defer f.Close() 75 | 76 | headerCopy := *header 77 | return GenMan(cmd, &headerCopy, f) 78 | } 79 | 80 | // GenManTreeOptions is the options for generating the man pages. 81 | // Used only in GenManTreeFromOpts. 82 | type GenManTreeOptions struct { 83 | Header *GenManHeader 84 | Path string 85 | CommandSeparator string 86 | } 87 | 88 | // GenManHeader is a lot like the .TH header at the start of man pages. These 89 | // include the title, section, source, and manual. We will use 90 | // "Auto generated by spf13/cobra" if the Source is unset. 91 | type GenManHeader struct { 92 | Title string 93 | Section string 94 | Source string 95 | Manual string 96 | } 97 | 98 | // GenMan will generate a man page for the given command and write it to 99 | // w. The header argument may be nil, however obviously w may not. 100 | func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error { 101 | if header == nil { 102 | header = &GenManHeader{} 103 | } 104 | if err := fillHeader(header, cmd.CommandPath()); err != nil { 105 | return err 106 | } 107 | 108 | b := genMan(cmd, header) 109 | _, err := w.Write(md2man.Render(b)) 110 | return err 111 | } 112 | 113 | func fillHeader(header *GenManHeader, name string) error { 114 | if header.Title == "" { 115 | header.Title = strings.ToUpper(strings.ReplaceAll(name, " ", "\\-")) 116 | } 117 | if header.Section == "" { 118 | header.Section = "1" 119 | } 120 | if header.Source == "" { 121 | header.Source = "Auto generated by spf13/cobra" 122 | } 123 | return nil 124 | } 125 | 126 | func manPreamble(buf *bytes.Buffer, header *GenManHeader, cmd *cobra.Command, dashedName string) { 127 | description := cmd.Long 128 | if description == "" { 129 | description = cmd.Short 130 | } 131 | 132 | buf.WriteString(fmt.Sprintf(`%% %s(%s) 133 | %% %s 134 | %% %s 135 | # NAME 136 | `, header.Title, header.Section, header.Source, header.Manual)) 137 | buf.WriteString(fmt.Sprintf("%s \\- %s\n\n", dashedName, cmd.Short)) 138 | buf.WriteString("# SYNOPSIS\n") 139 | buf.WriteString(fmt.Sprintf("**%s**\n\n", cmd.UseLine())) 140 | buf.WriteString("# DESCRIPTION\n") 141 | buf.WriteString(description + "\n\n") 142 | } 143 | 144 | func manPrintFlags(buf *bytes.Buffer, flags *pflag.FlagSet) { 145 | flags.VisitAll(func(flag *pflag.Flag) { 146 | if len(flag.Deprecated) > 0 || flag.Hidden { 147 | return 148 | } 149 | format := "" 150 | if len(flag.Shorthand) > 0 && flag.ShorthandDeprecated == "" { 151 | format = fmt.Sprintf("**-%s**, **--%s**", flag.Shorthand, flag.Name) 152 | } else { 153 | format = fmt.Sprintf("**--%s**", flag.Name) 154 | } 155 | if len(flag.NoOptDefVal) > 0 { 156 | format += "[" 157 | } 158 | if flag.Value.Type() == "string" { 159 | // put quotes on the value 160 | format += "=%q" 161 | } else { 162 | format += "=%s" 163 | } 164 | if len(flag.NoOptDefVal) > 0 { 165 | format += "]" 166 | } 167 | format += "\n\t%s\n\n" 168 | buf.WriteString(fmt.Sprintf(format, flag.DefValue, flag.Usage)) 169 | }) 170 | } 171 | 172 | func manPrintOptions(buf *bytes.Buffer, command *cobra.Command) { 173 | flags := command.NonInheritedFlags() 174 | if flags.HasAvailableFlags() { 175 | buf.WriteString("# OPTIONS\n") 176 | manPrintFlags(buf, flags) 177 | buf.WriteString("\n") 178 | } 179 | flags = command.InheritedFlags() 180 | if flags.HasAvailableFlags() { 181 | buf.WriteString("# OPTIONS INHERITED FROM PARENT COMMANDS\n") 182 | manPrintFlags(buf, flags) 183 | buf.WriteString("\n") 184 | } 185 | } 186 | 187 | func genMan(cmd *cobra.Command, header *GenManHeader) []byte { 188 | cmd.InitDefaultHelpCmd() 189 | cmd.InitDefaultHelpFlag() 190 | 191 | // something like `rootcmd-subcmd1-subcmd2` 192 | dashCommandName := strings.ReplaceAll(cmd.CommandPath(), " ", "-") 193 | 194 | buf := new(bytes.Buffer) 195 | 196 | manPreamble(buf, header, cmd, dashCommandName) 197 | manPrintOptions(buf, cmd) 198 | if len(cmd.Example) > 0 { 199 | buf.WriteString("# EXAMPLE\n") 200 | buf.WriteString(fmt.Sprintf("\n%s\n\n", cmd.Example)) 201 | } 202 | if hasSeeAlso(cmd) { 203 | buf.WriteString("# SEE ALSO\n") 204 | seealsos := make([]string, 0) 205 | if cmd.HasParent() { 206 | parentPath := cmd.Parent().CommandPath() 207 | dashParentPath := strings.ReplaceAll(parentPath, " ", "-") 208 | seealso := fmt.Sprintf("**%s(%s)**", dashParentPath, header.Section) 209 | seealsos = append(seealsos, seealso) 210 | cmd.VisitParents(func(c *cobra.Command) { 211 | if c.DisableAutoGenTag { 212 | cmd.DisableAutoGenTag = c.DisableAutoGenTag 213 | } 214 | }) 215 | } 216 | children := cmd.Commands() 217 | sort.Sort(byName(children)) 218 | for _, c := range children { 219 | if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { 220 | continue 221 | } 222 | seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section) 223 | seealsos = append(seealsos, seealso) 224 | } 225 | buf.WriteString(strings.Join(seealsos, ", ") + "\n") 226 | } 227 | if !cmd.DisableAutoGenTag { 228 | buf.WriteString("# HISTORY\n Auto generated by spf13/cobra\n") 229 | } 230 | return buf.Bytes() 231 | } 232 | -------------------------------------------------------------------------------- /cmd/docs/md_docs.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 The Tekton 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 | package main 15 | 16 | import ( 17 | "bytes" 18 | "fmt" 19 | "io" 20 | "os" 21 | "path/filepath" 22 | "sort" 23 | "strings" 24 | "time" 25 | 26 | "github.com/spf13/cobra" 27 | ) 28 | 29 | func printOptions(buf *bytes.Buffer, cmd *cobra.Command) error { 30 | flags := cmd.NonInheritedFlags() 31 | flags.SetOutput(buf) 32 | if flags.HasAvailableFlags() { 33 | buf.WriteString("### Options\n\n```\n") 34 | flags.PrintDefaults() 35 | buf.WriteString("```\n\n") 36 | } 37 | 38 | parentFlags := cmd.InheritedFlags() 39 | parentFlags.SetOutput(buf) 40 | if parentFlags.HasAvailableFlags() { 41 | buf.WriteString("### Options inherited from parent commands\n\n```\n") 42 | parentFlags.PrintDefaults() 43 | buf.WriteString("```\n\n") 44 | } 45 | return nil 46 | } 47 | 48 | // GenMarkdownCustom creates custom markdown output. 49 | func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error { 50 | cmd.InitDefaultHelpCmd() 51 | cmd.InitDefaultHelpFlag() 52 | 53 | buf := new(bytes.Buffer) 54 | name := cmd.CommandPath() 55 | 56 | short := cmd.Short 57 | long := cmd.Long 58 | if long == "" { 59 | long = short 60 | } 61 | 62 | buf.WriteString("## " + name + "\n\n") 63 | buf.WriteString(short + "\n\n") 64 | 65 | if len(cmd.Aliases) > 0 { 66 | buf.WriteString(fmt.Sprintf("***Aliases**: %s*\n\n", strings.Join(cmd.Aliases, ","))) 67 | } 68 | 69 | if cmd.Runnable() { 70 | buf.WriteString("### Usage\n\n") 71 | buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine())) 72 | } 73 | 74 | buf.WriteString("### Synopsis\n\n") 75 | 76 | buf.WriteString(long + "\n\n") 77 | 78 | if len(cmd.Example) > 0 { 79 | buf.WriteString("### Examples\n\n") 80 | buf.WriteString(fmt.Sprintf("%s\n\n", cmd.Example)) 81 | } 82 | 83 | if err := printOptions(buf, cmd); err != nil { 84 | return err 85 | } 86 | if hasSeeAlso(cmd) { 87 | buf.WriteString("### SEE ALSO\n\n") 88 | if cmd.HasParent() { 89 | parent := cmd.Parent() 90 | pname := parent.CommandPath() 91 | link := pname + ".md" 92 | link = strings.ReplaceAll(link, " ", "_") 93 | buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)) 94 | cmd.VisitParents(func(c *cobra.Command) { 95 | if c.DisableAutoGenTag { 96 | cmd.DisableAutoGenTag = c.DisableAutoGenTag 97 | } 98 | }) 99 | } 100 | 101 | children := cmd.Commands() 102 | sort.Sort(byName(children)) 103 | 104 | for _, child := range children { 105 | if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() { 106 | continue 107 | } 108 | cname := name + " " + child.Name() 109 | link := cname + ".md" 110 | link = strings.ReplaceAll(link, " ", "_") 111 | buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short)) 112 | } 113 | buf.WriteString("\n") 114 | } 115 | if !cmd.DisableAutoGenTag { 116 | buf.WriteString("###### Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "\n") 117 | } 118 | _, err := buf.WriteTo(w) 119 | return err 120 | } 121 | 122 | // GenMarkdownTree will generate a markdown page for this command and all 123 | // descendants in the directory given. The header may be nil. 124 | // This function may not work correctly if your command names have `-` in them. 125 | // If you have `cmd` with two subcmds, `sub` and `sub-third`, 126 | // and `sub` has a subcommand called `third`, it is undefined which 127 | // help output will be in the file `cmd-sub-third.1`. 128 | func GenMarkdownTree(cmd *cobra.Command, dir string) error { 129 | identity := func(s string) string { return s } 130 | emptyStr := func(s string) string { return "" } 131 | return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity) 132 | } 133 | 134 | // GenMarkdownTreeCustom is the the same as GenMarkdownTree, but 135 | // with custom filePrepender and linkHandler. 136 | func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error { 137 | for _, c := range cmd.Commands() { 138 | if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { 139 | continue 140 | } 141 | if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil { 142 | return err 143 | } 144 | } 145 | 146 | basename := strings.ReplaceAll(cmd.CommandPath(), " ", "_") + ".md" 147 | filename := filepath.Join(dir, basename) 148 | f, err := os.Create(filename) 149 | if err != nil { 150 | return err 151 | } 152 | defer f.Close() 153 | 154 | if _, err := io.WriteString(f, filePrepender(filename)); err != nil { 155 | return err 156 | } 157 | return GenMarkdownCustom(cmd, f, linkHandler) 158 | } 159 | 160 | // Test to see if we have a reason to print See Also information in docs 161 | // Basically this is a test for a parent commend or a subcommand which is 162 | // both not deprecated and not the autogenerated help command. 163 | func hasSeeAlso(cmd *cobra.Command) bool { 164 | if cmd.HasParent() { 165 | return true 166 | } 167 | for _, c := range cmd.Commands() { 168 | if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { 169 | continue 170 | } 171 | return true 172 | } 173 | return false 174 | } 175 | 176 | type byName []*cobra.Command 177 | 178 | func (s byName) Len() int { return len(s) } 179 | func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 180 | func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } 181 | -------------------------------------------------------------------------------- /cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/jenkins-x/jx/cmd/app" 7 | ) 8 | 9 | // Entrypoint for the command 10 | func main() { 11 | if err := app.Run(nil); err != nil { 12 | os.Exit(1) 13 | } 14 | os.Exit(0) 15 | } 16 | -------------------------------------------------------------------------------- /custom-boilerplate.go.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkins-x/jx/dcea318d940276b9e8a2a450773ba6d24461235a/custom-boilerplate.go.txt -------------------------------------------------------------------------------- /dependency-matrix/matrix.md: -------------------------------------------------------------------------------- 1 | # Dependency Matrix 2 | 3 | Dependency | Sources | Version | Mismatched versions 4 | ---------- | ------- | ------- | ------------------- 5 | [jenkins-x/jx-admin](https://github.com/jenkins-x/jx-admin.git) | | [0.0.143](https://github.com/jenkins-x/jx-admin/releases/tag/v0.0.143) | 6 | [jenkins-x/jx-secret](https://github.com/jenkins-x/jx-secret.git) | | [0.0.214](https://github.com/jenkins-x/jx-secret/releases/tag/v0.0.214) | 7 | [jenkins-x/jx-promote](https://github.com/jenkins-x/jx-promote.git) | | [0.0.148](https://github.com/jenkins-x/jx-promote/releases/tag/v0.0.148) | 8 | [jenkins-x/jx-project](https://github.com/jenkins-x/jx-project.git) | | [0.0.178](https://github.com/jenkins-x/jx-project/releases/tag/v0.0.178) | 9 | [jenkins-x/jx-verify](https://github.com/jenkins-x/jx-verify.git) | | [0.0.42](https://github.com/jenkins-x/jx-verify/releases/tag/v0.0.42) | 10 | [jenkins-x/jx-pipeline](https://github.com/jenkins-x/jx-pipeline.git) | | [0.0.88](https://github.com/jenkins-x/jx-pipeline/releases/tag/v0.0.88) | 11 | [jenkins-x/jx-application](https://github.com/jenkins-x/jx-application.git) | | [0.0.25](https://github.com/jenkins-x/jx-application/releases/tag/v0.0.25) | 12 | [jenkins-x/jx-gitops](https://github.com/jenkins-x/jx-gitops.git) | | [0.0.446](https://github.com/jenkins-x/jx-gitops/releases/tag/v0.0.446) | 13 | [jenkins-x/jx-preview](https://github.com/jenkins-x/jx-preview.git) | | [0.0.128](https://github.com/jenkins-x/jx-preview/releases/tag/v0.0.128) | 14 | [jenkins-x/jx-test](https://github.com/jenkins-x/jx-test.git) | | [0.0.25](https://github.com/jenkins-x/jx-test/releases/tag/v0.0.25) | 15 | [jenkins-x/jxl-base-image](https://github.com/jenkins-x/jxl-base-image) | | [0.0.61]() | 16 | [jenkins-x/jx-base-image](https://github.com/jenkins-x/jx-base-image.git) | | [0.0.43]() | 17 | [jenkins-x/jx-jenkins](https://github.com/jenkins-x/jx-jenkins.git) | | [0.0.29](https://github.com/jenkins-x/jx-jenkins/releases/tag/v0.0.29) | 18 | [jenkins-x-plugins/jx-scm](https://github.com/jenkins-x-plugins/jx-scm) | | [0.0.2](https://github.com/jenkins-x-plugins/jx-scm/releases/tag/v0.0.2) | 19 | [jenkins-x-plugins/jx-health](https://github.com/jenkins-x-plugins/jx-health.git) | | [0.0.66](https://github.com/jenkins-x-plugins/jx-health/releases/tag/v0.0.66) | 20 | [jenkins-x/octant-jx](https://github.com/jenkins-x/octant-jx.git) | | [0.0.38](https://github.com/jenkins-x/octant-jx/releases/tag/v0.0.38) | 21 | -------------------------------------------------------------------------------- /dependency-matrix/matrix.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - host: github.com 3 | owner: jenkins-x 4 | repo: jx-admin 5 | url: https://github.com/jenkins-x/jx-admin.git 6 | version: 0.0.143 7 | versionURL: https://github.com/jenkins-x/jx-admin/releases/tag/v0.0.143 8 | - host: github.com 9 | owner: jenkins-x 10 | repo: jx-secret 11 | url: https://github.com/jenkins-x/jx-secret.git 12 | version: 0.0.214 13 | versionURL: https://github.com/jenkins-x/jx-secret/releases/tag/v0.0.214 14 | - host: github.com 15 | owner: jenkins-x 16 | repo: jx-promote 17 | url: https://github.com/jenkins-x/jx-promote.git 18 | version: 0.0.148 19 | versionURL: https://github.com/jenkins-x/jx-promote/releases/tag/v0.0.148 20 | - host: github.com 21 | owner: jenkins-x 22 | repo: jx-project 23 | url: https://github.com/jenkins-x/jx-project.git 24 | version: 0.0.178 25 | versionURL: https://github.com/jenkins-x/jx-project/releases/tag/v0.0.178 26 | - host: github.com 27 | owner: jenkins-x 28 | repo: jx-verify 29 | url: https://github.com/jenkins-x/jx-verify.git 30 | version: 0.0.42 31 | versionURL: https://github.com/jenkins-x/jx-verify/releases/tag/v0.0.42 32 | - host: github.com 33 | owner: jenkins-x 34 | repo: jx-pipeline 35 | url: https://github.com/jenkins-x/jx-pipeline.git 36 | version: 0.0.88 37 | versionURL: https://github.com/jenkins-x/jx-pipeline/releases/tag/v0.0.88 38 | - host: github.com 39 | owner: jenkins-x 40 | repo: jx-application 41 | url: https://github.com/jenkins-x/jx-application.git 42 | version: 0.0.25 43 | versionURL: https://github.com/jenkins-x/jx-application/releases/tag/v0.0.25 44 | - host: github.com 45 | owner: jenkins-x 46 | repo: jx-gitops 47 | url: https://github.com/jenkins-x/jx-gitops.git 48 | version: 0.0.446 49 | versionURL: https://github.com/jenkins-x/jx-gitops/releases/tag/v0.0.446 50 | - host: github.com 51 | owner: jenkins-x 52 | repo: jx-preview 53 | url: https://github.com/jenkins-x/jx-preview.git 54 | version: 0.0.128 55 | versionURL: https://github.com/jenkins-x/jx-preview/releases/tag/v0.0.128 56 | - host: github.com 57 | owner: jenkins-x 58 | repo: jx-test 59 | url: https://github.com/jenkins-x/jx-test.git 60 | version: 0.0.25 61 | versionURL: https://github.com/jenkins-x/jx-test/releases/tag/v0.0.25 62 | - host: github.com 63 | owner: jenkins-x 64 | repo: jxl-base-image 65 | url: https://github.com/jenkins-x/jxl-base-image 66 | version: 0.0.61 67 | versionURL: "" 68 | - host: github.com 69 | owner: jenkins-x 70 | repo: jx-base-image 71 | url: https://github.com/jenkins-x/jx-base-image.git 72 | version: 0.0.43 73 | versionURL: "" 74 | - host: github.com 75 | owner: jenkins-x 76 | repo: jx-jenkins 77 | url: https://github.com/jenkins-x/jx-jenkins.git 78 | version: 0.0.29 79 | versionURL: https://github.com/jenkins-x/jx-jenkins/releases/tag/v0.0.29 80 | - host: github.com 81 | owner: jenkins-x-plugins 82 | repo: jx-scm 83 | url: https://github.com/jenkins-x-plugins/jx-scm 84 | version: 0.0.2 85 | versionURL: https://github.com/jenkins-x-plugins/jx-scm/releases/tag/v0.0.2 86 | - host: github.com 87 | owner: jenkins-x-plugins 88 | repo: jx-health 89 | url: https://github.com/jenkins-x-plugins/jx-health.git 90 | version: 0.0.66 91 | versionURL: https://github.com/jenkins-x-plugins/jx-health/releases/tag/v0.0.66 92 | - host: github.com 93 | owner: jenkins-x 94 | repo: octant-jx 95 | url: https://github.com/jenkins-x/octant-jx.git 96 | version: 0.0.38 97 | versionURL: https://github.com/jenkins-x/octant-jx/releases/tag/v0.0.38 98 | -------------------------------------------------------------------------------- /docs/cmd/jx.md: -------------------------------------------------------------------------------- 1 | ## jx 2 | 3 | Jenkins X 3.x command line 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Jenkins X 3.x command line 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for jx 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx add](jx_add.md) - Adds one or more resources 24 | * [jx create](jx_create.md) - Create one or more resources 25 | * [jx ctx](jx_ctx.md) - alias for: jx context 26 | * [jx dashboard](jx_dashboard.md) - View the Jenkins X Pipelines Dashboard 27 | * [jx get](jx_get.md) - Display one or more resources 28 | * [jx import](jx_import.md) - alias for: jx project import 29 | * [jx namespace](jx_namespace.md) - View or change the current namespace context in the current Kubernetes cluster 30 | * [jx start](jx_start.md) - Starts a resource 31 | * [jx stop](jx_stop.md) - Stops a resource 32 | * [jx ui](jx_ui.md) - Views the Jenkins X UI (octant) 33 | * [jx upgrade](jx_upgrade.md) - Upgrades resources 34 | * [jx version](jx_version.md) - Displays the version of this command 35 | 36 | ###### Auto generated by spf13/cobra on 14-Sep-2022 37 | -------------------------------------------------------------------------------- /docs/cmd/jx_add.md: -------------------------------------------------------------------------------- 1 | ## jx add 2 | 3 | Adds one or more resources 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx add TYPE [flags] 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Adds one or more resources 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for add 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | * [jx add app](jx_add_app.md) - alias for: jx gitops helmfile add 25 | 26 | ###### Auto generated by spf13/cobra on 14-Sep-2022 27 | -------------------------------------------------------------------------------- /docs/cmd/jx_add_app.md: -------------------------------------------------------------------------------- 1 | ## jx add app 2 | 3 | alias for: jx gitops helmfile add 4 | 5 | ***Aliases**: chart* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx add app 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx gitops helmfile add 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for app 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx add](jx_add.md) - Adds one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_create.md: -------------------------------------------------------------------------------- 1 | ## jx create 2 | 3 | Create one or more resources 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx create TYPE [flags] 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Create one or more resources 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for create 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | * [jx create project](jx_create_project.md) - alias for: jx project 25 | * [jx create pullrequest](jx_create_pullrequest.md) - alias for: jx project pullrequest 26 | * [jx create quickstart](jx_create_quickstart.md) - alias for: jx project quickstart 27 | * [jx create spring](jx_create_spring.md) - alias for: jx project spring 28 | 29 | ###### Auto generated by spf13/cobra on 14-Sep-2022 30 | -------------------------------------------------------------------------------- /docs/cmd/jx_create_project.md: -------------------------------------------------------------------------------- 1 | ## jx create project 2 | 3 | alias for: jx project 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx create project 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | alias for: jx project 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for project 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx create](jx_create.md) - Create one or more resources 24 | 25 | ###### Auto generated by spf13/cobra on 14-Sep-2022 26 | -------------------------------------------------------------------------------- /docs/cmd/jx_create_pullrequest.md: -------------------------------------------------------------------------------- 1 | ## jx create pullrequest 2 | 3 | alias for: jx project pullrequest 4 | 5 | ***Aliases**: pr* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx create pullrequest 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx project pullrequest 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for pullrequest 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx create](jx_create.md) - Create one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_create_quickstart.md: -------------------------------------------------------------------------------- 1 | ## jx create quickstart 2 | 3 | alias for: jx project quickstart 4 | 5 | ***Aliases**: qs* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx create quickstart 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx project quickstart 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for quickstart 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx create](jx_create.md) - Create one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_create_spring.md: -------------------------------------------------------------------------------- 1 | ## jx create spring 2 | 3 | alias for: jx project spring 4 | 5 | ***Aliases**: sb* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx create spring 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx project spring 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for spring 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx create](jx_create.md) - Create one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_ctx.md: -------------------------------------------------------------------------------- 1 | ## jx ctx 2 | 3 | alias for: jx context 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx ctx 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | alias for: jx context 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for ctx 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | 25 | ###### Auto generated by spf13/cobra on 14-Sep-2022 26 | -------------------------------------------------------------------------------- /docs/cmd/jx_dashboard.md: -------------------------------------------------------------------------------- 1 | ## jx dashboard 2 | 3 | View the Jenkins X Pipelines Dashboard 4 | 5 | ***Aliases**: dash* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx dashboard 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | View the Jenkins X Pipelines Dashboard. 16 | 17 | ### Examples 18 | 19 | # open the dashboard 20 | jx dashboard 21 | 22 | # display the URL only without opening a browser 23 | jx --no-open 24 | 25 | ### Options 26 | 27 | ``` 28 | -b, --batch-mode Runs in batch mode without prompting for user input 29 | -h, --help help for dashboard 30 | --log-level string Sets the logging level. If not specified defaults to $JX_LOG_LEVEL 31 | -n, --name string The name of the dashboard service (default "jx-pipelines-visualizer") 32 | --no-open Disable opening the URL; just show it on the console 33 | -s, --secret string The name of the Secret containing the basic auth login/password (default "jx-basic-auth-user-password") 34 | --verbose Enables verbose output. The environment variable JX_LOG_LEVEL has precedence over this flag and allows setting the logging level to any value of: panic, fatal, error, warn, info, debug, trace 35 | ``` 36 | 37 | ### SEE ALSO 38 | 39 | * [jx](jx.md) - Jenkins X 3.x command line 40 | 41 | ###### Auto generated by spf13/cobra on 14-Sep-2022 42 | -------------------------------------------------------------------------------- /docs/cmd/jx_get.md: -------------------------------------------------------------------------------- 1 | ## jx get 2 | 3 | Display one or more resources 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx get TYPE [flags] 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Display one or more resources 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for get 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | * [jx get activities](jx_get_activities.md) - alias for: jx pipeline activities 25 | * [jx get application](jx_get_application.md) - alias for: jx application get 26 | * [jx get build](jx_get_build.md) - Display one or more resources relating to a pipeline build 27 | * [jx get pipelines](jx_get_pipelines.md) - alias for: jx pipeline get 28 | * [jx get previews](jx_get_previews.md) - alias for: jx preview get 29 | 30 | ###### Auto generated by spf13/cobra on 14-Sep-2022 31 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_activities.md: -------------------------------------------------------------------------------- 1 | ## jx get activities 2 | 3 | alias for: jx pipeline activities 4 | 5 | ***Aliases**: act,activity* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get activities 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx pipeline activities 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for activities 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get](jx_get.md) - Display one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_application.md: -------------------------------------------------------------------------------- 1 | ## jx get application 2 | 3 | alias for: jx application get 4 | 5 | ***Aliases**: app,apps,applications* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get application 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx application get 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for application 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get](jx_get.md) - Display one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_build.md: -------------------------------------------------------------------------------- 1 | ## jx get build 2 | 3 | Display one or more resources relating to a pipeline build 4 | 5 | ***Aliases**: builds* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get build TYPE [flags] 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | Display one or more resources relating to a pipeline build 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for build 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get](jx_get.md) - Display one or more resources 26 | * [jx get build logs](jx_get_build_logs.md) - alias for: jx pipeline logs 27 | * [jx get build pods](jx_get_build_pods.md) - alias for: jx pipeline pods 28 | 29 | ###### Auto generated by spf13/cobra on 14-Sep-2022 30 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_build_logs.md: -------------------------------------------------------------------------------- 1 | ## jx get build logs 2 | 3 | alias for: jx pipeline logs 4 | 5 | ***Aliases**: log* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get build logs 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx pipeline logs 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for logs 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get build](jx_get_build.md) - Display one or more resources relating to a pipeline build 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_build_pods.md: -------------------------------------------------------------------------------- 1 | ## jx get build pods 2 | 3 | alias for: jx pipeline pods 4 | 5 | ***Aliases**: pod* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get build pods 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx pipeline pods 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for pods 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get build](jx_get_build.md) - Display one or more resources relating to a pipeline build 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_pipelines.md: -------------------------------------------------------------------------------- 1 | ## jx get pipelines 2 | 3 | alias for: jx pipeline get 4 | 5 | ***Aliases**: pipeline* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get pipelines 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx pipeline get 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for pipelines 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get](jx_get.md) - Display one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_get_previews.md: -------------------------------------------------------------------------------- 1 | ## jx get previews 2 | 3 | alias for: jx preview get 4 | 5 | ***Aliases**: preview* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx get previews 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx preview get 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for previews 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx get](jx_get.md) - Display one or more resources 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_import.md: -------------------------------------------------------------------------------- 1 | ## jx import 2 | 3 | alias for: jx project import 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx import 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | alias for: jx project import 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for import 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | 25 | ###### Auto generated by spf13/cobra on 14-Sep-2022 26 | -------------------------------------------------------------------------------- /docs/cmd/jx_namespace.md: -------------------------------------------------------------------------------- 1 | ## jx namespace 2 | 3 | View or change the current namespace context in the current Kubernetes cluster 4 | 5 | ***Aliases**: ns* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx namespace 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | Displays or changes the current namespace. 16 | 17 | ### Examples 18 | 19 | # view the current namespace 20 | jx --batch-mode ns 21 | 22 | # interactively select the namespace to switch to 23 | jx ns 24 | 25 | # change the current namespace to 'cheese' 26 | jx ns cheese 27 | 28 | # change the current namespace to 'brie' creating it if necessary 29 | jx ns --create brie 30 | 31 | # switch to the namespace of the staging environment 32 | jx ns --env staging 33 | 34 | # switch back to the dev environment namespace 35 | jx ns --e dev 36 | 37 | # interactively select the Environment to switch to 38 | jx ns --pick 39 | 40 | ### Options 41 | 42 | ``` 43 | -b, --batch-mode Enables batch mode 44 | -c, --create Creates the specified namespace if it does not exist 45 | -e, --env string The Environment name to switch to the namepsace 46 | -h, --help help for namespace 47 | -v, --pick Pick the Environment to switch to 48 | -q, --quiet Do not fail if the namespace does not exist 49 | ``` 50 | 51 | ### SEE ALSO 52 | 53 | * [jx](jx.md) - Jenkins X 3.x command line 54 | 55 | ###### Auto generated by spf13/cobra on 14-Sep-2022 56 | -------------------------------------------------------------------------------- /docs/cmd/jx_start.md: -------------------------------------------------------------------------------- 1 | ## jx start 2 | 3 | Starts a resource 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx start TYPE [flags] 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Starts a resource 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for start 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | * [jx start pipeline](jx_start_pipeline.md) - alias for: jx pipeline start 25 | 26 | ###### Auto generated by spf13/cobra on 14-Sep-2022 27 | -------------------------------------------------------------------------------- /docs/cmd/jx_start_pipeline.md: -------------------------------------------------------------------------------- 1 | ## jx start pipeline 2 | 3 | alias for: jx pipeline start 4 | 5 | ***Aliases**: pipelines* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx start pipeline 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx pipeline start 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for pipeline 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx start](jx_start.md) - Starts a resource 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_stop.md: -------------------------------------------------------------------------------- 1 | ## jx stop 2 | 3 | Stops a resource 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx stop TYPE [flags] 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Stops a resource 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for stop 19 | ``` 20 | 21 | ### SEE ALSO 22 | 23 | * [jx](jx.md) - Jenkins X 3.x command line 24 | * [jx stop pipeline](jx_stop_pipeline.md) - alias for: jx pipeline stop 25 | 26 | ###### Auto generated by spf13/cobra on 14-Sep-2022 27 | -------------------------------------------------------------------------------- /docs/cmd/jx_stop_pipeline.md: -------------------------------------------------------------------------------- 1 | ## jx stop pipeline 2 | 3 | alias for: jx pipeline stop 4 | 5 | ***Aliases**: pipelines* 6 | 7 | ### Usage 8 | 9 | ``` 10 | jx stop pipeline 11 | ``` 12 | 13 | ### Synopsis 14 | 15 | alias for: jx pipeline stop 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for pipeline 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx stop](jx_stop.md) - Stops a resource 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/cmd/jx_ui.md: -------------------------------------------------------------------------------- 1 | ## jx ui 2 | 3 | Views the Jenkins X UI (octant) 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx ui 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Views the Jenkins X UI (octant). 14 | 15 | ### Examples 16 | 17 | # open the UI 18 | jx ui 19 | # To pass arguments to octant 20 | jx ui -o --namespace=jx -o -v -o --browser-path="/#/jx/pipelines" 21 | 22 | ### Options 23 | 24 | ``` 25 | -b, --batch-mode Runs in batch mode without prompting for user input 26 | -p, --browser-path string The browser path inside octant to open (default "/#/jx/pipelines-recent") 27 | -h, --help help for ui 28 | --host string The host to listen on 29 | --log-level string Sets the logging level. If not specified defaults to $JX_LOG_LEVEL 30 | -o, --octant-args strings Extra arguments passed to the octant binary (default [--namespace=jx]) 31 | --port int The port for octant to listen on 32 | --verbose Enables verbose output. The environment variable JX_LOG_LEVEL has precedence over this flag and allows setting the logging level to any value of: panic, fatal, error, warn, info, debug, trace 33 | ``` 34 | 35 | ### SEE ALSO 36 | 37 | * [jx](jx.md) - Jenkins X 3.x command line 38 | 39 | ###### Auto generated by spf13/cobra on 14-Sep-2022 40 | -------------------------------------------------------------------------------- /docs/cmd/jx_upgrade.md: -------------------------------------------------------------------------------- 1 | ## jx upgrade 2 | 3 | Upgrades resources 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx upgrade 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Upgrades all of the plugins in your local Jenkins X CLI 14 | 15 | ### Examples 16 | 17 | # upgrades your plugin binaries 18 | jx upgrade 19 | 20 | ### Options 21 | 22 | ``` 23 | -h, --help help for upgrade 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [jx](jx.md) - Jenkins X 3.x command line 29 | * [jx upgrade cli](jx_upgrade_cli.md) - Upgrades your local Jenkins X CLI 30 | * [jx upgrade plugins](jx_upgrade_plugins.md) - Upgrades all of the plugins in your local Jenkins X CLI 31 | 32 | ###### Auto generated by spf13/cobra on 14-Sep-2022 33 | -------------------------------------------------------------------------------- /docs/cmd/jx_upgrade_cli.md: -------------------------------------------------------------------------------- 1 | ## jx upgrade cli 2 | 3 | Upgrades your local Jenkins X CLI 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx upgrade cli 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Upgrades your local Jenkins X CLI 14 | 15 | ### Examples 16 | 17 | # upgrades your jx CLI 18 | jx upgrade cli 19 | 20 | ### Options 21 | 22 | ``` 23 | -e, --from-environment Use the clusters dev environment to obtain the version stream URL to find correct version to upgrade the jx cli, this overrides version-stream-git-url 24 | -h, --help help for cli 25 | -v, --version string The specific version to upgrade to (requires --brew=false on macOS) 26 | --version-stream-git-url string The version stream git URL to lookup the jx cli version to upgrade to 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [jx upgrade](jx_upgrade.md) - Upgrades resources 32 | 33 | ###### Auto generated by spf13/cobra on 14-Sep-2022 34 | -------------------------------------------------------------------------------- /docs/cmd/jx_upgrade_plugins.md: -------------------------------------------------------------------------------- 1 | ## jx upgrade plugins 2 | 3 | Upgrades all of the plugins in your local Jenkins X CLI 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx upgrade plugins 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Upgrades all of the plugins in your local Jenkins X CLI 14 | 15 | ### Examples 16 | 17 | # upgrades your plugin binaries 18 | jx upgrade plugins 19 | 20 | ### Options 21 | 22 | ``` 23 | --boot only install plugins required for boot 24 | -h, --help help for plugins 25 | -m, --mandatory if set lets ignore optional plugins 26 | --path string creates a symlink to the binary plugins in this bin path dir (default "/usr/bin") 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [jx upgrade](jx_upgrade.md) - Upgrades resources 32 | 33 | ###### Auto generated by spf13/cobra on 14-Sep-2022 34 | -------------------------------------------------------------------------------- /docs/cmd/jx_version.md: -------------------------------------------------------------------------------- 1 | ## jx version 2 | 3 | Displays the version of this command 4 | 5 | ### Usage 6 | 7 | ``` 8 | jx version 9 | ``` 10 | 11 | ### Synopsis 12 | 13 | Displays the version of this command 14 | 15 | ### Options 16 | 17 | ``` 18 | -h, --help help for version 19 | -q, --quiet uses the quiet format of just outputting the version number only 20 | -s, --short uses the short format of just outputting the version number only 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [jx](jx.md) - Jenkins X 3.x command line 26 | 27 | ###### Auto generated by spf13/cobra on 14-Sep-2022 28 | -------------------------------------------------------------------------------- /docs/man/man1/jx-add-app.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-ADD\-APP" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-add\-app \- alias for: jx gitops helmfile add 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx add app\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx gitops helmfile add 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for app 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-add(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-add.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-ADD" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-add \- Adds one or more resources 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx add TYPE [flags]\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Adds one or more resources 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for add 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP, \fBjx\-add\-app(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-create-project.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-CREATE\-PROJECT" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-create\-project \- alias for: jx project 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx create project\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx project 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for project 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-create(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-create-pullrequest.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-CREATE\-PULLREQUEST" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-create\-pullrequest \- alias for: jx project pullrequest 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx create pullrequest\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx project pullrequest 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for pullrequest 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-create(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-create-quickstart.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-CREATE\-QUICKSTART" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-create\-quickstart \- alias for: jx project quickstart 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx create quickstart\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx project quickstart 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for quickstart 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-create(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-create-spring.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-CREATE\-SPRING" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-create\-spring \- alias for: jx project spring 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx create spring\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx project spring 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for spring 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-create(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-create.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-CREATE" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-create \- Create one or more resources 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx create TYPE [flags]\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Create one or more resources 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for create 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP, \fBjx\-create\-project(1)\fP, \fBjx\-create\-pullrequest(1)\fP, \fBjx\-create\-quickstart(1)\fP, \fBjx\-create\-spring(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-ctx.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-CTX" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-ctx \- alias for: jx context 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx ctx\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx context 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for ctx 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-dashboard.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-DASHBOARD" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-dashboard \- View the Jenkins X Pipelines Dashboard 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx dashboard\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | View the Jenkins X Pipelines Dashboard. 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-b\fP, \fB\-\-batch\-mode\fP[=false] 24 | Runs in batch mode without prompting for user input 25 | 26 | .PP 27 | \fB\-h\fP, \fB\-\-help\fP[=false] 28 | help for dashboard 29 | 30 | .PP 31 | \fB\-\-log\-level\fP="" 32 | Sets the logging level. If not specified defaults to $JX\_LOG\_LEVEL 33 | 34 | .PP 35 | \fB\-n\fP, \fB\-\-name\fP="jx\-pipelines\-visualizer" 36 | The name of the dashboard service 37 | 38 | .PP 39 | \fB\-\-no\-open\fP[=false] 40 | Disable opening the URL; just show it on the console 41 | 42 | .PP 43 | \fB\-s\fP, \fB\-\-secret\fP="jx\-basic\-auth\-user\-password" 44 | The name of the Secret containing the basic auth login/password 45 | 46 | .PP 47 | \fB\-\-verbose\fP[=false] 48 | Enables verbose output. The environment variable JX\_LOG\_LEVEL has precedence over this flag and allows setting the logging level to any value of: panic, fatal, error, warn, info, debug, trace 49 | 50 | 51 | .SH EXAMPLE 52 | .PP 53 | # open the dashboard 54 | jx dashboard 55 | 56 | .PP 57 | # display the URL only without opening a browser 58 | jx \-\-no\-open 59 | 60 | 61 | .SH SEE ALSO 62 | .PP 63 | \fBjx(1)\fP 64 | 65 | 66 | .SH HISTORY 67 | .PP 68 | Auto generated by spf13/cobra 69 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-activities.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-ACTIVITIES" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-activities \- alias for: jx pipeline activities 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get activities\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx pipeline activities 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for activities 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-application.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-APPLICATION" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-application \- alias for: jx application get 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get application\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx application get 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for application 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-build-logs.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-BUILD\-LOGS" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-build\-logs \- alias for: jx pipeline logs 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get build logs\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx pipeline logs 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for logs 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get\-build(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-build-pods.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-BUILD\-PODS" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-build\-pods \- alias for: jx pipeline pods 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get build pods\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx pipeline pods 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for pods 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get\-build(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-build.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-BUILD" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-build \- Display one or more resources relating to a pipeline build 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get build TYPE [flags]\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Display one or more resources relating to a pipeline build 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for build 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get(1)\fP, \fBjx\-get\-build\-logs(1)\fP, \fBjx\-get\-build\-pods(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-pipelines.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-PIPELINES" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-pipelines \- alias for: jx pipeline get 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get pipelines\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx pipeline get 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for pipelines 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get-previews.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET\-PREVIEWS" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get\-previews \- alias for: jx preview get 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get previews\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx preview get 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for previews 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-get(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-get.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-GET" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-get \- Display one or more resources 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx get TYPE [flags]\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Display one or more resources 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for get 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP, \fBjx\-get\-activities(1)\fP, \fBjx\-get\-application(1)\fP, \fBjx\-get\-build(1)\fP, \fBjx\-get\-pipelines(1)\fP, \fBjx\-get\-previews(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-import.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-IMPORT" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-import \- alias for: jx project import 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx import\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx project import 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for import 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-namespace.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-NAMESPACE" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-namespace \- View or change the current namespace context in the current Kubernetes cluster 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx namespace\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Displays or changes the current namespace. 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-b\fP, \fB\-\-batch\-mode\fP[=false] 24 | Enables batch mode 25 | 26 | .PP 27 | \fB\-c\fP, \fB\-\-create\fP[=false] 28 | Creates the specified namespace if it does not exist 29 | 30 | .PP 31 | \fB\-e\fP, \fB\-\-env\fP="" 32 | The Environment name to switch to the namepsace 33 | 34 | .PP 35 | \fB\-h\fP, \fB\-\-help\fP[=false] 36 | help for namespace 37 | 38 | .PP 39 | \fB\-v\fP, \fB\-\-pick\fP[=false] 40 | Pick the Environment to switch to 41 | 42 | .PP 43 | \fB\-q\fP, \fB\-\-quiet\fP[=false] 44 | Do not fail if the namespace does not exist 45 | 46 | 47 | .SH EXAMPLE 48 | .PP 49 | # view the current namespace 50 | jx \-\-batch\-mode ns 51 | 52 | .PP 53 | # interactively select the namespace to switch to 54 | jx ns 55 | 56 | .PP 57 | # change the current namespace to 'cheese' 58 | jx ns cheese 59 | 60 | .PP 61 | # change the current namespace to 'brie' creating it if necessary 62 | jx ns \-\-create brie 63 | 64 | .PP 65 | # switch to the namespace of the staging environment 66 | jx ns \-\-env staging 67 | 68 | .PP 69 | # switch back to the dev environment namespace 70 | jx ns \-\-e dev 71 | 72 | .PP 73 | # interactively select the Environment to switch to 74 | jx ns \-\-pick 75 | 76 | 77 | .SH SEE ALSO 78 | .PP 79 | \fBjx(1)\fP 80 | 81 | 82 | .SH HISTORY 83 | .PP 84 | Auto generated by spf13/cobra 85 | -------------------------------------------------------------------------------- /docs/man/man1/jx-start-pipeline.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-START\-PIPELINE" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-start\-pipeline \- alias for: jx pipeline start 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx start pipeline\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx pipeline start 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for pipeline 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-start(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-start.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-START" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-start \- Starts a resource 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx start TYPE [flags]\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Starts a resource 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for start 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP, \fBjx\-start\-pipeline(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-stop-pipeline.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-STOP\-PIPELINE" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-stop\-pipeline \- alias for: jx pipeline stop 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx stop pipeline\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | alias for: jx pipeline stop 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for pipeline 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-stop(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-stop.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-STOP" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-stop \- Stops a resource 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx stop TYPE [flags]\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Stops a resource 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for stop 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx(1)\fP, \fBjx\-stop\-pipeline(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /docs/man/man1/jx-ui.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-UI" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-ui \- Views the Jenkins X UI (octant) 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx ui\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Views the Jenkins X UI (octant). 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-b\fP, \fB\-\-batch\-mode\fP[=false] 24 | Runs in batch mode without prompting for user input 25 | 26 | .PP 27 | \fB\-p\fP, \fB\-\-browser\-path\fP="/#/jx/pipelines\-recent" 28 | The browser path inside octant to open 29 | 30 | .PP 31 | \fB\-h\fP, \fB\-\-help\fP[=false] 32 | help for ui 33 | 34 | .PP 35 | \fB\-\-host\fP="" 36 | The host to listen on 37 | 38 | .PP 39 | \fB\-\-log\-level\fP="" 40 | Sets the logging level. If not specified defaults to $JX\_LOG\_LEVEL 41 | 42 | .PP 43 | \fB\-o\fP, \fB\-\-octant\-args\fP=[\-\-namespace=jx] 44 | Extra arguments passed to the octant binary 45 | 46 | .PP 47 | \fB\-\-port\fP=0 48 | The port for octant to listen on 49 | 50 | .PP 51 | \fB\-\-verbose\fP[=false] 52 | Enables verbose output. The environment variable JX\_LOG\_LEVEL has precedence over this flag and allows setting the logging level to any value of: panic, fatal, error, warn, info, debug, trace 53 | 54 | 55 | .SH EXAMPLE 56 | .PP 57 | # open the UI 58 | jx ui 59 | # To pass arguments to octant 60 | jx ui \-o \-\-namespace=jx \-o \-v \-o \-\-browser\-path="/#/jx/pipelines" 61 | 62 | 63 | .SH SEE ALSO 64 | .PP 65 | \fBjx(1)\fP 66 | 67 | 68 | .SH HISTORY 69 | .PP 70 | Auto generated by spf13/cobra 71 | -------------------------------------------------------------------------------- /docs/man/man1/jx-upgrade-cli.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-UPGRADE\-CLI" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-upgrade\-cli \- Upgrades your local Jenkins X CLI 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx upgrade cli\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Upgrades your local Jenkins X CLI 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-e\fP, \fB\-\-from\-environment\fP[=false] 24 | Use the clusters dev environment to obtain the version stream URL to find correct version to upgrade the jx cli, this overrides version\-stream\-git\-url 25 | 26 | .PP 27 | \fB\-h\fP, \fB\-\-help\fP[=false] 28 | help for cli 29 | 30 | .PP 31 | \fB\-v\fP, \fB\-\-version\fP="" 32 | The specific version to upgrade to (requires \-\-brew=false on macOS) 33 | 34 | .PP 35 | \fB\-\-version\-stream\-git\-url\fP="" 36 | The version stream git URL to lookup the jx cli version to upgrade to 37 | 38 | 39 | .SH EXAMPLE 40 | .PP 41 | # upgrades your jx CLI 42 | jx upgrade cli 43 | 44 | 45 | .SH SEE ALSO 46 | .PP 47 | \fBjx\-upgrade(1)\fP 48 | 49 | 50 | .SH HISTORY 51 | .PP 52 | Auto generated by spf13/cobra 53 | -------------------------------------------------------------------------------- /docs/man/man1/jx-upgrade-plugins.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-UPGRADE\-PLUGINS" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-upgrade\-plugins \- Upgrades all of the plugins in your local Jenkins X CLI 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx upgrade plugins\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Upgrades all of the plugins in your local Jenkins X CLI 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-\-boot\fP[=false] 24 | only install plugins required for boot 25 | 26 | .PP 27 | \fB\-h\fP, \fB\-\-help\fP[=false] 28 | help for plugins 29 | 30 | .PP 31 | \fB\-m\fP, \fB\-\-mandatory\fP[=false] 32 | if set lets ignore optional plugins 33 | 34 | .PP 35 | \fB\-\-path\fP="/usr/bin" 36 | creates a symlink to the binary plugins in this bin path dir 37 | 38 | 39 | .SH EXAMPLE 40 | .PP 41 | # upgrades your plugin binaries 42 | jx upgrade plugins 43 | 44 | 45 | .SH SEE ALSO 46 | .PP 47 | \fBjx\-upgrade(1)\fP 48 | 49 | 50 | .SH HISTORY 51 | .PP 52 | Auto generated by spf13/cobra 53 | -------------------------------------------------------------------------------- /docs/man/man1/jx-upgrade.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-UPGRADE" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-upgrade \- Upgrades resources 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx upgrade\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Upgrades all of the plugins in your local Jenkins X CLI 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for upgrade 25 | 26 | 27 | .SH EXAMPLE 28 | .PP 29 | # upgrades your plugin binaries 30 | jx upgrade 31 | 32 | 33 | .SH SEE ALSO 34 | .PP 35 | \fBjx(1)\fP, \fBjx\-upgrade\-cli(1)\fP, \fBjx\-upgrade\-plugins(1)\fP 36 | 37 | 38 | .SH HISTORY 39 | .PP 40 | Auto generated by spf13/cobra 41 | -------------------------------------------------------------------------------- /docs/man/man1/jx-version.1: -------------------------------------------------------------------------------- 1 | .TH "JX\-VERSION" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx\-version \- Displays the version of this command 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx version\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Displays the version of this command 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for version 25 | 26 | .PP 27 | \fB\-q\fP, \fB\-\-quiet\fP[=false] 28 | uses the quiet format of just outputting the version number only 29 | 30 | .PP 31 | \fB\-s\fP, \fB\-\-short\fP[=false] 32 | uses the short format of just outputting the version number only 33 | 34 | 35 | .SH SEE ALSO 36 | .PP 37 | \fBjx(1)\fP 38 | 39 | 40 | .SH HISTORY 41 | .PP 42 | Auto generated by spf13/cobra 43 | -------------------------------------------------------------------------------- /docs/man/man1/jx.1: -------------------------------------------------------------------------------- 1 | .TH "JX" "1" "" "Auto generated by spf13/cobra" "" 2 | .nh 3 | .ad l 4 | 5 | 6 | .SH NAME 7 | .PP 8 | jx \- Jenkins X 3.x command line 9 | 10 | 11 | .SH SYNOPSIS 12 | .PP 13 | \fBjx\fP 14 | 15 | 16 | .SH DESCRIPTION 17 | .PP 18 | Jenkins X 3.x command line 19 | 20 | 21 | .SH OPTIONS 22 | .PP 23 | \fB\-h\fP, \fB\-\-help\fP[=false] 24 | help for jx 25 | 26 | 27 | .SH SEE ALSO 28 | .PP 29 | \fBjx\-add(1)\fP, \fBjx\-create(1)\fP, \fBjx\-ctx(1)\fP, \fBjx\-dashboard(1)\fP, \fBjx\-get(1)\fP, \fBjx\-import(1)\fP, \fBjx\-namespace(1)\fP, \fBjx\-start(1)\fP, \fBjx\-stop(1)\fP, \fBjx\-ui(1)\fP, \fBjx\-upgrade(1)\fP, \fBjx\-version(1)\fP 30 | 31 | 32 | .SH HISTORY 33 | .PP 34 | Auto generated by spf13/cobra 35 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jenkins-x/jx 2 | 3 | require ( 4 | github.com/blang/semver v3.5.1+incompatible 5 | github.com/cpuguy83/go-md2man v1.0.10 6 | github.com/jenkins-x/jx-api/v4 v4.7.6 7 | github.com/jenkins-x/jx-helpers/v3 v3.8.0 8 | github.com/jenkins-x/jx-kube-client/v3 v3.0.8 9 | github.com/jenkins-x/jx-logging/v3 v3.0.17 10 | github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 11 | github.com/rhysd/go-github-selfupdate v1.2.3 12 | github.com/spf13/cobra v1.8.1 13 | github.com/spf13/pflag v1.0.5 14 | github.com/stretchr/testify v1.9.0 15 | k8s.io/api v0.31.2 16 | k8s.io/apimachinery v0.31.2 17 | k8s.io/client-go v0.31.2 18 | sigs.k8s.io/kustomize/kyaml v0.17.1 19 | 20 | ) 21 | 22 | require ( 23 | dario.cat/mergo v1.0.0 // indirect 24 | github.com/AlecAivazis/survey/v2 v2.3.4 // indirect 25 | github.com/MakeNowJust/heredoc v1.0.0 // indirect 26 | github.com/cenkalti/backoff v2.2.1+incompatible // indirect 27 | github.com/creack/pty v1.1.18 // indirect 28 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 29 | github.com/emicklei/go-restful/v3 v3.12.1 // indirect 30 | github.com/fatih/color v1.15.0 // indirect 31 | github.com/fxamacker/cbor/v2 v2.7.0 // indirect 32 | github.com/ghodss/yaml v1.0.0 // indirect 33 | github.com/go-errors/errors v1.4.2 // indirect 34 | github.com/go-logr/logr v1.4.2 // indirect 35 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 36 | github.com/go-openapi/jsonreference v0.21.0 // indirect 37 | github.com/go-openapi/swag v0.23.0 // indirect 38 | github.com/go-stack/stack v1.8.1 // indirect 39 | github.com/gogo/protobuf v1.3.2 // indirect 40 | github.com/golang/glog v1.2.4 // indirect 41 | github.com/golang/protobuf v1.5.4 // indirect 42 | github.com/google/gnostic-models v0.6.8 // indirect 43 | github.com/google/go-cmp v0.6.0 // indirect 44 | github.com/google/go-github/v30 v30.1.0 // indirect 45 | github.com/google/go-querystring v1.0.0 // indirect 46 | github.com/google/gofuzz v1.2.0 // indirect 47 | github.com/google/uuid v1.6.0 // indirect 48 | github.com/imdario/mergo v0.3.16 // indirect 49 | github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect 50 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 51 | github.com/jenkins-x/logrus-stackdriver-formatter v0.2.7 // indirect 52 | github.com/josharian/intern v1.0.0 // indirect 53 | github.com/json-iterator/go v1.1.12 // indirect 54 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect 55 | github.com/mailru/easyjson v0.7.7 // indirect 56 | github.com/mattn/go-colorable v0.1.13 // indirect 57 | github.com/mattn/go-isatty v0.0.17 // indirect 58 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect 59 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 60 | github.com/modern-go/reflect2 v1.0.2 // indirect 61 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 62 | github.com/pkg/errors v0.9.1 // indirect 63 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 64 | github.com/rawlingsj/jsonschema v0.0.0-20210511142122-a9c2cfdb7dcf // indirect 65 | github.com/russross/blackfriday v1.6.0 // indirect 66 | github.com/sirupsen/logrus v1.9.3 // indirect 67 | github.com/tcnksm/go-gitconfig v0.1.2 // indirect 68 | github.com/ulikunitz/xz v0.5.9 // indirect 69 | github.com/vrischmann/envconfig v1.3.0 // indirect 70 | github.com/x448/float16 v0.8.4 // indirect 71 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect 72 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 73 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect 74 | golang.org/x/crypto v0.31.0 // indirect 75 | golang.org/x/net v0.33.0 // indirect 76 | golang.org/x/oauth2 v0.23.0 // indirect 77 | golang.org/x/sys v0.28.0 // indirect 78 | golang.org/x/term v0.27.0 // indirect 79 | golang.org/x/text v0.21.0 // indirect 80 | golang.org/x/time v0.7.0 // indirect 81 | google.golang.org/protobuf v1.35.1 // indirect 82 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 83 | gopkg.in/inf.v0 v0.9.1 // indirect 84 | gopkg.in/yaml.v2 v2.4.0 // indirect 85 | gopkg.in/yaml.v3 v3.0.1 // indirect 86 | k8s.io/klog/v2 v2.130.1 // indirect 87 | k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094 // indirect 88 | k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 // indirect 89 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect 90 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect 91 | sigs.k8s.io/yaml v1.4.0 // indirect 92 | ) 93 | 94 | go 1.23 95 | -------------------------------------------------------------------------------- /hack/changelog-header.md: -------------------------------------------------------------------------------- 1 | ## Linux 2 | 3 | ### amd64 4 | 5 | ```shell 6 | curl -L https://github.com/jenkins-x/jx/releases/download/v{{.Version}}/jx-linux-amd64.tar.gz | tar xzv 7 | sudo mv jx /usr/local/bin 8 | ``` 9 | 10 | ### arm 11 | 12 | ```shell 13 | curl -L https://github.com/jenkins-x/jx/releases/download/v{{.Version}}/jx-linux-arm.tar.gz | tar xzv 14 | sudo mv jx /usr/local/bin 15 | ``` 16 | 17 | ### arm64 18 | 19 | ```shell 20 | curl -L https://github.com/jenkins-x/jx/releases/download/v{{.Version}}/jx-linux-arm64.tar.gz | tar xzv 21 | sudo mv jx /usr/local/bin 22 | ``` 23 | 24 | ## macOS 25 | 26 | ### Using homebrew 27 | 28 | ```shell 29 | brew install --no-quarantine --cask jenkins-x/jx/jx 30 | ``` 31 | 32 | ### Using curl 33 | 34 | #### amd64 35 | 36 | ```shell 37 | curl -L https://github.com/jenkins-x/jx/releases/download/v{{.Version}}/jx-darwin-amd64.tar.gz | tar xzv 38 | sudo mv jx /usr/local/bin 39 | ``` 40 | 41 | #### arm64 42 | 43 | ```shell 44 | curl -L https://github.com/jenkins-x/jx/releases/download/v{{.Version}}/jx-darwin-arm64.tar.gz | tar xzv 45 | sudo mv jx /usr/local/bin 46 | ``` 47 | -------------------------------------------------------------------------------- /hack/ensure-test-classification.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # get the dir of this scipt 4 | dir=$(dirname "$0") 5 | 6 | declare -a unclassified 7 | 8 | while IFS= read -r -d '' file 9 | do 10 | [ -z "$(sed -n '/^\/\/ +build/p;q' "$file")" ] && unclassified+=("$file") 11 | done < <(find ${dir}/.. -name '*_test.go' -print0) 12 | 13 | if [ "${#unclassified[@]}" -eq "0" ]; then 14 | echo "OK - all test files contain a build tag" 15 | exit 0 16 | fi 17 | 18 | echo "The following ${#unclassified[@]} test files are not classified with a valid Go build tag [unit|integration]" 19 | for i in "${unclassified[@]}" 20 | do 21 | echo "$i" 22 | done 23 | exit 1 -------------------------------------------------------------------------------- /hack/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | RED='\033[0;31m' 6 | GREEN='\033[0;32m' 7 | RESET='\033[0m' 8 | 9 | if ! [ -x "$(command -v goimports)" ]; then 10 | echo "Installing goimports" 11 | go install golang.org/x/tools/cmd/goimports 12 | fi 13 | 14 | echo "Running validation scripts..." 15 | 16 | scripts=( 17 | ) 18 | fail=0 19 | for s in "${scripts[@]}"; do 20 | echo "RUN ${s}" 21 | set +e 22 | $s 23 | result=$? 24 | set -e 25 | if [[ $result -eq 0 ]]; then 26 | echo -e "${GREEN}PASSED${RESET} ${s}" 27 | else 28 | echo -e "${RED}FAILED${RESET} ${s}" 29 | fail=1 30 | fi 31 | done 32 | exit $fail 33 | -------------------------------------------------------------------------------- /hack/gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | files=$(find . -name "*.go" | grep -v vendor/ | grep -v ./pkg/client/openapi/all | grep -v Dockerfile | xargs gofmt -l -s) 4 | if [[ $files ]]; then 5 | echo "Gofmt errors in files:" 6 | echo "$files" 7 | diff=$(find . -name "*.go" | grep -v vendor/ | grep -v ./pkg/client/openapi/all | grep -v Dockerfile | xargs gofmt -d -s) 8 | echo "$diff" 9 | exit 1 10 | fi 11 | -------------------------------------------------------------------------------- /hack/linter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -o pipefail 4 | 5 | if [ "$DISABLE_LINTER" == "true" ] 6 | then 7 | exit 0 8 | fi 9 | 10 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 | 12 | linterVersion="$(golangci-lint --version | awk '{print $4}')" 13 | 14 | expectedLinterVersion=1.50.1 15 | 16 | if [ "${linterVersion}" != "${expectedLinterVersion}" ]; then 17 | echo "Install GolangCI-Lint version ${expectedLinterVersion}" 18 | exit 1 19 | fi 20 | 21 | export GO111MODULE=on 22 | golangci-lint run \ 23 | --verbose \ 24 | --build-tags build 25 | -------------------------------------------------------------------------------- /hack/upload_plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "uploading the plugin for version ${VERSION}" 4 | 5 | echo "creating the plugin.gz" 6 | cd dist 7 | 8 | echo "apiVersion: jenkins.io/v1 9 | kind: Plugin 10 | metadata: 11 | labels: 12 | jenkins.io/pluginCommand: jx 13 | name: remote 14 | spec: 15 | description: CloudBees plugin for remote environments 16 | name: remote 17 | subCommand: remote 18 | version: ${VERSION}" > plugin.yaml 19 | tar -czvf ../plugin.gz plugin.* *.zip *.gz *.txt *.md 20 | cd .. 21 | 22 | echo "created plugin.gz:" 23 | pwd 24 | ls -al *.gz 25 | 26 | echo "uploading the plugin distro to github" 27 | github-release upload \ 28 | --user jenkins-x \ 29 | --repo jx \ 30 | --tag v${VERSION} \ 31 | --name "plugin.gz" \ 32 | --file plugin.gz 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /jx.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEofm/QFAG18JrP+/t0gBTTwK+nstS 3 | ZIUiIMfC2HnLPndiThh+HxH9aSkrVZed/yK/0gbvmthxbe07dMre2VA/zw== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /pkg/cmd/dashboard/dashboard.go: -------------------------------------------------------------------------------- 1 | package dashboard 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/url" 7 | 8 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/helper" 9 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates" 10 | "github.com/jenkins-x/jx-helpers/v3/pkg/kube/services" 11 | "github.com/jenkins-x/jx-helpers/v3/pkg/options" 12 | "github.com/jenkins-x/jx-logging/v3/pkg/log" 13 | 14 | "github.com/spf13/cobra" 15 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 | 17 | "github.com/jenkins-x/jx-helpers/v3/pkg/kube" 18 | 19 | "github.com/jenkins-x/jx-helpers/v3/pkg/termcolor" 20 | "github.com/pkg/browser" 21 | apierrors "k8s.io/apimachinery/pkg/api/errors" 22 | "k8s.io/client-go/kubernetes" 23 | ) 24 | 25 | type Options struct { 26 | options.BaseOptions 27 | KubeClient kubernetes.Interface 28 | Namespace string 29 | ServiceName string 30 | BasicAuthSecretName string 31 | NoBrowser bool 32 | Quiet bool 33 | BrowserHandler Opener 34 | } 35 | 36 | type Opener interface { 37 | Open() error 38 | } 39 | 40 | type Browser struct { 41 | URL string 42 | } 43 | 44 | func (b *Browser) Open() error { 45 | err := browser.OpenURL(b.URL) 46 | if err != nil { 47 | return err 48 | } 49 | return nil 50 | } 51 | 52 | var ( 53 | cmdLong = templates.LongDesc(` 54 | View the Jenkins X Pipelines Dashboard.`) 55 | 56 | cmdExample = templates.Examples(` 57 | # open the dashboard 58 | jx dashboard 59 | 60 | # display the URL only without opening a browser 61 | jx --no-open 62 | `) 63 | 64 | info = termcolor.ColorInfo 65 | ) 66 | 67 | // NewCmdDashboard opens the dashboard 68 | func NewCmdDashboard() (*cobra.Command, *Options) { 69 | o := &Options{} 70 | cmd := &cobra.Command{ 71 | Use: "dashboard", 72 | Aliases: []string{"dash"}, 73 | Short: "View the Jenkins X Pipelines Dashboard", 74 | Long: cmdLong, 75 | Example: cmdExample, 76 | Run: func(_ *cobra.Command, _ []string) { 77 | err := o.Run() 78 | helper.CheckErr(err) 79 | }, 80 | } 81 | 82 | cmd.Flags().BoolVarP(&o.NoBrowser, "no-open", "", false, "Disable opening the URL; just show it on the console") 83 | cmd.Flags().StringVarP(&o.ServiceName, "name", "n", "jx-pipelines-visualizer", "The name of the dashboard service") 84 | cmd.Flags().StringVarP(&o.BasicAuthSecretName, "secret", "s", "jx-basic-auth-user-password", "The name of the Secret containing the basic auth login/password") 85 | o.BaseOptions.AddBaseFlags(cmd) 86 | return cmd, o 87 | } 88 | 89 | func (o *Options) Run() error { 90 | var err error 91 | o.KubeClient, o.Namespace, err = kube.LazyCreateKubeClientAndNamespace(o.KubeClient, o.Namespace) 92 | if err != nil { 93 | return fmt.Errorf("creating kubernetes client: %w", err) 94 | } 95 | client := o.KubeClient 96 | 97 | u, err := services.FindServiceURL(client, o.Namespace, o.ServiceName) 98 | if err != nil { 99 | return fmt.Errorf("failed to find dashboard URL. Check you have 'chart: jxgh/jx-pipelines-visualizer' in your helmfile.yaml: %w", err) 100 | } 101 | if u == "" { 102 | return fmt.Errorf("no dashboard URL. Check you have 'chart: jxgh/jx-pipelines-visualizer' in your helmfile.yaml") 103 | } 104 | 105 | log.Logger().Infof("Jenkins X dashboard is running at: %s", info(u)) 106 | 107 | if o.NoBrowser { 108 | return nil 109 | } 110 | 111 | u, err = o.addUserPasswordToURL(u) 112 | if err != nil { 113 | return fmt.Errorf("failed to enrich dashboard URL %s: %w", u, err) 114 | } 115 | 116 | log.Logger().Debugf("opening: %s", info(u)) 117 | 118 | if o.BrowserHandler == nil { 119 | o.BrowserHandler = &Browser{u} 120 | } 121 | err = o.BrowserHandler.Open() 122 | if err != nil { 123 | return err 124 | } 125 | return nil 126 | } 127 | 128 | func (o *Options) addUserPasswordToURL(urlText string) (string, error) { 129 | name := o.BasicAuthSecretName 130 | ns := o.Namespace 131 | secret, err := o.KubeClient.CoreV1().Secrets(ns).Get(context.Background(), name, metav1.GetOptions{}) 132 | if err != nil && !apierrors.IsNotFound(err) { 133 | return urlText, fmt.Errorf("failed to load Secret %s in namespace %s: %w", name, ns, err) 134 | } 135 | if secret.Data == nil { 136 | secret.Data = map[string][]byte{} 137 | } 138 | username := string(secret.Data["username"]) 139 | password := string(secret.Data["password"]) 140 | 141 | if username == "" { 142 | log.Logger().Warnf("secret %s in namespace %s has no username", name, ns) 143 | return urlText, nil 144 | } 145 | if password == "" { 146 | log.Logger().Warnf("secret %s in namespace %s has no password", name, ns) 147 | return urlText, nil 148 | } 149 | 150 | u, err := url.Parse(urlText) 151 | if err != nil { 152 | return urlText, fmt.Errorf("failed to parse URL %s: %w", urlText, err) 153 | } 154 | u.User = url.UserPassword(username, password) 155 | return u.String(), nil 156 | } 157 | -------------------------------------------------------------------------------- /pkg/cmd/dashboard/dashboard_test.go: -------------------------------------------------------------------------------- 1 | package dashboard_test 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/jenkins-x/jx/pkg/cmd/dashboard" 8 | "github.com/stretchr/testify/assert" 9 | v1 "k8s.io/api/core/v1" 10 | nv1 "k8s.io/api/networking/v1" 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | "k8s.io/client-go/kubernetes/fake" 13 | ) 14 | 15 | type FakeBrowser struct{} 16 | 17 | func (*FakeBrowser) Open() error { 18 | return nil 19 | } 20 | 21 | const testNamespace = "jx" 22 | 23 | func TestNewCmdDashboard(t *testing.T) { 24 | testCases := []struct { 25 | description string 26 | hasError bool 27 | NoBrowser bool 28 | secret map[string][]byte 29 | host string 30 | }{ 31 | { 32 | description: "Test Case 1 - do not open browser", 33 | hasError: false, 34 | NoBrowser: true, 35 | host: "hook-jx.1.2.3.4.nip.io", 36 | }, 37 | { 38 | description: "Test Case 2 - open browser", 39 | hasError: false, 40 | NoBrowser: false, 41 | secret: map[string][]byte{ 42 | "username": []byte("username"), 43 | "password": []byte("password"), 44 | }, 45 | host: "hook-jx.1.2.3.4.nip.io", 46 | }, 47 | { 48 | description: "Test Case 3 - nil secret", 49 | hasError: false, 50 | NoBrowser: false, 51 | secret: nil, 52 | host: "hook-jx.1.2.3.4.nip.io", 53 | }, 54 | { 55 | description: "Test Case 4 - empty username in secret", 56 | hasError: false, 57 | NoBrowser: false, 58 | secret: map[string][]byte{ 59 | "username": []byte(""), 60 | "password": []byte("password"), 61 | }, 62 | host: "hook-jx.1.2.3.4.nip.io", 63 | }, 64 | { 65 | description: "Test Case 5 - empty password in secret", 66 | hasError: false, 67 | NoBrowser: false, 68 | secret: map[string][]byte{ 69 | "username": []byte("username"), 70 | "password": []byte(""), 71 | }, 72 | host: "hook-jx.1.2.3.4.nip.io", 73 | }, 74 | { 75 | description: "Test Case 6 - invalid url", 76 | hasError: true, 77 | NoBrowser: false, 78 | secret: map[string][]byte{ 79 | "username": []byte("username"), 80 | "password": []byte("password"), 81 | }, 82 | host: "invalid url", 83 | }, 84 | } 85 | 86 | for _, tt := range testCases { 87 | t.Logf("Running Test case %s", tt.description) 88 | kubeClient := fake.NewSimpleClientset( 89 | &v1.Namespace{ 90 | ObjectMeta: metav1.ObjectMeta{ 91 | Name: testNamespace, 92 | }, 93 | }, 94 | &nv1.Ingress{ 95 | ObjectMeta: metav1.ObjectMeta{ 96 | Name: "jx-pipelines-visualizer", 97 | Namespace: testNamespace, 98 | }, 99 | Spec: nv1.IngressSpec{ 100 | Rules: []nv1.IngressRule{ 101 | { 102 | Host: tt.host, 103 | IngressRuleValue: nv1.IngressRuleValue{ 104 | HTTP: &nv1.HTTPIngressRuleValue{ 105 | Paths: []nv1.HTTPIngressPath{ 106 | { 107 | Path: "", 108 | Backend: nv1.IngressBackend{ 109 | Service: &nv1.IngressServiceBackend{ 110 | Name: "hook", 111 | Port: nv1.ServiceBackendPort{ 112 | Number: 80, 113 | }, 114 | }, 115 | }, 116 | }, 117 | }, 118 | }, 119 | }, 120 | }, 121 | }, 122 | }, 123 | }, 124 | &v1.Secret{ 125 | TypeMeta: metav1.TypeMeta{}, 126 | ObjectMeta: metav1.ObjectMeta{ 127 | Name: "jx-basic-auth-user-password", 128 | Namespace: testNamespace, 129 | }, 130 | Data: tt.secret, 131 | }) 132 | os.Setenv("KUBECONFIG", "testdata/kubeconfig") 133 | 134 | _, o := dashboard.NewCmdDashboard() 135 | o.KubeClient = kubeClient 136 | o.Namespace = testNamespace 137 | o.NoBrowser = tt.NoBrowser 138 | if !o.NoBrowser { 139 | o.BrowserHandler = &FakeBrowser{} 140 | } 141 | err := o.Run() 142 | if tt.hasError { 143 | assert.Error(t, err) 144 | } else { 145 | assert.NoError(t, err) 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /pkg/cmd/dashboard/testdata/kubeconfig: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | clusters: 3 | - cluster: 4 | certificate-authority-data: Y2VydGlmaWNhdGUtYXV0aG9yaXR5LWRhdGEK 5 | server: https://jx-rocks:6443 6 | name: jx-test 7 | contexts: 8 | - context: 9 | cluster: jx-test 10 | namespace: jx 11 | user: default 12 | name: namespace-test 13 | current-context: namespace-test 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: default 18 | user: 19 | client-certificate-data: Y2xpZW50LWNlcnRpZmljYXRlLWRhdGEK 20 | client-key-data: Y2xpZW50LWtleS1kYXRhCg== 21 | -------------------------------------------------------------------------------- /pkg/cmd/namespace/namespace_test.go: -------------------------------------------------------------------------------- 1 | package namespace_test 2 | 3 | // ToDo (@ankitm123): need to figure out how to test this 4 | // import ( 5 | // "os" 6 | // "testing" 7 | 8 | // jxv1 "github.com/jenkins-x/jx-api/v4/pkg/apis/jenkins.io/v1" 9 | // jxfake "github.com/jenkins-x/jx-api/v4/pkg/client/clientset/versioned/fake" 10 | // "github.com/jenkins-x/jx/pkg/cmd/namespace" 11 | // "github.com/stretchr/testify/assert" 12 | // v1 "k8s.io/api/core/v1" 13 | // metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 | // "k8s.io/client-go/kubernetes/fake" 15 | // ) 16 | 17 | // func TestNewCmdNamespace(t *testing.T) { 18 | // testCases := []struct { 19 | // description string 20 | // env string 21 | // args []string 22 | // ns string 23 | // }{ 24 | // { 25 | // description: "Test case 1", 26 | // env: "", 27 | // args: []string{""}, 28 | // ns: "jx", 29 | // }, 30 | // { 31 | // description: "Test case 2", 32 | // env: "dev", 33 | // args: []string{""}, 34 | // ns: "jx", 35 | // }, 36 | // { 37 | // description: "Test case 3", 38 | // env: "dev", 39 | // args: []string{"jx-staging"}, 40 | // ns: "jx", 41 | // }, 42 | // { 43 | // description: "Test case 4", 44 | // env: "", 45 | // args: []string{""}, 46 | // ns: "jx-test", 47 | // }, 48 | // { 49 | // description: "Test case 5", 50 | // env: "", 51 | // args: []string{"default"}, 52 | // ns: "jx", 53 | // }, 54 | // } 55 | // for k, tt := range testCases { 56 | // t.Logf("Running test case #%d: %s", k+1, tt.description) 57 | // kubeClient := fake.NewSimpleClientset(&v1.Namespace{ 58 | // ObjectMeta: metav1.ObjectMeta{ 59 | // Name: "jx", 60 | // }, 61 | // }, &v1.Namespace{ 62 | // ObjectMeta: metav1.ObjectMeta{ 63 | // Name: "default", 64 | // }, 65 | // }) 66 | // jxClient := jxfake.NewSimpleClientset(&jxv1.Environment{ 67 | // TypeMeta: metav1.TypeMeta{}, 68 | // ObjectMeta: metav1.ObjectMeta{ 69 | // Name: "dev", 70 | // Namespace: tt.ns, 71 | // }, 72 | // Spec: jxv1.EnvironmentSpec{ 73 | // Namespace: tt.ns, 74 | // }, 75 | // Status: jxv1.EnvironmentStatus{}, 76 | // }) 77 | // os.Setenv("KUBECONFIG", "testdata/kubeconfig") 78 | // _, o := namespace.NewCmdNamespace() 79 | // o.KubeClient = kubeClient 80 | // o.JXClient = jxClient 81 | // o.Env = tt.env 82 | // o.Args = tt.args 83 | // o.BatchMode = true 84 | // err := o.Run() 85 | // assert.NoError(t, err) 86 | // } 87 | // } 88 | -------------------------------------------------------------------------------- /pkg/cmd/namespace/testdata/kubeconfig: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | clusters: 3 | - cluster: 4 | certificate-authority-data: Y2VydGlmaWNhdGUtYXV0aG9yaXR5LWRhdGEK 5 | server: https://jx-rocks:6443 6 | name: jx-test 7 | contexts: 8 | - context: 9 | cluster: jx-test 10 | namespace: default 11 | user: default 12 | name: namespace-test 13 | current-context: namespace-test 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: default 18 | user: 19 | client-certificate-data: Y2xpZW50LWNlcnRpZmljYXRlLWRhdGEK 20 | client-key-data: Y2xpZW50LWtleS1kYXRhCg== 21 | -------------------------------------------------------------------------------- /pkg/cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | 8 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras" 9 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/helper" 10 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates" 11 | "github.com/jenkins-x/jx-helpers/v3/pkg/extensions" 12 | "github.com/jenkins-x/jx-helpers/v3/pkg/homedir" 13 | "github.com/jenkins-x/jx-helpers/v3/pkg/termcolor" 14 | "github.com/jenkins-x/jx-logging/v3/pkg/log" 15 | "github.com/jenkins-x/jx/pkg/cmd/dashboard" 16 | "github.com/jenkins-x/jx/pkg/cmd/namespace" 17 | "github.com/jenkins-x/jx/pkg/cmd/ui" 18 | "github.com/jenkins-x/jx/pkg/cmd/upgrade" 19 | "github.com/jenkins-x/jx/pkg/cmd/version" 20 | "github.com/jenkins-x/jx/pkg/plugins" 21 | "github.com/spf13/cobra" 22 | ) 23 | 24 | // Main creates the new command 25 | func Main(args []string) *cobra.Command { 26 | cmd := &cobra.Command{ 27 | Use: "jx", 28 | Short: "Jenkins X 3.x command line", 29 | Run: runHelp, 30 | // Hook before and after Run initialize and write profiles to disk, 31 | // respectively. 32 | PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 33 | 34 | if cmd.Name() == cobra.ShellCompRequestCmd || cmd.Name() == cobra.ShellCompNoDescRequestCmd { 35 | // This is the __complete or __completeNoDesc command which 36 | // indicates shell completion has been requested. 37 | plugins.SetupPluginCompletion(cmd, args) 38 | } 39 | return nil 40 | }, 41 | } 42 | 43 | po := &templates.Options{} 44 | getPluginCommandGroups := func() (templates.PluginCommandGroups, bool) { 45 | verifier := &extensions.CommandOverrideVerifier{ 46 | Root: cmd, 47 | SeenPlugins: make(map[string]string), 48 | } 49 | pluginCommandGroups, err := po.GetPluginCommandGroups(verifier, plugins.Plugins) 50 | if err != nil { 51 | log.Logger().Errorf("%v", err) 52 | } 53 | return pluginCommandGroups, false 54 | } 55 | doCmd := func(cmd *cobra.Command, args []string) { 56 | handleCommand(cmd, args) 57 | } 58 | 59 | generalCommands := []*cobra.Command{ 60 | cobras.SplitCommand(dashboard.NewCmdDashboard()), 61 | cobras.SplitCommand(namespace.NewCmdNamespace()), 62 | cobras.SplitCommand(ui.NewCmdUI()), 63 | cobras.SplitCommand(upgrade.NewCmdUpgrade()), 64 | cobras.SplitCommand(version.NewCmdVersion()), 65 | } 66 | 67 | // aliases to classic jx commands... 68 | getCmd := &cobra.Command{ 69 | Use: "get TYPE [flags]", 70 | Short: "Display one or more resources", 71 | Run: func(cmd *cobra.Command, _ []string) { 72 | err := cmd.Help() 73 | helper.CheckErr(err) 74 | }, 75 | SuggestFor: []string{"list", "ps"}, 76 | } 77 | addCmd := &cobra.Command{ 78 | Use: "add TYPE [flags]", 79 | Short: "Adds one or more resources", 80 | Run: func(cmd *cobra.Command, _ []string) { 81 | err := cmd.Help() 82 | helper.CheckErr(err) 83 | }, 84 | } 85 | getBuildCmd := &cobra.Command{ 86 | Use: "build TYPE [flags]", 87 | Short: "Display one or more resources relating to a pipeline build", 88 | Aliases: []string{"builds"}, 89 | Run: func(cmd *cobra.Command, _ []string) { 90 | err := cmd.Help() 91 | helper.CheckErr(err) 92 | }, 93 | } 94 | createCmd := &cobra.Command{ 95 | Use: "create TYPE [flags]", 96 | Short: "Create one or more resources", 97 | Run: func(cmd *cobra.Command, _ []string) { 98 | err := cmd.Help() 99 | helper.CheckErr(err) 100 | }, 101 | SuggestFor: []string{"new", "make"}, 102 | } 103 | startCmd := &cobra.Command{ 104 | Use: "start TYPE [flags]", 105 | Short: "Starts a resource", 106 | Run: func(cmd *cobra.Command, _ []string) { 107 | err := cmd.Help() 108 | helper.CheckErr(err) 109 | }, 110 | } 111 | stopCmd := &cobra.Command{ 112 | Use: "stop TYPE [flags]", 113 | Short: "Stops a resource", 114 | Run: func(cmd *cobra.Command, _ []string) { 115 | err := cmd.Help() 116 | helper.CheckErr(err) 117 | }, 118 | } 119 | addCmd.AddCommand( 120 | aliasCommand(cmd, doCmd, "app", []string{"gitops", "helmfile", "add"}, "chart"), 121 | ) 122 | getCmd.AddCommand( 123 | getBuildCmd, 124 | aliasCommand(cmd, doCmd, "activities", []string{"pipeline", "activities"}, "act", "activity"), 125 | aliasCommand(cmd, doCmd, "application", []string{"application", "get"}, "app", "apps", "applications"), 126 | aliasCommand(cmd, doCmd, "pipelines", []string{"pipeline", "get"}, "pipeline"), 127 | aliasCommand(cmd, doCmd, "previews", []string{"preview", "get"}, "preview"), 128 | ) 129 | getBuildCmd.AddCommand( 130 | aliasCommand(cmd, doCmd, "logs", []string{"pipeline", "logs"}, "log"), 131 | aliasCommand(cmd, doCmd, "pods", []string{"pipeline", "pods"}, "pod"), 132 | ) 133 | createCmd.AddCommand( 134 | aliasCommand(cmd, doCmd, "quickstart", []string{"project", "quickstart"}, "qs"), 135 | aliasCommand(cmd, doCmd, "spring", []string{"project", "spring"}, "sb"), 136 | aliasCommand(cmd, doCmd, "project", []string{"project"}), 137 | aliasCommand(cmd, doCmd, "pullrequest", []string{"project", "pullrequest"}, "pr"), 138 | ) 139 | startCmd.AddCommand( 140 | aliasCommand(cmd, doCmd, "pipeline", []string{"pipeline", "start"}, "pipelines"), 141 | ) 142 | stopCmd.AddCommand( 143 | aliasCommand(cmd, doCmd, "pipeline", []string{"pipeline", "stop"}, "pipelines"), 144 | ) 145 | generalCommands = append(generalCommands, addCmd, getCmd, createCmd, startCmd, stopCmd, 146 | aliasCommand(cmd, doCmd, "import", []string{"project", "import"}), 147 | aliasCommand(cmd, doCmd, "ctx", []string{"context"}), 148 | ) 149 | 150 | cmd.AddCommand(generalCommands...) 151 | 152 | var groups templates.CommandGroups 153 | command := templates.CommandGroup{ 154 | 155 | Message: "General:", 156 | Commands: generalCommands, 157 | } 158 | groups = append(groups, command) 159 | 160 | groups.Add(cmd) 161 | filters := []string{"options"} 162 | 163 | templates.ActsAsRootCommand(cmd, filters, getPluginCommandGroups, groups...) 164 | handleCommand(cmd, args) 165 | return cmd 166 | } 167 | 168 | func handleCommand(cmd *cobra.Command, args []string) { 169 | 170 | if len(args) == 0 { 171 | args = os.Args 172 | } 173 | if len(args) > 1 { 174 | cmdPathPieces := args[1:] 175 | pluginDir, err := homedir.DefaultPluginBinDir() 176 | if err != nil { 177 | log.Logger().Errorf("%v", err) 178 | os.Exit(1) 179 | } 180 | 181 | // only look for suitable executables if 182 | // the specified command does not already exist 183 | if _, _, err := cmd.Find(cmdPathPieces); err != nil { 184 | var cmdName string // first "non-flag" arguments 185 | for _, arg := range cmdPathPieces { 186 | if !strings.HasPrefix(arg, "-") { 187 | cmdName = arg 188 | break 189 | } 190 | } 191 | switch cmdName { 192 | case "help", cobra.ShellCompRequestCmd, cobra.ShellCompNoDescRequestCmd, "completion": 193 | // Don't search for a plugin 194 | default: 195 | if err := handleEndpointExtensions(cmdPathPieces, pluginDir); err != nil { 196 | log.Logger().Errorf("%v", err) 197 | os.Exit(1) 198 | } 199 | } 200 | } 201 | } 202 | } 203 | 204 | func aliasCommand(rootCmd *cobra.Command, fn func(cmd *cobra.Command, args []string), name string, args []string, aliases ...string) *cobra.Command { 205 | realArgs := append([]string{"jx"}, args...) 206 | cmd := &cobra.Command{ 207 | Use: name, 208 | Short: "alias for: " + strings.Join(realArgs, " "), 209 | Aliases: aliases, 210 | ValidArgsFunction: func(_ *cobra.Command, completeArgs []string, toComplete string) ([]string, cobra.ShellCompDirective) { 211 | cmd, pluginArgs, err := rootCmd.Find(args) 212 | if err != nil { 213 | return nil, cobra.ShellCompDirectiveNoFileComp 214 | } 215 | return plugins.PluginCompletion(cmd, append(pluginArgs, completeArgs...), toComplete) 216 | }, 217 | Run: func(_ *cobra.Command, args []string) { 218 | realArgs = append(realArgs, args...) 219 | log.Logger().Debugf("about to invoke alias: %s", strings.Join(realArgs, " ")) 220 | fn(rootCmd, realArgs) 221 | }, 222 | DisableFlagParsing: true, 223 | } 224 | return cmd 225 | } 226 | 227 | func runHelp(cmd *cobra.Command, _ []string) { 228 | cmd.Help() //nolint:errcheck 229 | } 230 | 231 | func handleEndpointExtensions(cmdArgs []string, pluginBinDir string) error { 232 | var remainingArgs []string // all "non-flag" arguments 233 | 234 | for idx := range cmdArgs { 235 | if strings.HasPrefix(cmdArgs[idx], "-") { 236 | break 237 | } 238 | remainingArgs = append(remainingArgs, strings.ReplaceAll(cmdArgs[idx], "-", "_")) 239 | } 240 | 241 | foundBinaryPath := "" 242 | 243 | // attempt to find binary, starting at longest possible name with given cmdArgs 244 | var err error 245 | for len(remainingArgs) > 0 { 246 | commandName := fmt.Sprintf("jx-%s", strings.Join(remainingArgs, "-")) 247 | 248 | // lets try the correct plugin versions first 249 | path := "" 250 | if plugins.PluginMap[commandName] != nil { 251 | p := *plugins.PluginMap[commandName] 252 | path, err = extensions.EnsurePluginInstalled(p, pluginBinDir) 253 | if err != nil { 254 | return fmt.Errorf("failed to install binary plugin %s version %s to %s: %w", commandName, p.Spec.Version, pluginBinDir, err) 255 | } 256 | } 257 | 258 | // lets see if there's a local build of the plugin on the PATH for developers... 259 | if path == "" { 260 | path, err = plugins.Lookup(commandName, pluginBinDir) 261 | } 262 | if path != "" { 263 | foundBinaryPath = path 264 | break 265 | } 266 | remainingArgs = remainingArgs[:len(remainingArgs)-1] 267 | } 268 | 269 | if foundBinaryPath == "" { 270 | return err 271 | } 272 | 273 | nextArgs := cmdArgs[len(remainingArgs):] 274 | log.Logger().Debugf("using the plugin command: %s", termcolor.ColorInfo(foundBinaryPath+" "+strings.Join(nextArgs, " "))) 275 | 276 | // Giving plugin information about how it was invoked, so it can give correct help 277 | pluginCommandName := os.Args[0] + " " + strings.Join(remainingArgs, " ") 278 | environ := append(os.Environ(), 279 | fmt.Sprintf("BINARY_NAME=%s", pluginCommandName), 280 | fmt.Sprintf("TOP_LEVEL_COMMAND=%s", pluginCommandName)) 281 | // invoke cmd binary relaying the current environment and args given 282 | // remainingArgs will always have at least one element. 283 | // execute will make remainingArgs[0] the "binary name". 284 | return plugins.Execute(foundBinaryPath, nextArgs, environ) 285 | } 286 | -------------------------------------------------------------------------------- /pkg/cmd/root_test.go: -------------------------------------------------------------------------------- 1 | package cmd_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/jenkins-x/jx/pkg/cmd" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestMain(t *testing.T) { 11 | rootCmd := cmd.Main([]string{""}) 12 | err := rootCmd.Execute() 13 | assert.NoError(t, err) 14 | } 15 | -------------------------------------------------------------------------------- /pkg/cmd/ui/ui.go: -------------------------------------------------------------------------------- 1 | package ui 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/jenkins-x/jx-api/v4/pkg/util" 10 | "github.com/jenkins-x/jx-helpers/v3/pkg/cmdrunner" 11 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/helper" 12 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates" 13 | "github.com/jenkins-x/jx-helpers/v3/pkg/files" 14 | "github.com/jenkins-x/jx-helpers/v3/pkg/options" 15 | "github.com/jenkins-x/jx-logging/v3/pkg/log" 16 | "github.com/jenkins-x/jx/pkg/plugins" 17 | 18 | "github.com/spf13/cobra" 19 | "k8s.io/client-go/util/homedir" 20 | 21 | "github.com/jenkins-x/jx-helpers/v3/pkg/termcolor" 22 | ) 23 | 24 | type Options struct { 25 | options.BaseOptions 26 | CommandRunner cmdrunner.CommandRunner 27 | BrowserPath string 28 | Host string 29 | Port int 30 | OctantArgs []string 31 | } 32 | 33 | var ( 34 | info = termcolor.ColorInfo 35 | 36 | cmdLong = templates.LongDesc(` 37 | Views the Jenkins X UI (octant).`) 38 | 39 | cmdExample = templates.Examples(` 40 | # open the UI 41 | jx ui 42 | # To pass arguments to octant 43 | jx ui -o --namespace=jx -o -v -o --browser-path="/#/jx/pipelines" 44 | `) 45 | ) 46 | 47 | // NewCmdUI opens the octant UI 48 | func NewCmdUI() (*cobra.Command, *Options) { 49 | o := &Options{} 50 | cmd := &cobra.Command{ 51 | Use: "ui", 52 | Short: "Views the Jenkins X UI (octant)", 53 | Long: cmdLong, 54 | Example: cmdExample, 55 | Run: func(_ *cobra.Command, _ []string) { 56 | err := o.Run() 57 | helper.CheckErr(err) 58 | }, 59 | } 60 | 61 | cmd.Flags().StringVarP(&o.BrowserPath, "browser-path", "p", "/#/jx/pipelines-recent", "The browser path inside octant to open") 62 | cmd.Flags().StringVarP(&o.Host, "host", "", "", "The host to listen on") 63 | cmd.Flags().IntVarP(&o.Port, "port", "", 0, "The port for octant to listen on") 64 | cmd.Flags().StringSliceVarP(&o.OctantArgs, "octant-args", "o", []string{"--namespace=jx"}, "Extra arguments passed to the octant binary") 65 | o.BaseOptions.AddBaseFlags(cmd) 66 | return cmd, o 67 | } 68 | 69 | func (o *Options) Run() error { 70 | if o.CommandRunner == nil { 71 | o.CommandRunner = cmdrunner.QuietCommandRunner 72 | } 73 | // lets find the octant binary... 74 | octantBin, err := plugins.GetOctantBinary("") 75 | if err != nil { 76 | return fmt.Errorf("failed to download the octant binary: %w", err) 77 | } 78 | 79 | err = VerifyOctantPlugins(o.CommandRunner) 80 | if err != nil { 81 | return fmt.Errorf("failed to download the Jenkins X octant plugins: %w", err) 82 | } 83 | 84 | args := append([]string{"--browser-path", o.BrowserPath}, o.OctantArgs...) 85 | 86 | if o.Port != 0 || o.Host != "" { 87 | if o.Port == 0 { 88 | o.Port = 8080 89 | } 90 | if o.Host == "" { 91 | o.Host = "localhost" 92 | } 93 | args = append(args, "--listener-addr", fmt.Sprintf("%s:%d", o.Host, o.Port)) 94 | } 95 | 96 | c := &cmdrunner.Command{ 97 | Name: octantBin, 98 | Args: args, 99 | Out: os.Stdout, 100 | Err: os.Stderr, 101 | In: os.Stdin, 102 | } 103 | _, err = o.CommandRunner(c) 104 | if err != nil { 105 | return fmt.Errorf("failed to start octant via: %s: %w", c.CLI(), err) 106 | } 107 | return nil 108 | } 109 | 110 | func VerifyOctantPlugins(runner cmdrunner.CommandRunner) error { 111 | err := VerifyOctantPluginVersion(runner, "octant-jx", plugins.OctantJXVersion, func() (string, error) { 112 | return plugins.GetOctantJXBinary(plugins.OctantJXVersion) 113 | }) 114 | if err != nil { 115 | return err 116 | } 117 | return VerifyOctantPluginVersion(runner, "octant-jxo", plugins.OctantJXVersion, func() (string, error) { 118 | return plugins.GetOctantJXOBinary(plugins.OctantJXVersion) 119 | }) 120 | } 121 | 122 | func VerifyOctantPluginVersion(runner cmdrunner.CommandRunner, pluginName, requiredVersion string, fn func() (string, error)) error { 123 | pluginDir := OctantPluginsDir() 124 | octantJxBin := filepath.Join(pluginDir, pluginName) 125 | 126 | version := "" 127 | exists, err := util.FileExists(octantJxBin) 128 | if err != nil { 129 | return fmt.Errorf("failed to check if file exists %s: %w", octantJxBin, err) 130 | } 131 | 132 | if exists { 133 | c := &cmdrunner.Command{ 134 | Name: octantJxBin, 135 | Args: []string{"version"}, 136 | } 137 | // lets try check the version 138 | out, err := runner(c) 139 | if err != nil { 140 | log.Logger().Warnf("failed to run command %s version: %s", octantJxBin, err.Error()) 141 | } else { 142 | version = strings.TrimSpace(out) 143 | } 144 | } 145 | 146 | if version == requiredVersion { 147 | log.Logger().Debugf("the %s plugin is already on version %s", info(pluginName), info(version)) 148 | return nil 149 | } 150 | if version != "" { 151 | log.Logger().Infof("the %s plugin %s is being upgraded to %s", info(pluginName), info(version), info(requiredVersion)) 152 | } 153 | jxBin, err := fn() 154 | if err != nil { 155 | return err 156 | } 157 | 158 | err = os.MkdirAll(pluginDir, util.DefaultWritePermissions) 159 | if err != nil { 160 | return fmt.Errorf("failed to create octant plugin directory %s: %w", pluginDir, err) 161 | } 162 | err = files.CopyFile(jxBin, octantJxBin) 163 | if err != nil { 164 | return fmt.Errorf("failed to copy new plugin version %s to %s: %w", jxBin, octantJxBin, err) 165 | } 166 | 167 | log.Logger().Debugf("updated plugin file %s", info(octantJxBin)) 168 | return nil 169 | } 170 | 171 | // OctantPluginsDir returns the location of octant plugins 172 | func OctantPluginsDir() string { 173 | return filepath.Join(homedir.HomeDir(), ".config", "octant", "plugins") 174 | } 175 | -------------------------------------------------------------------------------- /pkg/cmd/upgrade/testdata/kubeconfig: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | clusters: 3 | - cluster: 4 | certificate-authority-data: Y2VydGlmaWNhdGUtYXV0aG9yaXR5LWRhdGEK 5 | server: https://jx-rocks:6443 6 | name: jx-test 7 | contexts: 8 | - context: 9 | cluster: jx-test 10 | namespace: jx 11 | user: default 12 | name: namespace-test 13 | current-context: namespace-test 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: default 18 | user: 19 | client-certificate-data: Y2xpZW50LWNlcnRpZmljYXRlLWRhdGEK 20 | client-key-data: Y2xpZW50LWtleS1kYXRhCg== 21 | -------------------------------------------------------------------------------- /pkg/cmd/upgrade/upgrade.go: -------------------------------------------------------------------------------- 1 | package upgrade 2 | 3 | import ( 4 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras" 5 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/helper" 6 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | var ( 11 | cmdLong = templates.LongDesc(` 12 | Upgrades all of the plugins in your local Jenkins X CLI 13 | `) 14 | 15 | cmdExample = templates.Examples(` 16 | # upgrades your plugin binaries 17 | jx upgrade 18 | `) 19 | ) 20 | 21 | // UpgradeOptions the options for upgrading a cluster 22 | type Options struct { 23 | Cmd *cobra.Command 24 | } 25 | 26 | // NewCmdUpgrade creates a command object for the command 27 | func NewCmdUpgrade() (*cobra.Command, *Options) { 28 | o := &Options{} 29 | 30 | o.Cmd = &cobra.Command{ 31 | Use: "upgrade", 32 | Short: "Upgrades resources", 33 | Long: cmdLong, 34 | Example: cmdExample, 35 | Run: func(_ *cobra.Command, _ []string) { 36 | err := o.Run() 37 | helper.CheckErr(err) 38 | }, 39 | } 40 | 41 | o.Cmd.AddCommand(cobras.SplitCommand(NewCmdUpgradeCLI())) 42 | o.Cmd.AddCommand(cobras.SplitCommand(NewCmdUpgradePlugins())) 43 | 44 | return o.Cmd, o 45 | } 46 | 47 | // Run implements this command 48 | func (o *Options) Run() error { 49 | return o.Cmd.Help() 50 | } 51 | -------------------------------------------------------------------------------- /pkg/cmd/upgrade/upgrade_cli_test.go: -------------------------------------------------------------------------------- 1 | package upgrade_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/jenkins-x/jx-logging/v3/pkg/log" 8 | "github.com/jenkins-x/jx/pkg/cmd/upgrade" 9 | "github.com/jenkins-x/jx/pkg/cmd/version" 10 | 11 | "github.com/blang/semver" 12 | 13 | "github.com/stretchr/testify/assert" 14 | // typev1 "github.com/jenkins-x/jx-api/v4/pkg/client/clientset/versioned/typed/jenkins.io/v1" 15 | ) 16 | 17 | func TestNeedsUpgrade(t *testing.T) { 18 | type testData struct { 19 | current string 20 | latest string 21 | expectedUpgradeNeeded bool 22 | expectedMessage string 23 | } 24 | 25 | testCases := []testData{ 26 | { 27 | "1.0.0", "1.0.0", false, "You are already on the latest version of jx 1.0.0\n", 28 | }, 29 | { 30 | "1.0.0", "1.0.1", true, "", 31 | }, 32 | { 33 | "1.0.0", "0.0.99", true, "", 34 | }, 35 | } 36 | 37 | o := upgrade.CLIOptions{} 38 | for _, data := range testCases { 39 | currentVersion, _ := semver.New(data.current) 40 | latestVersion, _ := semver.New(data.latest) 41 | actualMessage := log.CaptureOutput(func() { 42 | actualUpgradeNeeded := o.NeedsUpgrade(*currentVersion, *latestVersion) 43 | assert.Equal(t, data.expectedUpgradeNeeded, actualUpgradeNeeded, fmt.Sprintf("Unexpected upgrade flag for %v", data)) 44 | }) 45 | assert.Equal(t, data.expectedMessage, actualMessage, fmt.Sprintf("Unexpected message for %v", data)) 46 | } 47 | } 48 | 49 | func TestNewCmdUpgradeCLI(t *testing.T) { 50 | cmd, o := upgrade.NewCmdUpgradeCLI() 51 | o.Version = "3.2.238" 52 | err := cmd.Execute() 53 | assert.NoError(t, err) 54 | } 55 | 56 | func TestVersionCheckWhenCurrentVersionIsGreaterThanReleaseVersion(t *testing.T) { 57 | jxVersion := semver.Version{Major: 1, Minor: 3, Patch: 153} 58 | version.Version = "1.4.0" 59 | opts := &upgrade.CLIOptions{} 60 | update, err := opts.ShouldUpdate(jxVersion) 61 | assert.NoError(t, err, "should check version without failure") 62 | assert.False(t, update, "should not update") 63 | } 64 | 65 | func TestVersionCheckWhenCurrentVersionIsEqualToReleaseVersion(t *testing.T) { 66 | jxVersion := semver.Version{Major: 1, Minor: 2, Patch: 3} 67 | version.Version = "1.2.3" 68 | opts := &upgrade.CLIOptions{} 69 | update, err := opts.ShouldUpdate(jxVersion) 70 | assert.NoError(t, err, "should check version without failure") 71 | assert.False(t, update, "should not update") 72 | } 73 | 74 | func TestVersionCheckWhenCurrentVersionIsLessThanReleaseVersion(t *testing.T) { 75 | jxVersion := semver.Version{Major: 1, Minor: 3, Patch: 153} 76 | version.Version = "1.0.0" 77 | opts := &upgrade.CLIOptions{} 78 | update, err := opts.ShouldUpdate(jxVersion) 79 | assert.NoError(t, err, "should check version without failure") 80 | assert.True(t, update, "should update") 81 | } 82 | 83 | func TestVersionCheckWhenCurrentVersionIsEqualToReleaseVersionWithPatch(t *testing.T) { 84 | var prVersions []semver.PRVersion 85 | prVersions = append(prVersions, semver.PRVersion{VersionStr: "dev"}) 86 | jxVersion := semver.Version{Major: 1, Minor: 2, Patch: 3, Pre: prVersions, Build: []string(nil)} 87 | version.Version = "1.2.3" 88 | opts := &upgrade.CLIOptions{} 89 | update, err := opts.ShouldUpdate(jxVersion) 90 | assert.NoError(t, err, "should check version without failure") 91 | assert.False(t, update, "should not update") 92 | } 93 | 94 | func TestVersionCheckWhenCurrentVersionWithPatchIsEqualToReleaseVersion(t *testing.T) { 95 | jxVersion := semver.Version{Major: 1, Minor: 2, Patch: 3} 96 | version.Version = "1.2.3-dev+6a8285f4" 97 | opts := &upgrade.CLIOptions{} 98 | update, err := opts.ShouldUpdate(jxVersion) 99 | assert.NoError(t, err, "should check version without failure") 100 | assert.False(t, update, "should not update") 101 | } 102 | 103 | func TestVersionCheckWhenCurrentVersionWithPatchIsLessThanReleaseVersion(t *testing.T) { 104 | jxVersion := semver.Version{Major: 1, Minor: 2, Patch: 3} 105 | version.Version = "1.2.2-dev+6a8285f4" 106 | opts := &upgrade.CLIOptions{} 107 | update, err := opts.ShouldUpdate(jxVersion) 108 | assert.NoError(t, err, "should check version without failure") 109 | assert.False(t, update, "should not update") 110 | } 111 | -------------------------------------------------------------------------------- /pkg/cmd/upgrade/upgrade_plugins.go: -------------------------------------------------------------------------------- 1 | package upgrade 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | 8 | "github.com/jenkins-x/jx-helpers/v3/pkg/cmdrunner" 9 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/helper" 10 | "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates" 11 | "github.com/jenkins-x/jx-helpers/v3/pkg/extensions" 12 | "github.com/jenkins-x/jx-helpers/v3/pkg/homedir" 13 | "github.com/jenkins-x/jx-helpers/v3/pkg/termcolor" 14 | "github.com/jenkins-x/jx-logging/v3/pkg/log" 15 | "github.com/jenkins-x/jx/pkg/plugins" 16 | 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | var ( 21 | cmdPluginsLong = templates.LongDesc(` 22 | Upgrades all of the plugins in your local Jenkins X CLI 23 | `) 24 | 25 | cmdPluginsExample = templates.Examples(` 26 | # upgrades your plugin binaries 27 | jx upgrade plugins 28 | `) 29 | 30 | bootPlugins = map[string]bool{ 31 | "gitops": true, 32 | "health": true, 33 | "secret": true, 34 | "verify": true, 35 | "changelog": true, 36 | } 37 | ) 38 | 39 | // UpgradeOptions the options for upgrading a cluster 40 | type PluginOptions struct { 41 | CommandRunner cmdrunner.CommandRunner 42 | OnlyMandatory bool 43 | Boot bool 44 | Path string 45 | } 46 | 47 | // NewCmdUpgrade creates a command object for the command 48 | func NewCmdUpgradePlugins() (*cobra.Command, *PluginOptions) { 49 | o := &PluginOptions{} 50 | 51 | cmd := &cobra.Command{ 52 | Use: "plugins", 53 | Short: "Upgrades all of the plugins in your local Jenkins X CLI", 54 | Long: cmdPluginsLong, 55 | Example: cmdPluginsExample, 56 | Run: func(_ *cobra.Command, _ []string) { 57 | err := o.Run() 58 | helper.CheckErr(err) 59 | }, 60 | } 61 | cmd.Flags().BoolVarP(&o.OnlyMandatory, "mandatory", "m", false, "if set lets ignore optional plugins") 62 | cmd.Flags().BoolVarP(&o.Boot, "boot", "", false, "only install plugins required for boot") 63 | cmd.Flags().StringVarP(&o.Path, "path", "", "/usr/bin", "creates a symlink to the binary plugins in this bin path dir") 64 | 65 | return cmd, o 66 | } 67 | 68 | // Run implements the command 69 | func (o *PluginOptions) Run() error { 70 | pluginBinDir, err := homedir.DefaultPluginBinDir() 71 | if err != nil { 72 | return fmt.Errorf("failed to find plugin bin directory: %w", err) 73 | } 74 | 75 | if o.CommandRunner == nil { 76 | o.CommandRunner = cmdrunner.DefaultCommandRunner 77 | } 78 | for k := range plugins.Plugins { 79 | p := plugins.Plugins[k] 80 | if o.Boot && !bootPlugins[p.Name] { 81 | continue 82 | } 83 | log.Logger().Infof("checking binary jx plugin %s version %s is installed", termcolor.ColorInfo(p.Name), termcolor.ColorInfo(p.Spec.Version)) 84 | fileName, err := extensions.EnsurePluginInstalled(p, pluginBinDir) 85 | if err != nil { 86 | return fmt.Errorf("failed to ensure plugin is installed %s: %w", p.Name, err) 87 | } 88 | 89 | if o.Boot { 90 | if p.Name == "gitops" { 91 | c := &cmdrunner.Command{ 92 | Name: fileName, 93 | Args: []string{"plugin", "upgrade", "--path", o.Path}, 94 | } 95 | _, err = o.CommandRunner(c) 96 | if err != nil { 97 | return fmt.Errorf("failed to upgrade gitops plugin %s: %w", p.Name, err) 98 | } 99 | } 100 | continue 101 | } 102 | 103 | // TODO we could use metadata on the plugin for this? 104 | if p.Name == "secret" { 105 | c := &cmdrunner.Command{ 106 | Name: fileName, 107 | Args: []string{"plugins", "upgrade"}, 108 | } 109 | _, err = o.CommandRunner(c) 110 | if err != nil { 111 | return fmt.Errorf("failed to upgrade plugin %s: %w", p.Name, err) 112 | } 113 | } 114 | } 115 | if !(o.OnlyMandatory || o.Boot) { 116 | // Upgrade the rest 117 | file, err := os.Open(pluginBinDir) 118 | if err != nil { 119 | return fmt.Errorf("failed to read plugin dir %s: %w", pluginBinDir, err) 120 | } 121 | defer file.Close() 122 | files, err := file.Readdirnames(0) 123 | if err != nil { 124 | return fmt.Errorf("failed to read plugin dir %s: %w", pluginBinDir, err) 125 | } 126 | pluginPattern := regexp.MustCompile("^(jx-.*)-[0-9.]+$") 127 | extraPlugins := make(map[string]bool) 128 | for _, plugin := range files { 129 | res := pluginPattern.FindStringSubmatch(plugin) 130 | if len(res) > 1 { 131 | cleanPlugin := res[1] 132 | if plugins.PluginMap[cleanPlugin] == nil { 133 | extraPlugins[cleanPlugin] = true 134 | } 135 | } 136 | } 137 | for plugin := range extraPlugins { 138 | _, err = plugins.InstallStandardPlugin(pluginBinDir, plugin) 139 | if err != nil { 140 | log.Logger().Warnf("Failed to upgrade plugin %s: %+v", plugin, err) 141 | } 142 | } 143 | } 144 | 145 | return nil 146 | } 147 | -------------------------------------------------------------------------------- /pkg/cmd/upgrade/upgrade_plugins_test.go: -------------------------------------------------------------------------------- 1 | package upgrade_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/jenkins-x/jx/pkg/cmd/upgrade" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestUpgrade(t *testing.T) { 11 | t.Parallel() 12 | 13 | cmd, _ := upgrade.NewCmdUpgradePlugins() 14 | 15 | err := cmd.Execute() 16 | require.NoError(t, err, "failed to run upgrade command") 17 | } 18 | -------------------------------------------------------------------------------- /pkg/cmd/upgrade/upgrade_test.go: -------------------------------------------------------------------------------- 1 | package upgrade_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/jenkins-x/jx/pkg/cmd/upgrade" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestNewCmdUpgrade(t *testing.T) { 11 | cmd, _ := upgrade.NewCmdUpgrade() 12 | err := cmd.Execute() 13 | assert.NoError(t, err) 14 | } 15 | -------------------------------------------------------------------------------- /pkg/cmd/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | 8 | "github.com/blang/semver" 9 | 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | // Build information. Populated at build-time. 14 | type buildInfo struct { 15 | Version string 16 | Revision string 17 | Branch string 18 | GitTreeState string 19 | BuildDate string 20 | GoVersion string 21 | } 22 | 23 | // Build information. Populated at build-time. 24 | var ( 25 | Version string 26 | Revision string 27 | BuildDate string 28 | GoVersion string 29 | Branch string 30 | GitTreeState string 31 | ) 32 | 33 | const ( 34 | 35 | // TestVersion used in test cases for the current version if no 36 | // version can be found - such as if the version property is not properly 37 | // included in the go test flags. 38 | TestVersion = "3.2.238" 39 | 40 | // TestRevision can be used in tests if no revision is passed in the test flags 41 | TestRevision = "04b628f48" 42 | 43 | // TestBranch can be used in tests if no tree state is passed in the test flags 44 | TestBranch = "main" 45 | 46 | // TestTreeState can be used in tests if no tree state is passed in the test flags 47 | TestTreeState = "clean" 48 | 49 | // TestBuildDate can be used in tests if no build date is passed in the test flags 50 | TestBuildDate = "2022-05-31T14:51:38Z" 51 | 52 | // TestGoVersion can be used in tests if no version is passed in the test flags 53 | TestGoVersion = "1.17.8" 54 | ) 55 | 56 | // ShowOptions the options for viewing running PRs 57 | type Options struct { 58 | Verbose bool 59 | Quiet bool 60 | Short bool 61 | Out io.Writer 62 | } 63 | 64 | // NewCmdVersion creates a command object for the "version" command 65 | func NewCmdVersion() (*cobra.Command, *Options) { 66 | o := &Options{} 67 | 68 | cmd := &cobra.Command{ 69 | Use: "version", 70 | Short: "Displays the version of this command", 71 | Run: func(_ *cobra.Command, _ []string) { 72 | o.run() 73 | }, 74 | } 75 | cmd.Flags().BoolVarP(&o.Quiet, "quiet", "q", false, "uses the quiet format of just outputting the version number only") 76 | cmd.Flags().BoolVarP(&o.Short, "short", "s", false, "uses the short format of just outputting the version number only") 77 | return cmd, o 78 | } 79 | 80 | // Run implements the command 81 | func (o *Options) run() { 82 | v := getBuildInfo() 83 | if o.Out == nil { 84 | o.Out = os.Stdout 85 | } 86 | if o.Quiet { 87 | fmt.Fprintln(o.Out, "The --quit, -q flag is being deprecated from JX on Oct 2022\nUse --short, -s instead") 88 | fmt.Fprintf(o.Out, "%s\n", v.Version) 89 | return 90 | } 91 | if o.Short { 92 | fmt.Fprintf(o.Out, "%s\n", v.Version) 93 | return 94 | } 95 | fmt.Fprintf(o.Out, "version: %s\n", v.Version) 96 | fmt.Fprintf(o.Out, "shaCommit: %s\n", v.Revision) 97 | fmt.Fprintf(o.Out, "buildDate: %s\n", v.BuildDate) 98 | fmt.Fprintf(o.Out, "goVersion: %s\n", v.GoVersion) 99 | fmt.Fprintf(o.Out, "branch: %s\n", v.Branch) 100 | fmt.Fprintf(o.Out, "gitTreeState: %s\n", v.GitTreeState) 101 | } 102 | 103 | func getBuildInfo() buildInfo { 104 | return buildInfo{ 105 | Version: getVersion(), 106 | Revision: getCommitSha(), 107 | Branch: getBranch(), 108 | GitTreeState: getTreeState(), 109 | BuildDate: getBuildDate(), 110 | GoVersion: getGoVersion(), 111 | } 112 | } 113 | 114 | func getVersion() string { 115 | if Version != "" { 116 | return Version 117 | } 118 | return TestVersion 119 | } 120 | 121 | func getGoVersion() string { 122 | if GoVersion != "" { 123 | return GoVersion 124 | } 125 | return TestGoVersion 126 | } 127 | 128 | func getCommitSha() string { 129 | if Revision != "" { 130 | return Revision 131 | } 132 | return TestRevision 133 | } 134 | 135 | func getBuildDate() string { 136 | if BuildDate != "" { 137 | return BuildDate 138 | } 139 | return TestBuildDate 140 | } 141 | 142 | func getBranch() string { 143 | if Branch != "" { 144 | return Branch 145 | } 146 | return TestBranch 147 | } 148 | 149 | func getTreeState() string { 150 | if GitTreeState != "" { 151 | return GitTreeState 152 | } 153 | return TestTreeState 154 | } 155 | 156 | func GetSemverVersion() (semver.Version, error) { 157 | text := getVersion() 158 | v, err := semver.Make(text) 159 | if err != nil { 160 | return v, fmt.Errorf("failed to parse version %s: %w", text, err) 161 | } 162 | return v, nil 163 | } 164 | -------------------------------------------------------------------------------- /pkg/cmd/version/version_test.go: -------------------------------------------------------------------------------- 1 | package version_test 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/jenkins-x/jx/pkg/cmd/version" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | // define a strtuct for test cases for the version command 13 | type TestCase struct { 14 | args []string 15 | err error 16 | description string 17 | out string 18 | } 19 | 20 | var testCases = []TestCase{ 21 | { 22 | args: nil, 23 | err: nil, 24 | description: "This is to test without flags", 25 | out: "version: 3.2.238\nshaCommit: 04b628f48\nbuildDate: 2022-05-31T14:51:38Z\ngoVersion: 1.17.8\nbranch: main\ngitTreeState: clean\n", 26 | }, 27 | { 28 | args: []string{"-q"}, 29 | err: nil, 30 | description: "This is to test -q flag", 31 | out: "The --quit, -q flag is being deprecated from JX on Oct 2022\nUse --short, -s instead\n3.2.238\n", 32 | }, 33 | { 34 | args: []string{"--quiet"}, 35 | err: nil, 36 | description: "This is to test --quiet flag", 37 | out: "The --quit, -q flag is being deprecated from JX on Oct 2022\nUse --short, -s instead\n3.2.238\n", 38 | }, 39 | { 40 | args: []string{"-s"}, 41 | err: nil, 42 | description: "This is to test -s flag", 43 | out: "3.2.238\n", 44 | }, 45 | { 46 | args: []string{"--short"}, 47 | err: nil, 48 | description: "This is to test --short flag", 49 | out: "3.2.238\n", 50 | }, 51 | } 52 | 53 | func TestNewCmdVersion(t *testing.T) { 54 | for _, testCase := range testCases { 55 | var buf bytes.Buffer 56 | cmd, options := version.NewCmdVersion() 57 | options.Out = &buf 58 | cmd.SetArgs(testCase.args) 59 | err := cmd.Execute() 60 | 61 | fmt.Println(testCase.description) 62 | assert.NoError(t, err) 63 | if testCase.err == nil { 64 | assert.Equal(t, testCase.out, buf.String()) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pkg/common/constants.go: -------------------------------------------------------------------------------- 1 | package common 2 | -------------------------------------------------------------------------------- /pkg/plugins/helpers_test.go: -------------------------------------------------------------------------------- 1 | package plugins_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/jenkins-x/jx/pkg/plugins" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestPlugins(t *testing.T) { 11 | t.Parallel() 12 | 13 | list := plugins.Plugins 14 | 15 | for _, p := range list { 16 | if p.Name != "gitops" { 17 | continue 18 | } 19 | assert.Equal(t, "jx-gitops", p.Spec.Name, "plugin.Spec.Name") 20 | 21 | foundLinux := false 22 | foundWindows := false 23 | for _, b := range p.Spec.Binaries { 24 | if b.Goos == "Linux" && b.Goarch == "amd64" { 25 | foundLinux = true 26 | assert.Equal(t, "https://github.com/jenkins-x-plugins/jx-gitops/releases/download/v"+plugins.GitOpsVersion+"/jx-gitops-linux-amd64.tar.gz", b.URL, "URL for linux binary") 27 | t.Logf("found linux binary URL %s", b.URL) 28 | } else if b.Goos == "Windows" && b.Goarch == "amd64" { 29 | foundWindows = true 30 | assert.Equal(t, "https://github.com/jenkins-x-plugins/jx-gitops/releases/download/v"+plugins.GitOpsVersion+"/jx-gitops-windows-amd64.zip", b.URL, "URL for windows binary") 31 | t.Logf("found windows binary URL %s", b.URL) 32 | } 33 | } 34 | assert.True(t, foundLinux, "did not find a linux binary in the plugin %#v", p) 35 | assert.True(t, foundWindows, "did not find a windows binary in the plugin %#v", p) 36 | } 37 | } 38 | 39 | func TestOctantPlugin(t *testing.T) { 40 | t.Parallel() 41 | 42 | plugin := plugins.CreateOctantPlugin("0.16.1") 43 | 44 | assert.Equal(t, plugins.OctantPluginName, plugin.Name, "plugin.Name") 45 | assert.Equal(t, plugins.OctantPluginName, plugin.Spec.Name, "plugin.Spec.Name") 46 | 47 | foundLinux := false 48 | foundWindows := false 49 | for _, b := range plugin.Spec.Binaries { 50 | if b.Goos == "Linux" && b.Goarch == "amd64" { 51 | foundLinux = true 52 | assert.Equal(t, "https://github.com/vmware-tanzu/octant/releases/download/v0.16.1/octant_0.16.1_Linux-64bit.tar.gz", b.URL, "URL for linux binary") 53 | t.Logf("found linux binary URL %s", b.URL) 54 | } else if b.Goos == "Windows" && b.Goarch == "amd64" { 55 | foundWindows = true 56 | assert.Equal(t, "https://github.com/vmware-tanzu/octant/releases/download/v0.16.1/octant_0.16.1_Windows-64bit.zip", b.URL, "URL for windows binary") 57 | t.Logf("found windows binary URL %s", b.URL) 58 | } else if b.Goos == "Darwin" { 59 | foundWindows = true 60 | assert.Equal(t, "https://github.com/vmware-tanzu/octant/releases/download/v0.16.1/octant_0.16.1_macOS-64bit.tar.gz", b.URL, "URL for macOs binary") 61 | t.Logf("found Darwin binary URL %s", b.URL) 62 | } 63 | } 64 | assert.True(t, foundLinux, "did not find a linux binary in the plugin %#v", plugin) 65 | assert.True(t, foundWindows, "did not find a windows binary in the plugin %#v", plugin) 66 | } 67 | 68 | func TestOctantJXPlugin(t *testing.T) { 69 | t.Parallel() 70 | 71 | plugin := plugins.CreateOctantJXPlugin("0.0.31") 72 | 73 | assert.Equal(t, plugins.OctantJXPluginName, plugin.Name, "plugin.Name") 74 | assert.Equal(t, plugins.OctantJXPluginName, plugin.Spec.Name, "plugin.Spec.Name") 75 | 76 | foundLinux := false 77 | foundWindows := false 78 | for _, b := range plugin.Spec.Binaries { 79 | if b.Goos == "Linux" && b.Goarch == "amd64" { 80 | foundLinux = true 81 | assert.Equal(t, "https://github.com/jenkins-x-plugins/octant-jx/releases/download/v0.0.31/octant-jx-linux-amd64.tar.gz", b.URL, "URL for linux binary") 82 | t.Logf("found linux binary URL %s", b.URL) 83 | } else if b.Goos == "Windows" && b.Goarch == "amd64" { 84 | foundWindows = true 85 | assert.Equal(t, "https://github.com/jenkins-x-plugins/octant-jx/releases/download/v0.0.31/octant-jx-windows-amd64.zip", b.URL, "URL for windows binary") 86 | t.Logf("found windows binary URL %s", b.URL) 87 | } 88 | } 89 | assert.True(t, foundLinux, "did not find a linux binary in the plugin %#v", plugin) 90 | assert.True(t, foundWindows, "did not find a windows binary in the plugin %#v", plugin) 91 | } 92 | -------------------------------------------------------------------------------- /pkg/plugins/versions.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | jenkinsv1 "github.com/jenkins-x/jx-api/v4/pkg/apis/jenkins.io/v1" 5 | "github.com/jenkins-x/jx-helpers/v3/pkg/extensions" 6 | ) 7 | 8 | const ( 9 | // AdminVersion the version of the jx admin plugin 10 | AdminVersion = "0.3.17" 11 | 12 | // ApplicationVersion the version of the jx application plugin 13 | ApplicationVersion = "0.3.7" 14 | 15 | // ChangelogVersion the version of the jx changelog plugin 16 | ChangelogVersion = "0.10.14" 17 | 18 | // GitOpsVersion the version of the jx gitops plugin 19 | GitOpsVersion = "0.26.0" 20 | 21 | // HealthVersion the version of the jx health plugin 22 | HealthVersion = "0.0.80" 23 | 24 | // OctantVersion the default version of octant to use 25 | OctantVersion = "0.23.0" 26 | 27 | // OctantJXVersion the default version of octant-jx plugin to use 28 | OctantJXVersion = "0.0.44" 29 | 30 | // PipelineVersion the version of the jx pipeline plugin 31 | PipelineVersion = "0.7.20" 32 | 33 | // PreviewVersion the version of the jx preview plugin 34 | PreviewVersion = "0.5.7" 35 | 36 | // ProjectVersion the version of the jx project plugin 37 | ProjectVersion = "0.2.74" 38 | 39 | // PromoteVersion the version of the jx promote plugin 40 | PromoteVersion = "0.6.11" 41 | 42 | // SecretVersion the version of the jx secret plugin 43 | SecretVersion = "0.4.13" 44 | 45 | // TestVersion the version of the jx test plugin 46 | TestVersion = "0.4.8" 47 | 48 | // VerifyVersion the version of the jx verify plugin 49 | VerifyVersion = "0.3.12" 50 | ) 51 | 52 | var ( 53 | // Plugins default plugins 54 | Plugins = []jenkinsv1.Plugin{ 55 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "admin", AdminVersion), 56 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "application", ApplicationVersion), 57 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "changelog", ChangelogVersion), 58 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "gitops", GitOpsVersion), 59 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "health", HealthVersion), 60 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "pipeline", PipelineVersion), 61 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "preview", PreviewVersion), 62 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "project", ProjectVersion), 63 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "promote", PromoteVersion), 64 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "secret", SecretVersion), 65 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "test", TestVersion), 66 | extensions.CreateJXPlugin(jenkinsxPluginsOrganisation, "verify", VerifyVersion), 67 | } 68 | 69 | // PluginMap a map of plugin names like `jx-gitops` to the Plugin object 70 | PluginMap = map[string]*jenkinsv1.Plugin{} 71 | ) 72 | 73 | func init() { 74 | for i := range Plugins { 75 | plugin := &Plugins[i] 76 | PluginMap[plugin.Spec.Name] = plugin 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /pkg/version/info.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package version 15 | 16 | import ( 17 | "fmt" 18 | "strings" 19 | 20 | "github.com/blang/semver" 21 | "github.com/jenkins-x/jx-logging/v3/pkg/log" 22 | ) 23 | 24 | // Build information. Populated at build-time. 25 | var ( 26 | Version string 27 | Revision string 28 | BuildDate string 29 | GoVersion string 30 | GitTreeState string 31 | ) 32 | 33 | // Map provides the iterable version information. 34 | var Map = map[string]string{ 35 | "version": Version, 36 | "revision": Revision, 37 | "buildDate": BuildDate, 38 | "goVersion": GoVersion, 39 | "gitTreeState": GitTreeState, 40 | } 41 | 42 | const ( 43 | // VersionPrefix string for setting pre-release etc 44 | VersionPrefix = "" 45 | 46 | // ExampleVersion shows an example version in the help 47 | // if no version could be found (which should never really happen!) 48 | ExampleVersion = "1.1.59" 49 | 50 | // TestVersion used in test cases for the current version if no 51 | // version can be found - such as if the version property is not properly 52 | // included in the go test flags. 53 | TestVersion = "3.2.238" 54 | 55 | // TestRevision can be used in tests if no revision is passed in the test flags 56 | TestRevision = "04b628f48" 57 | 58 | // TestTreeState can be used in tests if no tree state is passed in the test flags 59 | TestTreeState = "clean" 60 | 61 | // TestBuildDate can be used in tests if no build date is passed in the test flags 62 | TestBuildDate = "2020-05-31T14:51:38Z" 63 | 64 | // TestGoVersion can be used in tests if no version is passed in the test flags 65 | TestGoVersion = "1.13.8" 66 | ) 67 | 68 | // GetVersion gets the current version string 69 | func GetVersion() string { 70 | v := Map["version"] 71 | if v == "" { 72 | v = TestVersion 73 | } 74 | return v 75 | } 76 | 77 | // GetSemverVersion returns a semver.Version struct representing the current version 78 | func GetSemverVersion() (semver.Version, error) { 79 | text := strings.TrimPrefix(GetVersion(), VersionPrefix) 80 | v, err := semver.Make(text) 81 | if err != nil { 82 | return v, fmt.Errorf("failed to parse version %s: %w", text, err) 83 | } 84 | return v, nil 85 | } 86 | 87 | // GetRevision returns the short SHA1 hashes given a given revision 88 | func GetRevision() string { 89 | v := Map["revision"] 90 | if v == "" { 91 | v = TestRevision 92 | } 93 | return v 94 | } 95 | 96 | // GetTreeState returns the state of the working tree 97 | func GetTreeState() string { 98 | v := Map["gitTreeState"] 99 | if v == "" { 100 | v = TestTreeState 101 | } 102 | return v 103 | } 104 | 105 | // GetBuildDate returns the build date for the binary 106 | func GetBuildDate() string { 107 | v := Map["buildDate"] 108 | if v == "" { 109 | v = TestBuildDate 110 | } 111 | return v 112 | } 113 | 114 | // GetGoVersion returns the version of go used to build the binary 115 | func GetGoVersion() string { 116 | v := Map["goVersion"] 117 | if v == "" { 118 | v = TestGoVersion 119 | } 120 | return v 121 | } 122 | 123 | // StringDefault returns the current version string or returns a dummy 124 | // default value if there is an error 125 | func StringDefault(defaultValue string) string { 126 | v, err := GetSemverVersion() 127 | if err == nil { 128 | return v.String() 129 | } 130 | log.Logger().Warnf("Warning failed to load version: %s", err) 131 | return defaultValue 132 | } 133 | -------------------------------------------------------------------------------- /pkg/version/info_test.go: -------------------------------------------------------------------------------- 1 | //go:build unit 2 | 3 | package version_test 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/jenkins-x/jx/pkg/version" 9 | 10 | "github.com/blang/semver" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | var InputNonEmpty = map[string]string{ 15 | "version": "2.2.2", 16 | "revision": "abcdef", 17 | "buildDate": "20200526-19:28:09", 18 | "goVersion": "1.14.8", 19 | "gitTreeState": "dirty", 20 | } 21 | 22 | var OutputNonEmpty = InputNonEmpty 23 | 24 | var InputEmpty = map[string]string{ 25 | "version": "", 26 | "revision": "", 27 | "buildDate": "", 28 | "goVersion": "", 29 | "gitTreeState": "", 30 | } 31 | 32 | var OutputEmpty = map[string]string{ 33 | "version": version.TestVersion, 34 | "revision": version.TestRevision, 35 | "buildDate": version.TestBuildDate, 36 | "goVersion": version.TestGoVersion, 37 | "gitTreeState": version.TestTreeState, 38 | } 39 | 40 | var getterTests = []struct { 41 | description string 42 | in map[string]string 43 | out map[string]string 44 | }{ 45 | { 46 | "Case 1: build passes a value", 47 | InputNonEmpty, 48 | OutputNonEmpty, 49 | }, 50 | { 51 | "Case 2: No value passed during build", 52 | InputEmpty, 53 | OutputEmpty, 54 | }, 55 | } 56 | 57 | func TestGetters(t *testing.T) { 58 | for _, tt := range getterTests { 59 | t.Run(tt.description, func(t *testing.T) { 60 | version.Map["version"] = tt.in["version"] 61 | version.Map["revision"] = tt.in["revision"] 62 | version.Map["buildDate"] = tt.in["buildDate"] 63 | version.Map["goVersion"] = tt.in["goVersion"] 64 | version.Map["gitTreeState"] = tt.in["gitTreeState"] 65 | 66 | result := version.GetVersion() 67 | assert.Equal(t, tt.out["version"], result) 68 | 69 | result = version.GetRevision() 70 | assert.Equal(t, tt.out["revision"], result) 71 | 72 | result = version.GetBuildDate() 73 | assert.Equal(t, tt.out["buildDate"], result) 74 | 75 | result = version.GetGoVersion() 76 | assert.Equal(t, tt.out["goVersion"], result) 77 | 78 | result = version.GetTreeState() 79 | assert.Equal(t, tt.out["gitTreeState"], result) 80 | }) 81 | } 82 | } 83 | 84 | // TODO refactor to encapsulate 85 | func TestGetSemverVersisonWithStandardVersion(t *testing.T) { 86 | version.Map["version"] = "1.2.1" 87 | result, err := version.GetSemverVersion() 88 | expectedResult := semver.Version{Major: 1, Minor: 2, Patch: 1} 89 | assert.NoError(t, err, "GetSemverVersion should exit without failure") 90 | assert.Exactly(t, expectedResult, result) 91 | } 92 | 93 | // TODO refactor to encapsulate 94 | func TestGetSemverVersisonWithNonStandardVersion(t *testing.T) { 95 | version.Map["version"] = "1.3.153-dev+7a8285f4" 96 | result, err := version.GetSemverVersion() 97 | 98 | prVersions := []semver.PRVersion{{VersionStr: "dev"}} 99 | builds := []string{"7a8285f4"} 100 | expectedResult := semver.Version{Major: 1, Minor: 3, Patch: 153, Pre: prVersions, Build: builds} 101 | assert.NoError(t, err, "GetSemverVersion should exit without failure") 102 | assert.Exactly(t, expectedResult, result) 103 | } 104 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ## 3 | ## TODO - When the $TFO_RESOURCE approaches 253 characters, this script should 4 | ## truncate accordingly to make sure that any secrets/configmaps that 5 | ## get saved here don't get blocked by the K8S API due to names being 6 | ## too long. 7 | ## 8 | # Let the finalizer or manual destroy by passing in $DESTROY="true" 9 | # Terraforms will be applyed only then $APPLY="true" 10 | function run_terraform { 11 | # options: 12 | # destroy=true|false 13 | declare $@ 14 | 15 | if [ "$destroy" = "true" ];then 16 | destroy_when_true='-destroy' 17 | fi 18 | 19 | terraform -chdir=. init 20 | if [ $? -gt 0 ];then return 1;fi 21 | 22 | terraform -chdir=. plan $TFOPS_VARFILE_FLAG $destroy_when_true -out plan.out 2>&1| tee $TMP 23 | if [ ${PIPESTATUS[0]} -gt 0 ];then 24 | set +x 25 | save_plan 26 | set -x 27 | return 1 28 | else 29 | set +x 30 | save_plan 31 | set -x 32 | fi 33 | set +x 34 | 35 | n=0 36 | while true;do 37 | (( n++ )) 38 | get_action # sets $action variable 39 | if [ "$action" = "apply" ];then 40 | break 41 | elif [ "$action" = "abort" ];then 42 | exit 0 43 | fi 44 | if [ $n -gt 60 ];then 45 | echo "Waiting for user action. Check the cm/${TFO_RESOURCE}-action" 46 | n=0 47 | fi 48 | sleep 1 49 | done 50 | 51 | set -x 52 | terraform apply plan.out 53 | if [ $? -gt 0 ];then return 1;fi 54 | 55 | set +x 56 | # Replan to see what tf thinks should happen next. 57 | terraform -chdir=. plan $TFOPS_VARFILE_FLAG $destroy_when_true 2>&1| tee $TMP 58 | } 59 | 60 | function save_plan { 61 | # Clean the output from coloration 62 | cat $TMP | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > $CLEAN 63 | 64 | # Save the intermediate plan 65 | cp $CLEAN tfplan 66 | kubectl delete cm ${TFO_RESOURCE}-plan > /dev/null 2>&1 || true 67 | kubectl create cm ${TFO_RESOURCE}-plan --from-file tfplan 68 | } 69 | 70 | function save_output { 71 | # Save terraform output as a configmap 72 | # TODO sensative items should be stored as a secret 73 | cat << EOF > "$TFO_RESOURCE-output.yaml" 74 | --- 75 | apiVersion: v1 76 | kind: ConfigMap 77 | metadata: 78 | name: $TFO_RESOURCE-output 79 | namespace: $NAMESPACE 80 | data: 81 | $(terraform output -json| jq -r '.|keys[] as $k| " \($k): |-\n \(.[$k].value)"') 82 | EOF 83 | 84 | kubectl apply -f "$TFO_RESOURCE-output.yaml" 85 | 86 | } 87 | 88 | function get_action { 89 | action=`kubectl get cm ${TFO_RESOURCE}-action -ojsonpath='{.data.action}'` 90 | export action 91 | } 92 | 93 | if [ "${AWS_WEB_IDENTITY_TOKEN_FILE}" != "" ] ;then 94 | apk add --update-cache \ 95 | python \ 96 | python-dev \ 97 | py-pip \ 98 | build-base \ 99 | && pip install boto3 100 | cat << EOF_HERE > .get_assumed_credentials.py 101 | #!/usr/bin/python 102 | import os 103 | import boto3 104 | session = boto3.Session() 105 | credentials = session.get_credentials().get_frozen_credentials() 106 | print('export AWS_ACCESS_KEY_ID="{0}"\nexport AWS_SECRET_ACCESS_KEY="{1}"\nexport AWS_SECURITY_TOKEN="{2}"\nexport AWS_SESSION_TOKEN="{2}"'.format(credentials.access_key, credentials.secret_key, credentials.token)) 107 | EOF_HERE 108 | 109 | chmod +x .get_assumed_credentials.py 110 | eval `./.get_assumed_credentials.py` 111 | rm .get_assumed_credentials.py 112 | 113 | unset AWS_ROLE_ARN 114 | unset AWS_WEB_IDENTITY_TOKEN_FILE 115 | fi 116 | 117 | if [ "$GIT_PASSWORD" != "" ];then 118 | echo setting git password 119 | ASKPASS=`mktemp` 120 | cat << EOF > $ASKPASS 121 | #!/bin/sh 122 | exec echo "$GIT_PASSWORD" 123 | EOF 124 | chmod +x $ASKPASS 125 | export GIT_ASKPASS=$ASKPASS 126 | fi 127 | 128 | # Troubleshooting lines 129 | # env 130 | # ls -lah ~/.ssh 131 | 132 | # 133 | # Assume the default is to use git to pull tf files and 134 | # Assume the tfvars lives at "tfvars" in root of untar-ed dir 135 | export TMP=`mktemp` 136 | export CLEAN=`mktemp` 137 | REPO_COUNT=`find /tfops -type f -not -path /tfops -name repo.tar|wc -l` 138 | 139 | 140 | if [ "$STACK_REPO" != "" ];then 141 | set -x 142 | MAIN_MODULE_TMP=`mktemp -d` 143 | git clone $STACK_REPO $MAIN_MODULE_TMP/stack || exit $? 144 | cd $MAIN_MODULE_TMP/stack 145 | git checkout $STACK_REPO_HASH 146 | if [ "$STACK_REPO_SUBDIR" != "" ];then 147 | pwd 148 | ls -lah 149 | cp -r $STACK_REPO_SUBDIR /$TFOPS_MAIN_MODULE 150 | else 151 | mv $MAIN_MODULE_TMP/stack /$TFOPS_MAIN_MODULE 152 | fi 153 | elif [ "$REPO_COUNT" -gt 0 ];then 154 | find /tfops -type f -not -path /tfops -name repo.tar -exec tar -xf {} -C / \; 155 | else 156 | echo "No terraform stack to run" 157 | exit 1 158 | fi 159 | 160 | if [ "$TFOPS_CONFIGMAP_PATH" != "" ];then 161 | cp $TFOPS_CONFIGMAP_PATH/* /$TFOPS_MAIN_MODULE 162 | fi 163 | 164 | cd /$TFOPS_MAIN_MODULE 165 | 166 | # Load a custom backend 167 | if stat backend_override.tf >/dev/null 2>/dev/null; then 168 | echo "Using custom backend" 169 | else 170 | echo "Loading hashicorp backend" 171 | set -x 172 | envsubst < /backend.tf > /backend_override.tf 173 | mv /backend_override.tf . 174 | fi 175 | 176 | # Run the prerun script 177 | if stat prerun.sh >/dev/null 2>/dev/null; then 178 | # prerun.sh needs exec privileges 179 | chmod +x prerun.sh 180 | ./prerun.sh 181 | fi 182 | 183 | 184 | WAIT_TIME=${WAIT_TIME:-60} 185 | ATTEMPTS=${ATTEMPTS:-10} 186 | i=0 187 | until run_terraform destroy=$DESTROY || (( i++ >= $ATTEMPTS ));do 188 | echo "($i/$ATTEMPTS) Terraform did not exit 0, waiting $WAIT_TIME" 189 | sleep $WAIT_TIME 190 | done 191 | 192 | # Clean the output from coloration 193 | cat $TMP | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > $CLEAN 194 | 195 | # Status Helpers: 196 | awk '/^Error:/{y=1}y' $CLEAN > ERROR 197 | 198 | read -d '' -r -a arr <<< `grep "^Plan:" $CLEAN|tr -dc '0-9,'|tr ',' ' '` #` 199 | echo -n ${arr[0]} > PLAN 200 | echo -n ${arr[1]} > CHANGE 201 | echo -n ${arr[2]} > DESTROY 202 | 203 | kubectl delete cm ${TFO_RESOURCE}-status > /dev/null 2>&1 || true 204 | kubectl create cm ${TFO_RESOURCE}-status \ 205 | --from-file ERROR \ 206 | --from-file PLAN \ 207 | --from-file CHANGE \ 208 | --from-file DESTROY 209 | 210 | save_output 211 | save_plan 212 | 213 | # Run the postrun script 214 | if stat postrun.sh >/dev/null 2>/dev/null; then 215 | # postrun.sh needs exec privileges 216 | chmod +x postrun.sh 217 | ./postrun.sh 218 | fi --------------------------------------------------------------------------------