Gitlab CICD: use functions inside gitlab-ci.yml
Asked Answered
P

3

6

I have a .gitlab-ci.yml file which allows needs to execute the same function for every step. I have the following and this works.

image:
  name: hashicorp/terraform

before_script: 
  - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")

stages:
  - validate
  - plan

validate:
  stage: validate
  script:
    - terraform validate
    - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - terraform validate
    - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
  variables:
    msg: "Example2"

Given it is always the same curl command, I wanted to use a function which I declare once and can use in every step. Something along the lines of below snippet.

image:
  name: hashicorp/terraform

before_script: 
  - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")

.send_message: &send_message
  script:  
  - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'

stages:
  - validate
  - plan

validate:
  stage: validate
  script:
    - terraform validate
    - &send_message
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - terraform validate
    - &send_message
  variables:
    msg: "Example2"

How could I use such a function in a .gitlab-ci.yml file.

Pampero answered 1/12, 2021 at 15:33 Comment(0)
S
14

you can used include with !reference such as:

  • functions.yml
.send_message:
  script:  
  - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
  • .gitlab-ci.yml
include:
  - local: functions.yml

default:
  image:
    name: hashicorp/terraform
  before_script: 
    - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")

stages:
  - validate
  - plan

validate:
  stage: validate
  script:
    - terraform validate
    - !reference [.send_message, script]
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - terraform validate
    - !reference [.send_message, script]
  variables:
    msg: "Example2"

ref: https://docs.gitlab.com/ee/ci/yaml/yaml_optimization.html#reference-tags

Southward answered 1/12, 2021 at 17:11 Comment(1)
This was exactly what I was looking for. Works perfect!Pampero
M
8

You can also use a regular old bash function defined at the top:

before_script: 
  - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")
  - send_bearer () { terraform validate; curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $1" https://api.teams.com/v1/messages; }

...

validate:
  stage: validate
  script:
    - send_bearer $msg
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - send_bearer $msg
  variables:
    msg: "Example2"
Maida answered 11/5, 2022 at 15:3 Comment(1)
Just pointing out that if before_script is overridden in a job, it won't have that function definition anymore.Ferris
G
1

you can also define more complex function in fn_init section like below:

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - echo "before call function"
    - list_files
    - echo "after call function"
  only:
    - main

.fn_init: &fn_init |
  export CI_APPLICATION_REPOSITORY=$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG
  export CI_APPLICATION_TAG=$CI_COMMIT_SHA

  function list_files() {
    echo 'from my function'
  }

before_script:
- *fn_init
Gerek answered 11/6 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.