GithubHelp home page GithubHelp logo

circleci-public / orb-tools-orb Goto Github PK

View Code? Open in Web Editor NEW
49.0 15.0 74.0 338 KB

Various tools for authoring and publishing CircleCI orbs

Home Page: https://circleci.com/orbs/registry/orb/circleci/orb-tools

License: MIT License

Shell 100.00%
circleci-orbs

orb-tools-orb's Introduction

Orb Tools Orb CircleCI status CircleCI Orb Version GitHub license CircleCI Community

An orb for orb authors - provides a full suite of jobs for packing, validating, reviewing, testing and deploying your orbs to the orb registry.

Usage

The orb-tools orb is a key component of the "Orb Development Kit". For the full documentation for developing orbs, see the Intro to Authoring an Orb documentation.

When you initialize a new orb project using the Orb Development Kit, a customized .circleci/config.yml file is created containing a full CI pipeline for building, testing, and publishing your orb which utilizes the "orb-tools" orb for the majority of these functions. You can find the config template here.

Once automatically configured, on each code push to your repo, CircleCI will trigger the pipeline defined in the .circleci/config.yml file, which will execute (among several others) the orb-tools orb's jobs.

When you are ready to publish a new version of your orb, you can create a new release on GitHub and/or push a semantically versioned tag.

Quick Docs

Migrate From Older Orb Tools Versions

Follow the migration guide.

Local Usage

A subset of the orb-tools orb jobs and scripts can be ran locally. It is useful to be able to lint, shellcheck, and review your orbs locally, before committing. With this setup, it is possible to test your code locally, but integration tests of the built orb will be ran on CircleCI.

Local Linting

The orb-tools orb's orb-tools/lint job uses a utility yamllint, which can be downloaded an ran locally, or you can invoke the job locally with the CircleCI CLI.

Assuming you ./circleci/config.yml file appears similar to the one in this repository, you will have imported the orb-tools orb and defined the orb-tools/lint job in a workflow. Using the CLI from this directory, use the following command to locally lint your orb:

CircleCI Local Linting

$ circleci local execute --job orb-tools/lint

YamlLint Local Linting

$ yamllint ./src

Note: you will need a .yamllint file in the current directory to run the yamllint command. This will also be generated for you by the Orb Development Kit. Preview the file in the Orb Project Template.

Local Shellcheck

Shellcheck is a static analysis tool for shell scripts, and behaves like a linter for our shell scripts. Which of course can also be ran locally, or if defined within your configuration file, you can invoke the job locally with the CircleCI CLI.

CircleCI Local Shellcheck

$ circleci local execute --job shellcheck/check

You can not however pass in parameters to skip specific checks. Use the Shellcheck CLI locally for more control when running locally.

Shellcheck CLI Local Shellcheck

$ shellcheck ./src/scripts/*.sh --exclude SC2148,SC2038,SC2086,SC2002,SC2016

Local Review

The review job is a suite of Bash unit tests written using bats-core, a test automation framework for Bash. Each test focuses on checking for a best practice in the orb. The tests can be executed directly with the bats CLI, or you can invoke the job locally with the CircleCI CLI.

CircleCI Local Review

$ circleci local execute --job orb-tools/review

Note: You will always see a failure at the end of this job when ran locally because the job contains a step to upload test results to CircleCI.com, which is not supported in the local agent.

Bats CLI Review

You can also install the bats-core package locally and run the tests with the bats CLI.

$ bats ./src/scripts/review.bats

Contributing

We welcome issues to and pull requests against this repository!

For further questions/comments about this or other orbs, visit CircleCI's orbs discussion forum.

orb-tools-orb's People

Contributors

adamdmharvey avatar bjohnso5 avatar bradylill avatar burukuru avatar chasinglogic avatar chilipp avatar circlecai avatar eddiewebb avatar ericribeiro avatar iynere avatar jaryt avatar jrnail23 avatar juanca avatar kelvintaywl avatar killianhmyd avatar kyletryon avatar lironrisk avatar lokst avatar lukesmith avatar masutaka avatar meeroslav avatar ndintenfass avatar nise-nabe avatar particleflux avatar robzr avatar roopakv avatar sugarshin avatar surecloud-meason avatar wyardley avatar yaningo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orb-tools-orb's Issues

Unable to publish orb correctly; blocking development

Newly published version of orb does not contain the code newly added commands. The commands exist if you SSH in, and on https://circleci.com/developer/orbs/orb/stavvy-orb/stavvy-private-orb (private orb, visibility may be limited). But they are not able to be called. Calling 1.8.4 should call a lot more steps than it does. It's calling the steps from 1.5.11. But the page is updated.

This is blocking a fix for some mission critical tasks, including deploys. Any urgency would be appreciated.

orb-tools 11 incompatible with "monorepo" containing multiple orbs

Orb version:

11.1.3

What happened:

I attempted to migrate my build to 11, but it appears that there is no way to use the new tools jobs to lint/review/etc. a project that contains multiple orbs in a single repo. They expect everything to live in src/.

Expected behavior:

Handle publishing multiple orbs from one repository.

Additional Information:

My attempts at transitioning are here: https://github.com/OpenNMS/orb/tree/orb-tools-11-migration

semver default value for orb-tools/dev-promote-prod-from-commit-subject

the ideal place to control publishing based on commits to master is exactly what this job expects, but a finer control than/in addition to fail-if-semver-not-indicated would be e.g. semver-default (whose own default might be skip)
this would allow for greater flexibility with workflows, and probably a good number of users would opt to change the default to patch (were probably not the only ones calling this job with a branch filter)
im torn between submitting that PR and doing some pre-steps that just git commit --amend -m "[semver:$DEFAULT]" for this job in our workflow

`orb-tools/pack` fails if boolean parameter's default value is other than `true` or `false`

Orb version:

11.1.2

What happened:

According to the CircleCI documentation, boolean parameters can have the following values: y yes true on n no false off

However, if a command parameter is declared as a boolean with a default value other than true or false, the "Validating orb" step fails with:

Parameter error: default value of parameter '<parameter_name>' is 'on' (type string): expected type boolean

https://app.circleci.com/pipelines/github/orbiously/openvpn2-orb/53/workflows/b89b1c00-95d6-472b-aa8d-7f7158dcb9b2/jobs/334

Expected behavior:

The "Validating orb" step should pass if the boolean default value is any of: y yes true on n no false off

Additional Information:

Using:

circleci version
0.1.17183+341e493 (homebrew)
  • Locally running, circleci orb pack src > orb.yml then circleci orb validate orb.yml produces the same output:
Parameter error: default value of parameter 'killswitch' is 'on' (type string): expected type boolean

And the generated orb.yml contains a string value:

        parameters:
            killswitch:
                default: "on"
                type: boolean
  • However, locally running circleci config validate on the below configuration file is successful:
version: 2.1

jobs:       
  build:
    parameters:
      killswitch:
        type: boolean
        default: on
     machine:
       image: ubuntu-2004:202201-02
    steps:
      - run:
          shell: bash
          environment:
            KILLSWITCH: << parameters.killswitch >>          
          command: |
            echo $KILLSWITCH
workflows:
  build-and-release:
    jobs:
    - build:
        killswitch: off

 
I suspect the issue is caused by the use of "gopkg.in/yaml.v3" in https://github.com/CircleCI-Public/circleci-cli/blob/master/cmd/config.go#L17.

Specifically, as of v3 of the yaml package:

  • YAML 1.1 bools (yes/no, on/off) are supported as long as they are being decoded into a typed bool value. Otherwise they behave as a string. Booleans in YAML 1.2 are true/false only.

(Reference: https://pkg.go.dev/gopkg.in/yaml.v3#readme-compatibility)

Also see CircleCI-Public/circleci-cli#691

trigger-integration-workflow thinks the branch is new

Orb version

8.8.0

What have you done

Having switched my organisation to use CircleCI for our CI/CD needs, I have been working on creating an Orb with the most relevant functionality for my team. While the Orb itself is working, and I have managed to publish the Orb manually (through the CLI), I now wanted to create a circleci config for handling this continued effort.

I have used the https://github.com/CircleCI-Public/orb-tools-orb/tree/master as a guideline for setting it up. While most of it seems to be working, there is a specific issue with the trigger-integration-workflow that I have so far been unable to solve or find support on.

What happened

The issue is, that during this Job, it tries to determine whether the branch on which the config got triggered previously existed or not. To this, it responds that 'yes, develop is new and 1050c58dce8663a4b284519684f904252d24f539 is its only commit'.

This is incorrect as the develop branch has over 50 commits to its name in our repository. When it then tries to 'finding most recent ancestor commit from any other branch', it Exited with code 1.

Here is a link to an example Job that fails:
https://circleci.com/gh/pluralai/circleci-orbs/97

Expected behavior

When checking wether the branch is new or not, it should evaluate to false or NO, as the branch is already existing.

Source

version: 2.1

orbs:
  orb-tools: circleci/[email protected]
  plural-ai: pluralai/computing@dev:alpha

workflows:
  lint_validate_publish:
    jobs:
      - orb-tools/lint
      - orb-tools/pack:
          requires:
            - orb-tools/lint
          source-dir: computing
      - orb-tools/publish-dev:
          name: 'publish-orb-dev'
          filters:
            branches:
              only: develop
          requires:
            - orb-tools/pack
          context: plural-int
          orb-name: pluralai/computing
          publish-token-variable: 'PUBLISH_TOKEN_VARIABLE'
          validate: true
      - orb-tools/trigger-integration-workflow:
          name: 'trigger-integration-dev'
          filters:
            branches:
              only: develop
          requires:
            - publish-orb-dev
          ssh-fingerprints: 'my_ssh_fingerprint'

Add option to never automatically publish major releases

make auto-publish feature better conform to SemVer specifications (i.e., major release should only happen for breaking changes)—

instead of automating major releases, only automate minor / patch releases, & create an alternative mechanism in orb-tools for automating major releases (e.g., push a particular git tag, push to a specially named branch, etc.)

trigger-integration-workflow's cleanup-tags option only cleans up hardcoded tags

Orb version

v1.27.1

What happened

When running trigger-integration-workflow with cleanup-tags: true and with a non-default tag param (i.e., tag: custom_tag), my previous custom_tag-* tags don't get cleaned up.

Expected behavior

I expect my previous tags that match my tag param to be deleted.

Other comments

I noticed this in the trigger-integration-workflow source:

# delete local tags
git tag -d $(git tag -l "integration-*")
git tag -d $(git tag -l "master-skip-master-*")
# fetch remote tags
git fetch
# delete remote tags
git push origin --delete $(git tag -l "integration-*") || true
git push origin --delete $(git tag -l "master-skip-master-*") || true # pushing once should be faster than multiple timesshould be faster than multiple times

and it seems that

$(git tag -l "integration-*")

should probably be changed to

$(git tag -l "<<parameters.tag>>-*")

However, I'm not sure what to do about $(git tag -l "master-skip-master-*") though.

trigger-integration-workflow makes superflous use of `add_ssh_keys`

Orb version

8.3.0

What happened

Documentation shows that an ssh fingerprint needs to be specified with ssh-fingerprints to be then added to the executor with add_ssh_keys.

Adding the ssh key via add_ssh_keys is unnecessary. To quote from the documentation:

Even though all CircleCI jobs use ssh-agent to automatically sign all added SSH keys, you must use the add_ssh_keys key to actually add keys to a container.

For pushing to Git(hub) via SSH, it is completely sufficient to have the key available for signing in ssh-agent. There is no need to add the actual private key file to the container.

Expected behavior

The use of add_ssh_keys should be optional, as should be the associated ssh-fingerprints parameter.

This also allows for people using other means of authentication like for example Github tokens.

[BUG] .circleci/config.yml and src/* do not align

I'm looking to use some elements of this repo as reference for other orbs.
I assume (perhaps falsely) that src/* is being packed to .circleci/config.yml eg circleci config pack src > .circleci/config.yml however the content of .circleci/config.yml does not match the content of src.

As one example .circleci/config.yml has a test-commands job but there is no test-commands.yml in https://github.com/CircleCI-Public/orb-tools-orb/tree/master/src/jobs

Shellcheck job chokes on some parameter usages

Using v9.1.1 of the orb, I added the shellcheck job to my workflow, and it seems to be having trouble parsing some of my commands that use command parameters.
Also, FWIW, shellcheck is incorrectly complaining (warning) about variables not being used, but perhaps that's a side-effect of the parsing failure.

Here's a (private) link to my failed job: https://app.circleci.com/pipelines/github/socialtables/sonarcloud-orb/71/workflows/e389ee3f-d3e1-4733-a42b-87bfa3d7e81c/jobs/177/parallel-runs/0/steps/0-104

Here's the relevant output from the failing shellcheck job:

Scanning ./src/commands/scan.yml 
---
In - line 4: 
SONAR_PROJECT_KEY="<<parameters.project-key>>" 
^-- SC2034: SONAR_PROJECT_KEY appears unused. Verify it or export it.

In - line 5: 
SONAR_ORGANIZATION="<<parameters.organization>>" 
^-- SC2034: SONAR_ORGANIZATION appears unused. Verify it or export it.

In - line 6:
SONAR_HOST_URL="<<parameters.host-url>>"
^-- SC2034: SONAR_HOST_URL appears unused. Verify it or export it.

In - line 7:
SONAR_SCM_REVISION="${<<parameters.scm-revision>>}"
^-- SC2034: SONAR_SCM_REVISION appears unused. Verify it or export it.

In - line 8:
SONAR_BUILD_STRING="${<<parameters.build-string>>}"
^-- SC2034: SONAR_BUILD_STRING appears unused. Verify it or export it.

In - line 9:
SONAR_LOGIN="${<<parameters.sonar-login>>}"
^-- SC2034: SONAR_LOGIN appears unused. Verify it or export it.
 
In - line 10:
GITHUB_PROJECT_SLUG="<<parameters.github-project-slug>>"
^-- SC2034: GITHUB_PROJECT_SLUG appears unused. Verify it or export it.
 
In - line 11:
GITHUB_API_TOKEN="${<<parameters.github-api-token>>}"
^-- SC2034: GITHUB_API_TOKEN appears unused. Verify it or export it.

In - line 12:
LCOV_FILES=(<<parameters.coverage-paths>>) 
           ^-- SC1036: '(' is invalid here. Did you forget to escape it?
           ^-- SC1088: Parsing stopped here. Invalid use of parentheses?
 
Error discovered in ./src/commands/scan.yml at step 2 
---
----- 
Scanning ./src/commands/install-cli.yml
---
unless: condition: <<parameters.no-cache>> steps: - restore_cache: name: restoring cached sonar-scanner CLI key: &cache-key sonar-scanner-v<<parameters.cli-version>>-{{arch}}-<<parameters.cache-version>> when: always

Unable to shellcheck this command. Skipping.
---

In - line 23:
sonar-scanner --version \
^-- SC1009: The mentioned parser error was in this simple command.

In - line 24:
  <<#parameters.output-file>>| tee <<parameters.output-file>><</parameters.output-file>>;
  ^-- SC1073: Couldn't parse this here document.

Error discovered in ./src/commands/install-cli.yml at step 2
---

And here's the actual source of the above commands:

from scan.yml

shopt -s nullglob globstar
GLOBIGNORE="**/node_modules/**:node_modules/**:**/node_modules"

SONAR_PROJECT_KEY="<<parameters.project-key>>"
SONAR_ORGANIZATION="<<parameters.organization>>"
SONAR_HOST_URL="<<parameters.host-url>>"
SONAR_SCM_REVISION="${<<parameters.scm-revision>>}"
SONAR_BUILD_STRING="${<<parameters.build-string>>}"
SONAR_LOGIN="${<<parameters.sonar-login>>}"
GITHUB_PROJECT_SLUG="<<parameters.github-project-slug>>"
GITHUB_API_TOKEN="${<<parameters.github-api-token>>}"
LCOV_FILES=(<<parameters.coverage-paths>>)
TEST_RESULTS_FILES=(<<parameters.test-report-paths>>)
ESLINT_RESULTS_FILES=(<<parameters.eslint-report-paths>>)
STYLELINT_RESULTS_FILES=(<<parameters.stylelint-report-paths>>)
SONAR_COVERAGE_PLUGIN="<<parameters.covered-code-language>>"
SCM_BRANCH_NAME="${<<parameters.scm-branch-name>>}"
GITHUB_PR_URL="${<<parameters.github-pr-url>>}"
PROJECT_VERSION_PARAM="<<parameters.project-version>>"
RAW_SCANNER_ARGS=(<<parameters.raw-scanner-args>>)

GITHUB_API_AUTH_HEADER="Authorization: Bearer ${GITHUB_API_TOKEN}"
SONAR_PROJECT_VERSION="${PROJECT_VERSION_PARAM:-$(cat package.json | jq -r '.version')}"

declare -A SONAR_ARGS

if [ "$GITHUB_PR_URL" ]; then
  echo "USING PR: $GITHUB_PR_URL"
  SONAR_PR_KEY=$(basename $GITHUB_PR_URL)

  echo "SONAR_PR_KEY: $SONAR_PR_KEY"
  PR_BASE_BRANCH=$( \
    curl \
      -H "$GITHUB_API_AUTH_HEADER" \
      "https://api.github.com/repos/$GITHUB_PROJECT_SLUG/pulls/$SONAR_PR_KEY" | \
      jq -r '.base.ref' \
  )
  echo "PR_BASE_BRANCH: $PR_BASE_BRANCH"

  SONAR_ARGS+=(
    ["sonar.pullrequest.base"]=${PR_BASE_BRANCH} \
    ["sonar.pullrequest.branch"]=${SCM_BRANCH_NAME} \
    ["sonar.pullrequest.key"]=${SONAR_PR_KEY} \
  )

  git branch -f $PR_BASE_BRANCH origin/$PR_BASE_BRANCH

else
  if [ "$SCM_BRANCH_NAME" ]; then
    GITHUB_DEFAULT_BRANCH=$( \
      curl \
        -H "$GITHUB_API_AUTH_HEADER" \
        https://api.github.com/repos/$GITHUB_PROJECT_SLUG | \
        jq -r '.default_branch' \
    )
    echo "GITHUB_DEFAULT_BRANCH: $GITHUB_DEFAULT_BRANCH"

    SONAR_ARGS["sonar.branch.name"]=$SCM_BRANCH_NAME

    if [ "$SCM_BRANCH_NAME" != "$GITHUB_DEFAULT_BRANCH" ]; then
      SONAR_ARGS["sonar.branch.target"]=${GITHUB_DEFAULT_BRANCH}

      git branch -f $GITHUB_DEFAULT_BRANCH origin/$GITHUB_DEFAULT_BRANCH
    fi
  fi
fi

function toCSV { local IFS=","; echo "$*"; }
function splitRawParam {
  local IFS="="; read -ra PARAM \<<< "$1"
  echo ${PARAM[*]}
}

if [ ${#LCOV_FILES[@]} -gt 0 ]; then
  SONAR_ARGS["sonar.$SONAR_COVERAGE_PLUGIN.lcov.reportPaths"]="$(toCSV ${LCOV_FILES[@]})"
fi

if [ ${#TEST_RESULTS_FILES[@]} -gt 0 ]; then
  SONAR_ARGS["sonar.testExecutionReportPaths"]="$(toCSV $TEST_RESULTS_FILES)"
fi

if [ ${#ESLINT_RESULTS_FILES[@]} -gt 0 ]; then
  SONAR_ARGS["sonar.eslint.reportPaths"]="$(toCSV $ESLINT_RESULTS_FILES)"
fi

if [ ${#STYLELINT_RESULTS_FILES[@]} -gt 0 ]; then
  SONAR_ARGS["sonar.css.stylelint.reportPaths"]="$(toCSV $STYLELINT_RESULTS_FILES)"
fi

SONAR_ARGS+=( \
  ["sonar.host.url"]="$SONAR_HOST_URL" \
  ["sonar.organization"]="$SONAR_ORGANIZATION" \
  ["sonar.buildString"]="$SONAR_BUILD_STRING" \
  ["sonar.scm.revision"]="$SONAR_SCM_REVISION" \
  ["sonar.projectKey"]="$SONAR_PROJECT_KEY" \
  ["sonar.projectVersion"]="$SONAR_PROJECT_VERSION" \
  ["sonar.login"]="$SONAR_LOGIN" \
)

if [ ${#RAW_SCANNER_ARGS[@]} -gt 0 ]; then
  for param in "${RAW_SCANNER_ARGS[@]}";
  do
    param_parts=($(splitRawParam $param))
    SONAR_ARGS["${param_parts[0]}"]="${param_parts[1]}"
  done
fi

CLI_ARGS=()
echo "SONAR_ARGS:"
for key in "${!SONAR_ARGS[@]}";
do
  ARG="-D$key=${SONAR_ARGS[$key]}"
  CLI_ARGS+=($ARG)
  # exclude login here for security reasons
  if [ "$key" != "sonar.login" ]; then
    echo "$ARG";
  fi
done

export SONAR_SCANNER_OPTS="-server"
sonar-scanner ${CLI_ARGS[*]}

From install-cli.yml

CLI_VERSION="<<parameters.cli-version>>"
CLI_OS="<<parameters.os>>"
DOWNLOAD_URL="<<parameters.download-path>>sonar-scanner-cli-$CLI_VERSION-$CLI_OS.zip"

export UTILS_TO_INSTALL=""
hash jq 2>/dev/null || { UTILS_TO_INSTALL="${UTILS_TO_INSTALL} jq"; }
hash unzip 2>/dev/null || { UTILS_TO_INSTALL="${UTILS_TO_INSTALL} unzip"; }

if [ "$UTILS_TO_INSTALL" ]; then
  apt-get update -y
  apt-get install -y --no-install-recommends $UTILS_TO_INSTALL
fi

if test ! -d /tmp/sonar-scanner; then
  wget $DOWNLOAD_URL -O /tmp/sonar-scanner.zip
  unzip /tmp/sonar-scanner.zip -d /tmp
  rm /tmp/sonar-scanner.zip
  mv /tmp/sonar-scanner-$CLI_VERSION-$CLI_OS /tmp/sonar-scanner
fi
echo "export PATH=/tmp/sonar-scanner/bin:$PATH" >> $BASH_ENV
source $BASH_ENV

sonar-scanner --version \
  <<#parameters.output-file>>| tee <<parameters.output-file>><</parameters.output-file>>;

Allow passing DockerHub credentials to jobs

What would you like to be added

We'll need a way to pass the auth block to the docker configuration parameter (docs) for jobs used directly in workflows.

Why is this needed

Starting November 1, 2020, DockerHub will begin rate-limiting image pulls from DockerHub. Users need a way to pass their DockerHub credentials to avoid the rate limit. Without providing this configuration option, deployments from CircleCI will be impacted.

skip tag if skip publish in orb-tools/dev-promote-prod-from-commit-subject

the way it currently sits publish-version-tag: true in this job will attempt to add a tag even if [semver:skip] was present; it seems unlikely that someone would attempt to do that on purpose: promote nothing but tag the code (i think the tag is meant to capture the exact revision which was promoted)
this is a problem because in lieu of an increment, the tag is always already there and git push origin "$TAG" fails
another way of putting that is that publish-version-tag: true is only technically compatible with skipping a version bump -- out in the wild, it won't be

Inconsistent reporting of run commands in "review" job

Orb version:

11.1.0

What happened:

I have an orb with multiple "jobs"; RC008 and RCOO9 seem to behave somewhat inconsistently with the "review" job.

RC008: All Run steps should contain a name: I have multiple jobs that have run steps without a name, but only a single one shows up, and that is in a file like the second example below where there should be 2 violations, but only one shows up.

RC009: All Run step's commands should be imported: Almost all the same items that should be flagging above also fail this check; in this case, they are reported. However, some of the additional detail seems to be missing or confusing:

(in test file review.bats, line 160)
  `exit 1' failed
File: "./src/jobs/job1.yml"
Line number: 12
---
---
File: "./src/jobs/job2.yml"
Line number: 15
---
null
---

I can't easily throw up a public demo repo, but happy to provide links to examples to Circle employees offline (I'm on the discussion forum under the same account), or provide more details if you're not able to repro it easily. The examples below are lightly sanitized versions of 2 of the files, but of course there's other stuff in the orb repo as well.

Expected behavior:

Given the following two files, the two checks should fail on both (these are also slightly sanitized versions of the ones that cause the output above):

src/jobs/job1.yml:

description: "Do some things and then `foo bar`"
executor: <<parameters.executor>>
parameters:
  executor:
    description: The name of custom executor to use
    type: executor
    default: wizzle
steps:
  - checkout
  - restore-deps
  - setup-auth
  - run: npm install --no-save
  - save-deps

src/jobs/job2.yml:

description: "Run thing1 (and, optionally, thing2) on code"
executor: <<parameters.executor>>
parameters:
  executor:
    description: The name of custom executor to use
    type: executor
    default: wizzle
  run-thing2:
    description: whether or not to run foo
    type: boolean
    default: true
steps:
  - checkout
  - restore-deps
  - run: npm run thing1
  - when:
      condition: << parameters.run-thing2 >>
      steps:
        run: npm run thing2

Additional Information:

Also, I would love to see RC008 and RC009 retained / usable, but loosened up somewhat (I just have them ignored outright for now) - I see the value of encouraging good practices and failing on missing titles for very long run commands, or failing on long / complicated shell scripts, but IMO it's a bit overkill to require a single command with no interpolation, variables, or other complexity to be turned into a shell script

i.e.,

## not getting much value out of linting this IMO
run: npm run eslint

vs

run: <<include(scripts/script_that_runs_npm_run_eslint.sh)>>

The BATS based approach kind of makes sense, but it might be cleaner to build a linter into the CLI that has somewhat more readable output.

Anyway, while I'd frequently do something like

run:
   name: Setup stuff
   command: |
      here is
      a very long set of
      commands that I don't
      really want to see all of & 2>&1

IMO, for very simple use cases like this:

run: npm run foo

is probably (in many cases) clearer and easier to understand in both the Circle web UI and in the config itself

run:
  name: Run foo on files
  command: npm run foo

So, I know the logic would be much harder to do, but would love to see something that will flag examples where these recommended practices will really help in terms of reducing complexity or increasing readability.

Error running orb-tools/increment

I’ve successfully published a dev version of an orb (civicteam/helm@dev:orbs) via circleci using the circleci/[email protected] orb (publishing an orb for use in circleci via an orb on circleci is cool btw!)

However, I am getting this error when running Increment: "Error: User does not have access to publish SemVer orbs in this namespace.". I am using the same publish-token-variable for publish and increment and this is a token generated by my github admin account. I also created the namespace itself.

Is the publish-token-variable the place where circle gets the permissions from, or is this based on some other setting in the circle project such as the github ssh key? I presume if I am a github admin I should have permissions to run increment?

New job for not using destructured yaml

Orb version

8.27.4

What happened

Orb workflow indirectly forces use of destructured yaml.

Expected behavior

It should be just as easy to use a single orb file as it is to use destructured yaml

The example in the README uses the Lint - Pack - Publish-Dev - etc workflow. The Pack job expects a destructured yaml to be... well, destructured. So if someone creating a new Orb only has a single orb.yaml file, now they have to figure out how to move that file and persist it so that the Publish-Dev step can use it.

I'm requesting a job to not-pack, where it takes orb.yaml or an orb-path param and does the same persist to workspace magic that pack does. To be easier for newcomers.

Help with migration script: sed errors

Orb version:

Not sure how to answer...I guess 10 → 11??

What happened:

I was trying to follow the Migration Guide and got to the "run migrate.sh" step and:

bash migrate.sh
Namespace: geos-esm
Orb name: circleci-tools
Context name: orb-publishing
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   997  100   997    0     0   3720      0 --:--:-- --:--:-- --:--:--  3706
sed: can't read s/<namespace>/geos-esm/g: No such file or directory
sed: can't read s/<orb-name>/circleci-tools/g: No such file or directory
sed: can't read s/<publishing-context>/orb-publishing/g: No such file or directory
sed: can't read s/<namespace>/geos-esm/g: No such file or directory
sed: can't read s/<orb-name>/circleci-tools/g: No such file or directory
sed: can't read s/<publishing-context>/orb-publishing/g: No such file or directory
Successfully upgraded config files.
You must now open "test-deploy.yml" and add your integrations tests.
Docs: https://circleci.com/docs/2.0/testing-orbs/#integration-testing

When complete, delete the '.bak' files in the .circleci directory.
Commit your changes and the next version of your orb will be published when a tag is created.

And if I look in the produced .circleci/config.yml file:

      - orb-tools/publish:
          orb-name: <namespace>/<orb-name>
          vcs-type: << pipeline.project.type >>
          requires:
            [orb-tools/lint, orb-tools/review, orb-tools/pack, shellcheck/check]
          # Use a context to hold your publishing token.
          context: <publishing-context>
          filters: *filters

I'm guessing those should have been sed'd to what I provided? (Note: I'm not even sure if what I provided was correct. I'm not an Orb expert...

Expected behavior:

I'm guessing no sed errors?

Additional Information:

I am on a macOS machine and perhaps this script assumes GNU sed? I mean, I do have GNU sed from Homebrew and I've symlinked my sed to be the gsed from Homebrew:

which sed
/Users/mathomp4/bin/sedsed --version
sed (GNU sed) 4.8
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Jay Fenlason, Tom Lord, Ken Pizzini,
Paolo Bonzini, Jim Meyering, and Assaf Gordon.

This sed program was built without SELinux support.

GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <[email protected]>.

But maybe the script assumes something? Or it's picking up the horrible BSD sed that macOS comes with?

container image used by the lint job doesn't contain git

Orb version

8.14.0

What happened

I wanted to publish my orb to the registry when a tag is pushed. It happened that the checkout step for the orb-tools/lint job failed systematically and I noticed that the singapore/lint-condo image doesn't have git installed.

Either git or ssh (required by git to clone through SSH) is not installed in the image. Falling back to CircleCI's native git client but the behavior may be different from official git. If this is an issue, please use an image that has official git and ssh installed.
Enumerating objects: 136, done.
Counting objects: 100% (136/136), done.
Compressing objects: 100% (74/74), done.
Total 136 (delta 45), reused 125 (delta 43), pack-reused 0

object not found

https://circleci.com/gh/simonpasquier/prometheus-orb/96

I've worked around the issue by not running the lint job on tags. Which is mostly fine as the linting already happened when merging to master.

Expected behavior

No checkout error in the lint job.

integration test design in documentation is prone to race conditions

Orb version

8.3.0

What happened

The orb under test is referenced as orb@dev:alpha.

If I push two feature branches at once, it is quite possible that workflows will run in the following sequence:

  • lint_pack-validate_publish-dev-branch-1
  • lint_pack-validate_publish-dev-branch-2
  • integration-tests_prod-release-branch-1
  • integration-tests_prod-release-branch-2

In that case, integration-tests_prod-release-branch-1 will actually run the tests against branch-2.

Even worse, if I push master and a feature-branch at the same time, there is the possibility that the orb built from the feature-branch will be confused with the orb from the master branch, and is subsequently promoted to a release.

push git tag after `orb-tools/increment`

Hello.

I want to push the same tag as the orb'version

e.g.

#!/bin/bash -eo pipefail
circleci orb publish increment packed/orb.yml sue445/my-orb patch --token $CIRCLECI_API_TOKEN 
Orb `sue445/bundle-install` has been incremented to `sue445/[email protected]`.
Please note that this is an open orb and is world-readable.

#### I want to run this!
# git tag -a 1.2.3 -m "Release 1.2.3"
# git push origin --tags

But there is no way to acquire the automatically incremented version 😢

Do you have a good idea or feature?

My workaround

https://github.com/sue445/circleci-orb-bundle-install/blob/0.1.0/.circleci/config.yml#L114-L125

Running orb-tools/publish when only pushed tag.

Although this works, but dirty way...

Current examples reference non-existent shellcheck job

The v10.0.0 examples reference a orb job called shellcheck but it doesn't seem to be available:
https://circleci.com/orbs/registry/orb/circleci/orb-tools?version=10.0.0#usage-examples

When the example is used, I get a Cannot find a definition for job named orb-tools/shellcheck error:
image

Not sure if this is a bug with the example and we should be using the https://circleci.com/orbs/registry/orb/circleci/shellcheck orb directly, or if the job was incorrectly removed from this orb with v9 => v10 release?

Changelogs

Orb version

What happened

releases are published without any context

Expected behavior

releases should be published with a brief markdown changelog identifying major changes in a given new orb version

`add-pr-comment` posts `$PR_MESSAGE` instead of the actual PR message

Hi there!

I tried setting up these orbs, and using the add-pr-comment parameter of dev-promote-prod-from-commit-subject. After my orb was released, it did post on my PR, but it posted the literal message $PR_MESSAGE instead of the intended text.

It looks like originally, the job to post to github was included in-line:
https://github.com/CircleCI-Public/orb-tools-orb/pull/48/files#diff-fb366387fc25f0a7f13264f09741a3deda684c5ce175ae2f6247e20d4cb1b3b9R73

But at some point, it was split into its own job:
https://github.com/CircleCI-Public/orb-tools-orb/pull/73/files#diff-a1e9004fe47111f4a7dea78b06d30b23c95ad601a27f29686fc1d6a1abcb3226R114

I'm pretty sure that circle does not source $BASH_ENV when its populating pipeline variables, so $PR_MESSAGE is not available to be passed as a parameter to the post-pr-comment step.

I think I understand the problem, but I'm not sure how to fix it. Making the post-pr-comment step in-line seems like a regression, so that doesn't seem like the right path. And implicitly passing the message we want via the $BASH_ENV seems like too much magic to me.

Maybe the PR comment should be the name of a variable to use, like how bot-token-variable works?

Feature Idea: Enable shell scripts to be pre-processed into orb commands

Just an idea here...
I HATE writing significant shell commands in yaml. I always make typos, and the lack of syntax highlighting is a drag.

So here's an idea: what if we could write some of our commands in a .sh file, then pre-process them into our orb's commands, with args mapped to the command's parameters?

That way, we could even use something like shellcheck to validate our scripts before processing.

Pushing tags fail for orb from Bitbucket Team

Orb version

8.27.4

What happened

When building using the workflow outlined in your article on CI/CD on orbs we encounter a problem where the step promoting dev versions to a release version fails on the git config --global ... steps.

This seems to be because the CIRCLE_USERNAME environment variable is not set when the commit is coming from an SSH-key added to the project/team in Bitbucket.

Reproduced it with an example-orb here:
https://circleci.com/bb/cloudwheel/workflows/example-orb

If you see the build that triggered from commit 5f19504, it fails with a git error "tell me who you are".
The next commit (3ed9236) succeeds as I change the orb to our dev-version of it, I'll open a PR with this now.

Expected behavior

There should be a way to declare the git user.name and user.email for these cases, and when you want it to say something specific. We have made a change that we're running with now where we check for the existance of GIT_CONFIG_USER_NAME and GIT_CONFIG_USER_EMAIL environment variables.

Question: Should we add parameters for this? They could default to the current values for backward compatibility. So the order of evaluation would be:

  1. Are parameters set? If yes, use them
  2. Is CIRCLE_USERNAME set? If yes, use it
  3. Is GIT_CONFIG_USER_NAME and GIT_CONFIG_USER_EMAIL set? If yes, use them - else fail

Fun fact

Re-producing the error for this GitHub issue I started using my private bitbucket repo, but I was not able to reproduce it there: https://circleci.com/bb/haugene/workflows/example-orb

I added a step to print environment variables, and you can see that the CIRCLE_USERNAME is set to "haugene" for the tag in my private bitbucket project, but is not set when building a project that is owned by a team. I'm guessing this has to do with the link between my private project and user - while the team doesn't have the same setup in bitbucket cloud.

Private orb repos result in an orb-tools/review failure even if an ssh key is added to the repo

Orb version:

orb-tools: circleci/[email protected]
shellcheck: circleci/[email protected]

What happened:

Private orb repos result in an orb-tools/review failure

RC006: Source URL should be valid

(in test file review.bats, line 83)
  `exit 1' failed

Source URL: "<Our private repo>" is not reachable.
Check the Source URL for this orb.
display:
  home_url: "<Our private repo>"
  source_url: "<Our private repo>"

Expected behavior:

When a ssh key is added to the orb that can access the private repos, the source and home url checks should not fail.

Problems with parallel development of the orb

Hi.

We see some issues raising when more than one person is working on the orb on the same time.

Example:

  • user A creates a PR and adds command X. Adds tests for it and makes sure the CI "sees" the new command
  • user B creates another PR and makes non-related changes, runs a CI job
  • user A triggers job again and gets the config validation error "command X is not known". To fix this they need to disable integration test, build the dev orb again, then enable the tests again.

Am I right that each job triggered checks the "dev" orb published by the previous workflow only? So if there was some transient orb without the new command - an engineer will have to rebuild the dev job again?

Thank you

Automatic update examples with correct version of the orb

Describe Request:

It would be great if we could use a template value/variable to always have the examples show the correct version of the orb.

Examples:

Instead of writing the examples like this:

usage:
  version: 2.1
  orbs:
    my-orb: my-namespace/my-orb@dev:1.2.3

We could do something like this:

usage:
  version: 2.1
  orbs:
    my-orb: my-namespace/my-orb@${{ORB_VERSION}}

Supporting Documentation Links:

License missing

I noticed that this repository doesn't have a license yet.
I'd appreciate if you could add one, please.

Enhance check for source URL validity to skip private orbs

Out of the box, the review check to ensure the URL for source control needs to be public. This (likely? 95%? 😁 ) won't ever be the case for private orbs.

It would be great if this review could also somehow identify if the orb was private, and if so, pass this check successfully - or at least mark it skipped for testing output?

@test "RC006: Source URL should be valid." {
if [[ "${SKIPPED_REVIEW_CHECKS[*]}" =~ "RC006" ]]; then
skip
fi
SOURCE_URL=$(yq '.display.source_url' "${REVIEW_TEST_DIR}/src/@orb.yml")
HTTP_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" --retry 5 --retry-delay 5 "$SOURCE_URL")
if [[ "$HTTP_RESPONSE" -ne 200 ]]; then
echo
echo "Source URL: \"$SOURCE_URL\" is not reachable."
echo "Check the Source URL for this orb."
exit 1
fi
}

Otherwise, my company has to manually turn this off on all orbs we build as we only build private orbs at the moment.

trigger-integration-tests-workflow command succeeds despite circleci API error response

Using v9.0.0 of orb-tools, my workflow status is all green, despite the POST to circleci's API returning error messages.
Here are two examples, one with Permission denied, and another with Project not found:

#!/bin/bash -eo pipefail
VCS_TYPE=$(echo ${CIRCLE_BUILD_URL} | cut -d '/' -f 4)
curl -u ${CIRCLE_TOKEN}: -X POST --header "Content-Type: application/json" -d "{
  \"branch\": \"${CIRCLE_BRANCH}\",
  \"parameters\": {\"run-integration-tests\": true, \"dev-orb-version\": \"dev:${CIRCLE_SHA1:0:7}\"}
}" "https://circleci.com/api/v2/project/${VCS_TYPE}/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pipeline"
{
  "message" : "Project not found"
}
CircleCI received exit code 0
#!/bin/bash -eo pipefail
VCS_TYPE=$(echo ${CIRCLE_BUILD_URL} | cut -d '/' -f 4)
curl -u ${CIRCLE_TOKEN}: -X POST --header "Content-Type: application/json" -d "{
  \"branch\": \"${CIRCLE_BRANCH}\",
  \"parameters\": {\"run-integration-tests\": true, \"dev-orb-version\": \"dev:${CIRCLE_SHA1:0:7}\"}
}" "https://circleci.com/api/v2/project/${VCS_TYPE}/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pipeline"
{
  "message" : "Permission denied"
}
CircleCI received exit code 0

Local Review Doesn't Work

Orb version:

11+

What happened:

Method 1:
circleci local execute --job orb-tools/review

Why this wont work:
The review job utilizes the save_test_results step which isnt supported locally and will cause the job to fail

Step failed
====>> Uploading test results
Archiving the following test results
  * /tmp/orb_dev_kit/review/review.xml

Error: Failed uploading test results
Error not supported

Method 2:
bats ./src/scripts/review.bats

Why this wont work:
The review.bats script is local to the orb-tools orb and will not be present in the local files of another orb without cloning it down first.

Expected behavior:

Ideally, it would be possible to run the circleci local execute job locally, though we would need a way to retrieve and then ideally view the JUNIT output.

Better output can be achieved locally by not exporting to JUNIT, but we would need the user to have bats installed and the review script locally.

Other:

CircleCI-Public/circleci-cli#684

Parameter `fail-if-semver-not-indicated` set to `true` is ignored

As a user pointed out in this CircleCI Discuss post, setting fail-if-semver-not-indicated to true upon calling the dev-promote-prod-from-commit-subject orb's command doesn’t fail the build when the commit subject did not indicate which SemVer increment to make.

However the step's output confirms that semver was not detected:

Commit subject: change readme. Commit subject did not indicate which SemVer increment to make. To publish orb, you can ammend the commit or push another commit with [semver:FOO] in the subject where FOO is major, minor, patch. Note: To indicate intention to skip promotion, include [semver:skip] in the commit subject instead.

Make check-env-var-param command accept multiple param inputs (comma-separated)

for orbs w/ a lot of parameters, it would be helpful / useful if the check-env-var-param command accepted multiiple inputs in a comma-separated list

that way, we can include that command ONCE in some large orb job consisting of many commands, & have it check for any & all necessary param values that someone will have needed to provide

Issues with Local Usage

Orb version:

v11.1.2

What happened:

Running commands described here leads to error:

Example:

❯ circleci local execute --job orb-tools/review
Error: Error calling workflow: 'lint-pack'
Error calling job: 'orb-tools-alpha/continue'
Type error for argument pipeline-number: expected type: integer, actual value: "1" (type string)
❯ circleci config validate
Error: Error calling workflow: 'lint-pack'
Error calling job: 'orb-tools-alpha/continue'
Type error for argument pipeline-number: expected type: integer, actual value: "1" (type string)

Expected behavior:

I think all the jobs of the project should be executable locally, except maybe the publish and continue

Additional Information:

I suppose it is due to a default value given for pipeline-number parameter.
Maybe we could change it type for string as it seems to be only used to build the URL of the parent pipeline: https://github.com/CircleCI-Public/orb-tools-orb/blob/master/src/scripts/continue.sh#L40

Specify the job name the orb-tools/local-test-build command executes

Hi,

I'm currently building the CI/CD for my orb. I'm going to use the orb-tools/local-test-build and write the .circleci/config.yml like below:

version: 2.1
orbs:
  orb-tools: circleci/orb-tools@2
workflows:
  main:
    jobs:
      - orb-tools/test-in-builds:
          orb-location: src/orb.yml
          orb-name: inspecode
          test-steps:
            - orb-tools/local-test-build:
                test-config-location: test/valid.yml

The content of test/valid.yml is:

version: 2.1
workflows:
  main:
    jobs:
      - inspecode/run:
          api_token: "${INSPECODE_API_TOKEN}"

When I push these codes, it returns the error like below:

screen shot 2018-11-22 at 11 06 34

I think circleci local execute implicitly assumes the job name is build. In this case, I want to run the job inspecode/run instead. Is there any way to specify the job name or any workarounds?

`trigger-integration-tests-workflow` command triggers workflow using wrong user account

Hi.

It looks like the trigger-integration-tests-workflow command always uses the same user for the new workflow - the one corresponding to the CIRCLE_TOKEN which as it looks like is the token of the person who created the project initially. So if any other user (not the one who created a project initially) creates a PR and runs a workflow they see different users for the main workflow and the second "integration test" workflow that looks counter-intuitive.

In the end this creates vision that two different users ran the workflows sequentially which is not true

Is it possible to use the CircleCI token of the user who runs the first workflow to trigger the second one?

Add the ability to validate orbs that use a private dependent orb

Describe Request:

Currently, the "orb-tools/pack" workflow fails when using a private orb as a dependency during the "validate" step in the workflow. I would like to add the ability to either skip validation or add an option for a private circle token to allow for validation of the orb.

Examples:

circleci orb validate /path/to/orb.yml --token ${CIRCLE_TOKEN} should be able to validate orbs that depend on private orbs. Also, the previous versions of the orb before v11 did have the ability to skip validation, though it would be preferable to just pass the token in so the orb could still be validated.

Supporting Documentation Links:

Here is the v10 version of the "orb-tools" orb that had a "validate" option: https://circleci.com/developer/orbs/orb/circleci/orb-tools?version=10#jobs-pack

Conditional steps are not reviewed by RC008, RC009

Orb version:

v11.1.0

What happened:

First described in #128 by @wyardley, run-steps within conditional steps are not checked by RC008 and RC009

Expected behavior:

This is expected to fail RC008 and RC009

steps:
  - checkout
  - restore-deps
  - run: npm run thing1
  - when:
      condition: << parameters.run-thing2 >>
      steps:
        run: npm run thing2

Additional Information:

False positive result for `trigger-integration-dev` job on PRs from fork

Orb version:

10.0 (https://github.com/CircleCI-Public/Orb-Project-Template/blob/e388c329da98fba7ede5f7226b6aacb0b9eec185/.circleci/config.yml#L6)

What happened:

When working on a orb following the Orb-Project-Template, and opening a PR from a fork, the test-pack workflow will succeed including the trigger-integration-dev command. However, the integration-test_deploy workflow will not actually be triggered.

Logs of the last step (Trigger integration test workflow) are as follows:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   138  100    36  100   102    160    453 --:--:-- --:--:-- --:--:--   613
Pipeline triggered!
https://app.circleci.com/jobs/gh/<myOrg>/<myOrb>/null

CircleCI received exit code 0

Note the null at the end of the link.

Expected behavior:

Best case would be to work with forks.

Second best case if not possible would be to fail with a message saying that PR from forks are not supported.

Additional Information:

Feel free to contact me if more details are required.

dev-promote-prod-from-git-tag orb job should allow for user provided versions

One of the difficulties I have been facing with the orb-tools dev-promote-prod-from-git-tag job is that I use release-it to generate my github releases, and create git tags and have that integrated into my workflows.

It would be nice to be able to provide a parameter to the dev-promote-prod-git-tag job to allows the user to provide their own version

Example:

...
workflows:
   release:
      jobs:
        - create-release: # Calls Release-it to generate github release, and git tag
            filters:
              branches:
                only: master
              tags:
                ignore: /.*/
   deploy:
      jobs:
        - orb-tools/dev-promote-prod-from-git-tag:
            orb-name: <my-org>/<my-orb>
            add-pr-comment: false
            version: ${CIRCLE_TAG} # <-- Something like this
            filters:
              tags:
                only:
                  - /^v*[0-9]+.[0-9]+.[0-9]+$/
              branches:
                ignore: /.*/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.