Path: blob/main/components/gitpod-protocol/src/teams-projects-protocol.ts
2498 views
/**1* Copyright (c) 2021 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { PrebuiltWorkspaceState, Workspace, WorkspaceClasses } from "./protocol";7import { v4 as uuidv4 } from "uuid";8import { DeepPartial } from "./util/deep-partial";9import { WorkspaceInstance } from "./workspace-instance";1011export interface ProjectConfig {12".gitpod.yml": string;13}1415export interface ProjectSettings {16/**17* Controls settings of prebuilds for this project.18*/19prebuilds?: PrebuildSettings;2021// preferred workspace classes22workspaceClasses?: WorkspaceClasses;2324/**25* Controls workspace class restriction for this project, the list is a NOT ALLOW LIST. Empty array to allow all kind of workspace classes26*/27restrictedWorkspaceClasses?: string[];2829restrictedEditorNames?: string[];3031/**32* Enable automatic authentication for docker daemon with all credentials specified in GITPOD_IMAGE_AUTH33*/34enableDockerdAuthentication?: boolean;35}36export namespace PrebuildSettings {37export type BranchStrategy = "default-branch" | "all-branches" | "matched-branches";38export type TriggerStrategy = "activity-based" | "webhook-based";39export interface CloneSettings {40fullClone?: boolean;41}42}4344export interface PrebuildSettings {45enable?: boolean;4647/**48* Defines an interval of commits to run new prebuilds for. Defaults to 2049*/50prebuildInterval?: number;5152/**53* Which branches to consider to run new prebuilds on. Default to "all-branches"54*/55branchStrategy?: PrebuildSettings.BranchStrategy;56/**57* If `branchStrategy` s set to "matched-branches", this should define a glob-pattern to be used58* to match the branch to run new prebuilds on. Defaults to "**"59*/60branchMatchingPattern?: string;6162/**63* Preferred workspace class for prebuilds.64*/65workspaceClass?: string;6667/**68* The activation strategy for prebuilds. Defaults to "webhook-based"69*/70triggerStrategy?: PrebuildSettings.TriggerStrategy;7172cloneSettings?: PrebuildSettings.CloneSettings;73}7475export interface Project {76id: string;77name: string;78cloneUrl: string;79teamId: string;80appInstallationId: string;81settings?: ProjectSettings;82creationTime: string;83markedDeleted?: boolean;84}8586export namespace Project {87export function is(data?: any): data is Project {88return typeof data === "object" && ["id", "name", "cloneUrl", "teamId"].every((p) => p in data);89}9091export const create = (project: Omit<Project, "id" | "creationTime">): Project => {92return {93...project,94id: uuidv4(),95creationTime: new Date().toISOString(),96};97};9899export type PrebuildSettingsWithDefaults = Required<Pick<PrebuildSettings, "prebuildInterval">> & PrebuildSettings;100101export const PREBUILD_SETTINGS_DEFAULTS: PrebuildSettingsWithDefaults = {102enable: false,103branchMatchingPattern: "**",104prebuildInterval: 20,105branchStrategy: "all-branches",106triggerStrategy: "activity-based",107};108109/**110* Returns effective prebuild settings for the given project. The resulting settings111* contain default values for properties which are not set explicitly for this project.112*/113export function getPrebuildSettings(project: Project): PrebuildSettingsWithDefaults {114// ignoring persisted properties with `undefined` values to exclude them from the override.115const overrides = Object.fromEntries(116Object.entries(project.settings?.prebuilds ?? {}).filter(([_, value]) => value !== undefined),117);118119return {120...PREBUILD_SETTINGS_DEFAULTS,121...overrides,122};123}124125export function hasPrebuildSettings(project: Project) {126return !(typeof project.settings?.prebuilds === "undefined");127}128129export interface Overview {130branches: BranchDetails[];131isConsideredInactive?: boolean;132}133134export namespace Overview {135export function is(data?: any): data is Project.Overview {136return Array.isArray(data?.branches);137}138}139140export interface BranchDetails {141name: string;142url: string;143isDefault: boolean;144145// Latest commit146changeTitle: string;147changeDate?: string;148changeAuthor?: string;149changeAuthorAvatar?: string;150changePR?: string;151changeUrl?: string;152changeHash: string;153}154155export type Visibility = "public" | "org-public" | "private";156}157158export type PartialProject = DeepPartial<Project> & Pick<Project, "id">;159160export interface ProjectUsage {161lastWebhookReceived: string;162lastWorkspaceStart: string;163}164165export interface PrebuildWithStatus {166info: PrebuildInfo;167status: PrebuiltWorkspaceState;168workspace: Workspace;169instance?: WorkspaceInstance;170error?: string;171}172173export interface PrebuildInfo {174id: string;175buildWorkspaceId: string;176basedOnPrebuildId?: string;177178teamId?: string;179userId?: string;180181projectId: string;182projectName: string;183184cloneUrl: string;185branch: string;186187startedAt: string;188startedBy: string;189startedByAvatar?: string;190191changeTitle: string;192changeDate: string;193changeAuthor: string;194changeAuthorAvatar?: string;195changePR?: string;196changeUrl?: string;197changeHash: string;198}199export namespace PrebuildInfo {200export function is(data?: any): data is PrebuildInfo {201return typeof data === "object" && ["id", "buildWorkspaceId", "projectId", "branch"].every((p) => p in data);202}203}204205export interface StartPrebuildResult {206prebuildId: string;207wsid: string;208done: boolean;209}210211// alias for backwards compatibility212export type Team = Organization;213export interface Organization {214id: string;215name: string;216slug?: string;217creationTime: string;218markedDeleted?: boolean;219maintenanceMode?: boolean;220maintenanceNotification?: MaintenanceNotification;221}222export interface MaintenanceNotification {223enabled: boolean;224message?: string;225}226227export interface OrganizationSettings {228workspaceSharingDisabled?: boolean;229// undefined or empty string to reset to default230defaultWorkspaceImage?: string;231232// empty array to allow all kind of workspace classes233allowedWorkspaceClasses?: string[];234235pinnedEditorVersions?: { [key: string]: string };236237restrictedEditorNames?: string[];238239// what role new members will get, default is "member"240defaultRole?: OrgMemberRole;241242// the default organization-wide timeout settings for workspaces243timeoutSettings?: TimeoutSettings;244245roleRestrictions?: RoleRestrictions;246247// max number of parallel running workspaces per user248maxParallelRunningWorkspaces?: number;249250// onboarding settings for the organization251onboardingSettings?: OnboardingSettings;252253// whether to add a special annotation to commits that are created through Gitpod254annotateGitCommits?: boolean;255}256257export type TimeoutSettings = {258// default per-org workspace timeout259inactivity?: string;260261// If this field is true, workspaces neither a) pick up user-defined workspace timeouts, nor b) members can set custom timeouts during workspace runtime.262denyUserTimeouts?: boolean;263};264265export const VALID_ORG_MEMBER_ROLES = ["owner", "member", "collaborator"] as const;266267export type TeamMemberRole = OrgMemberRole;268export type OrgMemberRole = typeof VALID_ORG_MEMBER_ROLES[number];269270export type OrgMemberPermission = "start_arbitrary_repositories";271export type RoleRestrictions = Partial<Record<OrgMemberRole, OrgMemberPermission[]>>;272273export namespace TeamMemberRole {274export function isValid(role: unknown): role is TeamMemberRole {275return VALID_ORG_MEMBER_ROLES.includes(role as TeamMemberRole);276}277}278279export interface OnboardingSettings {280/**281* the link to an internal onboarding page for the organization, possibly featuring a custom onboarding guide and other resources282*/283internalLink?: string;284285/**286* the repository IDs of the repositories that are recommended for members to start with287*/288recommendedRepositories?: string[];289290/**291* the welcome message for new members of the organization292*/293welcomeMessage?: WelcomeMessage;294}295296export interface WelcomeMessage {297enabled?: boolean;298featuredMemberId?: string;299featuredMemberResolvedAvatarUrl?: string;300message?: string;301}302303export type TeamMemberInfo = OrgMemberInfo;304export interface OrgMemberInfo {305userId: string;306fullName?: string;307primaryEmail?: string;308avatarUrl?: string;309role: TeamMemberRole;310memberSince: string;311ownedByOrganization: boolean;312}313314export interface TeamMembershipInvite {315id: string;316teamId: string;317role: TeamMemberRole;318creationTime: string;319invalidationTime: string;320invitedEmail?: string;321322/** This is a flag that triggers the HARD DELETION of this entity */323deleted?: boolean;324}325326327