// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using EpicGames.Horde.Commits;
using EpicGames.Horde.Jobs;
using EpicGames.Horde.Jobs.Templates;
using EpicGames.Horde.Logs;
using EpicGames.Horde.Streams;
using EpicGames.Horde.Users;
#pragma warning disable CA2227 // Change collections to be read-only
namespace EpicGames.Horde.Issues
{
///
/// The severity of an issue
///
public enum IssueSeverity
{
///
/// Unspecified severity
///
Unspecified,
///
/// This error represents a warning
///
Warning,
///
/// This issue represents an error
///
Error,
}
///
/// Identifies a particular changelist and job
///
public class GetIssueStepResponse
{
///
/// The changelist number
///
[Obsolete("Use Commit instead")]
public int Change
{
get => _change ?? _commitId?.TryGetPerforceChange() ?? -1;
set => _change = value;
}
int? _change;
///
/// The commit for this step
///
public CommitIdWithOrder CommitId
{
get => _commitId ?? CommitIdWithOrder.FromPerforceChange(_change) ?? CommitIdWithOrder.Empty;
set => _commitId = value;
}
CommitIdWithOrder? _commitId;
///
/// Severity of the issue in this step
///
public IssueSeverity Severity { get; set; }
///
/// Name of the job containing this step
///
public string JobName { get; set; } = String.Empty;
///
/// The unique job id
///
public JobId JobId { get; set; }
///
/// The unique batch id
///
public JobStepBatchId BatchId { get; set; }
///
/// The unique step id
///
public JobStepId StepId { get; set; }
///
/// Time at which the step ran
///
public DateTime StepTime { get; set; }
///
/// The unique log id
///
public LogId? LogId { get; set; }
}
///
/// Trace of a set of node failures across multiple steps
///
public class GetIssueSpanResponse
{
///
/// Unique id of this span
///
public string Id { get; set; } = String.Empty;
///
/// The template containing this step
///
public TemplateId TemplateId { get; set; }
///
/// Name of the step
///
public string Name { get; set; } = String.Empty;
///
/// Workflow that this span belongs to
///
public WorkflowId? WorkflowId { get; set; }
///
/// The previous build
///
public GetIssueStepResponse? LastSuccess { get; set; }
///
/// The failing builds for a particular event
///
public List Steps { get; set; } = new List();
///
/// The following successful build
///
public GetIssueStepResponse? NextSuccess { get; set; }
}
///
/// Information about a particular step
///
public class GetIssueStreamResponse
{
///
/// Unique id of the stream
///
public StreamId StreamId { get; set; }
///
/// Minimum commit affected by this issue (ie. last successful build)
///
[Obsolete("Use MinCommitId instead")]
public int? MinChange
{
get => _minChange ?? _minCommitId?.GetPerforceChangeOrMinusOne();
set => _minChange = value;
}
int? _minChange;
///
/// Maximum commit affected by this issue (ie. next successful build)
///
[Obsolete("Use MaxCommitId instead")]
public int? MaxChange
{
get => _maxChange ?? _maxCommitId?.GetPerforceChangeOrMinusOne();
set => _maxChange = value;
}
int? _maxChange;
///
/// Minimum changelist affected by this issue (ie. last successful build)
///
public CommitIdWithOrder? MinCommitId
{
get => _minCommitId ?? CommitIdWithOrder.FromPerforceChange(_minChange);
set => _minCommitId = value;
}
CommitIdWithOrder? _minCommitId;
///
/// Maximum changelist affected by this issue (ie. next successful build)
///
public CommitIdWithOrder? MaxCommitId
{
get => _maxCommitId ?? CommitIdWithOrder.FromPerforceChange(_maxChange);
set => _maxCommitId = value;
}
CommitIdWithOrder? _maxCommitId;
///
/// Map of steps to (event signature id -> trace id)
///
public List Nodes { get; set; } = new List();
}
///
/// Outcome of a particular build
///
public enum IssueBuildOutcome
{
///
/// Unknown outcome
///
Unknown,
///
/// Build succeeded
///
Success,
///
/// Build failed
///
Error,
///
/// Build finished with warnings
///
Warning,
}
///
/// Information about a template affected by an issue
///
public class GetIssueAffectedTemplateResponse
{
///
/// The template id
///
public TemplateId TemplateId { get; set; }
///
/// The template name
///
public string TemplateName { get; set; } = String.Empty;
///
/// Whether it has been resolved or not
///
public bool Resolved { get; set; }
///
/// The issue severity of the affected template
///
public IssueSeverity Severity { get; set; }
}
///
/// Summary for the state of a stream in an issue
///
public class GetIssueAffectedStreamResponse
{
///
/// Id of the stream
///
public StreamId StreamId { get; set; }
///
/// Name of the stream
///
public string StreamName { get; set; } = String.Empty;
///
/// Whether the issue has been resolved in this stream
///
public bool Resolved { get; set; }
///
/// The affected templates
///
public List AffectedTemplates { get; set; } = new List();
///
/// List of affected template ids
///
public List TemplateIds { get; set; } = new List();
///
/// List of resolved template ids
///
public List ResolvedTemplateIds { get; set; } = new List();
///
/// List of unresolved template ids
///
public List UnresolvedTemplateIds { get; set; } = new List();
}
///
/// Stores information about a build health issue
///
public class GetIssueResponse
{
///
/// The unique object id
///
public int Id { get; set; }
///
/// Time at which the issue was created
///
public DateTime CreatedAt { get; set; }
///
/// Time at which the issue was retrieved
///
public DateTime RetrievedAt { get; set; }
///
/// The associated project for the issue
///
public string? Project { get; set; }
///
/// The summary text for this issue
///
public string Summary { get; set; } = String.Empty;
///
/// Detailed description text
///
public string? Description { get; set; }
///
/// Description of the current fingerprint used for issue identification
///
public string? FingerprintDescription { get; set; }
///
/// Severity of this issue
///
public IssueSeverity Severity { get; set; }
///
/// Whether the issue is promoted
///
public bool Promoted { get; set; }
///
/// Owner of the issue [DEPRECATED]
///
public string? Owner { get; set; }
///
/// User id of the owner [DEPRECATED]
///
public string? OwnerId { get; set; }
///
/// Owner of the issue
///
public GetThinUserInfoResponse? OwnerInfo { get; set; }
///
/// User that nominated the current owner [DEPRECATED]
///
public string? NominatedBy { get; set; }
///
/// Owner of the issue
///
public GetThinUserInfoResponse? NominatedByInfo { get; set; }
///
/// Time that the issue was acknowledged
///
public DateTime? AcknowledgedAt { get; set; }
///
/// Perforce changelist that fixed this issue
///
public int? FixChange
{
get => _fixChange ?? _fixCommitId?.GetPerforceChangeOrMinusOne();
set => _fixChange = value;
}
int? _fixChange;
///
/// Commit that fixed this issue
///
public CommitId? FixCommitId
{
get => _fixCommitId ?? CommitId.FromPerforceChange(_fixChange);
set => _fixCommitId = value;
}
CommitId? _fixCommitId;
///
/// Whether the issue is marked fixed as a systemic issue
///
public bool FixSystemic
{
get => _fixSystemic ?? (_fixChange < 0);
set => _fixSystemic = value;
}
bool? _fixSystemic;
///
/// Time at which the issue was resolved
///
public DateTime? ResolvedAt { get; set; }
///
/// Name of the user that resolved the issue [DEPRECATED]
///
public string? ResolvedBy { get; set; }
///
/// User id of the person that resolved the issue [DEPRECATED]
///
public string? ResolvedById { get; set; }
///
/// User that resolved the issue
///
public GetThinUserInfoResponse? ResolvedByInfo { get; set; }
///
/// Time at which the issue was verified
///
public DateTime? VerifiedAt { get; set; }
///
/// Time that the issue was last seen
///
public DateTime LastSeenAt { get; set; }
///
/// List of stream paths affected by this issue
///
public List Streams { get; set; } = new List();
///
/// List of affected stream ids
///
public List ResolvedStreams { get; set; } = new List();
///
/// List of unresolved streams
///
public List UnresolvedStreams { get; set; } = new List();
///
/// List of affected streams
///
public List AffectedStreams { get; set; } = new List();
///
/// Most likely suspects for causing this issue [DEPRECATED]
///
public List? PrimarySuspects { get; set; }
///
/// User ids of the most likely suspects [DEPRECATED]
///
public List? PrimarySuspectIds { get; set; }
///
/// Most likely suspects for causing this issue
///
public List PrimarySuspectsInfo { get; set; } = new List();
///
/// Whether to show alerts for this issue
///
public bool ShowDesktopAlerts { get; set; }
///
/// Key for this issue in external issue tracker
///
public string? ExternalIssueKey { get; set; }
///
/// User who quarantined the issue
///
public GetThinUserInfoResponse? QuarantinedByUserInfo { get; set; }
///
/// The UTC time when the issue was quarantined
///
public DateTime? QuarantineTimeUtc { get; set; }
///
/// User who force closed the issue
///
public GetThinUserInfoResponse? ForceClosedByUserInfo { get; set; }
///
/// The workflow thread url for this issue
///
public Uri? WorkflowThreadUrl { get; set; }
}
///
/// Information about a span within an issue
///
public class FindIssueSpanResponse
{
///
/// Unique id of this span
///
public string Id { get; set; } = String.Empty;
///
/// The template containing this step
///
public string TemplateId { get; set; } = String.Empty;
///
/// Name of the step
///
public string Name { get; set; } = String.Empty;
///
/// Workflow for this span
///
public WorkflowId? WorkflowId { get; set; }
///
/// The previous build
///
public GetIssueStepResponse? LastSuccess { get; set; }
///
/// The following successful build
///
public GetIssueStepResponse? NextSuccess { get; set; }
}
///
/// Stores information about a build health issue
///
public class FindIssueResponse
{
///
/// The unique object id
///
public int Id { get; set; }
///
/// Time at which the issue was created
///
public DateTime CreatedAt { get; set; }
///
/// Time at which the issue was retrieved
///
public DateTime RetrievedAt { get; set; }
///
/// The associated project for the issue
///
public string? Project { get; set; }
///
/// The summary text for this issue
///
public string Summary { get; set; } = String.Empty;
///
/// Detailed description text
///
public string? Description { get; set; }
///
/// Severity of this issue
///
public IssueSeverity Severity { get; set; }
///
/// Severity of this issue in the stream
///
public IssueSeverity? StreamSeverity { get; set; }
///
/// Whether the issue is promoted
///
public bool Promoted { get; set; }
///
/// Owner of the issue
///
public GetThinUserInfoResponse? Owner { get; set; }
///
/// Owner of the issue
///
public GetThinUserInfoResponse? NominatedBy { get; set; }
///
/// Time that the issue was acknowledged
///
public DateTime? AcknowledgedAt { get; set; }
///
/// Changelist that fixed this issue
///
public int? FixChange
{
get => _fixChange ?? ((_fixSystemic ?? false) ? -1 : _fixCommitId?.GetPerforceChangeOrMinusOne());
set => _fixChange = value;
}
int? _fixChange;
///
/// Changelist that fixed this issue
///
public CommitId? FixCommitId
{
get => _fixCommitId ?? CommitId.FromPerforceChange(_fixChange);
set => _fixCommitId = value;
}
CommitId? _fixCommitId;
///
/// Whether the issue is marked fixed as a systemic issue
///
public bool FixSystemic
{
get => _fixSystemic ?? (_fixChange < 0);
set => _fixSystemic = value;
}
bool? _fixSystemic;
///
/// Time at which the issue was resolved
///
public DateTime? ResolvedAt { get; set; }
///
/// User that resolved the issue
///
public GetThinUserInfoResponse? ResolvedBy { get; set; }
///
/// Time at which the issue was verified
///
public DateTime? VerifiedAt { get; set; }
///
/// Time that the issue was last seen
///
public DateTime LastSeenAt { get; set; }
///
/// Spans for this issue
///
public List? Spans { get; set; }
///
/// Key for this issue in external issue tracker
///
public string? ExternalIssueKey { get; set; }
///
/// User who quarantined the issue
///
public GetThinUserInfoResponse? QuarantinedBy { get; set; }
///
/// The UTC time when the issue was quarantined
///
public DateTime? QuarantineTimeUtc { get; set; }
///
/// The workflow thread url for this issue
///
public Uri? WorkflowThreadUrl { get; set; }
///
/// Workflows for which this issue is open
///
public List? OpenWorkflows { get; set; }
}
///
/// Request an issue to be updated
///
public class UpdateIssueRequest
{
///
/// Summary of the issue
///
public string? Summary { get; set; }
///
/// Description of the issue
///
public string? Description { get; set; }
///
/// Whether the issue is promoted or not
///
public bool? Promoted { get; set; }
///
/// New user id for owner of the issue, can be cleared by passing empty string
///
public string? OwnerId { get; set; }
///
/// User id that nominated the new owner
///
public string? NominatedById { get; set; }
///
/// Whether the issue has been acknowledged
///
public bool? Acknowledged { get; set; }
///
/// Whether the user has declined this issue
///
public bool? Declined { get; set; }
///
/// The change at which the issue is claimed fixed. 0 = not fixed, -1 = systemic issue.
///
[Obsolete("Use FixCommitId and FixSystemic instead")]
public int? FixChange
{
get => _fixChange ?? ((_fixSystemic ?? false) ? -1 : _fixCommitId?.GetPerforceChangeOrMinusOne());
set => _fixChange = value;
}
int? _fixChange;
///
/// The change at which the issue is claimed fixed. """" = not fixed.
///
public CommitId? FixCommitId
{
get => _fixCommitId ?? ((_fixChange < 0)? null : (_fixChange == 0)? CommitId.Empty : CommitId.FromPerforceChange(_fixChange));
set => _fixCommitId = value;
}
CommitId? _fixCommitId;
///
/// Set to mark the issue as fixed systemically
///
public bool FixSystemic
{
get => _fixSystemic ?? (_fixChange < 0);
set => _fixSystemic = value;
}
bool? _fixSystemic;
///
/// Whether the issue should be marked as resolved
///
public bool? Resolved { get; set; }
///
/// List of spans to add to this issue
///
public List? AddSpans { get; set; }
///
/// List of spans to remove from this issue
///
public List? RemoveSpans { get; set; }
///
/// A key to issue in external tracker
///
public string? ExternalIssueKey { get; set; }
///
/// Id of user quarantining issue
///
public string? QuarantinedById { get; set; }
///
/// Id of user who is forcibly closing this issue, skipping verification checks. This is useful for when a failing step has been removed for example
///
public string? ForceClosedById { get; set; }
}
///
/// External issue project information
///
public class GetExternalIssueProjectResponse
{
///
/// The project key
///
public string ProjectKey { get; set; } = String.Empty;
///
/// The name of the project
///
public string Name { get; set; } = String.Empty;
///
/// The id of the project
///
public string Id { get; set; } = String.Empty;
///
/// component id => name
///
public Dictionary Components { get; set; } = new Dictionary();
///
/// IssueType id => name
///
public Dictionary IssueTypes { get; set; } = new Dictionary();
}
///
/// Marks an issue as fixed by another user. Designed for use from a Perforce trigger.
///
public class MarkFixedViaPerforceRequest
{
///
/// Name of the user that fixed the issue
///
public string UserName { get; set; } = String.Empty;
///
/// Change that fixed the issue
///
public int FixChange { get; set; }
}
///
/// Request an issue to be created on external issue tracking system
///
public class CreateExternalIssueRequest
{
///
/// Horde issue which is linked to external issue
///
public int IssueId { get; set; } = 0;
///
/// StreamId of a stream with this issue
///
public string StreamId { get; set; } = String.Empty;
///
/// Summary text for external issue
///
public string Summary { get; set; } = String.Empty;
///
/// External issue project id
///
public string ProjectId { get; set; } = String.Empty;
///
/// External issue component id
///
public string ComponentId { get; set; } = String.Empty;
///
/// External issue type id
///
public string IssueTypeId { get; set; } = String.Empty;
///
/// Optional description text for external issue
///
public string? Description { get; set; }
///
/// Optional link to issue on Horde
///
public string? HordeIssueLink { get; set; }
}
///
/// Response for externally created issue
///
public class CreateExternalIssueResponse
{
///
/// External issue key
///
public string Key { get; set; }
///
/// Link to issue on external tracking site
///
public string? Link { get; set; }
///
/// Constructor
///
///
///
public CreateExternalIssueResponse(string key, string? link)
{
Key = key;
Link = link;
}
}
///
/// External issue response object
///
public class GetExternalIssueResponse
{
///
/// The external issue key
///
public string Key { get; set; } = String.Empty;
///
/// The issue link on external tracking site
///
public string? Link { get; set; }
///
/// The issue status name, "To Do", "In Progress", etc
///
public string? StatusName { get; set; }
///
/// The issue resolution name, "Fixed", "Closed", etc
///
public string? ResolutionName { get; set; }
///
/// The issue priority name, "1 - Critical", "2 - Major", etc
///
public string? PriorityName { get; set; }
///
/// The current assignee's user name
///
public string? AssigneeName { get; set; }
///
/// The current assignee's display name
///
public string? AssigneeDisplayName { get; set; }
///
/// The current assignee's email address
///
public string? AssigneeEmailAddress { get; set; }
}
}