Search code examples
bashshellcurlescapingampersand

cURL escape & (ampersand) in data


I wrote a script to run with GitLab CI and update badges, but I'm not getting it right. Here is the function:

vuejs_version() {

    vuejs_version='x.y.z'

    vuejs_badge_id=$(curl --header "PRIVATE-TOKEN:$BADGE_TOKEN" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/badges" | jq -c 'map(select(.name | contains("vuejs")))[0].id')

    response=$(curl --request PUT --header "PRIVATE-TOKEN:$BADGE_TOKEN" \
       --data "image_url=https://img.shields.io/static/v1?label=VueJs&message=$vuejs_version&color=orange" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/badges/$vuejs_badge_id")

    echo "cURL response: $response"

}

Then my response:

{
  "name":"vuejs",
  "link_url":"https://gitlab.com/%{project_path}/-/commits/%{default_branch}",
  "image_url":"https://img.shields.io/static/v1? label=VueJs",
  ...
}

As the response, image_url was missing args:

"image_url":"https://img.shields.io/static/v1? label=VueJs"

but it should be like:

'https://img.shields.io/static/v1?label=VueJs&message=x.y.z&color=red'


Solution

  • As Mr R answered, --data-urlencode works like a charm;

    also, i created a variable with data and url strings:

    vuejs_version() {
    
        vuejs_version='x.y.z'
    
        vuejs_badge_id=$(curl --header "PRIVATE-TOKEN:$BADGE_TOKEN" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/badges" | jq -c 'map(select(.name | contains("vuejs")))[0].id')
    
        data=$(echo "image_url=https://img.shields.io/static/v1?label=VueJs&message=${vuejs_version}&color=red" | sed -e "s/ //g")
        url=$(echo "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/badges/$vuejs_badge_id")
    
        response=$(curl --request PUT --header "PRIVATE-TOKEN:$BADGE_TOKEN" \
            --data-urlencode ${data} ${url})
    
        echo "cURL response: $response"
    
    }