diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md index 6db90fa294ca682341c620c5d7942ec585a27457..95423f05486f33c26522a625ae5c71ac7d5b5e83 100644 --- a/doc/api/pipelines.md +++ b/doc/api/pipelines.md @@ -386,6 +386,7 @@ Sample response: {{< history >}} - `iid` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/342223) in GitLab 14.6. +- `inputs` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/519958) in GitLab 17.10 [with a flag](../administration/feature_flags.md) named `ci_inputs_for_pipelines`. Disabled by default. {{< /history >}} @@ -398,11 +399,24 @@ POST /projects/:id/pipeline | `id` | integer/string | Yes | The ID or [URL-encoded path of the project](rest/_index.md#namespaced-paths) | | `ref` | string | Yes | The branch or tag to run the pipeline on. For merge request pipelines use the [merge requests endpoint](merge_requests.md#create-merge-request-pipeline). | | `variables` | array | No | An [array of hashes](rest/_index.md#array-of-hashes) containing the variables available in the pipeline, matching the structure `[{ 'key': 'UPLOAD_TO_S3', 'variable_type': 'file', 'value': 'true' }, {'key': 'TEST', 'value': 'test variable'}]`. If `variable_type` is excluded, it defaults to `env_var`. | +| `inputs` | hash | No | A [hash](rest/_index.md#hash) containing the inputs, as key-value pairs, to use when creating the pipeline. | + +Basic example: ```shell curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/pipeline?ref=main" ``` +Example request with [inputs](../ci/yaml/inputs.md): + +```shell +curl --request POST \ + --header "Content-Type: application/json" \ + --data '{"inputs": {"environment": "environment", "scan_security": false, "level": 3}}' \ + --header "PRIVATE-TOKEN: <your_access_token>" \ + "https://gitlab.example.com/api/v4/projects/1/pipeline?ref=main" +``` + Example of response ```json diff --git a/lib/api/ci/helpers/pipelines_helpers.rb b/lib/api/ci/helpers/pipelines_helpers.rb index c558166a4cfb41cf0de9db567ebb5139f3cd6e79..688ce58a34e662ea247cb172bc8ead27fc6769d6 100644 --- a/lib/api/ci/helpers/pipelines_helpers.rb +++ b/lib/api/ci/helpers/pipelines_helpers.rb @@ -33,6 +33,7 @@ module PipelinesHelpers values: ::Ci::PipelineVariable.variable_types.keys, default: 'env_var', desc: 'The type of variable, must be one of env_var or file. Defaults to env_var' end + optional :inputs, type: Hash, desc: 'The list of inputs to be used to create the pipeline.' end end end diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb index 2dfb703bfad2132f09ecf50149c8337241e7f9a4..a20ff1ff2f7fe6803e45579ecb5ae14422b64ed3 100644 --- a/lib/api/ci/pipelines.rb +++ b/lib/api/ci/pipelines.rb @@ -88,10 +88,10 @@ class Pipelines < ::API::Base pipeline_params = declared_params(include_missing: false) .merge(variables_attributes: params[:variables]) - .except(:variables) + .except(:variables, :inputs) response = ::Ci::CreatePipelineService.new(user_project, current_user, pipeline_params) - .execute(:api, ignore_skip_ci: true, save_on_errors: false) + .execute(:api, ignore_skip_ci: true, save_on_errors: false, inputs: params[:inputs]) new_pipeline = response.payload if response.success? diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb index 999b0b5aeebce896e7276cff2893cfa6acb2b5ff..9a26b0e3c3256be9341861ef7f476a1923fad13c 100644 --- a/spec/requests/api/ci/pipelines_spec.rb +++ b/spec/requests/api/ci/pipelines_spec.rb @@ -835,6 +835,70 @@ def expect_variables(variables, expected_variables) end end + context 'with gitlab-ci.yml including inputs' do + let(:inputs) do + { + deploy_strategy: 'blue-green', + job_stage: 'deploy', + test_script: ['echo "test"'], + parallel_jobs: 3, + allow_failure: true, + test_rules: [ + { if: '$CI_PIPELINE_SOURCE == "web"' } + ] + } + end + + before do + stub_ci_pipeline_yaml_file( + File.read(Rails.root.join('spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml')) + ) + end + + shared_examples 'creating a succesful pipeline' do + it 'creates a pipeline using inputs' do + expect { post_request }.to change { Ci::Pipeline.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + + pipeline = Ci::Pipeline.find(json_response['id']) + + expect(pipeline.builds.map { |b| "#{b.name} #{b.allow_failure}" }).to contain_exactly( + 'my-job-build 1/3 false', 'my-job-build 2/3 false', 'my-job-build 3/3 false', + 'my-job-test true', 'my-job-deploy false' + ) + end + end + + context 'when passing parameters as JSON' do + let(:headers) do + { 'Content-Type' => 'application/json' } + end + + subject(:post_request) do + post api("/projects/#{project.id}/pipeline", user), + headers: headers, + params: { ref: project.default_branch, inputs: inputs }.to_json + end + + it_behaves_like 'creating a succesful pipeline' + end + + context 'when passing parameters as form data' do + let(:headers) do + { 'Content-Type' => 'application/x-www-form-urlencoded' } + end + + subject(:post_request) do + post api("/projects/#{project.id}/pipeline", user), + headers: headers, + params: { ref: project.default_branch, inputs: inputs.transform_values(&:to_json) } + end + + it_behaves_like 'creating a succesful pipeline' + end + end + context 'without gitlab-ci.yml' do context 'without auto devops enabled' do before do