Remove AI Copilot feature and related components

- Deleted the CodeRepositoryPage component and its associated routes.
- Removed AI Copilot breadcrumbs and references from the PageMap and RouteMap.
- Eliminated the LLM Server deployment documentation and introduction content.
- Cleaned up related data migrations and jobs for Copilot actions.
- Updated navigation to exclude Copilot links.
This commit is contained in:
Nawaz Dhandala 2025-12-11 21:52:49 +00:00
parent c617372e37
commit 8f8704e2d0
No known key found for this signature in database
GPG key ID: 96C5DCA24769DBCA
66 changed files with 0 additions and 7095 deletions

View file

@ -1,15 +0,0 @@
## OneUptime Copilot
This folder contains the configuration files for the OneUptime Copilot. The Copilot is a tool that automatically improves your code. It can fix issues, improve code quality, and help you ship faster.
This folder has the following structure:
- `config.js`: The configuration file for the Copilot. You can customize the Copilot's behavior by changing this file.
- `scripts`: A folder containing scripts that the Copilot runs. These are hooks that run at different stages of the Copilot's process.
- `on-after-clone.sh`: A script that runs after the Copilot clones your repository.
- `on-before-code-change.sh`: A script that runs before the Copilot makes changes to your code.
- `on-after-code-change.sh`: A script that runs after the Copilot makes changes to your code.
- `on-before-commit.sh`: A script that runs before the Copilot commits changes to your repository.
- `on-after-commit.sh`: A script that runs after the Copilot commits changes to your repository.

View file

@ -1,10 +0,0 @@
// This is the configuration file for the oneuptime copilot.
const getCopilotConfig = () => {
return {
// The version of the schema for this configuration file.
schemaVersion: '1.0',
}
}
export default getCopilotConfig;

View file

@ -1,16 +0,0 @@
# Description: Copilot clones your repository and to improve your code.
# This scirpt runs after the clone process is completed.
# Some of the common tasks you can do here are:
# 1. Install dependencies
# 2. Run linting
# 3. Run tests
# 4. Run build
# 5. Run any other command that you want to run after the clone process is completed.
# If this script fails, copilot will not proceed with the next steps to improve your code.
# This step is to ensure that the code is in a good state before we start improving it.
# If you want to skip this script, you can keep this file empty.
# It's highly recommended to run linting and tests in this script to ensure the code is in a good state.
# This scirpt will run on ubuntu machine. So, make sure the commands you run are compatible with ubuntu.
npm install
npm run lint

View file

@ -1,13 +0,0 @@
# Description: Copilot will run this script after we make improvements to your code and write it to disk.
# Some of the common tasks you can do here are:
# 1. Run linting
# 2. Run tests
# 3. Run build
# 4. Run any other command that you want to run after the code is changed.
# If this script fails, copilot will not commit the changes to your repository.
# This step is to ensure that the code is in a good state before we commit the changes.
# If you want to skip this script, you can keep this file empty.
# It's highly recommended to run linting and tests in this script to ensure the code is in a good state.
# This scirpt will run on ubuntu machine. So, make sure the commands you run are compatible with ubuntu.
npm run fix

View file

@ -1 +0,0 @@
# Description: Copilot will run this script after the commit process is completed.

View file

@ -1,9 +0,0 @@
# Description: Copilot will run this script before we make changes to your code.
# Some of the common tasks you can do here are:
# 1. Install dependencies
# 2. Run any other command that you want to run before the code is changed.
# If this script fails, copilot will not make any changes to the code.
# This step is to ensure that the code is in a good state before we start making changes.
# If you want to skip this script, you can keep this file empty.
# It's highly recommended to run things like installing dependencies in this script.
# This scirpt will run on ubuntu machine. So, make sure the commands you run are compatible with ubuntu.

View file

@ -1 +0,0 @@
# Description: Copilot will run this script before we commit the changes to your repository.

View file

@ -3,9 +3,6 @@ import BaseAnalyticsAPI from "Common/Server/API/BaseAnalyticsAPI";
import BillingAPI from "Common/Server/API/BillingAPI";
import BillingInvoiceAPI from "Common/Server/API/BillingInvoiceAPI";
import BillingPaymentMethodAPI from "Common/Server/API/BillingPaymentMethodAPI";
import CopilotCodeRepositoryAPI from "Common/Server/API/CopilotCodeRepositoryAPI";
import CopilotActionAPI from "Common/Server/API/CopilotActionAPI";
import CopilotPullRequestAPI from "Common/Server/API/CopilotPullRequestAPI";
import FileAPI from "Common/Server/API/FileAPI";
import GlobalConfigAPI from "Common/Server/API/GlobalConfigAPI";
import MonitorGroupAPI from "Common/Server/API/MonitorGroupAPI";
@ -141,10 +138,6 @@ import LogService, {
LogService as LogServiceType,
} from "Common/Server/Services/LogService";
import CopilotActionTypePriorityService, {
Service as CopilotActionTypePriorityServiceType,
} from "Common/Server/Services/CopilotActionTypePriorityService";
import MetricService, {
MetricService as MetricServiceType,
} from "Common/Server/Services/MetricService";
@ -255,9 +248,6 @@ import ServiceCatalogOwnerUserService, {
import ServiceCatalogService, {
Service as ServiceCatalogServiceType,
} from "Common/Server/Services/ServiceCatalogService";
import ServiceCopilotCodeRepositoryService, {
Service as ServiceCopilotCodeRepositoryType,
} from "Common/Server/Services/ServiceCopilotCodeRepositoryService";
import ServiceCatalogDependencyService, {
Service as ServiceCatalogDependencyServiceType,
} from "Common/Server/Services/ServiceCatalogDependencyService";
@ -439,7 +429,6 @@ import ScheduledMaintenanceStateTimeline from "Common/Models/DatabaseModels/Sche
import ServiceCatalog from "Common/Models/DatabaseModels/ServiceCatalog";
import ServiceCatalogOwnerTeam from "Common/Models/DatabaseModels/ServiceCatalogOwnerTeam";
import ServiceCatalogOwnerUser from "Common/Models/DatabaseModels/ServiceCatalogOwnerUser";
import ServiceCopilotCodeRepository from "Common/Models/DatabaseModels/ServiceCopilotCodeRepository";
import ShortLink from "Common/Models/DatabaseModels/ShortLink";
import SmsLog from "Common/Models/DatabaseModels/SmsLog";
// Custom Fields API
@ -471,7 +460,6 @@ import ProbeOwnerUser from "Common/Models/DatabaseModels/ProbeOwnerUser";
import ServiceCatalogDependency from "Common/Models/DatabaseModels/ServiceCatalogDependency";
import ExceptionInstance from "Common/Models/AnalyticsModels/ExceptionInstance";
import TelemetyException from "Common/Models/DatabaseModels/TelemetryException";
import CopilotActionTypePriority from "Common/Models/DatabaseModels/CopilotActionTypePriority";
import WorkspaceNotificationLogService, {
Service as WorkspaceNotificationLogServiceType,
} from "Common/Server/Services/WorkspaceNotificationLogService";
@ -927,17 +915,6 @@ const BaseAPIFeatureSet: FeatureSet = {
new BaseAnalyticsAPI<Log, LogServiceType>(Log, LogService).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
CopilotActionTypePriority,
CopilotActionTypePriorityServiceType
>(
CopilotActionTypePriority,
CopilotActionTypePriorityService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<Dashboard, DashboardServiceType>(
@ -1066,17 +1043,6 @@ const BaseAPIFeatureSet: FeatureSet = {
new BaseAPI<Team, TeamServiceType>(Team, TeamService).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
ServiceCopilotCodeRepository,
ServiceCopilotCodeRepositoryType
>(
ServiceCopilotCodeRepository,
ServiceCopilotCodeRepositoryService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<MonitorGroupOwnerUser, MonitorGroupOwnerUserServiceType>(
@ -1667,21 +1633,6 @@ const BaseAPIFeatureSet: FeatureSet = {
new GlobalConfigAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new CopilotCodeRepositoryAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new CopilotActionAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new CopilotPullRequestAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new UserNotificationLogTimelineAPI().getRouter(),

View file

@ -1,772 +0,0 @@
import CodeRepository from "./CopilotCodeRepository";
import Project from "./Project";
import ServiceCatalog from "./ServiceCatalog";
import ServiceCopilotCodeRepository from "./ServiceCopilotCodeRepository";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import CopilotActionStatus from "../../Types/Copilot/CopilotActionStatus";
import CopilotActionType from "../../Types/Copilot/CopilotActionType";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
import CopilotPullRequest from "./CopilotPullRequest";
import CopilotActionProp from "../../Types/Copilot/CopilotActionProps/Index";
@CanAccessIfCanReadOn("codeRepository")
@EnableDocumentation()
@TenantColumn("projectId")
@TableAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
delete: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.DeleteCopilotAction,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotAction,
],
})
@EnableWorkflow({
create: true,
delete: false,
update: true,
})
@CrudApiEndpoint(new Route("/copilot-action"))
@TableMetadata({
tableName: "CopilotAction",
singularName: "Copilot Event",
pluralName: "Copilot Events",
icon: IconProp.Bolt,
tableDescription: "Copilot Event Resource",
})
@Entity({
name: "CopilotAction",
})
export default class CopilotAction extends BaseModel {
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: false,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "codeRepositoryId",
type: TableColumnType.Entity,
modelType: CodeRepository,
title: "Code Repository",
description:
"Relation to CodeRepository Resource in which this object belongs",
})
@ManyToOne(
() => {
return CodeRepository;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "codeRepositoryId" })
public codeRepository?: CodeRepository = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Code Repository ID",
description:
"ID of your OneUptime Code Repository in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public codeRepositoryId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.LongText,
title: "Commit Hash",
description:
"Commit Hash of the commit for this file in Code Repository where this event was triggered",
})
@Column({
type: ColumnType.LongText,
nullable: false,
})
public commitHash?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: "Copilot Event Type",
description:
"Type of Copilot Event that was triggered for this file in Code Repository",
})
@Column({
type: ColumnType.ShortText,
nullable: false,
})
public copilotActionType?: CopilotActionType = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "serviceCatalogId",
type: TableColumnType.Entity,
modelType: ServiceCatalog,
title: "Service Catalog",
description:
"Relation to Service Catalog Resource in which this object belongs",
})
@ManyToOne(
() => {
return ServiceCatalog;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "serviceCatalogId" })
public serviceCatalog?: ServiceCatalog = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Service Catalog ID",
description:
"ID of your OneUptime ServiceCatalog in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public serviceCatalogId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "serviceRepositoryId",
type: TableColumnType.Entity,
modelType: ServiceCopilotCodeRepository,
title: "Service Repository",
description:
"Relation to Service Repository Resource in which this object belongs",
})
@ManyToOne(
() => {
return ServiceCopilotCodeRepository;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "serviceRepositoryId" })
public serviceRepository?: ServiceCopilotCodeRepository = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Service Repository ID",
description:
"ID of your OneUptime Service Repository in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public serviceRepositoryId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "copilotPullRequestId",
type: TableColumnType.Entity,
required: false,
modelType: CopilotPullRequest,
title: "Pull Request",
description:
"Relation to Pull Request Resource in which this object belongs",
})
@ManyToOne(
() => {
return CopilotPullRequest;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "copilotPullRequestId" })
public copilotPullRequest?: CopilotPullRequest = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: false,
canReadOnRelationQuery: true,
title: "Copilot Pull Request ID",
description:
"ID of your OneUptime Copilot Pull Request in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public copilotPullRequestId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: "Copilot Event Status",
description:
"Status of Copilot Event that was triggered for this file in Code Repository",
})
@Column({
type: ColumnType.ShortText,
nullable: false,
})
public copilotActionStatus?: CopilotActionStatus = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.JSON,
title: "Action Props",
description:
"Action Props of Copilot Event that was triggered for this file in Code Repository",
})
@Column({
type: ColumnType.JSON,
nullable: true,
})
public copilotActionProp?: CopilotActionProp = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.LongText,
title: "Status Message",
description:
"Status Message of Copilot Event that was triggered for this file in Code Repository",
})
@Column({
type: ColumnType.VeryLongText,
nullable: true,
})
public statusMessage?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
required: false,
type: TableColumnType.VeryLongText,
title: "Logs",
description: "Logs",
})
@Column({
nullable: true,
type: ColumnType.VeryLongText,
})
public logs?: string = undefined;
// When this is true. Copilot tries to run this action as soon as possible.
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotAction,
],
})
@TableColumn({
required: false,
type: TableColumnType.Boolean,
title: "Is Priority",
description: "Is Priority",
defaultValue: false,
})
@Column({
nullable: false,
type: ColumnType.Boolean,
default: false,
})
public isPriority?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotAction,
],
})
@TableColumn({
required: false,
type: TableColumnType.Date,
title: "Status Changed at",
description: "When the status of this action was changed",
})
@Column({
nullable: true,
type: ColumnType.Date,
})
public statusChangedAt?: Date = undefined;
}

View file

@ -1,340 +0,0 @@
import CodeRepository from "./CopilotCodeRepository";
import Project from "./Project";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import CopilotActionType from "../../Types/Copilot/CopilotActionType";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
import ColumnLength from "../../Types/Database/ColumnLength";
@CanAccessIfCanReadOn("codeRepository")
@EnableDocumentation()
@TenantColumn("projectId")
@TableAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotAction,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
delete: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.DeleteCopilotAction,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotAction,
],
})
@EnableWorkflow({
create: true,
delete: false,
update: true,
})
@CrudApiEndpoint(new Route("/copilot-action-type-prority"))
@TableMetadata({
tableName: "CopilotActionType",
singularName: "Copilot Action Priority",
pluralName: "Copilot Action Priorities",
icon: IconProp.Bolt,
tableDescription: "Priority of Copilot Actions",
})
@Entity({
name: "CopilotActionTypePriority",
})
export default class CopilotActionTypePriority extends BaseModel {
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: false,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "codeRepositoryId",
type: TableColumnType.Entity,
modelType: CodeRepository,
title: "Code Repository",
description:
"Relation to CodeRepository Resource in which this object belongs",
})
@ManyToOne(
() => {
return CodeRepository;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "codeRepositoryId" })
public codeRepository?: CodeRepository = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Code Repository ID",
description:
"ID of your OneUptime Code Repository in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public codeRepositoryId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: "Copilot Action Type",
required: true,
description: "Copilot Action Type for this Code Repository",
})
@Column({
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
nullable: false,
})
public actionType?: CopilotActionType = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotAction,
],
update: [],
})
@TableColumn({
type: TableColumnType.Number,
title: "Priority",
required: true,
description: "Priority of Copilot Action Type for this Code Repository",
})
@Column({
type: ColumnType.Number,
nullable: false,
default: 1,
})
public priority?: number = undefined;
}

View file

@ -1,637 +0,0 @@
import Label from "./Label";
import Project from "./Project";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
import CodeRepositoryType from "../../Types/CodeRepository/CodeRepositoryType";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
import AccessControlColumn from "../../Types/Database/AccessControlColumn";
import ColumnLength from "../../Types/Database/ColumnLength";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import UniqueColumnBy from "../../Types/Database/UniqueColumnBy";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import {
Column,
Entity,
Index,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
} from "typeorm";
@AccessControlColumn("labels")
@EnableDocumentation()
@TenantColumn("projectId")
@TableBillingAccessControl({
create: PlanType.Growth,
read: PlanType.Growth,
update: PlanType.Growth,
delete: PlanType.Growth,
})
@TableAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
delete: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.DeleteCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@EnableWorkflow({
create: true,
delete: true,
update: true,
read: true,
})
@CrudApiEndpoint(new Route("/copilot-code-repository"))
@SlugifyColumn("name", "slug")
@TableMetadata({
tableName: "CopilotCodeRepository",
singularName: "Code Repository",
pluralName: "Code Repositories",
icon: IconProp.SquareStack,
tableDescription:
"A Code Repository is a place where you can store your code and collaborate with others. You can connect your Git Repository to OneUptime and we will improve your code automatically for you.",
})
@Entity({
name: "CopilotCodeRepository",
})
export default class CopilotCodeRepository extends BaseModel {
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: true,
type: TableColumnType.ShortText,
canReadOnRelationQuery: true,
title: "Name",
description: "Any friendly name of this object",
})
@Column({
nullable: false,
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
})
@UniqueColumnBy("projectId")
public name?: string = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@TableColumn({
required: true,
unique: true,
type: TableColumnType.Slug,
computed: true,
title: "Slug",
description: "Friendly globally unique name for your object",
})
@Column({
nullable: false,
type: ColumnType.Slug,
length: ColumnLength.Slug,
})
public slug?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: false,
type: TableColumnType.LongText,
title: "Description",
description: "Friendly description that will help you remember",
})
@Column({
nullable: true,
type: ColumnType.LongText,
length: ColumnLength.LongText,
})
public description?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: false,
type: TableColumnType.EntityArray,
modelType: Label,
title: "Labels",
description:
"Relation to Labels Array where this object is categorized in.",
})
@ManyToMany(
() => {
return Label;
},
{ eager: false },
)
@JoinTable({
name: "CopilotCodeRepositoryLabel",
inverseJoinColumn: {
name: "labelId",
referencedColumnName: "_id",
},
joinColumn: {
name: "CopilotCodeRepositoryId",
referencedColumnName: "_id",
},
})
public labels?: Array<Label> = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
isDefaultValueColumn: false,
computed: true,
title: "Secret Token",
description:
"Secret Token for this code repository. This is used to connect this code repository to OneUptime.",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public secretToken?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: true,
type: TableColumnType.ShortText,
canReadOnRelationQuery: true,
title: "Main Branch Name",
description: "Name of the main branch of this repository",
})
@Column({
nullable: false,
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
default: "master",
})
public mainBranchName?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: true,
type: TableColumnType.ShortText,
canReadOnRelationQuery: true,
title: "Repository Hosted At",
description:
"Where is this repository hosted at? GitHub, GitLab, Bitbucket, etc.",
})
@Column({
nullable: false,
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
default: CodeRepositoryType.GitHub,
})
public repositoryHostedAt?: CodeRepositoryType = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: true,
type: TableColumnType.ShortText,
canReadOnRelationQuery: true,
title: "Organization Name",
description:
"Name of the organization where this repo belongs. Eg: Your GitHub Organization Name",
})
@Column({
nullable: false,
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
})
public organizationName?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: true,
type: TableColumnType.ShortText,
canReadOnRelationQuery: true,
title: "Repository Name",
description: "Name of the repository. Eg: Your GitHub Repository Name",
})
@Column({
nullable: false,
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
})
public repositoryName?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditCopilotCodeRepository,
],
})
@TableColumn({
required: false,
type: TableColumnType.Date,
title: "Last Copilot Run Date Time",
description: "When did the last Copilot run on this repository?",
})
@Column({
nullable: true,
type: ColumnType.Date,
})
public lastCopilotRunDateTime?: Date = undefined;
}

View file

@ -1,470 +0,0 @@
import CodeRepository from "./CopilotCodeRepository";
import Project from "./Project";
import ServiceCatalog from "./ServiceCatalog";
import ServiceCopilotCodeRepository from "./ServiceCopilotCodeRepository";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import PullRequestState from "../../Types/CodeRepository/PullRequestState";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
@CanAccessIfCanReadOn("codeRepository")
@EnableDocumentation()
@TenantColumn("projectId")
@TableAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
delete: [],
update: [],
})
@EnableWorkflow({
create: true,
delete: false,
update: true,
})
@CrudApiEndpoint(new Route("/copilot-pull-request"))
@TableMetadata({
tableName: "CopilotPullRequest",
singularName: "Copilot Pull Request",
pluralName: "Copilot Pull Requests",
icon: IconProp.Bolt,
tableDescription:
"List of pull requests created by Copilot and status of those requests.",
})
@Entity({
name: "CopilotPullRequest",
})
export default class CopilotPullRequest extends BaseModel {
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: false,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "codeRepositoryId",
type: TableColumnType.Entity,
modelType: CodeRepository,
title: "Code Repository",
description:
"Relation to CodeRepository Resource in which this object belongs",
})
@ManyToOne(
() => {
return CodeRepository;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "codeRepositoryId" })
public codeRepository?: CodeRepository = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Code Repository ID",
description:
"ID of your OneUptime Code Repository in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public codeRepositoryId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "serviceCatalogId",
type: TableColumnType.Entity,
required: false,
modelType: ServiceCatalog,
title: "Service Catalog",
description:
"Relation to Service Catalog Resource in which this object belongs",
})
@ManyToOne(
() => {
return ServiceCatalog;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "serviceCatalogId" })
public serviceCatalog?: ServiceCatalog = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: false,
canReadOnRelationQuery: true,
title: "Service Catalog ID",
description:
"ID of your OneUptime ServiceCatalog in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public serviceCatalogId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "serviceRepositoryId",
type: TableColumnType.Entity,
required: false,
modelType: ServiceCopilotCodeRepository,
title: "Service Repository",
description:
"Relation to Service Repository Resource in which this object belongs",
})
@ManyToOne(
() => {
return ServiceCopilotCodeRepository;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "serviceRepositoryId" })
public serviceRepository?: ServiceCopilotCodeRepository = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: false,
canReadOnRelationQuery: true,
title: "Service Repository ID",
description:
"ID of your OneUptime Service Repository in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public serviceRepositoryId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
required: false,
isDefaultValueColumn: false,
canReadOnRelationQuery: true,
title: "Pull Request ID",
description:
"ID of Pull Request in the repository where this event was executed and then PR was created.",
})
@Column({
type: ColumnType.ShortText,
nullable: true,
})
public pullRequestId?: string = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: "Copilot Event Status",
canReadOnRelationQuery: true,
description:
"Status of Copilot Event that was triggered for this file in Code Repository",
})
@Column({
type: ColumnType.ShortText,
nullable: false,
})
public copilotPullRequestStatus?: PullRequestState = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadCopilotPullRequest,
],
update: [],
})
@TableColumn({
type: TableColumnType.Boolean,
title: "Is Setup Pull Request",
required: false,
description:
"Is this pull request created by Copilot for setting up the repository?",
})
@Column({
type: ColumnType.Boolean,
nullable: true,
})
public isSetupPullRequest?: boolean = undefined;
}

View file

@ -6,8 +6,6 @@ import ApiKeyPermission from "./ApiKeyPermission";
import BillingInvoice from "./BillingInvoice";
import BillingPaymentMethods from "./BillingPaymentMethod";
import CallLog from "./CallLog";
import CopilotCodeRepository from "./CopilotCodeRepository";
import CopilotAction from "./CopilotAction";
// Date migration
import DataMigration from "./DataMigration";
import Domain from "./Domain";
@ -98,7 +96,6 @@ import ScheduledMaintenanceStateTimeline from "./ScheduledMaintenanceStateTimeli
import ServiceCatalog from "./ServiceCatalog";
import ServiceCatalogOwnerTeam from "./ServiceCatalogOwnerTeam";
import ServiceCatalogOwnerUser from "./ServiceCatalogOwnerUser";
import ServiceCopilotCodeRepository from "./ServiceCopilotCodeRepository";
// Short link.
import ShortLink from "./ShortLink";
// SMS
@ -150,7 +147,6 @@ import UserSms from "./UserSMS";
import Workflow from "./Workflow";
import WorkflowLog from "./WorkflowLog";
import WorkflowVariables from "./WorkflowVariable";
import CopilotPullRequest from "./CopilotPullRequest";
import ServiceCatalogDependency from "./ServiceCatalogDependency";
import ServiceCatalogMonitor from "./ServiceCatalogMonitor";
import ServiceCatalogTelemetryService from "./ServiceCatalogTelemetryService";
@ -161,7 +157,6 @@ import UserWebAuthn from "./UserWebAuthn";
import TelemetryIngestionKey from "./TelemetryIngestionKey";
import TelemetryException from "./TelemetryException";
import CopilotActionTypePriority from "./CopilotActionTypePriority";
import ScheduledMaintenanceTemplate from "./ScheduledMaintenanceTemplate";
import ScheduledMaintenanceTemplateOwnerTeam from "./ScheduledMaintenanceTemplateOwnerTeam";
import ScheduledMaintenanceTemplateOwnerUser from "./ScheduledMaintenanceTemplateOwnerUser";
@ -374,12 +369,6 @@ const AllModelTypes: Array<{
ServiceCatalogMonitor,
ServiceCatalogTelemetryService,
CopilotCodeRepository,
CopilotAction,
ServiceCopilotCodeRepository,
CopilotPullRequest,
CopilotActionTypePriority,
ProbeOwnerTeam,
ProbeOwnerUser,

View file

@ -1,544 +0,0 @@
import CodeRepository from "./CopilotCodeRepository";
import Project from "./Project";
import ServiceCatalog from "./ServiceCatalog";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
import ColumnLength from "../../Types/Database/ColumnLength";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
@CanAccessIfCanReadOn("codeRepositoryId")
@EnableDocumentation()
@TenantColumn("projectId")
@TableBillingAccessControl({
create: PlanType.Growth,
read: PlanType.Growth,
update: PlanType.Growth,
delete: PlanType.Growth,
})
@TableAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
delete: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.DeleteServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@EnableWorkflow({
create: true,
delete: true,
update: true,
read: true,
})
@CrudApiEndpoint(new Route("/service-copilot-code-repository"))
@TableMetadata({
tableName: "ServiceCopilotCodeRepository",
singularName: "Service Code Repository for Copilot",
pluralName: "Service Code Repositories for Copilot",
icon: IconProp.SquareStack,
tableDescription:
"Add services to your code repository to categorize and manage them easily. This will help copilot understand and generate code.",
})
@Entity({
name: "ServiceCopilotCodeRepository",
})
export default class ServiceCopilotCodeRepository extends BaseModel {
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@TableColumn({
required: true,
isDefaultValueColumn: true,
type: TableColumnType.LongText,
canReadOnRelationQuery: true,
title: "Path in Repository",
description: "Path in your code repository where this service is located",
defaultValue: "/",
})
@Column({
nullable: false,
type: ColumnType.LongText,
length: ColumnLength.LongText,
default: "/",
})
public servicePathInRepository?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@TableColumn({
required: false,
isDefaultValueColumn: true,
type: TableColumnType.Number,
canReadOnRelationQuery: true,
title: "Limit Number of Open Pull Requests Count",
description: "Limit Number of Open Pull Requests Count for this service",
})
@Column({
nullable: true,
type: ColumnType.Number,
default: 3,
})
public limitNumberOfOpenPullRequestsCount?: number = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@TableColumn({
required: true,
isDefaultValueColumn: true,
type: TableColumnType.Boolean,
canReadOnRelationQuery: true,
title: "Enable Pull Requests",
description:
"Copilot will automatically improve your code by creating pull requests for this service",
})
@Column({
nullable: false,
type: ColumnType.Boolean,
default: true,
})
public enablePullRequests?: boolean = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@TableColumn({
manyToOneRelationColumn: "codeRepositoryId",
type: TableColumnType.Entity,
modelType: CodeRepository,
title: "Code Repository",
description:
"Relation to CodeRepository Resource in which this object belongs",
})
@ManyToOne(
() => {
return CodeRepository;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "codeRepositoryId" })
public codeRepository?: CodeRepository = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Code Repository ID",
description:
"ID of your OneUptime Code Repository in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public codeRepositoryId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@TableColumn({
manyToOneRelationColumn: "serviceCatalogId",
type: TableColumnType.Entity,
modelType: ServiceCatalog,
title: "Service Catalog",
description:
"Relation to Service Catalog Resource in which this object belongs",
})
@ManyToOne(
() => {
return ServiceCatalog;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "serviceCatalogId" })
public serviceCatalog?: ServiceCatalog = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceCopilotCodeRepository,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceCopilotCodeRepository,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceCopilotCodeRepository,
],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Service Catalog ID",
description:
"ID of your OneUptime ServiceCatalog in which this object belongs",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public serviceCatalogId?: ObjectID = undefined;
}

View file

@ -1,418 +0,0 @@
import CopilotCodeRepository from "../../Models/DatabaseModels/CopilotCodeRepository";
import CopilotActionService, {
Service as CopilotActionServiceType,
} from "../Services/CopilotActionService";
import {
ExpressRequest,
ExpressResponse,
NextFunction,
} from "../Utils/Express";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import CopilotAction from "../../Models/DatabaseModels/CopilotAction";
import CopilotCodeRepositoryService from "../Services/CopilotCodeRepositoryService";
import CodeRepositoryAuthorization from "../Middleware/CodeRepositoryAuthorization";
import CopilotActionStatus from "../../Types/Copilot/CopilotActionStatus";
import CopilotActionTypePriority from "../../Models/DatabaseModels/CopilotActionTypePriority";
import CopilotActionTypePriorityService from "../Services/CopilotActionTypePriorityService";
import SortOrder from "../../Types/BaseDatabase/SortOrder";
import JSONFunctions from "../../Types/JSONFunctions";
import CopilotActionType from "../../Types/Copilot/CopilotActionType";
import { JSONObject } from "../../Types/JSON";
import OneUptimeDate from "../../Types/Date";
export default class CopilotActionAPI extends BaseAPI<
CopilotAction,
CopilotActionServiceType
> {
public constructor() {
super(CopilotAction, CopilotActionService);
this.router.get(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/copilot-action-types-by-priority/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
const copilotActionTypes: Array<CopilotActionTypePriority> =
await CopilotActionTypePriorityService.findBy({
query: {
codeRepositoryId: codeRepository.id!,
},
select: {
_id: true,
actionType: true,
priority: true,
},
skip: 0,
sort: {
priority: SortOrder.Ascending,
},
limit: LIMIT_PER_PROJECT,
props: {
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
actionTypes: CopilotActionTypePriority.toJSONArray(
copilotActionTypes,
CopilotActionTypePriority,
),
});
} catch (err) {
next(err);
}
},
);
this.router.get(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/copilot-actions-in-queue/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const serviceCatalogId: string = req.body["serviceCatalogId"]!;
if (!serviceCatalogId) {
throw new BadDataException("Service catalog id is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
const copilotActions: Array<CopilotAction> =
await CopilotActionService.findBy({
query: {
codeRepositoryId: codeRepository.id!,
serviceCatalogId: new ObjectID(serviceCatalogId),
copilotActionStatus: CopilotActionStatus.IN_QUEUE,
},
select: {
_id: true,
codeRepositoryId: true,
serviceCatalogId: true,
copilotActionStatus: true,
copilotActionType: true,
copilotActionProp: true,
createdAt: true,
copilotPullRequest: {
_id: true,
pullRequestId: true,
copilotPullRequestStatus: true,
},
},
skip: 0,
limit: LIMIT_PER_PROJECT,
props: {
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
copilotActions: CopilotAction.toJSONArray(
copilotActions,
CopilotAction,
),
});
} catch (err) {
next(err);
}
},
);
this.router.get(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/get-copilot-action/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const serviceCatalogId: string = req.body["serviceCatalogId"]!;
if (!serviceCatalogId) {
throw new BadDataException("Service catalog id is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
const actionType: CopilotActionType = req.body["actionType"]!;
if (!actionType) {
throw new BadDataException("Action type is required");
}
const actionProps: JSONObject = req.body["actionProps"]!;
const copilotAction: CopilotAction | null =
await CopilotActionService.findOneBy({
query: {
codeRepositoryId: codeRepository.id!,
serviceCatalogId: new ObjectID(serviceCatalogId),
copilotActionType: actionType,
copilotActionProp: actionProps as any,
},
select: {
_id: true,
codeRepositoryId: true,
serviceCatalogId: true,
copilotActionStatus: true,
copilotActionType: true,
createdAt: true,
copilotPullRequest: {
_id: true,
pullRequestId: true,
copilotPullRequestStatus: true,
},
},
sort: {
createdAt: SortOrder.Descending,
},
props: {
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
copilotAction: copilotAction
? CopilotAction.toJSONObject(copilotAction, CopilotAction)
: null,
});
} catch (err) {
next(err);
}
},
);
this.router.post(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/create-copilot-action/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
projectId: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
const copilotAction: CopilotAction = CopilotAction.fromJSON(
req.body["copilotAction"],
CopilotAction,
) as CopilotAction;
copilotAction.codeRepositoryId = codeRepository.id!;
copilotAction.projectId = codeRepository.projectId!;
copilotAction.copilotActionStatus = CopilotActionStatus.IN_QUEUE;
const createdAction: CopilotAction =
await CopilotActionService.create({
data: copilotAction,
props: {
isRoot: true,
},
});
return Response.sendEntityResponse(
req,
res,
createdAction,
CopilotAction,
);
} catch (err) {
next(err);
}
},
);
this.router.post(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/update-copilot-action/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
projectId: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
req.body = JSONFunctions.deserialize(req.body);
const {
actionStatus,
pullRequestId,
commitHash,
statusMessage,
logs,
actionId,
}: {
actionStatus: CopilotActionStatus;
pullRequestId?: ObjectID | undefined;
commitHash?: string | undefined;
statusMessage?: string | undefined;
logs?: Array<string> | undefined;
actionId: ObjectID;
} = req.body;
const exisingAction: CopilotAction | null =
await CopilotActionService.findOneBy({
query: {
_id: actionId,
codeRepositoryId: codeRepository.id!,
},
select: {
_id: true,
},
props: {
isRoot: true,
},
});
if (!exisingAction) {
throw new BadDataException("Action not found");
}
await CopilotActionService.updateOneBy({
query: {
_id: actionId,
codeRepositoryId: codeRepository.id!,
},
data: {
copilotActionStatus: actionStatus!,
copilotPullRequestId: pullRequestId!,
commitHash: commitHash!,
statusMessage: statusMessage!,
statusChangedAt: OneUptimeDate.getCurrentDate(),
logs: logs?.join("\n") || "",
},
props: {
isRoot: true,
},
});
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
next(err);
}
},
);
}
}

View file

@ -1,127 +0,0 @@
import OneUptimeDate from "../../Types/Date";
import CodeRepositoryAuthorization from "../Middleware/CodeRepositoryAuthorization";
import CopilotCodeRepositoryService, {
Service as CopilotCodeRepositoryServiceType,
} from "../Services/CopilotCodeRepositoryService";
import ServiceCopilotCodeRepositoryService from "../Services/ServiceCopilotCodeRepositoryService";
import {
ExpressRequest,
ExpressResponse,
NextFunction,
} from "../Utils/Express";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import CopilotCodeRepository from "../../Models/DatabaseModels/CopilotCodeRepository";
import ServiceCopilotCodeRepository from "../../Models/DatabaseModels/ServiceCopilotCodeRepository";
export default class CopilotCodeRepositoryAPI extends BaseAPI<
CopilotCodeRepository,
CopilotCodeRepositoryServiceType
> {
public constructor() {
super(CopilotCodeRepository, CopilotCodeRepositoryService);
this.router.get(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/is-valid/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
next(err);
}
},
);
this.router.get(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/get-code-repository/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
name: true,
mainBranchName: true,
organizationName: true,
repositoryHostedAt: true,
repositoryName: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
// update last run time.
await CopilotCodeRepositoryService.updateOneById({
id: codeRepository.id!,
data: {
lastCopilotRunDateTime: OneUptimeDate.getCurrentDate(),
},
props: {
isRoot: true,
},
});
const servicesRepository: Array<ServiceCopilotCodeRepository> =
await ServiceCopilotCodeRepositoryService.findBy({
query: {
codeRepositoryId: codeRepository.id!,
enablePullRequests: true,
},
select: {
serviceCatalog: {
name: true,
_id: true,
techStack: true,
},
servicePathInRepository: true,
limitNumberOfOpenPullRequestsCount: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
props: {
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
codeRepository: CopilotCodeRepository.toJSON(
codeRepository,
CopilotCodeRepository,
),
servicesRepository: ServiceCopilotCodeRepository.toJSONArray(
servicesRepository,
ServiceCopilotCodeRepository,
),
});
} catch (err) {
next(err);
}
},
);
}
}

View file

@ -1,243 +0,0 @@
import CopilotCodeRepository from "../../Models/DatabaseModels/CopilotCodeRepository";
import CopilotPullRequestService, {
Service as CopilotPullRequestServiceType,
} from "../Services/CopilotPullRequestService";
import {
ExpressRequest,
ExpressResponse,
NextFunction,
} from "../Utils/Express";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import CopilotCodeRepositoryService from "../Services/CopilotCodeRepositoryService";
import CodeRepositoryAuthorization from "../Middleware/CodeRepositoryAuthorization";
import CopilotPullRequest from "../../Models/DatabaseModels/CopilotPullRequest";
import PullRequestState from "../../Types/CodeRepository/PullRequestState";
export default class CopilotPullRequestAPI extends BaseAPI<
CopilotPullRequest,
CopilotPullRequestServiceType
> {
public constructor() {
super(CopilotPullRequest, CopilotPullRequestService);
this.router.get(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/get-pending-pull-requests/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
const copilotPullRequests: Array<CopilotPullRequest> =
await CopilotPullRequestService.findBy({
query: {
codeRepositoryId: codeRepository.id!,
copilotPullRequestStatus: PullRequestState.Open, // only get pending pull requests
},
select: {
_id: true,
codeRepositoryId: true,
projectId: true,
copilotPullRequestStatus: true,
pullRequestId: true,
isSetupPullRequest: true,
serviceCatalogId: true,
serviceRepositoryId: true,
},
skip: 0,
limit: LIMIT_PER_PROJECT,
props: {
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
copilotPullRequests: CopilotPullRequest.toJSONArray(
copilotPullRequests,
CopilotPullRequest,
),
});
} catch (err) {
next(err);
}
},
);
this.router.post(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/add-pull-request/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
projectId: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
if (!req.body["copilotPullRequest"]) {
throw new BadDataException("Copilot pull request is required");
}
const copilotPullRequest: CopilotPullRequest =
CopilotPullRequest.fromJSON(
req.body["copilotPullRequest"],
CopilotPullRequest,
) as CopilotPullRequest;
copilotPullRequest.codeRepositoryId = codeRepository.id!;
copilotPullRequest.projectId = codeRepository.projectId!;
copilotPullRequest.copilotPullRequestStatus = PullRequestState.Open;
const createdPullRequest: CopilotPullRequest =
await CopilotPullRequestService.create({
data: copilotPullRequest,
props: {
isRoot: true,
},
});
return Response.sendEntityResponse(
req,
res,
createdPullRequest,
CopilotPullRequest,
);
} catch (err) {
next(err);
}
},
);
this.router.post(
`${new this.entityType()
.getCrudApiPath()
?.toString()}/update-pull-request-status/:secretkey`,
CodeRepositoryAuthorization.isAuthorizedRepository,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const codeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
projectId: true,
},
props: {
isRoot: true,
},
});
if (!codeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
if (!req.body["copilotPullRequestId"]) {
throw new BadDataException("Copilot pull request is required");
}
// check copilotPullRequestStatus
if (!req.body["copilotPullRequestStatus"]) {
throw new BadDataException(
"Copilot pull request status is required",
);
}
const copilotPullRequestId: ObjectID = new ObjectID(
req.body["copilotPullRequestId"],
);
const copilotPullRequest: CopilotPullRequest | null =
await CopilotPullRequestService.findOneById({
id: copilotPullRequestId,
select: {
copilotPullRequestStatus: true,
pullRequestId: true,
},
props: {
isRoot: true,
},
});
if (!copilotPullRequest) {
throw new BadDataException("Copilot pull request not found");
}
await CopilotPullRequestService.updateOneById({
id: copilotPullRequestId,
data: {
copilotPullRequestStatus: req.body["copilotPullRequestStatus"],
},
props: {
isRoot: true,
},
});
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
next(err);
}
},
);
}
}

View file

@ -1,50 +0,0 @@
import BadDataException from "../../Types/Exception/BadDataException";
import {
ExpressRequest,
ExpressResponse,
NextFunction,
} from "../Utils/Express";
import CopilotCodeRepository from "../../Models/DatabaseModels/CopilotCodeRepository";
import CopilotCodeRepositoryService from "../Services/CopilotCodeRepositoryService";
import ObjectID from "../../Types/ObjectID";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export default class CopilotCodeRepositoryAuthorization {
@CaptureSpan()
public static async isAuthorizedRepository(
req: ExpressRequest,
_res: ExpressResponse,
next: NextFunction,
): Promise<void> {
try {
const secretkey: string = req.params["secretkey"]!;
if (!secretkey) {
throw new BadDataException("Secret key is required");
}
const CopilotCodeRepository: CopilotCodeRepository | null =
await CopilotCodeRepositoryService.findOneBy({
query: {
secretToken: new ObjectID(secretkey),
},
select: {
_id: true,
},
props: {
isRoot: true,
},
});
if (!CopilotCodeRepository) {
throw new BadDataException(
"Code repository not found. Secret key is invalid.",
);
}
next();
} catch (err) {
next(err);
}
}
}

View file

@ -1,10 +0,0 @@
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/CopilotAction";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
}
export default new Service();

View file

@ -1,67 +0,0 @@
import CopilotActionType from "../../Types/Copilot/CopilotActionType";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import CreateBy from "../Types/Database/CreateBy";
import { OnCreate } from "../Types/Database/Hooks";
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/CopilotActionTypePriority";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
@CaptureSpan()
protected override async onBeforeCreate(
createBy: CreateBy<Model>,
): Promise<OnCreate<Model>> {
// check if the action exits witht he same name exists in the same repo.
const actionType: CopilotActionType | undefined = createBy.data.actionType;
const codeRepositoryId: ObjectID | undefined =
createBy.data.codeRepositoryId;
if (!actionType) {
throw new BadDataException("ActionType is required");
}
if (!codeRepositoryId) {
throw new BadDataException("CodeRepositoryId is required");
}
const existingItem: Model | null = await this.findOneBy({
query: {
actionType,
codeRepositoryId,
},
props: {
isRoot: true,
},
});
if (existingItem) {
throw new BadDataException(
"Action Type already exists for this repository.",
);
}
// check if the priority is in between 1 and 5.
const priority: number | undefined = createBy.data.priority;
if (!priority) {
throw new BadDataException("Priority is required");
}
if (priority < 1 || priority > 5) {
throw new BadDataException("Priority must be between 1 and 5");
}
return {
createBy: createBy,
carryForward: null,
};
}
}
export default new Service();

View file

@ -1,62 +0,0 @@
import CreateBy from "../Types/Database/CreateBy";
import { OnCreate } from "../Types/Database/Hooks";
import DatabaseService from "./DatabaseService";
import ObjectID from "../../Types/ObjectID";
import Model from "../../Models/DatabaseModels/CopilotCodeRepository";
import {
CopilotActionTypeData,
CopilotActionTypeUtil,
} from "../../Types/Copilot/CopilotActionType";
import CopilotActionTypePriority from "../../Models/DatabaseModels/CopilotActionTypePriority";
import CopilotActionTypePriorityService from "./CopilotActionTypePriorityService";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
@CaptureSpan()
protected override async onBeforeCreate(
createBy: CreateBy<Model>,
): Promise<OnCreate<Model>> {
createBy.data.secretToken = ObjectID.generate();
return {
carryForward: null,
createBy: createBy,
};
}
@CaptureSpan()
protected override async onCreateSuccess(
_onCreate: OnCreate<Model>,
createdItem: Model,
): Promise<Model> {
// add all the actions.
const repo: Model = createdItem;
const defaultCopilotActionTypes: Array<CopilotActionTypeData> =
CopilotActionTypeUtil.getAllCopilotActionTypes();
for (const defaultAction of defaultCopilotActionTypes) {
const copilotActionTypePriority: CopilotActionTypePriority =
new CopilotActionTypePriority();
copilotActionTypePriority.projectId = repo.projectId!;
copilotActionTypePriority.actionType = defaultAction.type;
copilotActionTypePriority.priority = defaultAction.defaultPriority;
copilotActionTypePriority.codeRepositoryId = repo.id!;
await CopilotActionTypePriorityService.create({
data: copilotActionTypePriority,
props: {
isRoot: true,
},
});
}
return createdItem;
}
}
export default new Service();

View file

@ -1,10 +0,0 @@
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/CopilotPullRequest";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
}
export default new Service();

View file

@ -11,8 +11,6 @@ import BillingPaymentMethodsService from "./BillingPaymentMethodService";
import BillingService from "./BillingService";
import CallLogService from "./CallLogService";
import CallService from "./CallService";
import CodeRepositoryService from "./CopilotCodeRepositoryService";
import CopilotActionService from "./CopilotActionService";
import DataMigrationService from "./DataMigrationService";
import DomainService from "./DomainService";
import EmailLogService from "./EmailLogService";
@ -89,7 +87,6 @@ import ServiceCatalogOwnerUserService from "./ServiceCatalogOwnerUserService";
import ServiceCatalogService from "./ServiceCatalogService";
import ServiceCatalogMonitorService from "./ServiceCatalogMonitorService";
import ServiceCatalogTelemetryServiceService from "./ServiceCatalogTelemetryServiceService";
import ServiceCopilotCodeRepositoryService from "./ServiceCopilotCodeRepositoryService";
import ShortLinkService from "./ShortLinkService";
// SMS Log Service
import SmsLogService from "./SmsLogService";
@ -139,11 +136,9 @@ import WorkflowLogService from "./WorkflowLogService";
import WorkflowService from "./WorkflowService";
import WorkflowVariablesService from "./WorkflowVariableService";
import AnalyticsBaseModel from "../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
import CopilotPullRequestService from "./CopilotPullRequestService";
import ServiceCatalogDependencyService from "./ServiceCatalogDependencyService";
import TelemetryExceptionService from "./TelemetryExceptionService";
import ExceptionInstanceService from "./ExceptionInstanceService";
import CopilotActionTypePriorityService from "./CopilotActionTypePriorityService";
import ScheduledMaintenanceTemplateService from "./ScheduledMaintenanceTemplateService";
import ScheduledMaintenanceTemplateOwnerTeamService from "./ScheduledMaintenanceTemplateOwnerTeamService";
import ScheduledMaintenanceTemplateOwnerUserService from "./ScheduledMaintenanceTemplateOwnerUserService";
@ -327,12 +322,6 @@ const services: Array<BaseService> = [
ServiceCatalogMonitorService,
ServiceCatalogTelemetryServiceService,
CodeRepositoryService,
CopilotActionService,
ServiceCopilotCodeRepositoryService,
CopilotPullRequestService,
CopilotActionTypePriorityService,
TelemetryExceptionService,
// scheduled maintenance templates

View file

@ -1,10 +0,0 @@
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/ServiceCopilotCodeRepository";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
}
export default new Service();

View file

@ -1,3 +0,0 @@
export default interface DirectoryActionProp {
directoryPath: string;
}

View file

@ -1,4 +0,0 @@
export default interface ExceptionActionProp {
fingerprint: string;
message: string;
}

View file

@ -1,7 +0,0 @@
export default interface FileActionProp {
filePath: string;
// if startLineNumber and endLineNumber are not provided, the whole file will be considered
startLineNumber?: number | undefined;
endLineNumber?: number | undefined;
}

View file

@ -1,5 +0,0 @@
export default interface FunctionActionProp {
filePath: string;
className?: string | undefined; // some languages are not class based.
functionName: string;
}

View file

@ -1,96 +0,0 @@
import DirectoryActionProp from "./DirectoryActionProp";
import FileActionProp from "./FileActionProp";
import ExceptionActionProp from "./ExceptionActionProp";
import SpanActionProp from "./SpanActionProp";
import FunctionActionProp from "./FunctionActionProp";
import CopilotActionType from "../CopilotActionType";
type CopilotActionProp =
| DirectoryActionProp
| FileActionProp
| ExceptionActionProp
| SpanActionProp
| FunctionActionProp;
export enum CopilotActionPropType {
Directory = "Directory",
File = "File",
Exception = "Exception",
Span = "Span",
Metric = "Metric",
Function = "Function",
}
export class CopilotActionPropUtil {
public static getCopilotActionPropByActionType(
actionType: CopilotActionType,
): CopilotActionPropType {
if (actionType === CopilotActionType.FIX_EXCEPTIONS) {
return CopilotActionPropType.Exception;
}
if (actionType === CopilotActionType.FIX_PERFORMANCE_ISSUES) {
return CopilotActionPropType.Span;
}
if (actionType === CopilotActionType.FIX_BUGS) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.IMPROVE_LOGS) {
return CopilotActionPropType.File;
}
if (actionType === CopilotActionType.IMPROVE_SPANS) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.IMPROVE_METRICS) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.ADD_LOGS) {
return CopilotActionPropType.File;
}
if (actionType === CopilotActionType.ADD_SPANS) {
return CopilotActionPropType.File;
}
if (actionType === CopilotActionType.ADD_METRICS) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.REFACTOR_CODE) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.WRITE_UNIT_TESTS) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.IMPROVE_UNIT_TESTS) {
return CopilotActionPropType.Function;
}
if (actionType === CopilotActionType.IMPROVE_COMMENTS) {
return CopilotActionPropType.File;
}
if (actionType === CopilotActionType.ADD_COMMENTS) {
return CopilotActionPropType.File;
}
if (actionType === CopilotActionType.ADD_README) {
return CopilotActionPropType.Directory;
}
if (actionType === CopilotActionType.IMPROVE_README) {
return CopilotActionPropType.File;
}
return CopilotActionPropType.File;
}
}
export default CopilotActionProp;

View file

@ -1,4 +0,0 @@
export default interface SpanActionProp {
traceId: string;
spanId?: string;
}

View file

@ -1,114 +0,0 @@
enum CopilotActionStatus {
// Processed States.
PR_CREATED = "Pull Request Created", // PR created and waiting for review
NO_ACTION_REQUIRED = "No Action Required", // Code is all good. No action required. No PR created.
CANNOT_FIX = "Cannot Fix", // OneUptime Copilot tried to fix the issue but failed.
// Processing States
PROCESSING = "Processing", // Action is being processed.
// In Queue
IN_QUEUE = "In Queue", // Action is in queue.
}
export interface CopilotActionStatusData {
status: CopilotActionStatus;
description: string;
}
export class CopilotActionStatusUtil {
public static getAllCopilotActionStatuses(): Array<CopilotActionStatus> {
return [
CopilotActionStatus.PR_CREATED,
CopilotActionStatus.NO_ACTION_REQUIRED,
CopilotActionStatus.CANNOT_FIX,
CopilotActionStatus.PROCESSING,
CopilotActionStatus.IN_QUEUE,
];
}
public static getCopilotActionStatus(status: string): CopilotActionStatus {
switch (status) {
case CopilotActionStatus.PR_CREATED:
return CopilotActionStatus.PR_CREATED;
case CopilotActionStatus.NO_ACTION_REQUIRED:
return CopilotActionStatus.NO_ACTION_REQUIRED;
case CopilotActionStatus.CANNOT_FIX:
return CopilotActionStatus.CANNOT_FIX;
case CopilotActionStatus.PROCESSING:
return CopilotActionStatus.PROCESSING;
case CopilotActionStatus.IN_QUEUE:
return CopilotActionStatus.IN_QUEUE;
default:
throw new Error(`Invalid CopilotActionStatus: ${status}`);
}
}
public static isCopilotActionStatus(status: string): boolean {
return CopilotActionStatusUtil.getAllCopilotActionStatuses().includes(
status as CopilotActionStatus,
);
}
public static isCopilotActionStatusArray(statuses: Array<string>): boolean {
return statuses.every((status: string) => {
return CopilotActionStatusUtil.isCopilotActionStatus(status);
});
}
// get processing status
public static getProcessingStatus(): CopilotActionStatus {
return CopilotActionStatus.PROCESSING;
}
// get in queue status
public static getInQueueStatus(): CopilotActionStatus {
return CopilotActionStatus.IN_QUEUE;
}
// get processed status
public static getProcessedStatus(): Array<CopilotActionStatus> {
return [
CopilotActionStatus.PR_CREATED,
CopilotActionStatus.NO_ACTION_REQUIRED,
CopilotActionStatus.CANNOT_FIX,
];
}
// get copilot actiomn status data
public static getCopilotActionStatusData(
status: CopilotActionStatus,
): CopilotActionStatusData {
switch (status) {
case CopilotActionStatus.PR_CREATED:
return {
status: CopilotActionStatus.PR_CREATED,
description: "Pull Request Created",
};
case CopilotActionStatus.NO_ACTION_REQUIRED:
return {
status: CopilotActionStatus.NO_ACTION_REQUIRED,
description: "No Action Required",
};
case CopilotActionStatus.CANNOT_FIX:
return {
status: CopilotActionStatus.CANNOT_FIX,
description: "Cannot Fix",
};
case CopilotActionStatus.PROCESSING:
return {
status: CopilotActionStatus.PROCESSING,
description: "Processing",
};
case CopilotActionStatus.IN_QUEUE:
return {
status: CopilotActionStatus.IN_QUEUE,
description: "In Queue",
};
default:
throw new Error(`Invalid CopilotActionStatus: ${status}`);
}
}
}
export default CopilotActionStatus;

View file

@ -1,212 +0,0 @@
enum CopilotActionType {
IMPROVE_COMMENTS = "Improve Comments",
ADD_COMMENTS = "Add Comments",
IMPROVE_README = "Improve Readme",
ADD_README = "Add Readme",
FIX_GRAMMAR_AND_SPELLING = "Fix Grammar and Spelling",
IMPROVE_VARIABLE_NAMES = "Improve Variable Names",
REFACTOR_CODE = "Refactor Code",
WRITE_UNIT_TESTS = "Write Unit Tests",
IMPROVE_UNIT_TESTS = "Improve Unit Tests",
IMPROVE_LOGS = "Improve Logs",
ADD_LOGS = "Add Logs",
IMPROVE_SPANS = "Improve Spans",
ADD_SPANS = "Add Spans",
IMPROVE_METRICS = "Improve Metrics",
ADD_METRICS = "Add Metrics",
FIX_EXCEPTIONS = "Fix Exceptions",
FIX_PERFORMANCE_ISSUES = "Fix Performance Issues",
FIX_BUGS = "Fix Bugs",
// SETUP_ACTIONS
SETUP_OPEN_TELEMETRY = "Setup OpenTelemetry",
// Setup Unit Test Framework
SETUP_UNIT_TEST_FRAMEWORK = "Setup Unit Test Framework",
}
export interface CopilotActionTypeData {
type: CopilotActionType;
description: string;
defaultPriority: number;
dependsOn: Array<CopilotActionType>;
}
export class CopilotActionTypeUtil {
public static getAllCopilotActionTypes(): Array<CopilotActionTypeData> {
return [
// Fix broken code.
{
type: CopilotActionType.FIX_EXCEPTIONS,
description: "Fix exceptions in your codebase",
defaultPriority: 1,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.FIX_PERFORMANCE_ISSUES,
description: "Fix performance issues in your codebase",
defaultPriority: 1,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.FIX_BUGS,
description: "Fix simple bugs and small issues in your codebase",
defaultPriority: 1,
dependsOn: [],
},
// Improve debugging.
// add logs, metircs and spans.
{
type: CopilotActionType.ADD_LOGS,
description: "Add OpenTelemetry logs in your codebase",
defaultPriority: 2,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.ADD_SPANS,
description: "Add OpenTelemetry spans in your codebase",
defaultPriority: 2,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.ADD_METRICS,
description: "Add OpenTelemetry metrics in your codebase",
defaultPriority: 2,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.IMPROVE_LOGS,
description:
"Improve OpenTelemetry logs in your codebase where required to make debugging easier.",
defaultPriority: 2,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.IMPROVE_SPANS,
description:
"Improve OpenTelemetry spans in your codebase where required to make debugging easier.",
defaultPriority: 2,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
{
type: CopilotActionType.IMPROVE_METRICS,
description:
"Improve OpenTelemetry metrics in your codebase where required to make debugging easier.",
defaultPriority: 2,
dependsOn: [CopilotActionType.SETUP_OPEN_TELEMETRY],
},
// Improve code and test quality.
{
type: CopilotActionType.REFACTOR_CODE,
description: "Refactor code and make it into smaller units",
defaultPriority: 3,
dependsOn: [],
},
{
type: CopilotActionType.WRITE_UNIT_TESTS,
description: "Add unit tests",
defaultPriority: 3,
dependsOn: [CopilotActionType.SETUP_UNIT_TEST_FRAMEWORK],
},
{
type: CopilotActionType.IMPROVE_UNIT_TESTS,
description: "Improve unit tests",
defaultPriority: 3,
dependsOn: [CopilotActionType.SETUP_UNIT_TEST_FRAMEWORK],
},
// add comments.
{
type: CopilotActionType.IMPROVE_COMMENTS,
description: "Improve comments in your codebase",
defaultPriority: 4,
dependsOn: [],
},
{
type: CopilotActionType.ADD_COMMENTS,
description: "Add comments in your codebase",
defaultPriority: 4,
dependsOn: [],
},
// Add or improve README file.
{
type: CopilotActionType.ADD_README,
description: "Add a README file",
defaultPriority: 4,
dependsOn: [],
},
{
type: CopilotActionType.IMPROVE_README,
description: "Improve the README file",
defaultPriority: 4,
dependsOn: [],
},
// Fix grammar and spelling mistakes
{
type: CopilotActionType.FIX_GRAMMAR_AND_SPELLING,
description: "Fix grammar and spelling mistakes",
defaultPriority: 5,
dependsOn: [],
},
{
type: CopilotActionType.IMPROVE_VARIABLE_NAMES,
description: "Improve variable names and make it understandable",
defaultPriority: 5,
dependsOn: [],
},
];
}
public static getSetupActionTypes(): Array<CopilotActionTypeData> {
return [
{
type: CopilotActionType.SETUP_OPEN_TELEMETRY,
description: "Setup OpenTelemetry in your codebase",
defaultPriority: 1,
dependsOn: [],
},
{
type: CopilotActionType.SETUP_UNIT_TEST_FRAMEWORK,
description: "Setup Unit Test Framework in your codebase",
defaultPriority: 1,
dependsOn: [],
},
];
}
public static getCopilotActionType(
type: CopilotActionType,
): CopilotActionTypeData {
return this.getAllCopilotActionTypes().find(
(copilotActionTypeData: CopilotActionTypeData) => {
return copilotActionTypeData.type === type;
},
) as CopilotActionTypeData;
}
// get actions by priority.
public static getActionsByPriority(
priority: number,
): Array<CopilotActionTypeData> {
return this.getAllCopilotActionTypes().filter(
(copilotActionTypeData: CopilotActionTypeData) => {
return copilotActionTypeData.defaultPriority === priority;
},
);
}
}
export default CopilotActionType;

View file

@ -624,18 +624,6 @@ enum Permission {
EditServiceCatalogTelemetryService = "EditServiceCatalogTelemetryService",
ReadServiceCatalogTelemetryService = "ReadServiceCatalogTelemetryService",
CreateCopilotCodeRepository = "CreateCopilotCodeRepository",
DeleteCopilotCodeRepository = "DeleteCopilotCodeRepository",
EditCopilotCodeRepository = "EditCopilotCodeRepository",
ReadCopilotCodeRepository = "ReadCopilotCodeRepository",
ReadCopilotAction = "ReadCopilotAction",
CreateCopilotAction = "CreateCopilotAction",
DeleteCopilotAction = "DeleteCopilotAction",
EditCopilotAction = "EditCopilotAction",
ReadCopilotPullRequest = "ReadCopilotPullRequest",
CreateProbeOwnerTeam = "CreateProbeOwnerTeam",
DeleteProbeOwnerTeam = "DeleteProbeOwnerTeam",
EditProbeOwnerTeam = "EditProbeOwnerTeam",
@ -646,11 +634,6 @@ enum Permission {
EditProbeOwnerUser = "EditProbeOwnerUser",
ReadProbeOwnerUser = "ReadProbeOwnerUser",
CreateServiceCopilotCodeRepository = "CreateServiceCopilotCodeRepository",
DeleteServiceCopilotCodeRepository = "DeleteServiceCopilotCodeRepository",
EditServiceCopilotCodeRepository = "EditServiceCopilotCodeRepository",
ReadServiceCopilotCodeRepository = "ReadServiceCopilotCodeRepository",
CreateTableView = "CreateTableView",
DeleteTableView = "DeleteTableView",
EditTableView = "EditTableView",
@ -3241,102 +3224,6 @@ export class PermissionHelper {
isAccessControlPermission: false,
},
{
permission: Permission.CreateCopilotCodeRepository,
title: "Create Code Repository",
description: "This permission can create Code Repository this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.DeleteCopilotCodeRepository,
title: "Delete Code Repository",
description:
"This permission can delete Code Repository of this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.EditCopilotCodeRepository,
title: "Edit Code Repository",
description:
"This permission can edit Code Repository of this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.ReadCopilotCodeRepository,
title: "Read Code Repository",
description:
"This permission can read Code Repository of this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.CreateServiceCopilotCodeRepository,
title: "Create Service Repository",
description:
"This permission can create Service Repository this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.DeleteServiceCopilotCodeRepository,
title: "Delete Service Repository",
description:
"This permission can delete Service Repository of this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.EditServiceCopilotCodeRepository,
title: "Edit Service Repository",
description:
"This permission can edit Service Repository of this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.ReadServiceCopilotCodeRepository,
title: "Read Service Repository",
description:
"This permission can read Service Repository of this project.",
isAssignableToTenant: true,
isAccessControlPermission: true,
},
{
permission: Permission.ReadCopilotAction,
title: "Read Copilot Event",
description: "This permission can read Copilot Event of this project.",
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.EditCopilotAction,
title: "Edit Copilot Event",
description: "This permission can edit Copilot Event of this project.",
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.DeleteCopilotAction,
title: "Delete Copilot Event",
description:
"This permission can delete Copilot Event of this project.",
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CreateCopilotAction,
title: "Create Copilot Event",
description:
"This permission can create Copilot Event of this project.",
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CreateProbeOwnerTeam,
title: "Create Probe Owner Team",

View file

@ -93,11 +93,6 @@ const ServiceCatalogRoutes: React.LazyExoticComponent<
> = lazy(() => {
return import("./Routes/ServiceCatalogRoutes");
});
const AICopilotRoutes: React.LazyExoticComponent<
React.FunctionComponent<PageComponentProps>
> = lazy(() => {
return import("./Routes/AICopilotRoutes");
});
const IncidentsRoutes: React.LazyExoticComponent<
React.FunctionComponent<PageComponentProps>
> = lazy(() => {
@ -453,12 +448,6 @@ const App: () => JSX.Element = () => {
element={<ServiceCatalogRoutes {...commonPageProps} />}
/>
{/** Reliability Copilot */}
<PageRoute
path={RouteMap[PageMap.AI_COPILOT_ROOT]?.toString() || ""}
element={<AICopilotRoutes {...commonPageProps} />}
/>
{/* Incidents */}
<PageRoute
path={RouteMap[PageMap.INCIDENTS_ROOT]?.toString() || ""}

View file

@ -1,117 +0,0 @@
import React, { FunctionComponent, ReactElement } from "react";
import CopilotActionType from "Common/Types/Copilot/CopilotActionType";
import CopilotActionProp, {
CopilotActionPropType,
CopilotActionPropUtil,
} from "Common/Types/Copilot/CopilotActionProps/Index";
import DirectoryActionProp from "Common/Types/Copilot/CopilotActionProps/DirectoryActionProp";
import FileActionProp from "Common/Types/Copilot/CopilotActionProps/FileActionProp";
import SpanActionProp from "Common/Types/Copilot/CopilotActionProps/SpanActionProp";
import TraceElement from "../../Traces/TraceElement";
import TelemetryExceptionElement from "../../Exceptions/ExceptionElement";
import ExceptionActionProp from "Common/Types/Copilot/CopilotActionProps/ExceptionActionProp";
import FunctionActionProp from "Common/Types/Copilot/CopilotActionProps/FunctionActionProp";
export interface ComponentProps {
actionType: CopilotActionType;
actionProps: CopilotActionProp;
}
const CopilotActionPropViewer: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
if (!props.actionProps) {
return <>-</>;
}
if (!props.actionType) {
return <>-</>;
}
const actionPropType: CopilotActionPropType =
CopilotActionPropUtil.getCopilotActionPropByActionType(props.actionType);
if (actionPropType === CopilotActionPropType.Directory) {
return (
<div>
<p className="text-gray-900">Directory Path</p>
<p>{(props.actionProps as DirectoryActionProp).directoryPath || "-"}</p>
</div>
);
}
if (actionPropType === CopilotActionPropType.File) {
return (
<div>
<p className="text-gray-900">File Path</p>
<p>{(props.actionProps as FileActionProp).filePath || "-"}</p>
</div>
);
}
// exception
if (actionPropType === CopilotActionPropType.Exception) {
return (
<div>
<p className="text-gray-900">Exception</p>
<p>
{(props.actionProps as ExceptionActionProp).fingerprint && (
<TelemetryExceptionElement
message={(props.actionProps as ExceptionActionProp).message}
fingerprint={
(props.actionProps as ExceptionActionProp).fingerprint
}
/>
)}
{!(props.actionProps as ExceptionActionProp).fingerprint && <p>-</p>}
</p>
</div>
);
}
if (actionPropType === CopilotActionPropType.Span) {
return (
<div>
<p className="text-gray-900">Trace ID</p>
<p>
{!(props.actionProps as SpanActionProp).traceId && <p>-</p>}
{(props.actionProps as SpanActionProp).traceId && (
<TraceElement
traceId={(props.actionProps as SpanActionProp).traceId}
/>
)}
</p>
</div>
);
}
if (actionPropType === CopilotActionPropType.Function) {
if (!(props.actionProps as FunctionActionProp).functionName) {
return <>-</>;
}
return (
<div>
<p className="text-gray-900">Details</p>
<p>
<p>
{(props.actionProps as FunctionActionProp).functionName} function
</p>
<p>
{(props.actionProps as FunctionActionProp).className &&
` in ${(props.actionProps as FunctionActionProp).className} Class`}
</p>
<p>
{(props.actionProps as FunctionActionProp).filePath &&
` in ${(props.actionProps as FunctionActionProp).filePath} File`}
</p>
</p>
</div>
);
}
return <>-</>;
};
export default CopilotActionPropViewer;

View file

@ -1,38 +0,0 @@
import { Gray500, Green500, Red500, Yellow500 } from "Common/Types/BrandColors";
import CopilotActionStatus from "Common/Types/Copilot/CopilotActionStatus";
import Pill from "Common/UI/Components/Pill/Pill";
import React, { FunctionComponent, ReactElement } from "react";
export interface ComponentProps {
copilotActionStatus: CopilotActionStatus;
}
const CopilotActionStatusElement: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
if (props.copilotActionStatus === CopilotActionStatus.PR_CREATED) {
return <Pill color={Green500} isMinimal={true} text={"PR Created"} />;
}
if (props.copilotActionStatus === CopilotActionStatus.NO_ACTION_REQUIRED) {
return (
<Pill color={Green500} isMinimal={true} text={"No Action Required"} />
);
}
if (props.copilotActionStatus === CopilotActionStatus.CANNOT_FIX) {
return <Pill color={Red500} text={"Cannot Fix"} />;
}
if (props.copilotActionStatus === CopilotActionStatus.IN_QUEUE) {
return <Pill color={Gray500} text={"In Queue"} />;
}
if (props.copilotActionStatus === CopilotActionStatus.PROCESSING) {
return <Pill color={Yellow500} text={"Processing"} />;
}
return <></>;
};
export default CopilotActionStatusElement;

View file

@ -1,303 +0,0 @@
import ModelTable from "Common/UI/Components/ModelTable/ModelTable";
import FieldType from "Common/UI/Components/Types/FieldType";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useState,
} from "react";
import PullRequestViewElement from "../../CodeRepository/PullRequestView";
import CopilotAction from "Common/Models/DatabaseModels/CopilotAction";
import Query from "Common/Types/BaseDatabase/Query";
import CopilotActionStatus from "Common/Types/Copilot/CopilotActionStatus";
import Columns from "Common/UI/Components/ModelTable/Columns";
import CopilotActionStatusElement from "./CopilotActionStatusElement";
import CodeRepositoryType from "Common/Types/CodeRepository/CodeRepositoryType";
import Modal, { ModalWidth } from "Common/UI/Components/Modal/Modal";
import SimpleLogViewer from "Common/UI/Components/SimpleLogViewer/SimpleLogViewer";
import { ButtonStyleType } from "Common/UI/Components/Button/Button";
import IconProp from "Common/Types/Icon/IconProp";
import ServiceCatalogElement from "../../ServiceCatalog/ServiceElement";
import CopilotActionPropViewer from "./CopilotActionPropViewer";
import ProjectUtil from "Common/UI/Utils/Project";
export interface ComponentProps {
query: Query<CopilotAction>;
repoOrganizationName: string;
repoName: string;
repoType: CodeRepositoryType;
title: string;
description: string;
}
const CopilotActionTable: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const [showViewLogsModal, setShowViewLogsModal] = useState<boolean>(false);
const [logs, setLogs] = useState<string>("");
const [showStatusMessageModal, setShowStatusMessageModal] =
useState<boolean>(false);
const [statusMessage, setStatusMessage] = useState<string>("");
let isPullRequestTable: boolean = false;
if (props.query.copilotActionStatus === CopilotActionStatus.PR_CREATED) {
isPullRequestTable = true;
}
const columns: Columns<CopilotAction> = [
{
field: {
copilotActionType: true,
},
title: "Action Type",
type: FieldType.Text,
},
{
field: {
copilotActionProp: true,
},
title: "More Details",
type: FieldType.Element,
getElement: (item: CopilotAction): ReactElement => {
return (
<CopilotActionPropViewer
actionProps={item.copilotActionProp!}
actionType={item.copilotActionType!}
/>
);
},
},
{
field: {
serviceCatalog: {
name: true,
serviceColor: true,
},
},
title: "Service",
type: FieldType.Element,
getElement: (item: CopilotAction): ReactElement => {
if (!item.serviceCatalog) {
return <p>-</p>;
}
return <ServiceCatalogElement serviceCatalog={item.serviceCatalog} />;
},
},
{
field: {
copilotActionStatus: true,
},
title: "Status",
type: FieldType.Element,
getElement: (item: CopilotAction): ReactElement => {
if (!item.copilotActionStatus) {
return <p>-</p>;
}
return (
<CopilotActionStatusElement
copilotActionStatus={item.copilotActionStatus}
/>
);
},
},
];
const isProcessingAction: boolean =
props.query.copilotActionStatus === CopilotActionStatus.PROCESSING;
if (isProcessingAction) {
columns.push({
field: {
statusChangedAt: true,
},
title: "Processing At",
type: FieldType.DateTime,
});
}
const isQueuedAction: boolean =
props.query.copilotActionStatus === CopilotActionStatus.IN_QUEUE;
if (isQueuedAction) {
columns.push({
field: {
createdAt: true,
},
title: "Created At",
type: FieldType.DateTime,
});
}
if (isPullRequestTable) {
// then
columns.push({
field: {
copilotPullRequest: {
pullRequestId: true,
copilotPullRequestStatus: true,
},
},
title: "Pull Request",
type: FieldType.Element,
getElement: (item: CopilotAction): ReactElement => {
if (!item.copilotPullRequest) {
return <p>-</p>;
}
return (
<Fragment>
<PullRequestViewElement
pullRequestId={item.copilotPullRequest.pullRequestId!}
organizationName={props.repoOrganizationName}
repositoryName={props.repoName}
repoType={props.repoType}
pullRequestStatus={
item.copilotPullRequest.copilotPullRequestStatus!
}
/>
</Fragment>
);
},
});
columns.push({
field: {
statusChangedAt: true,
},
title: "PR Created At",
type: FieldType.DateTime,
});
}
const isPendingAction: boolean =
props.query.copilotActionStatus === CopilotActionStatus.IN_QUEUE;
return (
<div>
<ModelTable<CopilotAction>
modelType={CopilotAction}
id="table-copiolt-pull-requests"
name="Code Repository > Pull Requests"
userPreferencesKey="copilot-action-table"
isDeleteable={isPendingAction}
isCreateable={false}
isEditable={false}
isViewable={false}
showViewIdButton={false}
query={{
projectId: ProjectUtil.getCurrentProjectId()!,
...props.query,
}}
actionButtons={[
{
title: "View Logs",
buttonStyleType: ButtonStyleType.NORMAL,
isVisible: (item: CopilotAction) => {
return Boolean(item.logs);
},
icon: IconProp.List,
onClick: async (
item: CopilotAction,
onCompleteAction: VoidFunction,
) => {
setLogs(item["logs"] as string);
setShowViewLogsModal(true);
onCompleteAction();
},
},
// status message
{
title: "View Status Message",
buttonStyleType: ButtonStyleType.NORMAL,
isVisible: (item: CopilotAction) => {
return Boolean(item.statusMessage);
},
onClick: async (
item: CopilotAction,
onCompleteAction: VoidFunction,
) => {
setStatusMessage(item["statusMessage"] as string);
setShowStatusMessageModal(true);
onCompleteAction();
},
},
]}
selectMoreFields={{
copilotPullRequest: {
pullRequestId: true,
copilotPullRequestStatus: true,
},
}}
cardProps={{
title: props.title,
description: props.description,
}}
noItemsMessage={"No items found."}
showRefreshButton={true}
filters={[
{
field: {
copilotActionType: true,
},
type: FieldType.Text,
title: "Action",
},
{
field: {
createdAt: true,
},
type: FieldType.DateTime,
title: "Created At",
},
]}
columns={columns}
/>
{showViewLogsModal && (
<Modal
title={"Workflow Logs"}
description="Here are the logs for this workflow"
isLoading={false}
modalWidth={ModalWidth.Large}
onSubmit={() => {
setShowViewLogsModal(false);
}}
submitButtonText={"Close"}
submitButtonStyleType={ButtonStyleType.NORMAL}
>
<SimpleLogViewer>
{logs.split("\n").map((log: string, i: number) => {
return <div key={i}>{log}</div>;
})}
</SimpleLogViewer>
</Modal>
)}
{/** Status Message */}
{showStatusMessageModal && (
<Modal
title={"Status Message"}
description="Here is the status message for this action"
isLoading={false}
modalWidth={ModalWidth.Large}
onSubmit={() => {
setShowStatusMessageModal(false);
}}
submitButtonText={"Close"}
submitButtonStyleType={ButtonStyleType.NORMAL}
>
<p>{statusMessage}</p>
</Modal>
)}
</div>
);
};
export default CopilotActionTable;

View file

@ -1,27 +0,0 @@
import React, { FunctionComponent, ReactElement } from "react";
import CopilotActionType, {
CopilotActionTypeData,
CopilotActionTypeUtil,
} from "Common/Types/Copilot/CopilotActionType";
export interface ComponentProps {
copilotAction: CopilotActionType;
}
const CopilotActionTypeElement: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const copilotActionTypeData: CopilotActionTypeData =
CopilotActionTypeUtil.getCopilotActionType(props.copilotAction);
return (
<div>
<p className="font-semibold text-gray-900">
{copilotActionTypeData.type}
</p>
<p>{copilotActionTypeData.description}</p>
</div>
);
};
export default CopilotActionTypeElement;

View file

@ -1,51 +0,0 @@
import React, { FunctionComponent, ReactElement } from "react";
import Alert, { AlertType } from "Common/UI/Components/Alerts/Alert";
import OneUptimeDate from "Common/Types/Date";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import PageMap from "../../Utils/PageMap";
export interface ComponentProps {
lastRunAt?: undefined | Date;
codeRepositoryId: ObjectID;
}
const CopilotLastRunAt: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<>
{props.lastRunAt && (
<Alert
type={AlertType.INFO}
strongTitle="Data Updated At"
title={`Copilot ran at ${OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(props.lastRunAt)}. Please run copilot again to update data.`}
/>
)}
{!props.lastRunAt && (
<Alert
className="cursor-pointer"
onClick={() => {
Navigation.navigate(
RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION
]!,
{
modelId: props.codeRepositoryId,
},
),
);
}}
type={AlertType.INFO}
strongTitle="Copilot Did Not Run Yet"
title={`Copilot improves your code and fixes them automatically. Please click here to learn more.`}
/>
)}
</>
);
};
export default CopilotLastRunAt;

View file

@ -83,14 +83,6 @@ const DashboardNavbar: FunctionComponent<ComponentProps> = (
// Build the "More" menu items
const moreMenuItems: MoreMenuItem[] = [
{
title: "Reliability Copilot",
description: "Fix and improve your code automatically.",
route: RouteUtil.populateRouteParams(
RouteMap[PageMap.RELIABILITY_COPILOT] as Route,
),
icon: IconProp.Bolt,
},
{
title: "Service Catalog",
description: "Manage your services and their dependencies.",

View file

@ -1,107 +0,0 @@
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import ModelTable from "Common/UI/Components/ModelTable/ModelTable";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import CopilotActionTypePriority from "Common/Models/DatabaseModels/CopilotActionTypePriority";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import PageComponentProps from "../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import SortOrder from "Common/Types/BaseDatabase/SortOrder";
import DropdownUtil from "Common/UI/Utils/Dropdown";
import CopilotActionType from "Common/Types/Copilot/CopilotActionType";
import CopilotActionTypeElement from "../../../../Components/Copilot/CopilotAction/CopilotActionTypeElement";
import ProjectUtil from "Common/UI/Utils/Project";
const CopilotPriorities: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<ModelTable<CopilotActionTypePriority>
modelType={CopilotActionTypePriority}
query={{
projectId: ProjectUtil.getCurrentProjectId()!,
codeRepositoryId: modelId,
}}
sortBy={"priority"}
sortOrder={SortOrder.Ascending}
userPreferencesKey="copilot-priorities-table"
id="priority-table"
name="Settings > priority"
isDeleteable={true}
isEditable={true}
isCreateable={true}
cardProps={{
title: "Actions",
description:
"Actions lets you define what would you like to be improved in your codebase.",
}}
noItemsMessage={"No actions found."}
viewPageRoute={Navigation.getCurrentRoute()}
formFields={[
{
field: {
actionType: true,
},
title: "Action",
fieldType: FormFieldSchemaType.Dropdown,
dropdownOptions:
DropdownUtil.getDropdownOptionsFromEnum(CopilotActionType),
},
{
field: {
priority: true,
},
title: "Priority",
fieldType: FormFieldSchemaType.Number,
required: true,
defaultValue: 1,
placeholder:
"Please enter priority for this action. Please enter a number from 1 to 5.",
},
]}
createVerb="Add"
singularName="Action"
pluralName="Actions"
showRefreshButton={true}
onBeforeCreate={(
copilotActionTypePriority: CopilotActionTypePriority,
) => {
copilotActionTypePriority.codeRepositoryId = modelId;
return Promise.resolve(copilotActionTypePriority);
}}
showViewIdButton={true}
filters={[]}
columns={[
{
field: {
actionType: true,
},
title: "Action",
type: FieldType.Element,
getElement: (
copilotActionTypePriority: CopilotActionTypePriority,
) => {
return (
<CopilotActionTypeElement
copilotAction={copilotActionTypePriority.actionType!}
/>
);
},
},
{
field: {
priority: true,
},
title: "Priotiry",
type: FieldType.Number,
},
]}
/>
</Fragment>
);
};
export default CopilotPriorities;

View file

@ -1,31 +0,0 @@
import PageMap from "../../../../Utils/PageMap";
import RouteMap from "../../../../Utils/RouteMap";
import PageComponentProps from "../../../PageComponentProps";
import Route from "Common/Types/API/Route";
import ObjectID from "Common/Types/ObjectID";
import ModelDelete from "Common/UI/Components/ModelDelete/ModelDelete";
import Navigation from "Common/UI/Utils/Navigation";
import CodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const CodeRepositoryDelete: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<ModelDelete
modelType={CodeRepository}
modelId={modelId}
onDeleteSuccess={() => {
Navigation.navigate(
RouteMap[PageMap.AI_COPILOT_CODE_REPOSITORY] as Route,
);
}}
/>
</Fragment>
);
};
export default CodeRepositoryDelete;

View file

@ -1,128 +0,0 @@
import ObjectID from "Common/Types/ObjectID";
import Card from "Common/UI/Components/Card/Card";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import PageComponentProps from "../../../PageComponentProps";
import Navigation from "Common/UI/Utils/Navigation";
import CopilotCodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import API from "Common/UI/Utils/API/API";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import MarkdownViewer from "Common/UI/Components/Markdown.tsx/MarkdownViewer";
import URL from "Common/Types/API/URL";
import { DOCS_URL } from "Common/UI/Config";
import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
import HTTPResponse from "Common/Types/API/HTTPResponse";
import { JSONObject } from "Common/Types/JSON";
const CopilotDocuementationPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const codeRepositoryId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [documentation, setDocumentation] = useState<string | null>(null);
// get code repository
const [codeRepository, setCodeRepository] =
useState<CopilotCodeRepository | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchCodeRepositoryAndDocumentation: PromiseVoidFunction =
async (): Promise<void> => {
// get item.
setIsLoading(true);
setError("");
try {
const item: CopilotCodeRepository | null = await ModelAPI.getItem({
modelType: CopilotCodeRepository,
id: codeRepositoryId,
select: {
repositoryHostedAt: true,
repositoryName: true,
organizationName: true,
lastCopilotRunDateTime: true,
},
});
if (!item) {
setError(`Code Repository not found`);
return;
}
/*
* Send api request to get documentation
* http://localhost/docs/copilot/introduction
*/
const documentation: HTTPErrorResponse | HTTPResponse<JSONObject> =
(await API.get({
url: URL.fromString(DOCS_URL.toString()).addRoute(
"/as-markdown/copilot/introduction",
),
})) as HTTPErrorResponse | HTTPResponse<JSONObject>;
if (documentation instanceof HTTPErrorResponse) {
setError(API.getFriendlyMessage(documentation));
}
if (documentation.data && documentation.data["data"]) {
setDocumentation(
(documentation.data as JSONObject)["data"] as string,
);
}
setCodeRepository(item);
} catch (err) {
setError(API.getFriendlyMessage(err));
}
setIsLoading(false);
};
useEffect(() => {
fetchCodeRepositoryAndDocumentation().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
if (isLoading) {
return <PageLoader isVisible={true} />;
}
if (error) {
return <ErrorMessage message={error} />;
}
if (!codeRepository) {
return <ErrorMessage message={"Code Repository not found"} />;
}
if (!documentation) {
return <ErrorMessage message={"Documentation not found"} />;
}
return (
<Fragment>
<Card
title={``}
description={
<div className="space-y-2 w-full mt-5">
<MarkdownViewer text={documentation || ""} />
</div>
}
/>
</Fragment>
);
};
export default CopilotDocuementationPage;

View file

@ -1,107 +0,0 @@
import PageComponentProps from "../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import CopilotCodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import API from "Common/UI/Utils/API/API";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import CopilotActionTable from "../../../../Components/Copilot/CopilotAction/CopilotActionTable";
import CopilotActionStatus from "Common/Types/Copilot/CopilotActionStatus";
const CopilotPullRequestPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const codeRepositoryId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [codeRepository, setCodeRepository] =
useState<CopilotCodeRepository | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchCodeRepository: PromiseVoidFunction = async (): Promise<void> => {
// get item.
setIsLoading(true);
setError("");
try {
const item: CopilotCodeRepository | null = await ModelAPI.getItem({
modelType: CopilotCodeRepository,
id: codeRepositoryId,
select: {
repositoryHostedAt: true,
repositoryName: true,
organizationName: true,
lastCopilotRunDateTime: true,
},
});
if (!item) {
setError(`Code Repository not found`);
return;
}
setCodeRepository(item);
} catch (err) {
setError(API.getFriendlyMessage(err));
}
setIsLoading(false);
};
useEffect(() => {
fetchCodeRepository().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
if (isLoading) {
return <PageLoader isVisible={true} />;
}
if (error) {
return <ErrorMessage message={error} />;
}
if (!codeRepository) {
return <ErrorMessage message={"Code Repository not found"} />;
}
return (
<Fragment>
<CopilotActionTable
query={{
codeRepositoryId,
copilotActionStatus: CopilotActionStatus.IN_QUEUE,
}}
title="In Queue"
description="Copilot jobs in queue for this repository."
repoName={codeRepository.repositoryName!}
repoOrganizationName={codeRepository.organizationName!}
repoType={codeRepository.repositoryHostedAt!}
/>
<CopilotActionTable
query={{
codeRepositoryId,
copilotActionStatus: CopilotActionStatus.PROCESSING,
}}
title="Processing"
description="Copilot jobs in processing for this repository."
repoName={codeRepository.repositoryName!}
repoOrganizationName={codeRepository.organizationName!}
repoType={codeRepository.repositoryHostedAt!}
/>
</Fragment>
);
};
export default CopilotPullRequestPage;

View file

@ -1,284 +0,0 @@
import LabelsElement from "Common/UI/Components/Label/Labels";
import PageComponentProps from "../../../PageComponentProps";
import CodeRepositoryType from "Common/Types/CodeRepository/CodeRepositoryType";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FieldType from "Common/UI/Components/Types/FieldType";
import DropdownUtil from "Common/UI/Utils/Dropdown";
import Navigation from "Common/UI/Utils/Navigation";
import CopilotCodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import Label from "Common/Models/DatabaseModels/Label";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import CopilotLastRunAt from "../../../../Components/Copilot/LastRunMessage";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import PageMap from "../../../../Utils/PageMap";
import ServiceCopilotCodeRepository from "Common/Models/DatabaseModels/ServiceCopilotCodeRepository";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import API from "Common/UI/Utils/API/API";
import Alert, { AlertType } from "Common/UI/Components/Alerts/Alert";
import RouteMap, { RouteUtil } from "../../../../Utils/RouteMap";
const CopilotPageView: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID();
const [codeRepository, setCodeRepository] =
useState<CopilotCodeRepository | null>(null);
const [serviceCount, setServiceCount] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);
type FetchServiceCount = () => Promise<void>;
const fetchServiceCount: FetchServiceCount = async (): Promise<void> => {
try {
const count: number = await ModelAPI.count<ServiceCopilotCodeRepository>({
modelType: ServiceCopilotCodeRepository,
query: {
codeRepositoryId: modelId,
},
});
setServiceCount(count);
} catch (error: unknown) {
setError(API.getFriendlyMessage(error));
}
};
useEffect(() => {
fetchServiceCount().catch((error: unknown) => {
setError(API.getFriendlyMessage(error));
});
}, []);
if (error) {
return <ErrorMessage message={error} />;
}
return (
<Fragment>
{/* CopilotCodeRepository View */}
{serviceCount !== null && serviceCount === 0 && (
<Alert
className="cursor-pointer"
type={AlertType.WARNING}
strongTitle="Next Step"
title="Please click here to add services to this code repository."
onClick={() => {
return Navigation.navigate(
RouteUtil.populateRouteParams(
RouteMap[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES]!,
{ modelId: modelId },
),
);
}}
/>
)}
<CopilotLastRunAt
codeRepositoryId={modelId}
lastRunAt={codeRepository?.lastCopilotRunDateTime}
/>
<CardModelDetail<CopilotCodeRepository>
name="Git Repository > Repository Details"
cardProps={{
title: "Repository Details",
description: "Here are more details for this repository.",
}}
formSteps={[
{
title: "Repository Info",
id: "repository-info",
},
{
title: "Details",
id: "details",
},
{
title: "Labels",
id: "labels",
},
]}
isEditable={true}
formFields={[
{
field: {
name: true,
},
title: "Name",
stepId: "repository-info",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "Service Name",
validation: {
minLength: 2,
},
},
{
field: {
description: true,
},
stepId: "repository-info",
title: "Description",
fieldType: FormFieldSchemaType.LongText,
required: false,
placeholder: "Description",
},
{
field: {
mainBranchName: true,
},
title: "Main Branch Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "master",
validation: {
minLength: 2,
noSpaces: true,
noSpecialCharacters: true,
},
stepId: "details",
},
{
field: {
repositoryHostedAt: true,
},
title: "Repository Hosted At",
fieldType: FormFieldSchemaType.Dropdown,
required: true,
dropdownOptions:
DropdownUtil.getDropdownOptionsFromEnum(CodeRepositoryType),
stepId: "details",
},
{
field: {
organizationName: true,
},
title: "Organization Name (on GitHub, GitLab, etc.)",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "org-name",
stepId: "details",
},
{
field: {
repositoryName: true,
},
title: "Repository Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "repo-name",
stepId: "details",
},
{
field: {
labels: true,
},
title: "Labels ",
stepId: "labels",
description:
"Team members with access to these labels will only be able to access this resource. This is optional and an advanced feature.",
fieldType: FormFieldSchemaType.MultiSelectDropdown,
dropdownModal: {
type: Label,
labelField: "name",
valueField: "_id",
},
required: false,
placeholder: "Labels",
},
]}
modelDetailProps={{
selectMoreFields: {
lastCopilotRunDateTime: true,
},
onItemLoaded: (item: CopilotCodeRepository) => {
if (!codeRepository) {
setCodeRepository(item);
}
},
showDetailsInNumberOfColumns: 2,
modelType: CopilotCodeRepository,
id: "model-detail-service-catalog",
fields: [
{
field: {
_id: true,
},
title: "Service ID",
},
{
field: {
name: true,
},
title: "Service Name",
},
{
field: {
labels: {
name: true,
color: true,
},
},
title: "Labels",
fieldType: FieldType.Element,
getElement: (item: CopilotCodeRepository): ReactElement => {
return <LabelsElement labels={item["labels"] || []} />;
},
},
{
field: {
description: true,
},
title: "Description",
},
{
field: {
mainBranchName: true,
},
title: "Main Branch Name",
},
{
field: {
organizationName: true,
},
title: "Organization Name",
},
{
field: {
repositoryName: true,
},
title: "Repository Name",
},
{
field: {
repositoryHostedAt: true,
},
title: "Repository Hosted At",
},
{
field: {
secretToken: true,
},
title: "Secret Token",
fieldType: FieldType.HiddenText,
},
],
modelId: modelId,
}}
/>
</Fragment>
);
};
export default CopilotPageView;

View file

@ -1,32 +0,0 @@
import { getCodeRepositoryBreadcrumbs } from "../../../../Utils/Breadcrumbs";
import { RouteUtil } from "../../../../Utils/RouteMap";
import PageComponentProps from "../../../PageComponentProps";
import SideMenu from "./SideMenu";
import ObjectID from "Common/Types/ObjectID";
import ModelPage from "Common/UI/Components/Page/ModelPage";
import Navigation from "Common/UI/Utils/Navigation";
import CopilotCodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet, useParams } from "react-router-dom";
const CopilotCodeRepositoryViewLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const { id } = useParams();
const modelId: ObjectID = new ObjectID(id || "");
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<ModelPage
title="Repository"
modelType={CopilotCodeRepository}
modelId={modelId}
modelNameField="name"
breadcrumbLinks={getCodeRepositoryBreadcrumbs(path)}
sideMenu={<SideMenu modelId={modelId} />}
>
<Outlet />
</ModelPage>
);
};
export default CopilotCodeRepositoryViewLayout;

View file

@ -1,119 +0,0 @@
import PageComponentProps from "../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import CopilotCodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import API from "Common/UI/Utils/API/API";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import CopilotActionTable from "../../../../Components/Copilot/CopilotAction/CopilotActionTable";
import CopilotActionStatus from "Common/Types/Copilot/CopilotActionStatus";
const CopilotPullRequestPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const codeRepositoryId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [codeRepository, setCodeRepository] =
useState<CopilotCodeRepository | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchCodeRepository: PromiseVoidFunction = async (): Promise<void> => {
// get item.
setIsLoading(true);
setError("");
try {
const item: CopilotCodeRepository | null = await ModelAPI.getItem({
modelType: CopilotCodeRepository,
id: codeRepositoryId,
select: {
repositoryHostedAt: true,
repositoryName: true,
organizationName: true,
lastCopilotRunDateTime: true,
},
});
if (!item) {
setError(`Code Repository not found`);
return;
}
setCodeRepository(item);
} catch (err) {
setError(API.getFriendlyMessage(err));
}
setIsLoading(false);
};
useEffect(() => {
fetchCodeRepository().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
if (isLoading) {
return <PageLoader isVisible={true} />;
}
if (error) {
return <ErrorMessage message={error} />;
}
if (!codeRepository) {
return <ErrorMessage message={"Code Repository not found"} />;
}
return (
<Fragment>
<CopilotActionTable
query={{
codeRepositoryId,
copilotActionStatus: CopilotActionStatus.PR_CREATED,
}}
title="Pull Requests"
description="List of Pull Requests created by copilot for this repository."
repoName={codeRepository.repositoryName!}
repoOrganizationName={codeRepository.organizationName!}
repoType={codeRepository.repositoryHostedAt!}
/>
<CopilotActionTable
query={{
codeRepositoryId,
copilotActionStatus: CopilotActionStatus.CANNOT_FIX,
}}
title="Cannot Fix"
description="List of jobs that Copilot cannot fix for this repository."
repoName={codeRepository.repositoryName!}
repoOrganizationName={codeRepository.organizationName!}
repoType={codeRepository.repositoryHostedAt!}
/>
<CopilotActionTable
query={{
codeRepositoryId,
copilotActionStatus: CopilotActionStatus.NO_ACTION_REQUIRED,
}}
title="No Action Required"
description="List of jobs that Copilot has determined do not require any action for this repository."
repoName={codeRepository.repositoryName!}
repoOrganizationName={codeRepository.organizationName!}
repoType={codeRepository.repositoryHostedAt!}
/>
</Fragment>
);
};
export default CopilotPullRequestPage;

View file

@ -1,180 +0,0 @@
import ServiceCatalogElement from "../../../../Components/ServiceCatalog/ServiceElement";
import PageComponentProps from "../../../PageComponentProps";
import BadDataException from "Common/Types/Exception/BadDataException";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import ModelTable from "Common/UI/Components/ModelTable/ModelTable";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import ServiceCatalog from "Common/Models/DatabaseModels/ServiceCatalog";
import ServiceCopilotCodeRepository from "Common/Models/DatabaseModels/ServiceCopilotCodeRepository";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import ProjectUtil from "Common/UI/Utils/Project";
const ServiceCopilotCodeRepositoryPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const codeRepositoryId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<ModelTable<ServiceCopilotCodeRepository>
modelType={ServiceCopilotCodeRepository}
id="table-service-repository-page"
name="Code Repository > Service Repository"
userPreferencesKey="service-copilot-code-repositories-table"
isDeleteable={true}
createVerb={"Add"}
isCreateable={true}
isEditable={true}
isViewable={false}
showViewIdButton={true}
query={{
codeRepositoryId: codeRepositoryId,
projectId: ProjectUtil.getCurrentProjectId()!,
}}
onBeforeCreate={(
item: ServiceCopilotCodeRepository,
): Promise<ServiceCopilotCodeRepository> => {
item.codeRepositoryId = codeRepositoryId;
item.projectId = ProjectUtil.getCurrentProjectId()!;
return Promise.resolve(item);
}}
cardProps={{
title: "Services",
description:
"List of services that are associated with this code repository.",
}}
noItemsMessage={
"No services associated with this code repository so far. Please add some to activate copilot."
}
formFields={[
{
field: {
serviceCatalog: true,
},
title: "Service",
fieldType: FormFieldSchemaType.Dropdown,
required: true,
placeholder: "Select Service",
description:
"Select the service that this repository is for. You can add a service from the Service Catalog.",
dropdownModal: {
type: ServiceCatalog,
labelField: "name",
valueField: "_id",
},
doNotShowWhenEditing: true,
},
{
field: {
servicePathInRepository: true,
},
title: "Service Path in Repository",
fieldType: FormFieldSchemaType.Text,
required: true,
description:
"If this repository is a mono-repo, please provide the path to the service in the repository. If this repository is a single service repository, please provide /.",
placeholder: "/",
},
{
field: {
limitNumberOfOpenPullRequestsCount: true,
},
title: "Number of Open Pull Requests for this service",
fieldType: FormFieldSchemaType.Number,
defaultValue: 5,
required: true,
description:
"OneUptime will not create a new pull request if the number of open pull requests for this service is more than the limit specified here.",
placeholder: "/",
},
{
field: {
enablePullRequests: true,
},
title: "Enable Pull Requests",
fieldType: FormFieldSchemaType.Checkbox,
defaultValue: true,
required: false,
description:
"If enabled, OneUptime will create pull requests for this service and automatically improve code.",
},
]}
showRefreshButton={true}
viewPageRoute={Navigation.getCurrentRoute()}
filters={[
{
field: {
serviceCatalog: true,
},
type: FieldType.Entity,
title: "Service",
filterEntityType: ServiceCatalog,
filterQuery: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
filterDropdownField: {
label: "name",
value: "_id",
},
},
{
field: {
servicePathInRepository: true,
},
title: "Service Path in Repository",
type: FieldType.Text,
},
]}
columns={[
{
field: {
serviceCatalog: {
name: true,
serviceColor: true,
},
},
title: "Service",
type: FieldType.Entity,
getElement: (item: ServiceCopilotCodeRepository): ReactElement => {
if (!item["serviceCatalog"]) {
throw new BadDataException("Service not found");
}
return (
<ServiceCatalogElement
serviceCatalog={item["serviceCatalog"] as ServiceCatalog}
/>
);
},
},
{
field: {
servicePathInRepository: true,
},
title: "Service Path in Repository",
type: FieldType.Text,
},
{
field: {
limitNumberOfOpenPullRequestsCount: true,
},
title: "Number of Open Pull Requests",
type: FieldType.Number,
},
{
field: {
enablePullRequests: true,
},
title: "Enable Pull Requests",
type: FieldType.Boolean,
},
]}
/>
</Fragment>
);
};
export default ServiceCopilotCodeRepositoryPage;

View file

@ -1,26 +0,0 @@
import PageComponentProps from "../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import ResetObjectID from "Common/UI/Components/ResetObjectID/ResetObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import CodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<ResetObjectID<CodeRepository>
modelType={CodeRepository}
fieldName={"secretToken"}
title={"Reset Secret Token"}
description={"Reset the secret token to a new value."}
modelId={modelId}
/>
</Fragment>
);
};
export default ServiceDelete;

View file

@ -1,127 +0,0 @@
import PageMap from "../../../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import IconProp from "Common/Types/Icon/IconProp";
import ObjectID from "Common/Types/ObjectID";
import SideMenu from "Common/UI/Components/SideMenu/SideMenu";
import SideMenuItem from "Common/UI/Components/SideMenu/SideMenuItem";
import SideMenuSection from "Common/UI/Components/SideMenu/SideMenuSection";
import React, { FunctionComponent, ReactElement } from "react";
export interface ComponentProps {
modelId: ObjectID;
}
const DashboardSideMenu: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<SideMenu>
<SideMenuSection title="Basic">
<SideMenuItem
link={{
title: "Overview",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Info}
/>
<SideMenuItem
link={{
title: "Services",
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES
] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.SquareStack}
/>
<SideMenuItem
link={{
title: "Documentation",
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION
] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Info}
/>
</SideMenuSection>
<SideMenuSection title="Code Changes">
<SideMenuItem
link={{
title: "In Queue",
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE
] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Logs}
/>
<SideMenuItem
link={{
title: "Processed",
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED
] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.CheckCircle}
/>
</SideMenuSection>
<SideMenuSection title="Advanced">
<SideMenuItem
link={{
title: "Actions",
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES
] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.CPUChip}
/>
<SideMenuItem
link={{
title: "Settings",
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS
] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Settings}
/>
<SideMenuItem
link={{
title: "Delete",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Trash}
className="danger-on-hover"
/>
</SideMenuSection>
</SideMenu>
);
};
export default DashboardSideMenu;

View file

@ -1,220 +0,0 @@
import Banner from "Common/UI/Components/Banner/Banner";
import LabelsElement from "Common/UI/Components/Label/Labels";
import ProjectUtil from "Common/UI/Utils/Project";
import PageMap from "../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import PageComponentProps from "../PageComponentProps";
import Route from "Common/Types/API/Route";
import CodeRepositoryType from "Common/Types/CodeRepository/CodeRepositoryType";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import ModelTable from "Common/UI/Components/ModelTable/ModelTable";
import Page from "Common/UI/Components/Page/Page";
import FieldType from "Common/UI/Components/Types/FieldType";
import DropdownUtil from "Common/UI/Utils/Dropdown";
import Navigation from "Common/UI/Utils/Navigation";
import CodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import Label from "Common/Models/DatabaseModels/Label";
import React, { FunctionComponent, ReactElement } from "react";
import URL from "Common/Types/API/URL";
const CodeRepositoryPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
return (
<Page
title={"Reliability Copilot"}
breadcrumbLinks={[
{
title: "Project",
to: RouteUtil.populateRouteParams(RouteMap[PageMap.HOME] as Route),
},
{
title: "Reliability Copilot",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.RELIABILITY_COPILOT] as Route,
),
},
]}
>
<Banner
title="Beta Software"
description="Reliability Copilot is a beta software. Please let us know your feedback and report any bugs on GitHub."
openInNewTab={true}
link={URL.fromString("https://github.com/OneUptime/oneuptime/issues")}
hideOnMobile={true}
/>
<ModelTable<CodeRepository>
modelType={CodeRepository}
id="service-catalog-table"
isDeleteable={false}
isEditable={false}
isCreateable={true}
userPreferencesKey="reliability-copilot-code-repositories-table"
createVerb="Add"
name="Git Repositories"
isViewable={true}
cardProps={{
title: "Git Repository",
description:
"Git repositores where the Reliability Copilot can improve your code.",
}}
viewPageRoute={
new Route(
Navigation.getCurrentRoute().toString() + "/code-repository",
)
}
showViewIdButton={true}
noItemsMessage={"No repositories found."}
formSteps={[
{
title: "Repository Info",
id: "repository-info",
},
{
title: "Details",
id: "details",
},
]}
formFields={[
{
field: {
name: true,
},
title: "Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "Friendly Name",
validation: {
minLength: 2,
},
stepId: "repository-info",
},
{
field: {
description: true,
},
title: "Description",
fieldType: FormFieldSchemaType.LongText,
required: false,
placeholder: "Description",
stepId: "repository-info",
},
{
field: {
repositoryHostedAt: true,
},
title: "Repository Hosted At",
fieldType: FormFieldSchemaType.Dropdown,
required: true,
dropdownOptions:
DropdownUtil.getDropdownOptionsFromEnum(CodeRepositoryType),
stepId: "details",
},
{
field: {
organizationName: true,
},
title: "Organization Name (on GitHub, GitLab, etc.)",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "org-name",
stepId: "details",
},
{
field: {
repositoryName: true,
},
title: "Repository Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "repo-name",
stepId: "details",
},
{
field: {
mainBranchName: true,
},
title: "Main Branch Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "master",
validation: {
minLength: 2,
noSpaces: true,
noSpecialCharacters: true,
},
stepId: "details",
},
]}
showRefreshButton={true}
filters={[
{
field: {
name: true,
},
title: "Name",
type: FieldType.Text,
},
{
field: {
description: true,
},
title: "Description",
type: FieldType.LongText,
},
{
field: {
labels: {
name: true,
color: true,
},
},
title: "Labels",
type: FieldType.EntityArray,
filterEntityType: Label,
filterQuery: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
filterDropdownField: {
label: "name",
value: "_id",
},
},
]}
columns={[
{
field: {
name: true,
},
title: "Name",
type: FieldType.Text,
},
{
field: {
description: true,
},
noValueMessage: "-",
title: "Description",
type: FieldType.LongText,
},
{
field: {
labels: {
name: true,
color: true,
},
},
title: "Labels",
type: FieldType.EntityArray,
getElement: (item: CodeRepository): ReactElement => {
return <LabelsElement labels={item["labels"] || []} />;
},
},
]}
/>
</Page>
);
};
export default CodeRepositoryPage;

View file

@ -1,241 +0,0 @@
import Loader from "../Components/Loader/Loader";
import CodeRepositoryViewLayout from "../Pages/AICopilot/CodeRepository/View/Layout";
import ComponentProps from "../Pages/PageComponentProps";
import PageMap from "../Utils/PageMap";
import RouteMap, {
CodeRepositoryRoutePath,
RouteUtil,
} from "../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import React, {
FunctionComponent,
LazyExoticComponent,
ReactElement,
Suspense,
lazy,
} from "react";
import { Route as PageRoute, Routes } from "react-router-dom";
// Pages
const AiCopilot: LazyExoticComponent<FunctionComponent<ComponentProps>> = lazy(
() => {
return import("../Pages/AICopilot/Index");
},
);
const CodeRepositoryView: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Index");
});
const CodeRepositoryViewActionsInQueue: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/InQueue");
});
const CodeRepositoryViewProcessed: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Processed");
});
const CodeRepositoryViewDocumentation: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Documentation");
});
const CodeRepositoryViewDelete: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Delete");
});
const CodeRepositoryViewSettings: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Settings");
});
const CodeRepositoryViewPriorities: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Actions");
});
const CodeRepositoryViewServices: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/AICopilot/CodeRepository/View/Services");
});
const CodeRepositoryRoutes: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<Routes>
<PageRoute
path={CodeRepositoryRoutePath[PageMap.RELIABILITY_COPILOT] || ""}
element={
<Suspense fallback={Loader}>
<AiCopilot
{...props}
pageRoute={RouteMap[PageMap.RELIABILITY_COPILOT] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={
CodeRepositoryRoutePath[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW] || ""
}
element={<CodeRepositoryViewLayout {...props} />}
>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<CodeRepositoryView
{...props}
pageRoute={
RouteMap[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewActionsInQueue
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE
] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewProcessed
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED
] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewDocumentation
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION
] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewDelete
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE
] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewSettings
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS
] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewPriorities
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES
] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES,
)}
element={
<Suspense fallback={Loader}>
<CodeRepositoryViewServices
{...props}
pageRoute={
RouteMap[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES
] as Route
}
/>
</Suspense>
}
/>
</PageRoute>
</Routes>
);
};
export default CodeRepositoryRoutes;

View file

@ -1,55 +0,0 @@
import PageMap from "../PageMap";
import { BuildBreadcrumbLinksByTitles } from "./Helper";
import Dictionary from "Common/Types/Dictionary";
import Link from "Common/Types/Link";
export function getCodeRepositoryBreadcrumbs(
path: string,
): Array<Link> | undefined {
const breadcrumpLinksMap: Dictionary<Link[]> = {
...BuildBreadcrumbLinksByTitles(PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW, [
"Project",
"Reliability Copilot",
"View Git Repository",
]),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE,
[
"Project",
"Reliability Copilot",
"View Git Repository",
"Delete Repository",
],
),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE,
["Project", "Reliability Copilot", "View Git Repository", "In Queue"],
),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED,
["Project", "Reliability Copilot", "View Git Repository", "Processed"],
),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION,
[
"Project",
"Reliability Copilot",
"View Git Repository",
"Documentation",
],
),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS,
["Project", "Reliability Copilot", "View Git Repository", "Settings"],
),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES,
["Project", "Reliability Copilot", "View Git Repository", "Priorities"],
),
...BuildBreadcrumbLinksByTitles(
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES,
["Project", "Reliability Copilot", "View Git Repository", "Services"],
),
};
return breadcrumpLinksMap[path];
}

View file

@ -8,5 +8,4 @@ export * from "./TelemetryBreadcrumbs";
export * from "./SettingsBreadcrumbs";
export * from "./MonitorGroupBreadcrumbs";
export * from "./ServiceCatalogBreadcrumbs";
export * from "./AICopilotBreadcrumbs";
export * from "./DashboardBreadCrumbs";

View file

@ -174,18 +174,6 @@ enum PageMap {
SERVICE_CATALOG_VIEW_DEPENDENCIES = "SERVICE_CATALOG_VIEW_DEPENDENCIES",
SERVICE_CATALOG_DEPENDENCY_GRAPH = "SERVICE_CATALOG_DEPENDENCY_GRAPH",
AI_COPILOT_ROOT = "AI_COPILOT_ROOT",
RELIABILITY_COPILOT = "RELIABILITY_COPILOT",
AI_COPILOT_CODE_REPOSITORY = "AI_COPILOT_CODE_REPOSITORY",
AI_COPILOT_CODE_REPOSITORY_VIEW = "AI_COPILOT_CODE_REPOSITORY_VIEW",
AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION = "AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION",
AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE = "AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE",
AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS = "AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS",
AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES = "AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES",
AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES = "AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES",
AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE = "AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE",
AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED = "AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED",
DASHBOARDS_ROOT = "DASHBOARDS_ROOT",
DASHBOARDS = "DASHBOARDS",
DASHBOARD_VIEW = "DASHBOARD_VIEW",

View file

@ -46,17 +46,6 @@ export const ServiceCatalogRoutePath: Dictionary<string> = {
[PageMap.SERVICE_CATALOG_VIEW_TELEMETRY_SERVICES]: `${RouteParams.ModelID}/telemetry-service`,
};
export const CodeRepositoryRoutePath: Dictionary<string> = {
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW]: `code-repository/${RouteParams.ModelID}`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE]: `code-repository/${RouteParams.ModelID}/delete`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED]: `code-repository/${RouteParams.ModelID}/processed`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE]: `code-repository/${RouteParams.ModelID}/in-queue`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION]: `code-repository/${RouteParams.ModelID}/documentation`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS]: `code-repository/${RouteParams.ModelID}/settings`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES]: `code-repository/${RouteParams.ModelID}/action-types`,
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES]: `code-repository/${RouteParams.ModelID}/services`,
};
export const WorkflowRoutePath: Dictionary<string> = {
[PageMap.WORKFLOWS_LOGS]: "logs",
[PageMap.WORKFLOWS_VARIABLES]: "variables",
@ -834,74 +823,6 @@ const RouteMap: Dictionary<Route> = {
}`,
),
[PageMap.AI_COPILOT_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/*`,
),
[PageMap.RELIABILITY_COPILOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/code-repository`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_IN_QUEUE
]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTIONS_PROCESSED
]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DOCUMENTATION
]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_DELETE]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SETTINGS]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[
PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_ACTION_TYPES
]
}`,
),
[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES]: new Route(
`/dashboard/${RouteParams.ProjectID}/copilot/${
CodeRepositoryRoutePath[PageMap.AI_COPILOT_CODE_REPOSITORY_VIEW_SERVICES]
}`,
),
[PageMap.SERVICE_CATALOG_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/service-catalog/*`,
),

View file

@ -1,67 +0,0 @@
## Deploy LLM Server
This step is optional. You need to deploy LLM Server only if you want to use Copilot with LLM Server on your infrastructure for data privacy reasons. If you are comfortable with OpenAI's privacy policy, you can skip this step and use OpenAI directly.
### Pre-requisites
Before you deploy LLM Server, you need to make sure you have the following:
- **Docker**: You need to have Docker installed on your machine.
- **Docker Compose**: You need to have Docker Compose installed on your machine.
- **System Requirements**: You need to have at least 64 GB of RAM, 32 GB GPU (compitable with CUDA & Docker), 8 CPU cores, and 100 GB of disk space. You could get away with less resources, but we recommend the above configuration for optimal performance.
- **GPU is accessible by Docker**: You need to make sure that the GPU is accessible by Docker. Please read this [guide](https://docs.docker.com/compose/gpu-support/) for more information.
### Environment Variables
You need to set the following environment variables in the `docker-compose.yml` file:
- `HF_TOKEN`: This is the Hugging Face API token. You can get this token by signing up on Hugging Face and creating a new API token.
- `HF_MODEL_NAME` (optional): This is the model name from Hugging Face. You can get this model name from the Hugging Face model hub. If you do not set this, we will use `meta-llama/Meta-Llama-3-8B-Instruct` as the default model.
### Installation
To deploy LLM Server, you need to follow the following steps with docker-compose:
Create a `docker-compose.yml` file with the following content:
```yaml
llm:
extends:
file: ./docker-compose.base.yml
service: llm
ports:
- '8547:8547'
image: 'oneuptime/llm:release'
environment:
- HF_TOKEN=<TOKEN_FROM_HUGGINGFACE>
- HF_MODEL_NAME=<MODEL_NAME_FROM_HUGGING_FACE>
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
```
Run the following command to start the LLM Server:
```bash
docker compose up -d
```
You can now access the LLM Server at `http://localhost:8547`.
### TLS/SSL Configuration
You can set up TLS/SSL by having a reverse proxy in front of the LLM Server. This is recommended for production deployments and is beyond the scope of this document.
### Public Access
Please make sure this server is publicly accessible. So, it can be accessed by Copilot.
### Security
Please also make sure to secure the server by setting up a firewall so only copilot can access it.

View file

@ -1,140 +0,0 @@
## OneUptime Copilot
OneUptime Copilot is a tool that helps you improve your codebase automatically. Copilot can fix following issues automatically:
- **Performance Issues**: Improve database queries, optimize code, reduce memory usage, decrease API response time, etc.
- **Security Issues**: Fix security vulnerabilities, prevent SQL injection, XSS, CSRF, etc.
- **Code Quality Issues**: Improve code readability, maintainability, and scalability. Improve comments, naming conventions, refactor code, etc.
- **Error Handling Issues**: Improve error handling, exception handling, logging, etc.
- **Testing Issues**: Improve test coverage, test quality, test performance, etc.
- **Documentation Issues**: Improve documentation quality, comments, README, etc.
### Architecture
Copilot can be installed as a CI/CD tool and can be run on every merge to master / main branch. Copilot can also be scheduled to run as a cron on the CI/CD pipeline. We recommend you run Copilot atleast once/day.
There are three services when running copilot:
- **OneUptime**: You need to deploy or use OneUptime Cloud (https://oneuptime.com) to run Copilot. When you deploy OneUptime, url should be publicily accessible.
- **Copilot**: Copilot is the main service that runs the Copilot engine. Copilot engine is responsible for analyzing the codebase and fixing issues.
- **LLM Server** (Optional): Copilot sends your code to LLM Server to analyze and fix issues. The source-code and docker-image is [open-source](https://github.com/OneUptime/oneuptime/tree/master/LLM) and can be found at [Docker Hub](https://hub.docker.com/r/oneuptime/llm). This can be self-deployed if you want to run Copilot on-premises or you can use the hosted version.
### FAQ
**Is my code sent to OneUptime?**
No, your code is not sent to OneUptime. Copilot runs on your CI/CD pipeline and sends the code to LLM Server for analysis. LLM Server can be self-hosted.
**Is my code sent to Self-Hosted LLM Server?**
Yes, but you can self host LLM server so code is not sent outside of your infrastructure. Your code is sent to LLM Server for analysis. LLM Server is responsible for analyzing the code and fixing issues.
**Is my code sent to any third-party?**
No. We strictly do not send any telemetry data or code to any third-party.
**Is my code sent to OpenAI?**
No, If you host LLM Server yourself.
Yes, if you choose to use OpenAI by setting `OPENAI_API_KEY`. We recommend you to use OpenAI only if you are comfortable with OpenAI's privacy policy. We're not responsible for any data sent to OpenAI or how your code is analyzed / used by OpenAI.
### Pre-requisites
Before you install Copilot, you need to make sure you have the following:
- **OneUptime Account**: You need to have a OneUptime account to use Copilot. You can sign up for a free account at [OneUptime](https://oneuptime.com). You can either use OneUptime Cloud or deploy OneUptime on your infrastructure.
- **GitHub Account**: You need to have a GitHub account to use Copilot. You can sign up for a free account at [GitHub](https://github.com). You can also use GitLab, Bitbucket, etc.
You also need either of the following:
- **LLM Server** (Optional): You need to have LLM Server to run Copilot. [Please check this guide to deploy LLM Server](https://oneuptime.com/docs/copilot/deploy-llm-server).
or
- **OpenAI** (Optional): You need to have OpenAI API Key and Model to run Copilot. Please check env vars for more information.
### Installation
To install Copilot, you need to follow the following steps:
#### Environment Variables
You need to set the following environment variables to run Copilot:
**Required Environment Variables**:
- **ONEUPTIME_REPOSITORY_SECRET_KEY**: The secret key of the repository. You can get this key from OneUptime Dashboard -> Reliability Copilot -> View Repository. If you don't have a repository, you can create a new repository, then click on "View Repository" to get the secret key.
- **CODE_REPOSITORY_USERNAME**: OneUptime uses this username to commit and push changes to GitHub / GitLab / etc. This should be the username of the existing user on GitHub that has access to the repository.
- **CODE_REPOSITORY_PASSWORD**: OneUptime uses this password to commit and push changes to GitHub / GitLab / etc. This should be the password of the existing user on GitHub that has access to the repository. You can also use Personal Access Tokens instead of Password. Please make sure the token has write permissions to the repo.
**Optional Environment Variables**:
- **ONEUPTIME_URL**: The URL of OneUptime Cloud. If left empty, Copilot will default to `https://oneuptime.com`.
If you are using LLM Server, you need to set the following environment variables:
- **ONEUPTIME_LLM_SERVER_URL**: The URL of LLM Server. (For example: https://your-llm-server.com:8547)
If you are using OpenAI, you need to set the following environment variables:
- **OPENAI_API_KEY**: The API key of OpenAI. You can get this key from OpenAI Dashboard.
**Important**: You need to provide either `ONEUPTIME_LLM_SERVER_URL` or `OPENAI_API_KEY` in order to use Copilot.
#### GitHub Actions
You can use GitHub Actions to run Copilot on every merge to master / main branch.
```yaml
name: "OneUptime Reliability Copilot"
on:
push:
# change this to main if you are using main branch.
branches: [ master ]
schedule:
# Run every day at midnight UTC
- cron: '0 0 * * *'
jobs:
analyze:
name: Analyze Code
runs-on: ubuntu-latest
steps:
# Run Reliability Copilot in Docker Container
- name: Run Copilot
run: |
docker run --rm \
-e CODE_REPOSITORY_PASSWORD='<YOUR_GITHUB_PASSWORD>' \ # Required. Please make sure to use GitHub secrets.
-e CODE_REPOSITORY_USERNAME='<YOUR_GITHUB_USERNAME>' \ # Required.
-e ONEUPTIME_URL='https://oneuptime.com' \ # Optional. Leave empty to use OneUptime Cloud.
-e ONEUPTIME_REPOSITORY_SECRET_KEY='<ONEUPTIME_REPOSITORY_SECRET_KEY>' \ # Required. Please make sure to use GitHub secrets.
-e ONEUPTIME_LLM_SERVER_URL='<YOUR_ONEUPTIME_LLM_SERVER>' \ # Optional. Leave empty to use OneUptime LLM Server.
-e OPENAI_API_KEY='<YOUR_OPENAI_API_KEY>' \ # Optional. Leave empty to not use OpenAI.
--net=host oneuptime/copilot:release
```
#### Docker (with any CI/CD)
You can also run Copilot using docker. You can run this in any CI/CD of your choice.
```bash
docker run --rm \
-e CODE_REPOSITORY_PASSWORD='<YOUR_GITHUB_PASSWORD>' \ # Required. Please make sure to use GitHub secrets.
-e CODE_REPOSITORY_USERNAME='<YOUR_GITHUB_USERNAME>' \ # Required.
-e ONEUPTIME_URL='https://oneuptime.com' \ # Optional. Leave empty to use OneUptime Cloud.
-e ONEUPTIME_REPOSITORY_SECRET_KEY='<ONEUPTIME_REPOSITORY_SECRET_KEY>' \ # Required. Please make sure to use GitHub secrets.
-e ONEUPTIME_LLM_SERVER_URL='<YOUR_ONEUPTIME_LLM_SERVER>' \ # Optional. Leave empty to use OneUptime LLM Server.
-e OPENAI_API_KEY='<YOUR_OPENAI_API_KEY>' \ # Optional. Leave empty to not use OpenAI.
--net=host oneuptime/copilot:release
```
### Support
If you have any questions or need help, please contact us at support@oneuptime.com

View file

@ -43,7 +43,3 @@ Measure and optimize the performance of your online apps and services. Track key
Detect and diagnose errors in your online services. Get detailed error reports with stack traces, context, and user feedback. Replace tools like Sentry.
##### Reliability Copilot
Scan your code and fix performance issues and errors automatically. Get recommendations for improving the reliability of your online services.

View file

@ -162,14 +162,8 @@ The OneUptime MCP Server provides access to 126 different resource types across
- **Exception**: Track application exceptions
- **ExceptionInstance**: Individual exception occurrences
## Development and Code Analysis
### Code Repository Integration
- **CodeRepository**: Connect code repositories
- **ServiceCodeRepositoryForCopilot**: Repository configuration for Copilot
- **CopilotEvent**: Copilot-generated events
- **CopilotPullRequest**: Track pull requests analyzed by Copilot
- **CopilotActionPriority**: Prioritize Copilot actions
## Communication and Notifications

View file

@ -192,13 +192,6 @@ const DocsNav: NavGroup[] = [
{ title: "Syslog", url: "/docs/telemetry/syslog" },
],
},
{
title: "Copilot",
links: [
{ title: "Installation", url: "/docs/copilot/introduction" },
{ title: "Deploy LLM Server", url: "/docs/copilot/deploy-llm-server" },
],
},
{
title: "MCP Server",
links: [

View file

@ -53,7 +53,6 @@ Measure and optimize the performance of your online apps and services. Track key
#### Coming Soon
- **Error Tracking**: Detect and diagnose errors in your online services. Get detailed error reports with stack traces, context, and user feedback. Replace tools like Sentry.
- **Reliability Copilot**: Scan your code and fix performance issues and errors automatically. Get recommendations for improving the reliability of your online services.
All under one platform.

View file

@ -1,59 +0,0 @@
import DataMigrationBase from "./DataMigrationBase";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import CopilotCodeRepository from "Common/Models/DatabaseModels/CopilotCodeRepository";
import CopilotCodeRepositoryService from "Common/Server/Services/CopilotCodeRepositoryService";
import {
CopilotActionTypeData,
CopilotActionTypeUtil,
} from "Common/Types/Copilot/CopilotActionType";
import CopilotActionTypePriority from "Common/Models/DatabaseModels/CopilotActionTypePriority";
import CopilotActionTypePriorityService from "Common/Server/Services/CopilotActionTypePriorityService";
export default class AddDefaultCopilotActionTypes extends DataMigrationBase {
public constructor() {
super("AddDefaultCopilotActionTypes");
}
public override async migrate(): Promise<void> {
// get all the users with email isVerified true.
const repositories: Array<CopilotCodeRepository> =
await CopilotCodeRepositoryService.findBy({
query: {},
select: {
_id: true,
projectId: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
for (const repo of repositories) {
const defaultCopilotActionTypes: Array<CopilotActionTypeData> =
CopilotActionTypeUtil.getAllCopilotActionTypes();
for (const defaultAction of defaultCopilotActionTypes) {
const copilotActionTypePriority: CopilotActionTypePriority =
new CopilotActionTypePriority();
copilotActionTypePriority.projectId = repo.projectId!;
copilotActionTypePriority.actionType = defaultAction.type;
copilotActionTypePriority.priority = defaultAction.defaultPriority;
copilotActionTypePriority.codeRepositoryId = repo.id!;
await CopilotActionTypePriorityService.create({
data: copilotActionTypePriority,
props: {
isRoot: true,
},
});
}
}
}
public override async rollback(): Promise<void> {
return;
}
}

View file

@ -34,7 +34,6 @@ import UpdateGlobalConfigFromEnv from "./UpdateGlobalCongfigFromEnv";
import MigrateServiceLanguageToTechStack from "./MigrateServiceLanguageToTechStack";
import DeleteOldTelemetryTable from "./DeleteOldTelelmetryTable";
import MoveTelemetryServiceTokenToTelemetryIngestionKey from "./MoveTelemetryServiceTokenToTelemetryIngestionKey";
import AddDefaultCopilotActionTypes from "./AddDefaultCopilotActionTypes";
import AddDefaultAlertSeverityAndStateToExistingProjects from "./AddDefaultAlertSeverityAndStateToExistingProjects";
import RefreshDefaultUserNotificationSetting from "./RefreshUserNotificationSetting";
import AddServiceTypeColumnToMetricsTable from "./AddServiceTypeColumnToMetricTable";
@ -93,7 +92,6 @@ const DataMigrations: Array<DataMigrationBase> = [
new MigrateServiceLanguageToTechStack(),
new DeleteOldTelemetryTable(),
new MoveTelemetryServiceTokenToTelemetryIngestionKey(),
new AddDefaultCopilotActionTypes(),
new AddDefaultAlertSeverityAndStateToExistingProjects(),
new RefreshDefaultUserNotificationSetting(),
new AddServiceTypeColumnToMetricsTable(),

View file

@ -1,48 +0,0 @@
import RunCron from "../../Utils/Cron";
import { EVERY_THIRTY_MINUTES } from "Common/Utils/CronTime";
import OneUptimeDate from "Common/Types/Date";
import CopilotAction from "Common/Models/DatabaseModels/CopilotAction";
import CopilotActionService from "Common/Server/Services/CopilotActionService";
import CopilotActionStatus from "Common/Types/Copilot/CopilotActionStatus";
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
RunCron(
"CopilotAction:MoveThemBackToQueueIfProcessingForLongtime",
{ schedule: EVERY_THIRTY_MINUTES, runOnStartup: false },
async () => {
const lastHour: Date = OneUptimeDate.addRemoveHours(
OneUptimeDate.getCurrentDate(),
-1,
);
//get stalled copilot actions and move them back to queue so they can be processed again.
const stalledActions: Array<CopilotAction> =
await CopilotActionService.findAllBy({
query: {
copilotActionStatus: CopilotActionStatus.PROCESSING,
statusChangedAt: QueryHelper.lessThanEqualToOrNull(lastHour),
},
select: {
_id: true,
},
skip: 0,
props: {
isRoot: true,
},
});
for (const stalledAction of stalledActions) {
await CopilotActionService.updateOneById({
id: stalledAction.id!,
data: {
copilotActionStatus: CopilotActionStatus.IN_QUEUE,
statusChangedAt: null,
},
props: {
isRoot: true,
},
});
}
},
);

View file

@ -87,9 +87,6 @@ import "./Jobs/Workflow/TimeoutJobs";
import "./Jobs/Probe/SendOwnerAddedNotification";
import "./Jobs/Probe/UpdateConnectionStatus";
// Copilot Actions.
import "./Jobs/CopilotActions/MoveThemBackToQueueIfProcessingForLongtime";
// Telemetry Monitors.
import "./Jobs/TelemetryMonitor/MonitorTelemetryMonitor";