How to test multiple versions by triggering jobs with a shell function


#1

UPDATE 2017-06-20: With the introduction of Workflows, this workaround is no longer necessary - see the updated example below: How to test multiple versions by triggering jobs with a shell function and the Workflows documentation

If you want to trigger multiple jobs from an initial build job on CircleCI 2.0 Beta you can do so using a shell function.

This is useful if you want to test against different versions of a language or database. A nice benefit of doing this with jobs on 2.0 is that each job will report to GitHub or BitBucket with it’s status so you can see which versions passed or failed like this:

Note: In the future we will introduce a more elegant solution for managing multiple jobs. We’re posing this for people who will find it useful while we’re in Beta with CircleCI 2.0.

Preparation: Before you can run the following example, you’ll need to create an API token for your project with ‘All’ permissions in the CircleCI > API Permissions screen. Then you need to add this token as an environment variable called $CIRCLE_API_TOKEN in the Environment Variables screen.

Example config: (adapt to taste)

version: 2
jobs:
  build:
    working_directory: ~/your_project
    docker:
      - image: python:3.6.0
    steps:
      - checkout
      - run:
            name: Trigger Jobs
            command: |
              # a similar function will liekly get built in into the circleci cli 
              function trigger_job() {
                job_name=$1
                curl -u ${CIRCLE_API_TOKEN}: \
                  -d build_parameters[CIRCLE_JOB]=${job_name} \
                  -d revision=$CIRCLE_SHA1 \
                  https://circleci.com/api/v1.1/project/github/your_org/your_project/tree/$CIRCLE_BRANCH
              }      
              trigger_job build-python27
              trigger_job build-python35
              trigger_job build-python36
      - deploy:
          name: Echo
          command: echo "I would deploy here"

  # here are our jobs with different Python versions
  build-python27:
       docker:
         - image: python:2.7.13 
       working_directory: ~/your_project
       steps:
         - run: echo "hello python 2.7.13"
  
  build-python35:
       docker:
         - image: python:3.5.3 
       working_directory: ~/your_project
       steps:
         - run: echo "hello python 3.5.3"
  
  build-python36:
       docker:
         - image: python:3.6.0
       working_directory: ~/your_project
       steps:
         - run: echo "hello python 3.6.0"

Note re: deploy step: In this example it might look like the deploy step will only run if the triggered jobs are successful. This is not the case, the deploy step will always run. Please see our docs for a conditionally triggering jobs. You could combine both these examples to get more fine-grained control. As mentioned above, we’ll make it easier to manage this kind of workflow with future updates to 2.0.


Multiple PHP Environments
Trigger different jobs from GitHub
Git status checks for multiple CircleCI projects
Trigger build via webhook
Parallel jobs with different base images
#2

Awesome!
But the steps of each build are exactly same in my situation.
Can I avoid the duplication?
I just want to run same steps in multiple Node.js versions like travis-ci.


#3

Maybe advanced YAML would help here https://en.wikipedia.org/wiki/YAML#Advanced_components


#4

Thanks! YAML has a awesome feature!

It works in CircieCI 2.0.


https://circleci.com/gh/teppeis-sandbox/circleci-multiple-versions/27


#5

Glad to hear that worked - and thanks for sharing your config file :slight_smile:


#6

Does this work with private project builds? I tried using the example and doing a cURL request to https://circleci.com/api/v1.1/project/github//$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/tree/$CIRCLE_BRANCH returns a json payload saying the project isn’t found. And if I do https://circleci.com/api/v1.1/project/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/tree/$CIRCLE_BRANCH I just get back the HTML for what looks like the homepage


#7

It’ll work as long as your $CIRCLE_TOKEN is valid for that repo.


#8

Should I be using $CIRCLE_API_TOKEN or $CIRCLE_TOKEN?


#9

Nevermind, I was missing the key step of setting the variable myself. Forgot the token wasn’t available automatically


#10

We are enabling first class support for running multiple jobs for CircleCI 2.0. Right now we are adding only limited number of customers. If you are interested in trying out, please reach out at beta+workflows@circleci.com with your VCS organization and repository name. Thanks!


#11

I got error “Permission denied”.

My test repository is public.
https://circleci.com/gh/n0ts/practice-circleci/270#tests/containers/0

I configured CIRCLE_API_TOKEN environment variable.

Thanks,


#12

Can you SSH in and try that manually? It worked for me when I tried manually from my local machine;

https://circleci.com/gh/n0ts/practice-circleci/359


#13

Thanks for reply.

Sorry, I missed that add CIRCLE_API_TOKEN…

I used POST method.
https://circleci.com/gh/n0ts/practice-circleci/370

And I have a one question.

Is it possible override environments?

For example,

  build-common: &common-build
    docker:
      - image: n0ts/ubuntu

    environment:
      BAR: foo

    steps:
      - run:
          command: |
            echo $BAR => BAR is hoge...

  build-test-1:
    <<: *common-build
    docker:
      - image: n0ts/ubuntu-java

    environment:
      BAR: hoge

Thanks.


#14

Yes that’s possible today.


#15

With the recent introduction of Workflows, this seems like a good candidate for this feature.

.circleci/config.yml example

version: 2
jobs:
  build-python27:
    docker:
      - image: python:2.7.13
    working_directory: ~/your_project
    steps:
      - run: echo "hello python 2.7.13"
  build-python35:
    docker:
      - image: python:3.5.3
    working_directory: ~/your_project
    steps:
      - run: echo "hello python 3.5.3"
  build-python36:
    docker:
      - image: python:3.6.0
    working_directory: ~/your_project
    steps:
      - run: echo "hello python 3.6.0"

workflows:
  version: 2
  build:
    jobs:
      - build-python27
      - build-python35
      - build-python36

PR display

See more details about Workflows in the docs.


#16

Thanks for the updated example. You’re correct - workflows is the way to go for this now :slight_smile:

I’m closing this topic now. Please feel free to open new topics on workflows and build matrix type behaviour.


#17