├── .circleci ├── config.yml └── test-deploy.yml ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .yamllint ├── LICENSE ├── README.md └── src ├── @orb.yml ├── commands ├── install.yml └── setup.yml ├── examples └── setup.yml ├── executors ├── default.yml ├── google.yml └── machine.yml └── scripts ├── install.sh └── setup.sh /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | setup: true 3 | orbs: 4 | orb-tools: circleci/orb-tools@11.4 5 | shellcheck: circleci/shellcheck@3.1 6 | 7 | filters: &filters 8 | tags: 9 | only: /.*/ 10 | 11 | workflows: 12 | lint-pack: 13 | jobs: 14 | - orb-tools/lint: 15 | filters: *filters 16 | - orb-tools/pack: 17 | filters: *filters 18 | - orb-tools/review: 19 | filters: *filters 20 | - shellcheck/check: 21 | exclude: 'SC2153' 22 | filters: *filters 23 | - orb-tools/publish: 24 | orb-name: circleci/gcp-cli 25 | vcs-type: << pipeline.project.type >> 26 | requires: 27 | [orb-tools/lint, orb-tools/review, orb-tools/pack, shellcheck/check] 28 | context: orb-publisher 29 | filters: *filters 30 | - orb-tools/continue: 31 | pipeline-number: << pipeline.number >> 32 | vcs-type: << pipeline.project.type >> 33 | requires: [orb-tools/publish] 34 | filters: *filters 35 | -------------------------------------------------------------------------------- /.circleci/test-deploy.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | gcp-cli: circleci/gcp-cli@dev:<> 5 | orb-tools: circleci/orb-tools@11.4 6 | 7 | filters: &filters 8 | tags: 9 | only: /.*/ 10 | 11 | post-steps: 12 | - run: &check-cli-version-skip-install 13 | name: "Check if the CLI was installed and the version is correct" 14 | command: | 15 | if [ << parameters.version >> = "latest" ] || [ << parameters.skip_installation >> != 1 ]; then 16 | gcloud version || exit 1 17 | else 18 | gcloud --version 19 | gcloud --version | grep -q "Google Cloud SDK << parameters.version >>" || exit 1 20 | fi 21 | 22 | - run: &check-cli-version 23 | name: "Check if the CLI was installed and the version is correct" 24 | command: | 25 | if [ << parameters.version >> = "latest" ]; then 26 | gcloud version || exit 1 27 | else 28 | gcloud --version 29 | gcloud --version | grep -q "Google Cloud SDK << parameters.version >>" || exit 1 30 | fi 31 | 32 | - run: &check-cli-version-alpine 33 | name: "Check if the CLI was installed and the version is correct" 34 | command: | 35 | . $BASH_ENV 36 | if [ << parameters.version >> = "latest" ]; then 37 | gcloud version || exit 1 38 | else 39 | gcloud --version 40 | gcloud --version | grep -q "Google Cloud SDK << parameters.version >>" || exit 1 41 | fi 42 | 43 | - run: &check-cli-version-bash 44 | name: "Check if the CLI was installed and the version is correct" 45 | shell: bash.exe 46 | command: | 47 | if [ << parameters.version >> = "latest" ]; then 48 | gcloud version || exit 1 49 | else 50 | gcloud --version 51 | gcloud --version | grep -q "Google Cloud SDK << parameters.version >>" || exit 1 52 | fi 53 | 54 | - run: &check-cli-version-cmd 55 | name: "Check if the CLI was installed and the version is correct" 56 | shell: cmd.exe 57 | command: | 58 | bash gcloud version 59 | 60 | - run: &check-cli-version-powershell 61 | name: "Check if the CLI was installed and the version is correct" 62 | shell: powershell.exe 63 | command: | 64 | bash gcloud version 65 | 66 | - run: &check-gcloud-auth-gcr-bash 67 | name: "Check if the CLI can generate docker configuration json file to pull images from gcr" 68 | shell: bash.exe 69 | command: | 70 | gcloud auth configure-docker --quiet 71 | test -f /c/Users/circleci/.docker/config.json 72 | rm /c/Users/circleci/.docker/config.json 73 | 74 | - run: &check-gcloud-auth-gcr-powershell 75 | name: "Check if the CLI can generate docker configuration json file to pull images from gcr" 76 | shell: powershell.exe 77 | command: | 78 | bash gcloud auth configure-docker --quiet 79 | Test-Path C:\Users\circleci\.docker\config.json 80 | rm C:\Users\circleci\.docker\config.json 81 | 82 | - run: &push-and-pull-docker-image 83 | name: "Builds a Docker image and publishes it to gcr" 84 | command: | 85 | cat \< Dockerfile 86 | FROM alpine:edge 87 | ARG JOB_NUMBER 88 | RUn echo $JOB_NUMBER > job_number 89 | RUN apk update 90 | RUN apk add curl 91 | CMD ["curl", "--version"] 92 | EOF 93 | R=$(printf "%s%s" $(date) $(seq 10 | shuf | tr -d '\n') | sha256sum | cut -f1 -d' ') 94 | docker build . --build-arg JOB_NUMBER=$CIRCLE_BUILD_NUM -t gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" 95 | gcloud auth configure-docker --quiet 96 | docker push gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" 97 | docker image prune -af 98 | docker pull gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" 99 | docker image prune -af 100 | gcloud container images delete gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" --quiet 101 | 102 | - run: &push-and-pull-docker-image-win 103 | name: "Builds a Docker image and publishes it to gcr" 104 | command: | 105 | R=$(printf "%s%s-win" $(date) $(seq 10 | shuf | tr -d '\n') | sha256sum | cut -f1 -d' ') 106 | gcloud auth configure-docker --quiet 107 | docker pull mcr.microsoft.com/azureiotedge/sqlite:1.0 108 | docker tag mcr.microsoft.com/azureiotedge/sqlite:1.0 gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" 109 | docker push gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" 110 | docker image prune -af 111 | gcloud container images delete gcr.io/cpe-gcp-orb-testing/gcp-cli-orb-test-image:"$R" --quiet 112 | 113 | jobs: 114 | install: 115 | parameters: 116 | executor: 117 | type: executor 118 | version: 119 | type: string 120 | executor: <> 121 | steps: 122 | - gcp-cli/install: 123 | version: <> 124 | - run: *check-cli-version 125 | 126 | install-win: 127 | parameters: 128 | executor: 129 | type: executor 130 | version: 131 | type: string 132 | executor: <> 133 | steps: 134 | - gcp-cli/install: 135 | version: <> 136 | - run: *check-cli-version-bash 137 | - run: *check-cli-version-cmd 138 | - run: *check-cli-version-powershell 139 | - run: *check-gcloud-auth-gcr-bash 140 | - run: *check-gcloud-auth-gcr-powershell 141 | 142 | install-alpine: 143 | parameters: 144 | version: 145 | type: string 146 | executor: "alpine" 147 | steps: 148 | - run: 149 | name: Install curl 150 | command: apk add curl 151 | - gcp-cli/install: 152 | version: << parameters.version >> 153 | - run: *check-cli-version-alpine 154 | 155 | install-macos: 156 | parameters: 157 | version: 158 | type: string 159 | executor: 160 | type: executor 161 | executor: <> 162 | steps: 163 | - gcp-cli/install: 164 | version: <> 165 | - run: *check-cli-version 166 | 167 | install-google: 168 | parameters: 169 | version: 170 | type: string 171 | executor: 172 | type: executor 173 | executor: << parameters.executor >> 174 | steps: 175 | - run: 176 | name: Install sudo 177 | command: apt-get install sudo -y 178 | - gcp-cli/install: 179 | version: << parameters.version >> 180 | - run: *check-cli-version 181 | 182 | install-google-skip-install: 183 | parameters: 184 | version: 185 | type: string 186 | executor: 187 | type: executor 188 | skip_installation: 189 | type: boolean 190 | default: true 191 | executor: << parameters.executor >> 192 | steps: 193 | - run: 194 | name: Install sudo 195 | command: apt-get install sudo -y 196 | - gcp-cli/install: 197 | version: << parameters.version >> 198 | skip_installation: << parameters.skip_installation >> 199 | - run: *check-cli-version-skip-install 200 | 201 | install-components: 202 | parameters: 203 | executor: 204 | type: executor 205 | version: 206 | type: string 207 | executor: <> 208 | steps: 209 | - checkout 210 | - gcp-cli/setup: 211 | components: kubectl package-go-module 212 | version: <> 213 | - run: gcloud components list | grep package-go-module || exit 1 214 | 215 | auth-oidc: 216 | parameters: 217 | executor: 218 | type: executor 219 | version: 220 | type: string 221 | executor: <> 222 | steps: 223 | - checkout 224 | - gcp-cli/setup: 225 | use_oidc: true 226 | version: <> 227 | - run: *check-cli-version 228 | 229 | auth-oidc-docker: 230 | parameters: 231 | executor: 232 | type: executor 233 | version: 234 | type: string 235 | executor: <> 236 | steps: 237 | - checkout 238 | - gcp-cli/setup: 239 | use_oidc: true 240 | version: <> 241 | - run: *check-cli-version 242 | - run: *push-and-pull-docker-image 243 | 244 | auth-oidc-docker-win: 245 | parameters: 246 | executor: 247 | type: executor 248 | version: 249 | type: string 250 | executor: <> 251 | steps: 252 | - checkout 253 | - gcp-cli/setup: 254 | use_oidc: true 255 | version: <> 256 | - run: *check-cli-version 257 | - run: *push-and-pull-docker-image-win 258 | 259 | executors: 260 | alpine: 261 | docker: 262 | - image: python:3.8-alpine 263 | windows-2019: 264 | machine: 265 | resource_class: windows.medium 266 | image: windows-server-2019-vs2019:current 267 | windows-2022: 268 | machine: 269 | resource_class: windows.medium 270 | image: windows-server-2022-gui:current 271 | ubuntu-2204-edge: 272 | machine: 273 | image: ubuntu-2204:edge 274 | macos-xcode-16-2-0: 275 | macos: 276 | xcode: 16.2.0 277 | macos-xcode-16-1-0: 278 | macos: 279 | xcode: 16.1.0 280 | macos-xcode-16-0-0: 281 | macos: 282 | xcode: 16.0.0 283 | macos-xcode-15-4-0: 284 | macos: 285 | xcode: 15.4.0 286 | macos-xcode-15-3-0: 287 | macos: 288 | xcode: 15.3.0 289 | macos-xcode-14-3-1: 290 | macos: 291 | xcode: 14.3.1 292 | google-gcp-cli-451-0-0: 293 | docker: 294 | - image: google/cloud-sdk:451.0.0 295 | 296 | workflows: 297 | test-deploy: 298 | jobs: 299 | - install: 300 | matrix: 301 | alias: test-executor-versions 302 | parameters: 303 | executor: [gcp-cli/default, gcp-cli/machine, ubuntu-2204-edge] 304 | version: [latest, 460.0.0] 305 | context: orb-publisher 306 | filters: *filters 307 | 308 | - install-win: 309 | matrix: 310 | alias: test-win-executor-versions 311 | parameters: 312 | executor: [windows-2019, windows-2022] 313 | version: [latest, 460.0.0] 314 | context: orb-publisher 315 | filters: *filters 316 | 317 | - install-alpine: 318 | matrix: 319 | alias: test-alpine-versions 320 | parameters: 321 | version: [latest, 460.0.0] 322 | context: orb-publisher 323 | filters: *filters 324 | 325 | - install-macos: 326 | matrix: 327 | alias: test-macos-versions-500 328 | parameters: 329 | executor: [macos-xcode-16-2-0, macos-xcode-16-1-0, macos-xcode-16-0-0] 330 | version: [500.0.0] 331 | context: orb-publisher 332 | filters: *filters 333 | 334 | - install-macos: 335 | matrix: 336 | alias: test-macos-versions-400 337 | parameters: 338 | executor: [macos-xcode-15-4-0, macos-xcode-15-3-0, macos-xcode-14-3-1] 339 | version: [460.0.0] 340 | context: orb-publisher 341 | filters: *filters 342 | 343 | - install-google: 344 | matrix: 345 | alias: test-google-versions 346 | parameters: 347 | version: [latest, 460.0.0, 451.0.1] 348 | executor: [gcp-cli/google, google-gcp-cli-451-0-0] 349 | context: orb-publisher 350 | filters: *filters 351 | 352 | - install-google-skip-install: 353 | matrix: 354 | alias: test-google-versions-skip-install 355 | parameters: 356 | version: [latest, 460.0.0, 451.0.1] 357 | executor: [gcp-cli/google, google-gcp-cli-451-0-0] 358 | context: orb-publisher 359 | filters: *filters 360 | 361 | - auth-oidc: 362 | matrix: 363 | alias: test-auth-oidc 364 | parameters: 365 | executor: [gcp-cli/machine, ubuntu-2204-edge, windows-2019, windows-2022] 366 | version: [latest, 460.0.0] 367 | context: 368 | - cpe-gcp 369 | 370 | - auth-oidc-docker: 371 | matrix: 372 | alias: test-auth-oidc-docker 373 | parameters: 374 | executor: [gcp-cli/machine, ubuntu-2204-edge] 375 | version: [latest, 460.0.0] 376 | context: 377 | - cpe-gcp 378 | 379 | #- auth-oidc-docker-win: 380 | # matrix: 381 | # alias: test-auth-oidc-docker-win 382 | # parameters: 383 | # executor: [windows-2019, windows-2022] 384 | # version: [latest, 460.0.0] 385 | # context: 386 | # - cpe-gcp 387 | 388 | - install-components: 389 | matrix: 390 | alias: test-install-components 391 | parameters: 392 | executor: [gcp-cli/default, gcp-cli/machine, ubuntu-2204-edge, windows-2019, windows-2022] 393 | version: [latest, 460.0.0] 394 | context: 395 | - cpe-gcp 396 | 397 | - orb-tools/pack: 398 | filters: *filters 399 | 400 | - orb-tools/publish: 401 | orb-name: circleci/gcp-cli 402 | vcs-type: << pipeline.project.type >> 403 | pub-type: production 404 | requires: 405 | - test-executor-versions 406 | - test-win-executor-versions 407 | - test-google-versions 408 | - test-google-versions-skip-install 409 | - test-alpine-versions 410 | - test-macos-versions-400 411 | - test-macos-versions-500 412 | - test-install-components 413 | - test-auth-oidc 414 | - test-auth-oidc-docker 415 | - orb-tools/pack 416 | context: orb-publisher 417 | filters: 418 | branches: 419 | ignore: /.*/ 420 | tags: 421 | only: /^v[0-9]+\.[0-9]+\.[0-9]+$/ 422 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Ping these folks when changes are made to this repository 2 | * @CircleCI-Public/orb-publishers 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Orb version 2 | 3 | 10 | 11 | ### What happened 12 | 13 | 17 | 18 | ### Expected behavior 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Checklist 2 | 3 | 8 | 9 | - [ ] All new jobs, commands, executors, parameters have descriptions 10 | - [ ] Examples have been added for any significant new features 11 | - [ ] README has been updated, if necessary 12 | 13 | ### Motivation, issues 14 | 15 | 20 | 21 | ### Description 22 | 23 | 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | orb.yml -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | extends: relaxed 2 | 3 | rules: 4 | line-length: 5 | max: 200 6 | allow-non-breakable-inline-mappings: true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 CircleCI Public 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GCP CLI Orb [![CircleCI Build Status](https://circleci.com/gh/CircleCI-Public/gcp-cli-orb.svg?style=shield "CircleCI Build Status")](https://circleci.com/gh/CircleCI-Public/gcp-cli-orb) [![CircleCI Orb Version](https://badges.circleci.com/orbs/circleci/gcp-cli.svg)](https://circleci.com/orbs/registry/orb/circleci/gcp-cli) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/CircleCI-Public/gcp-cli-orb/master/LICENSE) [![CircleCI Community](https://img.shields.io/badge/community-CircleCI%20Discuss-343434.svg)](https://discuss.circleci.com/c/ecosystem/orbs) 2 | 3 | Easily install and configure the Google Cloud CLI in your CircleCI jobs. 4 | 5 | ## Usage 6 | 7 | _For full usage guidelines, see the [orb registry listing](http://circleci.com/orbs/registry/orb/circleci/gcp-cli)._ 8 | 9 | ## Contributing 10 | 11 | We welcome [issues](https://github.com/CircleCI-Public/gcp-cli-orb/issues) to and [pull requests](https://github.com/CircleCI-Public/gcp-cli-orb/pulls) against this repository! 12 | 13 | For further questions/comments about this or other orbs, visit [CircleCI's orbs discussion forum](https://discuss.circleci.com/c/orbs). 14 | -------------------------------------------------------------------------------- /src/@orb.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | description: | 4 | Easily install and configure the Google Cloud CLI (gcloud CLI). 5 | Supports the Docker and Machine executors. 6 | 7 | display: 8 | home_url: https://cloud.google.com/sdk 9 | source_url: https://github.com/CircleCI-Public/gcp-cli-orb 10 | -------------------------------------------------------------------------------- /src/commands/install.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | Install the gcloud CLI. When installing within the Docker executor, the 3 | install will only occur if the CLI isn't already installed. If installing in 4 | a Linux machine image, it will remove the pre-installed version and instead 5 | install the version specified by this orb. 6 | 7 | parameters: 8 | version: 9 | type: string 10 | default: "latest" 11 | description: > 12 | The version of the gcloud CLI to install. 13 | If left to "latest", the latest version will be installed. 14 | Otherwise, provide the full version number as it appears in the URL on this page: https://cloud.google.com/sdk/docs/downloads-versioned-archives" 15 | components: 16 | type: string 17 | default: "" 18 | description: > 19 | The list of gcloud components to install. Space separated. 20 | See https://cloud.google.com/sdk/docs/components for additional info. 21 | skip_installation: 22 | type: boolean 23 | default: false 24 | description: > 25 | Useful flag to use when the executor already contains a valid gcloud installation. 26 | 27 | steps: 28 | - run: 29 | name: Install latest gcloud CLI version, if not available 30 | environment: 31 | ORB_VAL_VERSION: <> 32 | ORB_VAL_COMPONENTS: <> 33 | ORB_VAL_SKIP_INSTALLATION: <> 34 | command: << include(scripts/install.sh) >> 35 | -------------------------------------------------------------------------------- /src/commands/setup.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | Install and initialize the gcloud CLI. When installing within the Docker executor, the 3 | install will only occur if the CLI isn't already installed. If installing in 4 | a Linux machine image, it will remove the pre_installed version and instead 5 | install the version specified by this orb. 6 | 7 | parameters: 8 | version: 9 | type: string 10 | default: "latest" 11 | description: > 12 | The version of the gcloud CLI to install. 13 | If left to "latest", the latest version will be installed. 14 | Otherwise, provide the full version number as it appears in the URL on this page: https://cloud.google.com/sdk/docs/downloads-versioned-archives 15 | 16 | skip_install: 17 | type: boolean 18 | default: false 19 | description: Set to true, if want to install step 20 | 21 | components: 22 | type: string 23 | default: "" 24 | description: > 25 | The list of gcloud components to install. Space separated. 26 | See https://cloud.google.com/sdk/docs/components for additional info. 27 | 28 | gcloud_service_key: 29 | type: env_var_name 30 | default: GCLOUD_SERVICE_KEY 31 | description: | 32 | Name of environment variable storing the full service key JSON file 33 | for the Google project. 34 | 35 | google_project_id: 36 | type: env_var_name 37 | default: GOOGLE_PROJECT_ID 38 | description: | 39 | Name of environment variable storing the Google project ID to set as 40 | default for the gcloud CLI. 41 | 42 | google_compute_zone: 43 | type: env_var_name 44 | default: GOOGLE_COMPUTE_ZONE 45 | description: | 46 | Name of environment variable storing the Google compute zone to set as 47 | default for the gcloud CLI. 48 | 49 | google_compute_region: 50 | type: env_var_name 51 | default: GOOGLE_COMPUTE_REGION 52 | description: | 53 | Name of environment variable storing the Google compute region to set as 54 | default for the gcloud CLI. 55 | 56 | # OIDC parameters 57 | 58 | use_oidc: 59 | type: boolean 60 | default: false 61 | description: Set to true to enable OIDC 62 | 63 | google_project_number: 64 | type: env_var_name 65 | default: GOOGLE_PROJECT_NUMBER 66 | description: | 67 | Name of environment variable storing the Google project number 68 | used to configure OIDC. 69 | 70 | workload_identity_pool_id: 71 | type: env_var_name 72 | default: OIDC_WIP_ID 73 | description: | 74 | Environment variable containing OIDC configured workload identity pool is stored. 75 | 76 | workload_identity_pool_provider_id: 77 | type: env_var_name 78 | default: OIDC_WIP_PROVIDER_ID 79 | description: | 80 | Environment variable containing OIDC configured workload identity pool provider ID is stored. 81 | 82 | service_account_email: 83 | type: env_var_name 84 | default: OIDC_SERVICE_ACCOUNT_EMAIL 85 | description: Environment variable containing OIDC service account email. 86 | 87 | gcp_cred_config_file_path: 88 | type: string 89 | default: ~/gcp_cred_config.json 90 | description: Output location of OIDC credentials. 91 | 92 | steps: 93 | - when: 94 | condition: 95 | not: << parameters.skip_install >> 96 | steps: 97 | - install: 98 | version: << parameters.version >> 99 | components: << parameters.components >> 100 | - run: 101 | name: Initialize gcloud CLI to connect to Google Cloud 102 | environment: 103 | ORB_ENV_SERVICE_KEY: <> 104 | ORB_ENV_PROJECT_ID: <> 105 | ORB_ENV_COMPUTE_ZONE: <> 106 | ORB_ENV_COMPUTE_REGION: <> 107 | # OIDC 108 | ORB_VAL_USE_OIDC: <> 109 | ORB_ENV_PROJECT_NUMBER: <> 110 | ORB_EVAL_CRED_FILE: <> 111 | ORB_ENV_POOL_ID: <> 112 | ORB_ENV_POOL_PROVIDER_ID: <> 113 | ORB_ENV_SERVICE_EMAIL: <> 114 | command: << include(scripts/setup.sh) >> 115 | -------------------------------------------------------------------------------- /src/examples/setup.yml: -------------------------------------------------------------------------------- 1 | description: Install and initalize the gcloud CLI. 2 | 3 | usage: 4 | version: 2.1 5 | 6 | orbs: 7 | gcp-cli: circleci/gcp-cli@3.2.2 8 | 9 | jobs: 10 | use-gcp: 11 | executor: gcp-cli/default 12 | steps: 13 | - gcp-cli/setup: 14 | version: 404.0.0 15 | 16 | workflows: 17 | install_and_configure_cli: 18 | jobs: 19 | - use-gcp: # optionally pass in the GCP CLI version 20 | context: myContext # store your gCloud service key via Contexts, or project-level environment variables 21 | -------------------------------------------------------------------------------- /src/executors/default.yml: -------------------------------------------------------------------------------- 1 | description: The default executor is the CircleCI Python Convenience Image. 2 | 3 | parameters: 4 | version: 5 | type: string 6 | default: "3.8" 7 | description: | 8 | Python version to use. Take into account the versions of Python available 9 | from CircleCI (https://hub.docker.com/r/cimg/python/tags) as well as what 10 | is supported by gcloud CLI itself (https://cloud.google.com/sdk/docs/install). 11 | 12 | docker: 13 | - image: cimg/python:<> 14 | -------------------------------------------------------------------------------- /src/executors/google.yml: -------------------------------------------------------------------------------- 1 | description: The official Google Docker image with gcloud SDK and CLI pre-installed. 2 | 3 | parameters: 4 | sdk-version: 5 | type: string 6 | default: "latest" 7 | description: > 8 | What version of the Google Cloud SDK Docker image? For full 9 | options, see https://hub.docker.com/r/google/cloud-sdk/tags 10 | 11 | docker: 12 | - image: google/cloud-sdk:<> 13 | -------------------------------------------------------------------------------- /src/executors/machine.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | CircleCI's machine executor: 3 | https://circleci.com/docs/2.0/executor-types/#using-machine 4 | 5 | parameters: 6 | image: 7 | type: string 8 | default: ubuntu-2204:current 9 | description: | 10 | Which machine executor image to use. For details, see 11 | https://circleci.com/docs/2.0/configuration-reference/#machine 12 | 13 | machine: 14 | image: <> 15 | -------------------------------------------------------------------------------- /src/scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # shellcheck disable=SC3043 # while "local" isn't POSIX, it's supported in many shells. See: https://www.shellcheck.net/wiki/SC3043 3 | 4 | fetch_latest_version() { 5 | local release_notes 6 | local release_notes_exit_code 7 | 8 | release_notes="$(curl --location --silent --fail --retry 3 https://cloud.google.com/sdk/docs/release-notes)" 9 | release_notes_exit_code="$?" 10 | 11 | [ "$release_notes_exit_code" -gt 0 ] && { printf '%s\n' "Failed to get release notes"; return "$release_notes_exit_code"; } 12 | 13 | local releases 14 | releases="$(printf '%s\n' "$release_notes" | grep -E '

[0-9]+.[0-9]+.[0-9]+.*

' | sed 's/\([0-9]*.[0-9]*.[0-9]*\).*<\/h2>/\1/')" 15 | 16 | local latest_version 17 | latest_version="$(printf '%s\n' "$releases" | head -n 1)" 18 | 19 | [ -z "$latest_version" ] && { printf '%s\n' "Couldn't find out what is the latest version available."; return 1; } 20 | version="$latest_version" 21 | } 22 | 23 | # $1: version 24 | install() { 25 | local arg_version="$1" 26 | [ -z "$arg_version" ] && { printf '%s\n' "No version provided."; return 1; } 27 | 28 | local install_dir 29 | install_dir="$(mktemp -d)" 30 | 31 | # after version 370, gcloud is called "cli" rather than "sdk" 32 | major_version="$(echo "$1" | awk -F. '{print $1}')" 33 | if [ "$major_version" -gt 370 ]; then url_path_fixture="cli" 34 | else url_path_fixture="sdk"; fi 35 | 36 | download_with_retry "$url_path_fixture" "$arg_version" "$install_dir" || exit 1 37 | printf '%s\n' ". $install_dir/google-cloud-sdk/path.bash.inc" >> ~/.bashrc 38 | printf '%s\n' ". $install_dir/google-cloud-sdk/path.fish.inc" >> ~/.fishrc 39 | printf '%s\n' ". $install_dir/google-cloud-sdk/path.zsh.inc" >> ~/.zshrc 40 | printf '%s\n' "export PATH=$PATH:$install_dir/google-cloud-sdk/bin" >> ~/.profile 41 | printf '%s\n' ". $install_dir/google-cloud-sdk/path.bash.inc" >> "$BASH_ENV" 42 | 43 | # If the environment is Alpine, remind the user to source $BASH_ENV in every step. 44 | if [ -f /etc/os-release ] && grep -q "Alpine" "/etc/os-release"; then 45 | printf '%s\n' "Alpine detected. Please make sure to source \$BASH_ENV in every step." 46 | printf '%s\n' "Otherwise gcloud won't be available." 47 | printf '%s\n' "You can do this by adding the following line in the beginning of your command:" 48 | printf '%s\n' "\". \$BASH_ENV\"" 49 | 50 | # Alpine also needs a workaround since Google's "path.bash.inc" doesn't work. 51 | printf '%s\n' "export PATH=$install_dir/google-cloud-sdk/bin:$PATH" >> "$BASH_ENV" 52 | fi 53 | 54 | # shellcheck disable=SC1090 55 | . "$BASH_ENV" 56 | if ! command -v gcloud > /dev/null 2>&1; then return 1; fi 57 | printf '%s\n' "Google Cloud SDK version: $(gcloud --version)" 58 | } 59 | 60 | uninstall() { 61 | if [ "${platform}" != "windows" ] && ! command -v sudo > /dev/null 2>&1; then 62 | printf '%s\n' "sudo is required to uninstall the Google Cloud SDK." 63 | printf '%s\n' "Please install it and try again." 64 | return 1 65 | fi 66 | 67 | # Set sudo to work whether logged in as root user or non-root user. 68 | if [ "$(id -u)" -eq 0 ] || [ "${platform}" = "windows" ]; then sudo=""; else sudo="sudo"; fi 69 | 70 | local installation_directory 71 | installation_directory="$(gcloud info --format='value(installation.sdk_root)')" 72 | 73 | local config_directory 74 | config_directory="$(gcloud info --format='value(config.paths.global_config_dir)')" 75 | 76 | # shellcheck disable=SC2086 # $sudo is not a variable, it's a command. 77 | $sudo rm -rf "$installation_directory" || return 1 78 | 79 | # shellcheck disable=SC2086 # $sudo is not a variable, it's a command. 80 | $sudo rm -rf "$config_directory" || return 1 81 | } 82 | 83 | download_and_extract() { 84 | local url_path_fixture="$1" 85 | local version="$2" 86 | local install_directory="$3" 87 | 88 | if [ "${platform}" = "windows" ]; then 89 | output_file="$install_directory/google-cloud-sdk.zip" 90 | curl --location --silent --fail --retry 3 --output "$output_file" "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-$url_path_fixture-$version-windows-x86_64.zip" 91 | unzip "$output_file" -d "$install_directory" 92 | else 93 | output_file="$install_directory/google-cloud-sdk.tar.gz" 94 | curl --location --silent --fail --retry 3 --output "$output_file" "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-$url_path_fixture-$version-$platform-x86_64.tar.gz" 95 | tar -xzf "$output_file" -C "$install_directory" 96 | fi 97 | 98 | return $? 99 | } 100 | 101 | download_with_retry() { 102 | local url_path_fixture="$1" 103 | local version="$2" 104 | local install_directory="$3" 105 | local download_tries=0 106 | local max_download_tries=3 107 | 108 | while [ $download_tries -lt $max_download_tries ]; do 109 | if download_and_extract "$url_path_fixture" "$version" "$install_directory"; then 110 | break 111 | else 112 | download_tries=$((download_tries + 1)) 113 | printf "Download failed, retrying... (attempt: %d)\n" "$download_tries" 114 | rm -rf "${install_directory:?}"/* 115 | fi 116 | done 117 | 118 | if [ $download_tries -ge $max_download_tries ]; then 119 | printf "Failed to download and extract the tar file after %d attempts.\n" "$max_download_tries" 120 | return 1 121 | fi 122 | } 123 | 124 | # Check if curl is installed 125 | if ! command -v curl > /dev/null 2>&1; then 126 | printf '%s\n' "curl is required to install the Google Cloud SDK." 127 | printf '%s\n' "Please install it and try again." 128 | exit 1 129 | fi 130 | 131 | unameOut="$(uname -s)" 132 | case "${unameOut}" in 133 | Linux*) platform=linux;; 134 | Darwin*) platform=darwin;; 135 | CYGWIN*) platform=windows;; 136 | MINGW*) platform=windows;; 137 | MSYS_NT*) platform=windows;; 138 | *) platform="UNKNOWN:${unameOut}" 139 | esac 140 | 141 | printf "Detected platform: %s (%s)\n" "${platform}" "$(python --version)" 142 | 143 | sort_versions () { 144 | local installed_version="$1" 145 | local version="$2" 146 | 147 | if [ "$platform" = "windows" ]; then 148 | # this leans on the knowledge that node is bundled in the machine images 149 | printf "%s %s" "$installed_version" "$version" | xargs npx semver | head -n 1 150 | else 151 | printf '%s\n%s\n' "$installed_version" "$version" | sort -V | head -n 1 152 | fi 153 | } 154 | 155 | # Figure out what is latest version available if "latest" is passed as an argument. 156 | version="$ORB_VAL_VERSION" 157 | [ "$version" = "latest" ] && fetch_latest_version 158 | 159 | if command -v gcloud > /dev/null 2>&1; then 160 | installed_version="$(gcloud version | head -n 1 | sed 's/Google Cloud SDK \([0-9]*.[0-9]*.[0-9]*\)/\1/')" 161 | 162 | if [ "$ORB_VAL_SKIP_INSTALLATION" != 1 ]; then 163 | 164 | if [ "$installed_version" != "$version" ]; then 165 | # Figure out which version is older between the installed version and the requested version. 166 | older_version="$(sort_versions "$installed_version" "$version")" 167 | 168 | # If the version requested is "latest" and the installed version is newer than the latest version available, skip installation. 169 | if [ "$ORB_VAL_VERSION" = "latest" ] && [ "$older_version" = "$version" ]; then 170 | printf '%s\n' "The version installed ($installed_version) is newer than the latest version listed in the release notes ($version)." 171 | printf '%s\n' "Skipping installation." 172 | else 173 | printf '%s\n' "The version installed ($installed_version) differs from the version requested ($version)." 174 | printf '%s\n' "Uninstalling v${installed_version}..." 175 | if ! uninstall; then printf '%s\n' "Failed to uninstall the current version."; exit 1; fi 176 | 177 | printf '%s\n' "Installing v${version}..." 178 | if ! install "$version"; then printf '%s\n' "Failed to install the requested version."; exit 1; fi 179 | fi 180 | else 181 | printf '%s\n' "The version installed ($installed_version) matches the version requested ($version)." 182 | printf '%s\n' "Skipping installation." 183 | fi 184 | else 185 | printf '%s\n' "Found gcloud installed: ($installed_version)." 186 | printf '%s\n' "Skipping installation." 187 | fi 188 | 189 | else 190 | printf '%s\n' "Google Cloud SDK is not installed. Installing it." 191 | if ! install "$version"; then printf '%s\n' "Failed to install the requested version."; exit 1; fi 192 | fi 193 | 194 | # Install user provided gcloud components 195 | if [ -n "$ORB_VAL_COMPONENTS" ]; then 196 | set -f 197 | for component in $ORB_VAL_COMPONENTS; do 198 | set -- "$@" "$component" 199 | done 200 | set +f 201 | 202 | gcloud --quiet components install "$@" 203 | fi 204 | -------------------------------------------------------------------------------- /src/scripts/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Expand parameters 4 | readonly service_key=${!ORB_ENV_SERVICE_KEY} 5 | readonly project_id=${!ORB_ENV_PROJECT_ID} 6 | readonly compute_zone=${!ORB_ENV_COMPUTE_ZONE} 7 | readonly compute_region=${!ORB_ENV_COMPUTE_REGION} 8 | 9 | # Eval parameters 10 | cred_file_path=$(eval "echo $ORB_EVAL_CRED_FILE") 11 | 12 | # Store service account 13 | printf '%s\n' "$service_key" > "$HOME"/gcloud-service-key.json 14 | 15 | # Initialize gcloud CLI 16 | gcloud --quiet config set core/disable_usage_reporting true 17 | gcloud --quiet config set component_manager/disable_update_check true 18 | 19 | if [ -z "$CLOUDSDK_AUTH_ACCESS_TOKEN" ]; then # check issue/93 20 | # Use oidc 21 | if [ "$ORB_VAL_USE_OIDC" = 1 ]; then 22 | echo "Authorizing using OIDC token" 23 | 24 | if [ -z "$CIRCLE_OIDC_TOKEN" ]; then 25 | echo "Ensure this job has a context to populate OIDC token" 26 | echo "See more: https://circleci.com/docs/openid-connect-tokens/#openid-connect-id-token-availability" 27 | exit 1 28 | fi 29 | 30 | echo "$CIRCLE_OIDC_TOKEN" > "$HOME/oidc_token" 31 | # Store OIDC token in temp file 32 | gcloud iam workload-identity-pools create-cred-config \ 33 | "projects/${!ORB_ENV_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${!ORB_ENV_POOL_ID}/providers/${!ORB_ENV_POOL_PROVIDER_ID}" \ 34 | --service-account="${!ORB_ENV_SERVICE_EMAIL}" \ 35 | --credential-source-type="text" \ 36 | --credential-source-file="$HOME/oidc_token" \ 37 | --output-file="$cred_file_path" 38 | 39 | # Configure gcloud to leverage the generated credential configuration 40 | gcloud auth login --brief --cred-file "$cred_file_path" 41 | # Configure ADC 42 | echo "export GOOGLE_APPLICATION_CREDENTIALS='$cred_file_path'" | tee -a "$BASH_ENV" 43 | else 44 | gcloud auth activate-service-account --key-file="$HOME"/gcloud-service-key.json 45 | fi 46 | fi 47 | 48 | gcloud --quiet config set project "$project_id" 49 | 50 | if [[ -n "$compute_zone" ]]; then 51 | gcloud --quiet config set compute/zone "$compute_zone" 52 | fi 53 | 54 | if [[ -n "$compute_region" ]]; then 55 | gcloud --quiet config set compute/region "$compute_region" 56 | fi 57 | --------------------------------------------------------------------------------