mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
refactor: Update GitHub token handling in Config.ts
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
enum CodeRepositoryType {
|
||||
GitHub = "GitHub",
|
||||
GitLab = "GitLab",
|
||||
GitHub = 'GitHub',
|
||||
GitLab = 'GitLab',
|
||||
}
|
||||
|
||||
export default CodeRepositoryType;
|
||||
export default CodeRepositoryType;
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import GenericObject from "../Types/GenericObject";
|
||||
import GenericObject from '../Types/GenericObject';
|
||||
|
||||
export default class EnumUtil {
|
||||
public static isValidEnumValue<T extends GenericObject>(enumType: T, value: any): boolean {
|
||||
export default class EnumUtil {
|
||||
public static isValidEnumValue<T extends GenericObject>(
|
||||
enumType: T,
|
||||
value: any
|
||||
): boolean {
|
||||
return this.getValues(enumType).includes(value);
|
||||
}
|
||||
|
||||
public static getValues<T extends GenericObject>(enumType: T): Array<string> {
|
||||
public static getValues<T extends GenericObject>(
|
||||
enumType: T
|
||||
): Array<string> {
|
||||
return Object.values(enumType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import ServiceRepository from 'Model/Models/ServiceRepository';
|
||||
import UserMiddleware from '../Middleware/UserAuthorization';
|
||||
import CodeRepositoryService, {
|
||||
Service as CodeRepositoryServiceType,
|
||||
@@ -11,10 +10,11 @@ import {
|
||||
} from '../Utils/Express';
|
||||
import Response from '../Utils/Response';
|
||||
import BaseAPI from './BaseAPI';
|
||||
import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
|
||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import CodeRepository from 'Model/Models/CodeRepository';
|
||||
import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
|
||||
import ServiceRepository from 'Model/Models/ServiceRepository';
|
||||
|
||||
export default class CodeRepositoryAPI extends BaseAPI<
|
||||
CodeRepository,
|
||||
@@ -54,40 +54,41 @@ export default class CodeRepositoryAPI extends BaseAPI<
|
||||
},
|
||||
});
|
||||
|
||||
if(!codeRepository) {
|
||||
if (!codeRepository) {
|
||||
throw new BadDataException('Code repository not found');
|
||||
}
|
||||
|
||||
|
||||
const servicesRepository: Array<ServiceRepository> = await ServiceRepositoryService.findBy({
|
||||
query: {
|
||||
codeRepositoryId: codeRepository.id!,
|
||||
enablePullRequests: true,
|
||||
},
|
||||
select: {
|
||||
serviceCatalog: {
|
||||
name: true,
|
||||
_id: true,
|
||||
const servicesRepository: Array<ServiceRepository> =
|
||||
await ServiceRepositoryService.findBy({
|
||||
query: {
|
||||
codeRepositoryId: codeRepository.id!,
|
||||
enablePullRequests: true,
|
||||
},
|
||||
servicePathInRepository: true,
|
||||
limitNumberOfOpenPullRequestsCount: true,
|
||||
},
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
select: {
|
||||
serviceCatalog: {
|
||||
name: true,
|
||||
_id: true,
|
||||
},
|
||||
servicePathInRepository: true,
|
||||
limitNumberOfOpenPullRequestsCount: true,
|
||||
},
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
return Response.sendJsonObjectResponse(
|
||||
req,
|
||||
res,
|
||||
{
|
||||
"codeRepository": CodeRepository.toJSON(codeRepository, CodeRepository),
|
||||
"servicesRepository": ServiceRepository.toJSONArray(servicesRepository, ServiceRepository),
|
||||
}
|
||||
);
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
codeRepository: CodeRepository.toJSON(
|
||||
codeRepository,
|
||||
CodeRepository
|
||||
),
|
||||
servicesRepository: ServiceRepository.toJSONArray(
|
||||
servicesRepository,
|
||||
ServiceRepository
|
||||
),
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class MigrationName1718186569787 implements MigrationInterface {
|
||||
public name = 'MigrationName1718186569787';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "CodeRepository" DROP COLUMN "mainBranchName"`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class MigrationName1718188920011 implements MigrationInterface {
|
||||
public name = 'MigrationName1718188920011';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "CodeRepository" ADD "mainBranchName" character varying(100) NOT NULL DEFAULT 'master'`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "CodeRepository" ADD "repositoryHostedAt" character varying(100) NOT NULL DEFAULT 'GitHub'`
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "CodeRepository" DROP COLUMN "repositoryHostedAt"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "CodeRepository" DROP COLUMN "mainBranchName"`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { MigrationName1718101665865 } from './1718101665865-MigrationName';
|
||||
import { MigrationName1718119926223 } from './1718119926223-MigrationName';
|
||||
import { MigrationName1718124277321 } from './1718124277321-MigrationName';
|
||||
import { MigrationName1718126316684 } from './1718126316684-MigrationName';
|
||||
import { MigrationName1718186569787 } from './1718186569787-MigrationName';
|
||||
import { MigrationName1718188920011 } from './1718188920011-MigrationName';
|
||||
|
||||
export default [
|
||||
InitialMigration,
|
||||
@@ -23,5 +23,5 @@ export default [
|
||||
MigrationName1718119926223,
|
||||
MigrationName1718124277321,
|
||||
MigrationName1718126316684,
|
||||
MigrationName1718186569787,
|
||||
MigrationName1718188920011,
|
||||
];
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { DatabaseName } from '../../EnvironmentConfig';
|
||||
import DatabaseType from 'Common/Types/DatabaseType';
|
||||
import ProdDataSourceOptions from './DataSourceOptions';
|
||||
import Faker from 'Common/Utils/Faker';
|
||||
import Entities from 'Model/Models/Index';
|
||||
import { DataSourceOptions } from 'typeorm';
|
||||
|
||||
type GetTestDataSourceOptions = () => DataSourceOptions;
|
||||
@@ -10,15 +9,13 @@ const getTestDataSourceOptions: GetTestDataSourceOptions =
|
||||
(): DataSourceOptions => {
|
||||
// we use process.env values directly here because it can change during test runs and we need to get the latest values.
|
||||
return {
|
||||
type: DatabaseType.Postgres,
|
||||
...ProdDataSourceOptions,
|
||||
host: process.env['DATABASE_HOST'] || 'localhost',
|
||||
port: parseInt(process.env['DATABASE_PORT']?.toString() || '5432'),
|
||||
username: process.env['DATABASE_USERNAME'] || 'postgres',
|
||||
password: process.env['DATABASE_PASSWORD'] || 'password',
|
||||
database: DatabaseName + Faker.randomNumbers(16),
|
||||
entities: Entities,
|
||||
synchronize: true,
|
||||
};
|
||||
} as DataSourceOptions;
|
||||
};
|
||||
|
||||
export default getTestDataSourceOptions;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import URL from 'Common/Types/API/URL';
|
||||
import CodeRepositoryType from 'Common/Types/CodeRepository/CodeRepositoryType';
|
||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
import EnumUtil from 'Common/Utils/Enum';
|
||||
|
||||
type GetStringFunction = () => string;
|
||||
type GetURLFunction = () => URL;
|
||||
@@ -20,29 +17,7 @@ export const GetLocalRepositoryPath: GetStringFunction = (): string => {
|
||||
return process.env['ONEUPTIME_LOCAL_REPOSITORY_PATH'] || '/repository';
|
||||
};
|
||||
|
||||
export const GetRepositoryType: GetStringFunction = (): CodeRepositoryType => {
|
||||
const repoType: string | undefined = process.env['REPOSITORY_TYPE'];
|
||||
|
||||
if(!repoType) {
|
||||
return CodeRepositoryType.GitHub;
|
||||
}
|
||||
|
||||
if(EnumUtil.isValidEnumValue(CodeRepositoryType, repoType)) {
|
||||
return repoType as CodeRepositoryType;
|
||||
}
|
||||
// check if the repository type is valid and is from the values in the enum.
|
||||
|
||||
throw new BadDataException(`Invalid Repository Type ${repoType}. It should be one of ${EnumUtil.getValues(CodeRepositoryType).join(', ')}`);
|
||||
};
|
||||
|
||||
|
||||
export const GetGitHubToken: GetStringFunction = (): string => {
|
||||
const token: string = process.env['GITHUB_TOKEN'] || '';
|
||||
|
||||
|
||||
if(GetRepositoryType() === CodeRepositoryType.GitHub && !token) {
|
||||
throw new BadDataException('GitHub Token is required for GitHub Repository');
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import { GetLocalRepositoryPath } from './Config';
|
||||
import CodeRepositoryUtil, { CodeRepositoryResult } from './Utils/CodeRepository';
|
||||
import { CodeRepositoryResult } from './Utils/CodeRepository';
|
||||
import InitUtil from './Utils/Init';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
import { PromiseVoidFunction } from 'Common/Types/FunctionTypes';
|
||||
import CodeRepositoryCommonServerUtil from 'CommonServer/Utils/CodeRepository/CodeRepository';
|
||||
import CodeRepositoryFile from 'CommonServer/Utils/CodeRepository/CodeRepositoryFile';
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import dotenv from 'dotenv';
|
||||
import InitUtil from './Utils/Init';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
logger.info('OneUptime Copilot is starting...');
|
||||
|
||||
const init: PromiseVoidFunction = async (): Promise<void> => {
|
||||
|
||||
await InitUtil.validate(); // validate all the configurations
|
||||
|
||||
const codeRepositoryResult: CodeRepositoryResult =
|
||||
await CodeRepositoryUtil.getCodeRepository();
|
||||
const codeRepositoryResult: CodeRepositoryResult = await InitUtil.init();
|
||||
|
||||
const allFiles: Dictionary<CodeRepositoryFile> =
|
||||
await CodeRepositoryCommonServerUtil.getFilesInDirectoryRecursive({
|
||||
|
||||
@@ -15,7 +15,13 @@ export interface CodeRepositoryResult {
|
||||
}
|
||||
|
||||
export default class CodeRepositoryUtil {
|
||||
public static async getCodeRepository(): Promise<CodeRepositoryResult> {
|
||||
public static codeRepositoryResult: CodeRepositoryResult | null = null;
|
||||
|
||||
public static async getCodeRepositoryResult(): Promise<CodeRepositoryResult> {
|
||||
if (this.codeRepositoryResult) {
|
||||
return this.codeRepositoryResult;
|
||||
}
|
||||
|
||||
const repositorySecretKey: string = GetRepositorySecretKey();
|
||||
|
||||
if (!repositorySecretKey) {
|
||||
@@ -44,14 +50,14 @@ export default class CodeRepositoryUtil {
|
||||
CodeRepositoryModel
|
||||
) as CodeRepositoryModel;
|
||||
|
||||
const servicesRepository: Array<ServiceRepository> =
|
||||
(codeRepositoryResult.data['servicesRepository'] as JSONArray).map(
|
||||
(serviceRepository: JSONObject) =>
|
||||
ServiceRepository.fromJSON(
|
||||
serviceRepository,
|
||||
ServiceRepository
|
||||
) as ServiceRepository
|
||||
);
|
||||
const servicesRepository: Array<ServiceRepository> = (
|
||||
codeRepositoryResult.data['servicesRepository'] as JSONArray
|
||||
).map((serviceRepository: JSONObject) => {
|
||||
return ServiceRepository.fromJSON(
|
||||
serviceRepository,
|
||||
ServiceRepository
|
||||
) as ServiceRepository;
|
||||
});
|
||||
|
||||
if (!codeRepository) {
|
||||
throw new BadDataException(
|
||||
@@ -68,14 +74,38 @@ export default class CodeRepositoryUtil {
|
||||
logger.info(`Code Repository found: ${codeRepository.name}`);
|
||||
|
||||
logger.info('Services found in the repository:');
|
||||
|
||||
|
||||
servicesRepository.forEach((serviceRepository: ServiceRepository) => {
|
||||
logger.info(`- ${serviceRepository.serviceCatalog?.name}`);
|
||||
});
|
||||
|
||||
return {
|
||||
this.codeRepositoryResult = {
|
||||
codeRepository,
|
||||
servicesRepository,
|
||||
};
|
||||
|
||||
return this.codeRepositoryResult;
|
||||
}
|
||||
|
||||
public static async getCodeRepository(): Promise<CodeRepositoryModel> {
|
||||
if (!this.codeRepositoryResult) {
|
||||
const result: CodeRepositoryResult =
|
||||
await this.getCodeRepositoryResult();
|
||||
return result.codeRepository;
|
||||
}
|
||||
|
||||
return this.codeRepositoryResult.codeRepository;
|
||||
}
|
||||
|
||||
public static async getServiceRepositories(): Promise<
|
||||
Array<ServiceRepository>
|
||||
> {
|
||||
if (!this.codeRepositoryResult) {
|
||||
const result: CodeRepositoryResult =
|
||||
await this.getCodeRepositoryResult();
|
||||
return result.servicesRepository;
|
||||
}
|
||||
|
||||
return this.codeRepositoryResult.servicesRepository;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import CodeRepositoryType from "Common/Types/CodeRepository/CodeRepositoryType";
|
||||
import { GetGitHubToken, GetRepositorySecretKey, GetRepositoryType } from "../Config";
|
||||
import BadDataException from "Common/Types/Exception/BadDataException";
|
||||
import { GetGitHubToken, GetRepositorySecretKey } from '../Config';
|
||||
import CodeRepositoryUtil, { CodeRepositoryResult } from './CodeRepository';
|
||||
import CodeRepositoryType from 'Common/Types/CodeRepository/CodeRepositoryType';
|
||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
|
||||
export default class InitUtil {
|
||||
public static async validate(): Promise<void> {
|
||||
public static async init(): Promise<CodeRepositoryResult> {
|
||||
if (!GetRepositorySecretKey()) {
|
||||
throw new BadDataException('Repository Secret Key is required');
|
||||
}
|
||||
|
||||
const codeRepositoryResult: CodeRepositoryResult =
|
||||
await CodeRepositoryUtil.getCodeRepositoryResult();
|
||||
|
||||
// Check if the repository type is GitHub and the GitHub token is provided
|
||||
if(GetRepositoryType() === CodeRepositoryType.GitHub && !GetGitHubToken()){
|
||||
throw new BadDataException("GitHub token is required");
|
||||
|
||||
if (
|
||||
codeRepositoryResult.codeRepository.repositoryHostedAt ===
|
||||
CodeRepositoryType.GitHub &&
|
||||
!GetGitHubToken()
|
||||
) {
|
||||
throw new BadDataException(
|
||||
'GitHub token is required for this repository. Please provide the GitHub token in the environment variables.'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if(!GetRepositorySecretKey()){
|
||||
throw new BadDataException("Repository Secret Key is required");
|
||||
}
|
||||
return codeRepositoryResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import LabelsElement from '../../../../Components/Label/Labels';
|
||||
import PageComponentProps from '../../../PageComponentProps';
|
||||
import CodeRepositoryType from 'Common/Types/CodeRepository/CodeRepositoryType';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import FormFieldSchemaType from 'CommonUI/src/Components/Forms/Types/FormFieldSchemaType';
|
||||
import CardModelDetail from 'CommonUI/src/Components/ModelDetail/CardModelDetail';
|
||||
import FieldType from 'CommonUI/src/Components/Types/FieldType';
|
||||
import DropdownUtil from 'CommonUI/src/Utils/Dropdown';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import CodeRepository from 'Model/Models/CodeRepository';
|
||||
import Label from 'Model/Models/Label';
|
||||
@@ -28,6 +30,10 @@ const StatusPageView: FunctionComponent<PageComponentProps> = (
|
||||
title: 'Repository Info',
|
||||
id: 'repository-info',
|
||||
},
|
||||
{
|
||||
title: 'Details',
|
||||
id: 'details',
|
||||
},
|
||||
{
|
||||
title: 'Labels',
|
||||
id: 'labels',
|
||||
@@ -58,6 +64,34 @@ const StatusPageView: FunctionComponent<PageComponentProps> = (
|
||||
required: true,
|
||||
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: {
|
||||
labels: true,
|
||||
@@ -118,6 +152,18 @@ const StatusPageView: FunctionComponent<PageComponentProps> = (
|
||||
},
|
||||
title: 'Description',
|
||||
},
|
||||
{
|
||||
field: {
|
||||
mainBranchName: true,
|
||||
},
|
||||
title: 'Main Branch Name',
|
||||
},
|
||||
{
|
||||
field: {
|
||||
repositoryHostedAt: true,
|
||||
},
|
||||
title: 'Repository Hosted At',
|
||||
},
|
||||
{
|
||||
field: {
|
||||
secretToken: true,
|
||||
|
||||
@@ -4,10 +4,12 @@ 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 'CommonUI/src/Components/Forms/Types/FormFieldSchemaType';
|
||||
import ModelTable from 'CommonUI/src/Components/ModelTable/ModelTable';
|
||||
import Page from 'CommonUI/src/Components/Page/Page';
|
||||
import FieldType from 'CommonUI/src/Components/Types/FieldType';
|
||||
import DropdownUtil from 'CommonUI/src/Utils/Dropdown';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import CodeRepository from 'Model/Models/CodeRepository';
|
||||
import Label from 'Model/Models/Label';
|
||||
@@ -55,6 +57,16 @@ const CodeRepositoryPage: FunctionComponent<PageComponentProps> = (
|
||||
}
|
||||
showViewIdButton={true}
|
||||
noItemsMessage={'No repositories found.'}
|
||||
formSteps={[
|
||||
{
|
||||
title: 'Repository Info',
|
||||
id: 'repository-info',
|
||||
},
|
||||
{
|
||||
title: 'Details',
|
||||
id: 'details',
|
||||
},
|
||||
]}
|
||||
formFields={[
|
||||
{
|
||||
field: {
|
||||
@@ -67,6 +79,7 @@ const CodeRepositoryPage: FunctionComponent<PageComponentProps> = (
|
||||
validation: {
|
||||
minLength: 2,
|
||||
},
|
||||
stepId: 'repository-info',
|
||||
},
|
||||
{
|
||||
field: {
|
||||
@@ -76,6 +89,35 @@ const CodeRepositoryPage: FunctionComponent<PageComponentProps> = (
|
||||
fieldType: FormFieldSchemaType.LongText,
|
||||
required: true,
|
||||
placeholder: 'Description',
|
||||
stepId: 'repository-info',
|
||||
},
|
||||
{
|
||||
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',
|
||||
},
|
||||
]}
|
||||
showRefreshButton={true}
|
||||
|
||||
@@ -4,6 +4,7 @@ import User from './User';
|
||||
import BaseModel from 'Common/Models/BaseModel';
|
||||
import Route from 'Common/Types/API/Route';
|
||||
import { PlanSelect } from 'Common/Types/Billing/SubscriptionPlan';
|
||||
import CodeRepositoryType from 'Common/Types/CodeRepository/CodeRepositoryType';
|
||||
import ColumnAccessControl from 'Common/Types/Database/AccessControl/ColumnAccessControl';
|
||||
import TableAccessControl from 'Common/Types/Database/AccessControl/TableAccessControl';
|
||||
import TableBillingAccessControl from 'Common/Types/Database/AccessControl/TableBillingAccessControl';
|
||||
@@ -493,6 +494,44 @@ export default class CodeRepository extends BaseModel {
|
||||
nullable: false,
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
default: 'master',
|
||||
})
|
||||
public mainBranchName?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateCodeRepository,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadCodeRepository,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditCodeRepository,
|
||||
],
|
||||
})
|
||||
@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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user