From a388306bc5e9dc14c7618ce394f4acd3dfc4a4f4 Mon Sep 17 00:00:00 2001 From: "api-clients-generation-pipeline[bot]" <54105614+api-clients-generation-pipeline[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:18:40 +0000 Subject: [PATCH 1/3] Add new DeleteAssignee endpoint to Error Tracking APIs (#3404) Co-authored-by: ci.datadog-api-spec --- .generator/schemas/v2/openapi.yaml | 29 ++++++++ api/datadogV2/api_error_tracking.go | 68 +++++++++++++++++++ api/datadogV2/doc.go | 1 + .../v2/error-tracking/DeleteIssueAssignee.go | 28 ++++++++ ...n_issue_returns_No_Content_response.freeze | 1 + ..._an_issue_returns_No_Content_response.yaml | 37 ++++++++++ ...an_issue_returns_Not_Found_response.freeze | 1 + ...f_an_issue_returns_Not_Found_response.yaml | 19 ++++++ .../features/v2/error_tracking.feature | 22 ++++++ tests/scenarios/features/v2/undo.json | 6 ++ 10 files changed, 212 insertions(+) create mode 100644 examples/v2/error-tracking/DeleteIssueAssignee.go create mode 100644 tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.freeze create mode 100644 tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.yaml create mode 100644 tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.freeze create mode 100644 tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.yaml diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 329c0e6965c..9cf7a6300d0 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -61011,6 +61011,35 @@ paths: tags: - Error Tracking /api/v2/error-tracking/issues/{issue_id}/assignee: + delete: + description: Remove the assignee of an issue by `issue_id`. + operationId: DeleteIssueAssignee + parameters: + - $ref: '#/components/parameters/IssueIDPathParameter' + responses: + '204': + description: No Content + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - error_tracking_read + - error_tracking_write + - cases_read + - cases_write + summary: Remove the assignee of an issue + tags: + - Error Tracking put: description: Update the assignee of an issue by `issue_id`. operationId: UpdateIssueAssignee diff --git a/api/datadogV2/api_error_tracking.go b/api/datadogV2/api_error_tracking.go index ff1d50b1acc..5730e0f23dc 100644 --- a/api/datadogV2/api_error_tracking.go +++ b/api/datadogV2/api_error_tracking.go @@ -15,6 +15,74 @@ import ( // ErrorTrackingApi service type type ErrorTrackingApi datadog.Service +// DeleteIssueAssignee Remove the assignee of an issue. +// Remove the assignee of an issue by `issue_id`. +func (a *ErrorTrackingApi) DeleteIssueAssignee(ctx _context.Context, issueId string) (*_nethttp.Response, error) { + var ( + localVarHTTPMethod = _nethttp.MethodDelete + localVarPostBody interface{} + ) + + localBasePath, err := a.Client.Cfg.ServerURLWithContext(ctx, "v2.ErrorTrackingApi.DeleteIssueAssignee") + if err != nil { + return nil, datadog.GenericOpenAPIError{ErrorMessage: err.Error()} + } + + localVarPath := localBasePath + "/api/v2/error-tracking/issues/{issue_id}/assignee" + localVarPath = datadog.ReplacePathParameter(localVarPath, "{issue_id}", _neturl.PathEscape(datadog.ParameterToString(issueId, ""))) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + localVarFormParams := _neturl.Values{} + localVarHeaderParams["Accept"] = "*/*" + + if a.Client.Cfg.DelegatedTokenConfig != nil { + err = datadog.UseDelegatedTokenAuth(ctx, &localVarHeaderParams, a.Client.Cfg.DelegatedTokenConfig) + if err != nil { + return nil, err + } + } else { + datadog.SetAuthKeys( + ctx, + &localVarHeaderParams, + [2]string{"apiKeyAuth", "DD-API-KEY"}, + [2]string{"appKeyAuth", "DD-APPLICATION-KEY"}, + ) + } + req, err := a.Client.PrepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, nil) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.Client.CallAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := datadog.ReadBody(localVarHTTPResponse) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := datadog.GenericOpenAPIError{ + ErrorBody: localVarBody, + ErrorMessage: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 || localVarHTTPResponse.StatusCode == 401 || localVarHTTPResponse.StatusCode == 403 || localVarHTTPResponse.StatusCode == 404 || localVarHTTPResponse.StatusCode == 429 { + var v APIErrorResponse + err = a.Client.Decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + return localVarHTTPResponse, newErr + } + newErr.ErrorModel = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + // GetIssueOptionalParameters holds optional parameters for GetIssue. type GetIssueOptionalParameters struct { Include *[]GetIssueIncludeQueryParameterItem diff --git a/api/datadogV2/doc.go b/api/datadogV2/doc.go index bba5fe1ea31..2cdb4f3a2be 100644 --- a/api/datadogV2/doc.go +++ b/api/datadogV2/doc.go @@ -226,6 +226,7 @@ // - [DowntimesApi.ListDowntimes] // - [DowntimesApi.ListMonitorDowntimes] // - [DowntimesApi.UpdateDowntime] +// - [ErrorTrackingApi.DeleteIssueAssignee] // - [ErrorTrackingApi.GetIssue] // - [ErrorTrackingApi.SearchIssues] // - [ErrorTrackingApi.UpdateIssueAssignee] diff --git a/examples/v2/error-tracking/DeleteIssueAssignee.go b/examples/v2/error-tracking/DeleteIssueAssignee.go new file mode 100644 index 00000000000..dc457bb65f4 --- /dev/null +++ b/examples/v2/error-tracking/DeleteIssueAssignee.go @@ -0,0 +1,28 @@ +// Remove the assignee of an issue returns "No Content" response + +package main + +import ( + "context" + "fmt" + "os" + + "github.com/DataDog/datadog-api-client-go/v2/api/datadog" + "github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" +) + +func main() { + // there is a valid "issue" in the system + IssueID := os.Getenv("ISSUE_ID") + + ctx := datadog.NewDefaultContext(context.Background()) + configuration := datadog.NewConfiguration() + apiClient := datadog.NewAPIClient(configuration) + api := datadogV2.NewErrorTrackingApi(apiClient) + r, err := api.DeleteIssueAssignee(ctx, IssueID) + + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ErrorTrackingApi.DeleteIssueAssignee`: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} diff --git a/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.freeze b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.freeze new file mode 100644 index 00000000000..1c36c01bc37 --- /dev/null +++ b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.freeze @@ -0,0 +1 @@ +2025-10-17T14:43:40.022Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.yaml b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.yaml new file mode 100644 index 00000000000..189d17529b7 --- /dev/null +++ b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_No_Content_response.yaml @@ -0,0 +1,37 @@ +interactions: +- request: + body: | + {"data":{"attributes":{"from":1759416220000,"query":"service:synthetics-browser","to":1760712220000,"track":"rum"},"type":"search_request"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + id: 0 + method: POST + url: https://api.datadoghq.com/api/v2/error-tracking/issues/search + response: + body: '{"data":[{"id":"d3ab59c6-84ee-11f0-87bb-da7ad0900002","type":"error_tracking_search_result","attributes":{"impacted_sessions":4316,"total_count":8640},"relationships":{"issue":{"data":{"id":"d3ab59c6-84ee-11f0-87bb-da7ad0900002","type":"issue"}}}},{"id":"a5bb2896-a4d0-11f0-bd76-da7ad0900002","type":"error_tracking_search_result","attributes":{"impacted_sessions":280,"total_count":272},"relationships":{"issue":{"data":{"id":"a5bb2896-a4d0-11f0-bd76-da7ad0900002","type":"issue"}}}},{"id":"e2a89d14-6f07-11f0-8a88-da7ad0900002","type":"error_tracking_search_result","attributes":{"impacted_sessions":1,"total_count":4},"relationships":{"issue":{"data":{"id":"e2a89d14-6f07-11f0-8a88-da7ad0900002","type":"issue"}}}},{"id":"5f8ebd5c-6dd9-11f0-8a28-da7ad0900002","type":"error_tracking_search_result","attributes":{"impacted_sessions":1,"total_count":1},"relationships":{"issue":{"data":{"id":"5f8ebd5c-6dd9-11f0-8a28-da7ad0900002","type":"issue"}}}},{"id":"e2a89134-6f07-11f0-8d36-da7ad0900002","type":"error_tracking_search_result","attributes":{"impacted_sessions":1,"total_count":1},"relationships":{"issue":{"data":{"id":"e2a89134-6f07-11f0-8d36-da7ad0900002","type":"issue"}}}}]}' + code: 200 + duration: 0ms + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK +- request: + body: '' + form: {} + headers: + Accept: + - '*/*' + id: 1 + method: DELETE + url: https://api.datadoghq.com/api/v2/error-tracking/issues/d3ab59c6-84ee-11f0-87bb-da7ad0900002/assignee + response: + body: '' + code: 204 + duration: 0ms + headers: {} + status: 204 No Content +version: 2 diff --git a/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.freeze b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.freeze new file mode 100644 index 00000000000..ed269c62a73 --- /dev/null +++ b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.freeze @@ -0,0 +1 @@ +2025-10-17T14:43:41.755Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.yaml b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.yaml new file mode 100644 index 00000000000..e15a32493a5 --- /dev/null +++ b/tests/scenarios/cassettes/TestScenarios/v2/Feature_Error_Tracking/Scenario_Remove_the_assignee_of_an_issue_returns_Not_Found_response.yaml @@ -0,0 +1,19 @@ +interactions: +- request: + body: '' + form: {} + headers: + Accept: + - '*/*' + id: 0 + method: DELETE + url: https://api.datadoghq.com/api/v2/error-tracking/issues/67d80aa3-36ff-44b9-a694-c501a7591737/assignee + response: + body: '{"errors":[{"status":"404","title":"Not Found","detail":"issue not found"}]}' + code: 404 + duration: 0ms + headers: + Content-Type: + - application/vnd.api+json + status: 404 Not Found +version: 2 diff --git a/tests/scenarios/features/v2/error_tracking.feature b/tests/scenarios/features/v2/error_tracking.feature index 97f8ceeedd9..253c3b24b23 100644 --- a/tests/scenarios/features/v2/error_tracking.feature +++ b/tests/scenarios/features/v2/error_tracking.feature @@ -32,6 +32,28 @@ Feature: Error Tracking Then the response status is 200 OK And the response "data.id" is equal to "{{ issue.id }}" + @generated @skip @team:DataDog/error-tracking + Scenario: Remove the assignee of an issue returns "Bad Request" response + Given new "DeleteIssueAssignee" request + And request contains "issue_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/error-tracking + Scenario: Remove the assignee of an issue returns "No Content" response + Given new "DeleteIssueAssignee" request + And there is a valid "issue" in the system + And request contains "issue_id" parameter from "issue.id" + When the request is sent + Then the response status is 204 No Content + + @team:DataDog/error-tracking + Scenario: Remove the assignee of an issue returns "Not Found" response + Given new "DeleteIssueAssignee" request + And request contains "issue_id" parameter with value "67d80aa3-36ff-44b9-a694-c501a7591737" + When the request is sent + Then the response status is 404 Not Found + @team:DataDog/error-tracking Scenario: Search error tracking issues returns "Bad Request" response Given new "SearchIssues" request diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index f804a3dce1d..6c74e264b65 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -1319,6 +1319,12 @@ "type": "safe" } }, + "DeleteIssueAssignee": { + "tag": "Error Tracking", + "undo": { + "type": "idempotent" + } + }, "UpdateIssueAssignee": { "tag": "Error Tracking", "undo": { From 178704ddcf8b5db4ccf6a75754b094a20f3d1077 Mon Sep 17 00:00:00 2001 From: "api-clients-generation-pipeline[bot]" <54105614+api-clients-generation-pipeline[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:01:06 +0000 Subject: [PATCH 2/3] Update ci_app description with max 1 year event run duration restriction (#3358) Co-authored-by: ci.datadog-api-spec --- .generator/schemas/v2/openapi.yaml | 4 +++- api/datadogV2/api_ci_visibility_pipelines.go | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 9cf7a6300d0..364018c47d5 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -57293,7 +57293,9 @@ paths: Pipeline events can be submitted with a timestamp that is up to 18 hours in - the past.' + the past. + + The duration between the event start and end times cannot exceed 1 year.' operationId: CreateCIAppPipelineEvent requestBody: content: diff --git a/api/datadogV2/api_ci_visibility_pipelines.go b/api/datadogV2/api_ci_visibility_pipelines.go index 7cd91c0414d..cb3900e0ff1 100644 --- a/api/datadogV2/api_ci_visibility_pipelines.go +++ b/api/datadogV2/api_ci_visibility_pipelines.go @@ -102,6 +102,7 @@ func (a *CIVisibilityPipelinesApi) AggregateCIAppPipelineEvents(ctx _context.Con // 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. +// The duration between the event start and end times cannot exceed 1 year. func (a *CIVisibilityPipelinesApi) CreateCIAppPipelineEvent(ctx _context.Context, body CIAppCreatePipelineEventRequest) (interface{}, *_nethttp.Response, error) { var ( localVarHTTPMethod = _nethttp.MethodPost From 7814b320dc37b2a8ab0f0dd2b5515d14c05ca0ef Mon Sep 17 00:00:00 2001 From: jack-edmonds-dd Date: Wed, 22 Oct 2025 13:39:24 -0400 Subject: [PATCH 3/3] Allow missing descriptions. (#3413) --- .generator/src/generator/formatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.generator/src/generator/formatter.py b/.generator/src/generator/formatter.py index 97ca258cbcb..7170cd9ee33 100644 --- a/.generator/src/generator/formatter.py +++ b/.generator/src/generator/formatter.py @@ -75,7 +75,7 @@ def is_primitive(schema): def block_comment(comment, prefix="#", first_line=True): - lines = comment.split("\n") + lines = (comment or "").split("\n") start = "" if first_line else lines[0] + "\n" return (start + "\n".join(f"{prefix} {line}".rstrip() for line in lines[(0 if first_line else 1) :])).rstrip()