diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 011c51ec120a..b915e9a88502 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -5994,7 +5994,7 @@ components: description: Request object. properties: data: - $ref: '#/components/schemas/CIAppCreatePipelineEventRequestData' + $ref: '#/components/schemas/CIAppCreatePipelineEventRequestDataSingleOrArray' type: object CIAppCreatePipelineEventRequestAttributes: description: Attributes of the pipeline event to create. @@ -6030,6 +6030,16 @@ components: type: $ref: '#/components/schemas/CIAppCreatePipelineEventRequestDataType' type: object + CIAppCreatePipelineEventRequestDataArray: + description: Array of pipeline events to create in batch. + items: + $ref: '#/components/schemas/CIAppCreatePipelineEventRequestData' + type: array + CIAppCreatePipelineEventRequestDataSingleOrArray: + description: Data of the pipeline events to create. + oneOf: + - $ref: '#/components/schemas/CIAppCreatePipelineEventRequestData' + - $ref: '#/components/schemas/CIAppCreatePipelineEventRequestDataArray' CIAppCreatePipelineEventRequestDataType: default: cipipeline_resource_request description: Type of the event. @@ -51718,6 +51728,9 @@ paths: we support, see [Pipeline Data Model And Execution Types](https://docs.datadoghq.com/continuous_integration/guides/pipeline_data_model/). + Multiple events can be sent in an array (up to 1000). + + Pipeline events can be submitted with a timestamp that is up to 18 hours in the past.' operationId: CreateCIAppPipelineEvent diff --git a/cassettes/features/v2/ci_visibility_pipelines/Send-several-pipeline-events-returns-Request-accepted-for-processing-response.frozen b/cassettes/features/v2/ci_visibility_pipelines/Send-several-pipeline-events-returns-Request-accepted-for-processing-response.frozen new file mode 100644 index 000000000000..8404e45ce422 --- /dev/null +++ b/cassettes/features/v2/ci_visibility_pipelines/Send-several-pipeline-events-returns-Request-accepted-for-processing-response.frozen @@ -0,0 +1 @@ +2025-09-02T15:10:26.479Z \ No newline at end of file diff --git a/cassettes/features/v2/ci_visibility_pipelines/Send-several-pipeline-events-returns-Request-accepted-for-processing-response.yml b/cassettes/features/v2/ci_visibility_pipelines/Send-several-pipeline-events-returns-Request-accepted-for-processing-response.yml new file mode 100644 index 000000000000..daf12b396d94 --- /dev/null +++ b/cassettes/features/v2/ci_visibility_pipelines/Send-several-pipeline-events-returns-Request-accepted-for-processing-response.yml @@ -0,0 +1,26 @@ +http_interactions: +- recorded_at: Tue, 02 Sep 2025 15:10:26 GMT + request: + body: + encoding: UTF-8 + string: '{"data":[{"attributes":{"provider_name":"example-provider","resource":{"end":"2025-09-02T15:09:56.479Z","git":{"author_email":"john.doe@email.com","repository_url":"https://github.com/DataDog/datadog-agent","sha":"7f263865994b76066c4612fd1965215e7dcb4cd2"},"level":"pipeline","name":"Deploy + to AWS","partial_retry":false,"start":"2025-09-02T15:08:26.479Z","status":"success","unique_id":"3eacb6f3-ff04-4e10-8a9c-46e6d054024a","url":"https://my-ci-provider.example/pipelines/my-pipeline/run/1"}},"type":"cipipeline_resource_request"},{"attributes":{"provider_name":"example-provider","resource":{"end":"2025-09-02T15:09:41.479Z","git":{"author_email":"jane.smith@email.com","repository_url":"https://github.com/DataDog/datadog-agent","sha":"9a4f7c28b3e5d12f8e6c9b2a5d8f3e1c7b4a6d9e"},"level":"pipeline","name":"Deploy + to Production","partial_retry":false,"start":"2025-09-02T15:07:26.479Z","status":"success","unique_id":"7b2c8f9e-aa15-4d22-9c7d-83f4e065138b","url":"https://my-ci-provider.example/pipelines/prod-pipeline/run/2"}},"type":"cipipeline_resource_request"}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v2/ci/pipeline + response: + body: + encoding: UTF-8 + string: '{"data":null}' + headers: + Content-Type: + - application/vnd.api+json + status: + code: 202 + message: Accepted +recorded_with: VCR 6.0.0 diff --git a/examples/v2/ci-visibility-pipelines/CreateCIAppPipelineEvent_2836340212.rb b/examples/v2/ci-visibility-pipelines/CreateCIAppPipelineEvent_2836340212.rb new file mode 100644 index 000000000000..cf457abce9c3 --- /dev/null +++ b/examples/v2/ci-visibility-pipelines/CreateCIAppPipelineEvent_2836340212.rb @@ -0,0 +1,52 @@ +# Send several pipeline events returns "Request accepted for processing" response + +require "datadog_api_client" +api_instance = DatadogAPIClient::V2::CIVisibilityPipelinesAPI.new + +body = DatadogAPIClient::V2::CIAppCreatePipelineEventRequest.new({ + data: [ + DatadogAPIClient::V2::CIAppCreatePipelineEventRequestData.new({ + attributes: DatadogAPIClient::V2::CIAppCreatePipelineEventRequestAttributes.new({ + provider_name: "example-provider", + resource: DatadogAPIClient::V2::CIAppPipelineEventFinishedPipeline.new({ + level: DatadogAPIClient::V2::CIAppPipelineEventPipelineLevel::PIPELINE, + unique_id: "3eacb6f3-ff04-4e10-8a9c-46e6d054024a", + name: "Deploy to AWS", + url: "https://my-ci-provider.example/pipelines/my-pipeline/run/1", + start: (Time.now + -120), + _end: (Time.now + -30), + status: DatadogAPIClient::V2::CIAppPipelineEventPipelineStatus::SUCCESS, + partial_retry: false, + git: DatadogAPIClient::V2::CIAppGitInfo.new({ + repository_url: "https://github.com/DataDog/datadog-agent", + sha: "7f263865994b76066c4612fd1965215e7dcb4cd2", + author_email: "john.doe@email.com", + }), + }), + }), + type: DatadogAPIClient::V2::CIAppCreatePipelineEventRequestDataType::CIPIPELINE_RESOURCE_REQUEST, + }), + DatadogAPIClient::V2::CIAppCreatePipelineEventRequestData.new({ + attributes: DatadogAPIClient::V2::CIAppCreatePipelineEventRequestAttributes.new({ + provider_name: "example-provider", + resource: DatadogAPIClient::V2::CIAppPipelineEventFinishedPipeline.new({ + level: DatadogAPIClient::V2::CIAppPipelineEventPipelineLevel::PIPELINE, + unique_id: "7b2c8f9e-aa15-4d22-9c7d-83f4e065138b", + name: "Deploy to Production", + url: "https://my-ci-provider.example/pipelines/prod-pipeline/run/2", + start: (Time.now + -180), + _end: (Time.now + -45), + status: DatadogAPIClient::V2::CIAppPipelineEventPipelineStatus::SUCCESS, + partial_retry: false, + git: DatadogAPIClient::V2::CIAppGitInfo.new({ + repository_url: "https://github.com/DataDog/datadog-agent", + sha: "9a4f7c28b3e5d12f8e6c9b2a5d8f3e1c7b4a6d9e", + author_email: "jane.smith@email.com", + }), + }), + }), + type: DatadogAPIClient::V2::CIAppCreatePipelineEventRequestDataType::CIPIPELINE_RESOURCE_REQUEST, + }), + ], +}) +p api_instance.create_ci_app_pipeline_event(body) diff --git a/features/v2/ci_visibility_pipelines.feature b/features/v2/ci_visibility_pipelines.feature index fa0a20d1d5fd..3c52a30f4b70 100644 --- a/features/v2/ci_visibility_pipelines.feature +++ b/features/v2/ci_visibility_pipelines.feature @@ -17,7 +17,7 @@ Feature: CI Visibility Pipelines When the request is sent Then the response status is 400 Bad Request - @team:DataDog/ci-app-backend + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Aggregate pipelines events returns "OK" response Given a valid "appKeyAuth" key in the system And new "AggregateCIAppPipelineEvents" request @@ -33,7 +33,7 @@ Feature: CI Visibility Pipelines When the request is sent Then the response status is 400 Bad Request - @team:DataDog/ci-app-backend + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Get a list of pipelines events returns "OK" response Given a valid "appKeyAuth" key in the system And new "ListCIAppPipelineEvents" request @@ -44,7 +44,7 @@ Feature: CI Visibility Pipelines When the request is sent Then the response status is 200 OK - @replay-only @skip-validation @team:DataDog/ci-app-backend @with-pagination + @replay-only @skip-java @skip-python @skip-typescript @skip-validation @team:DataDog/ci-app-backend @with-pagination Scenario: Get a list of pipelines events returns "OK" response with pagination Given a valid "appKeyAuth" key in the system And new "ListCIAppPipelineEvents" request @@ -63,7 +63,7 @@ Feature: CI Visibility Pipelines When the request is sent Then the response status is 400 Bad Request - @team:DataDog/ci-app-backend + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Search pipelines events returns "OK" response Given a valid "appKeyAuth" key in the system And new "SearchCIAppPipelineEvents" request @@ -71,7 +71,7 @@ Feature: CI Visibility Pipelines When the request is sent Then the response status is 200 OK - @replay-only @skip-validation @team:DataDog/ci-app-backend @with-pagination + @replay-only @skip-java @skip-python @skip-typescript @skip-validation @team:DataDog/ci-app-backend @with-pagination Scenario: Search pipelines events returns "OK" response with pagination Given a valid "appKeyAuth" key in the system And new "SearchCIAppPipelineEvents" request @@ -101,30 +101,37 @@ Feature: CI Visibility Pipelines When the request is sent Then the response status is 408 Request Timeout - @team:DataDog/ci-app-backend + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Send pipeline event returns "Request accepted for processing" response Given new "CreateCIAppPipelineEvent" request And body with value {"data": {"attributes": {"resource": {"level": "pipeline","unique_id": "3eacb6f3-ff04-4e10-8a9c-46e6d054024a","name": "Deploy to AWS","url": "https://my-ci-provider.example/pipelines/my-pipeline/run/1","start": "{{ timeISO('now - 120s') }}","end": "{{ timeISO('now - 30s') }}","status": "success","partial_retry": false,"git": {"repository_url": "https://github.com/DataDog/datadog-agent","sha": "7f263865994b76066c4612fd1965215e7dcb4cd2","author_email": "john.doe@email.com"}}},"type": "cipipeline_resource_request"}} When the request is sent Then the response status is 202 Request accepted for processing - @team:DataDog/ci-app-backend + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Send pipeline event with custom provider returns "Request accepted for processing" response Given new "CreateCIAppPipelineEvent" request And body with value {"data": {"attributes": {"provider_name": "example-provider", "resource": {"level": "pipeline","unique_id": "3eacb6f3-ff04-4e10-8a9c-46e6d054024a","name": "Deploy to AWS","url": "https://my-ci-provider.example/pipelines/my-pipeline/run/1","start": "{{ timeISO('now - 120s') }}","end": "{{ timeISO('now - 30s') }}","status": "success","partial_retry": false,"git": {"repository_url": "https://github.com/DataDog/datadog-agent","sha": "7f263865994b76066c4612fd1965215e7dcb4cd2","author_email": "john.doe@email.com"}}},"type": "cipipeline_resource_request"}} When the request is sent Then the response status is 202 Request accepted for processing - @skip @team:DataDog/ci-app-backend + @skip @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Send pipeline job event returns "Request accepted for processing" response Given new "CreateCIAppPipelineEvent" request And body with value {"data": {"attributes": {"resource": {"level": "job", "id": "cf9456de-8b9e-4c27-aa79-27b1e78c1a33", "name": "Build image", "pipeline_unique_id": "3eacb6f3-ff04-4e10-8a9c-46e6d054024a", "pipeline_name": "Deploy to AWS", "start": "{{ timeISO('now - 120s') }}", "end": "{{ timeISO('now - 30s') }}", "status": "error", "url": "https://my-ci-provider.example/jobs/my-jobs/run/1"}}, "type": "cipipeline_resource_request"}} When the request is sent Then the response status is 202 Request accepted for processing - @team:DataDog/ci-app-backend + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend Scenario: Send running pipeline event returns "Request accepted for processing" response Given new "CreateCIAppPipelineEvent" request And body with value {"data": {"attributes": {"resource": {"level": "pipeline","unique_id": "3eacb6f3-ff04-4e10-8a9c-46e6d054024a","name": "Deploy to AWS","url": "https://my-ci-provider.example/pipelines/my-pipeline/run/1","start": "{{ timeISO('now - 120s') }}","status": "running","partial_retry": false,"git": {"repository_url": "https://github.com/DataDog/datadog-agent","sha": "7f263865994b76066c4612fd1965215e7dcb4cd2","author_email": "john.doe@email.com"}}},"type": "cipipeline_resource_request"}} When the request is sent Then the response status is 202 Request accepted for processing + + @skip-java @skip-python @skip-typescript @team:DataDog/ci-app-backend + Scenario: Send several pipeline events returns "Request accepted for processing" response + Given new "CreateCIAppPipelineEvent" request + And body with value {"data": [{"attributes": {"provider_name": "example-provider", "resource": {"level": "pipeline","unique_id": "3eacb6f3-ff04-4e10-8a9c-46e6d054024a","name": "Deploy to AWS","url": "https://my-ci-provider.example/pipelines/my-pipeline/run/1","start": "{{ timeISO('now - 120s') }}","end": "{{ timeISO('now - 30s') }}","status": "success","partial_retry": false,"git": {"repository_url": "https://github.com/DataDog/datadog-agent","sha": "7f263865994b76066c4612fd1965215e7dcb4cd2","author_email": "john.doe@email.com"}}},"type": "cipipeline_resource_request"},{"attributes": {"provider_name": "example-provider", "resource": {"level": "pipeline","unique_id": "7b2c8f9e-aa15-4d22-9c7d-83f4e065138b","name": "Deploy to Production","url": "https://my-ci-provider.example/pipelines/prod-pipeline/run/2","start": "{{ timeISO('now - 180s') }}","end": "{{ timeISO('now - 45s') }}","status": "success","partial_retry": false,"git": {"repository_url": "https://github.com/DataDog/datadog-agent","sha": "9a4f7c28b3e5d12f8e6c9b2a5d8f3e1c7b4a6d9e","author_email": "jane.smith@email.com"}}},"type": "cipipeline_resource_request"}]} + When the request is sent + Then the response status is 202 Request accepted for processing diff --git a/lib/datadog_api_client/inflector.rb b/lib/datadog_api_client/inflector.rb index 4684c1fccaab..763235d23329 100644 --- a/lib/datadog_api_client/inflector.rb +++ b/lib/datadog_api_client/inflector.rb @@ -1324,6 +1324,7 @@ def overrides "v2.ci_app_create_pipeline_event_request_attributes" => "CIAppCreatePipelineEventRequestAttributes", "v2.ci_app_create_pipeline_event_request_attributes_resource" => "CIAppCreatePipelineEventRequestAttributesResource", "v2.ci_app_create_pipeline_event_request_data" => "CIAppCreatePipelineEventRequestData", + "v2.ci_app_create_pipeline_event_request_data_single_or_array" => "CIAppCreatePipelineEventRequestDataSingleOrArray", "v2.ci_app_create_pipeline_event_request_data_type" => "CIAppCreatePipelineEventRequestDataType", "v2.ci_app_event_attributes" => "CIAppEventAttributes", "v2.ci_app_git_info" => "CIAppGitInfo", diff --git a/lib/datadog_api_client/v2/api/ci_visibility_pipelines_api.rb b/lib/datadog_api_client/v2/api/ci_visibility_pipelines_api.rb index 72c56534d8a0..fb90dc2cee8d 100644 --- a/lib/datadog_api_client/v2/api/ci_visibility_pipelines_api.rb +++ b/lib/datadog_api_client/v2/api/ci_visibility_pipelines_api.rb @@ -102,6 +102,8 @@ def create_ci_app_pipeline_event(body, opts = {}) # # Send your pipeline event to your Datadog platform over HTTP. For details about how pipeline executions are modeled and what execution types we support, see [Pipeline Data Model And Execution Types](https://docs.datadoghq.com/continuous_integration/guides/pipeline_data_model/). # + # Multiple events can be sent in an array (up to 1000). + # # Pipeline events can be submitted with a timestamp that is up to 18 hours in the past. # # @param body [CIAppCreatePipelineEventRequest] diff --git a/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request.rb b/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request.rb index 267254cbbf56..26fa25d23623 100644 --- a/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request.rb +++ b/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request.rb @@ -21,7 +21,7 @@ module DatadogAPIClient::V2 class CIAppCreatePipelineEventRequest include BaseGenericModel - # Data of the pipeline event to create. + # Data of the pipeline events to create. attr_accessor :data attr_accessor :additional_properties @@ -38,7 +38,7 @@ def self.attribute_map # @!visibility private def self.openapi_types { - :'data' => :'CIAppCreatePipelineEventRequestData' + :'data' => :'CIAppCreatePipelineEventRequestDataSingleOrArray' } end diff --git a/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request_data_single_or_array.rb b/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request_data_single_or_array.rb new file mode 100644 index 000000000000..9124f47f068a --- /dev/null +++ b/lib/datadog_api_client/v2/models/ci_app_create_pipeline_event_request_data_single_or_array.rb @@ -0,0 +1,63 @@ +=begin +#Datadog API V2 Collection + +#Collection of all Datadog Public endpoints. + +The version of the OpenAPI document: 1.0 +Contact: support@datadoghq.com +Generated by: https://github.com/DataDog/datadog-api-client-ruby/tree/master/.generator + + Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + This product includes software developed at Datadog (https://www.datadoghq.com/). + Copyright 2020-Present Datadog, Inc. + +=end + +require 'date' +require 'time' + +module DatadogAPIClient::V2 + # Data of the pipeline events to create. + module CIAppCreatePipelineEventRequestDataSingleOrArray + class << self + include BaseOneOfModel + include BaseOneOfModelNoDiscriminator + + # List of class defined in oneOf (OpenAPI v3) + def openapi_one_of + [ + :'CIAppCreatePipelineEventRequestData', + :'Array' + ] + end + # Builds the object + # @param data [Mixed] Data to be matched against the list of oneOf items + # @return [Object] Returns the model or the data itself + def build(data) + # Go through the list of oneOf items and attempt to identify the appropriate one. + # Note: + # - We do not attempt to check whether exactly one item matches. + # - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 }) + # due to the way the deserialization is made in the base_object template (it just casts without verifying). + # - TODO: scalar values are de facto behaving as if they were nullable. + # - TODO: logging when debugging is set. + openapi_one_of.each do |klass| + begin + next if klass == :AnyType # "nullable: true" + typed_data = find_and_cast_into_type(klass, data) + next if typed_data.respond_to?(:_unparsed) && typed_data._unparsed + return typed_data if typed_data + rescue # rescue all errors so we keep iterating even if the current item lookup raises + end + end + + if openapi_one_of.include?(:AnyType) + data + else + self._unparsed = true + DatadogAPIClient::UnparsedObject.new(data) + end + end + end + end +end