Proposals for CI job inputs

Problem

With the introduction of Pipeline inputs as well as the existing include:inputs there seem to be a need for job-level inputs to be defined. Issues like https://gitlab.com/gitlab-org/gitlab/-/issues/527952+ are an example of how users want to pass input data to a job.

Today we use variables for overriding data but the problem with variables is that they can be arbitrary. Instead a job should define what inputs can receive at runtime and any other unexpected inputs should be rejected.

Example: when running a manual job and passing variables, a user is essentially passing some input data.

The current approach of using variables does not provide a consistent UX:

  • only variables with description field are displayed in the UI when running a manual job.
  • the list of variables above are not the only inputs that can be passed because any other arbitrary variables can be passed at runtime.

Questions

  • What type of inputs are normally passed to jobs at runtime?
  • If passing inputs to a job being retried, what did the previous values for those inputs/variables came from? Did they come from pipeline inputs or predefined variables?

Requirements

At the very minimum we should:

  1. Not allow arbitrary variables. The list of inputs/variables to be passed to a job should be explicitly defined. Inputs not defined should cause an error.

Related features

We need to ensure that job-level inputs can work seamlessly with CI steps inputs, include:inputs and Pipeline Inputs.

Proposal 1

MVP

Users can use arguments in their CI jobs alongside the variables they already use

test_job:
  arguments:
    test_echo: "echo me"
    test_file_path: $APP_TEST_PATH
  script:
    - echo "%[[ arguments.test_echo ]]"
    - rspec %[[ arguments.test_file_path ]]

When retrying the job, we'll have a form for the keys and values of the job arguments. The keys will be pre-populated with the job argument names. The values will be pre-populated with the job argument values from the first job run, and can be modified by the user.

Future iterations of Proposal 1

We give users the option to restrict jobs so they only have access to their arguments. Any variable values they want to use must be passed in as an argument. This will make job definitions easier to debug and more secure.

We also introduce outputs, which can be used to pass values between jobs. We could also make it possible to set artifacts as argument values.

build_job:
  script:
    - export TEST_VAR="test value"
    - touch test_file.rb
  artifacts:
    - name: test_file # we can use artifacts with arguments if we have a name to reference them with
      paths:
        - test_file.rb
  outputs:
    - value_for_test_job: $TEST_VAR # we can allow outputs to access variables defined in the job script

test_job:
  arguments:
    project_path: $PROJECT_PATH
    test_echo: outputs.build_job.value_for_test_job
    test_file: artifacts.build_job.test_file
  script:
    - rspec %[[ arguments.test_file ]]
    - echo "%[[ arguments.test_echo ]]"
    - echo "%[[ arguments.project_path ]]"
    - echo $PROJECT_PATH # nil because it is not passed in as an argument

Proposal 2

spec:
  inputs:
    compiler:
      default: gcc
    test_framework:
      default: unittest

---

job:
  script:
    - Compiling with $[[ inputs.compiler ]] and testing with $[[ job_inputs.test_framework ]]
  inputs: # can't be used to define attributes like job name, etc.
    test_framework:
      default: $[[ inputs.test_framework ]]

When interpolating this on the pipeline creation step:

  • first, we'll interpolate inputs as usual.
  • then, store the job YAML as it is.
  • then, interpolate job_inputs with defaults.

When retrying the job via the inputs form:

  • we'll list the inputs for the job.
  • when submitting the form, we'll re-interpolate the job with the inputs using the stored YAML.

Open questions/concerns:

  1. We should limit the usage of job_inputs in specific parts of the job. For example, it should not be used for building the job name or other static attributes.
Edited by Avielle Wolfe