Search code examples
gitlab-ci

Gitlab CI does not support variable expansion in needs keyword, is there any solution?


I'm creating a template for all the deploy jobs, and I need to be able to use needs keyword with different values for each deploy job, but GitLab CI, as far as I know, does not support using variable in needs keyword. Is there any workaround?

This is what I need to do:

# Deploy template
.deploy:
  stage: deploy
  only:
    - develop
  tags:
    - deploy
  needs: ["build:$PROJECT_NAME"]


# Deploy jobs

deploy:package1:
  extends: .deploy
  variables:
    PROJECT_NAME: 'package1'
  #needs: ['build:package1']

deploy:package2:
  extends: .deploy
  variables:
    PROJECT_NAME: 'package2'
  #needs: ['build:package2']

Solution

  • To anyone that still comes across this thread, there does now seem to be a solution that is working for me to use variables in the needs keyword(supported as of v15.11, currently on v16.7.6 when writing this). It requires the use of inputs. In my workflow, I have, "build-{env}-image", "deploy-{env}", dast_scan(manual), and "stop-{env}" jobs. {env} changes with the branch name. Each job needs the previous to ensure proper workflow and to allow the stop job to run in case the team didn't need to run dast_scan.

    First, I setup the spec header as follows:

    spec:
      inputs:
        env:
          default: "$CI_COMMIT_REF_SLUG"
    
    ---
    
    {Rest of yaml file}
    

    The job names are then defined as follows:

    build_$[[ inputs.env | expand_vars ]]_image:
      stage: build
      script:
        - "Build image script"
    

    The | expand_vars is only required if you are using variables in the spec like I have above. GitLab's docs talk more about the ability to use functions to manipulate strings as needed.

    The other jobs with "needs" has to use the needs:job syntax in order to use the inputs. This doesn't seem to work with the needs: ["job_name"] syntax.

    deploy_$[[ inputs.env | expand_vars ]]:
      stage: deploy
      script:
        - "Deploy script"
      needs:
        - job: build_$[[ inputs.env | expand_vars ]]_image
    

    I hope this helps anybody else. It took me a while to find and properly implement this like I want.

    Last note: The "inputs" feature also works with the environment:on_stop keyword.

    deploy_$[[ inputs.env | expand_vars ]]:
      environment:
        name: $ENVIRONMENT_NAME
        on_stop: stop_$[[ inputs.branch-slug | expand_vars ]]
    
    stop_$[[ inputs.env | expand_vars ]]:
      environment:
        name: $ENVIRONMENT_NAME
        action: stop