Conditional steps using when

Hello folks,

I’m trying to run some conditional steps using when to control when running or not a deployment step on my workflow as folllow.

version: 2.1

workflows: 
  ci-cd-production:
    jobs:
      - build
      - deploy:
          requires:
            - build

jobs:

  build:
    docker: 
      - image: cimg/node:lts-browsers
    steps:
      - checkout
      - run: echo "Run build Job"

  deploy:
    docker: 
      - image: cimg/node:lts-browsers
    steps:
      - run:
          name: 'Checks if its a Pull Request (PR)'
          command: |
            if [ -n "$CIRCLE_PULL_REQUEST" ]; then
              isPullRequest=true
            else
              isPullRequest=false
            fi
            echo isPullRequest: $isPullRequest
            echo export ISPULLREQUEST=$isPullRequest >> "$BASH_ENV"
      - when:
          condition: 
            equal: [ true, $isPullRequest ]
          steps:
            - run: echo "DEPLOY NOT EXECUTED"
      - when:
          condition:
            equal: [ false, $isPullRequest ]
          steps:
            - run: echo "DEPLOYING APPLICATION..."

For some reason my when condition to identify if it’s a PR or not is not working.
Both conditions true and false are not executed when the workflow is loaded.

Anyone has any hint to help?

Thanks in advance,

Hi @rsorelli-hedgepoint ,

The when condition expression will not evaluate runtime environment variables.
As such the above expressions will unfortunately not work.

You can however rely on simple bash if-else expression then.

- run: |
   if [ … ]; then
     echo true
   else
     echo false
   fi

Hope that clarifies your question :slight_smile:

Hi @kelvintaywl ,

Thanks for your reply and explanation.
Considering your points, is there any way I can trigger a step or even a workflow when it’s a PR or not a PR.

Long story short what I meant to do is:

if it’s a PR, than run build and test
if it’s not a PR, than run build, test and deploy

Best regards,

Which repo platform are you using as there are a number of parameters set based on the repo that you can use in condition statements as these are known at the time that the circle.yml script is processed.

 https://circleci.com/docs/pipeline-variables/

Depending on how you are using the repo and what processes you have in place using tags to pass information to the circleci script is quite common.

Hi @rit1010 ,

I’m using Github.

AFAIK according to CicleCI documentation the way to identify a pull request is thru the CIRCLE_PULL_REQUEST environment variable.

That’s why I’m recovering it from a “run command” and trying to use to manage the workflow/step execution. But as mentioned by kelvin it can’t be done.

I need to find a workarround to manage that and fit to my CI/CD pipeline.

Thanks,

Also, there is another possible option, but I have never had a need to try it so my knowledge is limited.

Circleci has continuation and dynamic-continuation orbs which allow the execution of a circleci yml script via the API. These would allow a simple main config.yml script to pull any environment variables you need to process into a parameter list that is then passed onto the yml script that does all the real work. As the values are available as parameters at the time the script is processed they should be useable in conditional commands.

Interesting point !
I’ll read the documentation and try to figure out how it can help in my scenario.

Thanks !

The best part of the docs can be found here

One thing I do know after a bit of playing around is when using the parameters parameter the JSON object is in fact a JSON object within a JSON string - so you put it in single quotes.

1 Like

May I make a suggestion?
I think you’re maybe overcomplicating it a little, and I also don’t think there’s a way to “fix” the above to work the way I think you want it to.

Also, if you don’t have “only build pull requests” set, you could also run into a deploy when someone pushes a commit to a random branch without making a PR, which I doubt you want? Do you have a large number of possible branches that could be getting deployed off of, and if so, do the branchnames have a predictable pattern?

IMO, your best bet is to deploy off either a cut tag, or on push to one or more branches or branch patterns. Then you can do something like

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - checkout
      - lint:
          requires:
            - checkout
      - build:
          requires:
            - checkout
      - deploy:
          requires:
            - lint
            - build
          # Only deploy on pushes to "main" and "develop" branches
          filters:
            branches:
              only:
                # Note: filters for branches or tags can also be regexes, so 
                # you can get pretty elaborate here
                - main
                - develop

A better in some ways, but slightly more complex, option, would be to have something like semantic-release that runs on pushes to main, and cuts a tag when a release is needed, then have a separate workflow that deploys off that tag once it’s cut.

Is there a reason something like that won’t work for you?

All that said, I think even if you want to go the original route, it might be easier to have a single deploy step and have that in an if condition based directly on CIRCLE_PULL_REQUEST vs trying to define and redefine 3-4 different env vars (none of which will be accessible to Circle when it runs that conditional logic). That will work, whereas I could be wrong, but pretty sure the when condition (which IIRC is evaluated before your job even runs) won’t have any env vars (whether they’re in $BASH_ENV or not) in scope / available.

So, again, I personally wouldn’t recommend this, and see suggestions above, but something like this might work.

  deploy:
    steps:
      - run:
          name: deploy
          command: |
            if [ -n "$CIRCLE_PULL_REQUEST" ]; then
              echo "Not deploying"
            else
              echo "Deploying..."
              do some other stuff here
            fi              

In theory, you could use pipeline parameters (Project values and variables - CircleCI), however pipeline.trigger_parameters.circleci.event_type seems to be GitLab specific, so depending on your VCS provider, this might not be an option.

1 Like

@wyardley

Thanks for your sugestion.
Filtering by branch worked like a charm.
I really appreciate your support and time.

Best,

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.