cUrl Post Request in CI/CD Pipeline

Hi,

I am currently trying to call an API from a CI/CD pipeline.
I’ve been able to run a GET request but found out that I’d like to pass some metadata as well with a POST request

I’m almost there, but I’ve been stuck with CI/CD not reading/accessing the pipeline variables as I hoped.

Working GET and POST request is structured like this:

auto_deploy:
  stage: auto_deploy
  only:
    - test-qa
  script:
     - 'curl --request GET -H "ApiKey: $ApiKeyQA" -H "Deploytoken: $QA_DEPLOY_TOKEN" "$QA_DEPLOY_SERVICE_URL""$CI_PROJECT_NAME/"'

    - curl --request POST -H "ApiKey:$ApiKeyQA" -H "Deploytoken:$QA_DEPLOY_TOKEN" -H "Content-Type:application/json" -d '{ "environment":"qa", "repo_name":"$CI_PROJECT_NAME", "pr_message":"$CI_COMMIT_TITLE" }' $QA_DEPLOY_URL_POST

They both currently run and work, but the CI variables in the POST request are " $ci_project_name and $CI_COMMIT_TITLE", when I read it on the API side meaning they are not read/accessed correctly in the pipeline.

I’ve tried many variations and tried to Google around, but have not found any viable solutions yet. Would appreciate some feedback!

Thanks,
Anton

Hey Anton,

Could you try writing your variables in the JSON part of your request as ${CI_PROJECT_NAME} - note the curly brackets?

E.g.

'{ "environment":"qa", "repo_name":"${CI_PROJECT_NAME}", "pr_message":"${CI_COMMIT_TITLE}" }'

Kind regards,
Paula

I did that and it seems like the API is getting just the dollar sign $, I’ll have to debug to see what the payload is currently

Hello,
I’m having the exact same problem, I don’t know how to expand CI variables inside a POST request data field.
What I’m trying to do more specifically is to automate a release each time a tag is created. I would like to use only the $CI_COMMIT_TAG as parameter for “tag_name” field but it seems like it is not correctly interpolated inside the command. Indeed the API asks for a “ref” parameter.
Here’s my CI conf file:

release_job:
  stage: deploy
  image: curlimages/curl:latest
  script:
    - |
      curl --header 'Content-Type: application/json' --header "JOB-TOKEN: $CI_JOB_TOKEN" \
           --data '{"tag_name": "${CI_COMMIT_TAG}"}' \
           --request POST "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases"
      echo "Created release $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG

The echo command works fine and prints the tag name correctly. This is the job’s output:

{"message":"Ref is not specified"}Created release rel4.18

What am I doing wrong?

Thank you so much!

Hi @gblangiardi ,

Interesting.

TBH, I’m not sure how is curl expanding those variables inside json… usually it needs bunch of quoting and escaping…

But, could you perhaps try the following:

release_job:
  stage: deploy
  image: curlimages/curl:latest
  script:
    - |
      curl --header 'Content-Type: application/json' --header "JOB-TOKEN: $CI_JOB_TOKEN" \
           --data tag_name=${CI_COMMIT_TAG} \
           --request POST "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases"
      echo "Created release $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG

curl should automatically translate this into json with that field name because you specified the Content-Type in the header.

Hello @paula.kokic,
thanks for the reply.
Unfortunately, trying to pass fields the way you suggested yields to a “Bad Request” error.
I’m running out of ideas, perhaps you know if there’s an easier way to automate releases when a tag is pushed?

Thanks for the help.

Yes, GitLab actually has quite a nice solution with their Release CLI tool. Have a look at the example in the docs.

P.S. There are two ways to use the CLI. One is using the built-in yaml fields, and second is using the tool in the bash, like a regular cli. For both ways you can use the same docker image registry.gitlab.com/gitlab-org/release-cli:latest :slight_smile:

P.P.S. Yes, the Release CLI is deprecated, but I am not sure if the successor supports creating releases yet.