JSON string as input parameter gets stripped from double quotes

Problem to solve

I’m in the process of developing a GitLab component. The component has an input parameter of type string and I want to set it to a JSON String submitting a complex value to the component.

Unfortunately in all my tryouts the GitLab CI strips all double quotes of the JSON string making it unusable from inside the component.

Is there any way to let the JSON String untouched. So far I tried YAML variants of single line with single quotes, multi line with single quotes and unquoted JSON string.

Steps to reproduce

  1. Define a component with an input of type string.
  2. Use it in a GitLab pipeline with a JSON string as concrete parameter.
  3. Try to use it in the component.

Configuration

The relevant part of the CI Pipeline looks like this:

include:
  - local: "/src/main/ci/templates/subst/subst.yaml"
    inputs:
      subst-context: '[ { "inputFile": "src/main/helm/feature/weblate/values.yaml", "outputFile": "target/helm/weblate/values.yaml" } ]'
      target-path: target

The component looks like this:

# Substitutes placeholders in files with environment variables

spec:
  inputs:
    stage:
      description: Optional stage of the job
      type: string
      default: subst

    subst-context:
      description: "An JSON array with input and output files to process"
      type: array

    target-path:
      description: "The path where the substituted files are written to"
      type: string

    depends-on:
      description: "Optional job dependencies"
      type: array
      default: []

---
subst-job:
  stage: $[[ inputs.stage ]]
  needs: $[[ inputs.depends-on ]]
  script: |
    # Check if input is a valid JSON array
    echo "Received subst-context: $[[ inputs.subst-context ]]"
    echo "$[[ inputs.subst-context ]]" | jq 'if (type != "array") then error("Input is not an array") end'

Versions

Please select whether options apply, and add the version information.

  • Self-managed
  • GitLab.com SaaS
  • Dedicated
  • Self-hosted Runners

Versions

  • GitLab v18.1.2 Community Editon
  • GitLab Runner, self hosted

I found one solution that might not be optimal, but its working. The hint I’ve found is from the Array Types Documentation part of the GitLab documentation about CI/CD inputs.

It reads:

The content of the items in an array type can be any valid YAML map, sequence, or scalar. More complex YAML features like !reference cannot be used. When using the value of an array input in a string (for example echo "My rules: $[[ inputs.rules-config ]]" in your script: section), you might see unexpected results. The array input is converted to its string representation, which might not match your expectations for complex YAML structures such as maps.

And:

Array inputs must be formatted as JSON, for example ["array-input-1", "array-input-2"], when manually passing inputs for:

So changing the input type to array does the job, although it is not that obvious.

In my code, and I will show only relevant parts, I use the spec now like that:

spec:
  inputs:
    subst-context:
      description: "A JSON array with input and output files to process"
      type: array

---
subst-job:
  script: |
    # Check if input is a valid JSON array
    echo "Input subst-context is: '$[[ inputs.subst-context ]]'"
    echo "$[[ inputs.subst-context ]]" | jq 'if (type != "array") then error("Input subst-context is not an array") else null end'

And the job definition in `.gitlab-ci.yml`:

include:
   - local: "src/main/ci/templates/subst/subst.yaml"
    inputs:
      subst-context: [ '{ "inputFile": "src/main/helm/feature/weblate/values.yaml", "outputFile": "target/helm/weblate/values.yaml" }' ]
      target-path: target
      depends-on:
        - prepare-job

Notice the escaping of the only element of the YAML array with single quotes. That will lead to transmitting the element as a JSON string to the component.