From f24a6101ee42803914838eab2e47abd98e34db3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Tron=C3=AD=C4=8Dek?= Date: Mon, 24 Jun 2024 15:59:19 +0200 Subject: [PATCH] Enable displaying JB warmup tasks in the Prebuilds UI (#19945) * Enable displaying JB warmup tasks in the Prebuilds UI * a hacky comment * shorten jb warmup task id prefix * update converter tests * Capitalize product names * Fix IDE order * update golden test results --- .../fixtures/toPrebuild_1.golden | 39 ++++++++++++- .../fixtures/toPrebuild_1.json | 28 +++++++++- .../src/public-api-converter.ts | 55 +++++++++++++++++-- .../supervisor/pkg/supervisor/config.go | 9 ++- 4 files changed, 123 insertions(+), 8 deletions(-) diff --git a/components/public-api/typescript-common/fixtures/toPrebuild_1.golden b/components/public-api/typescript-common/fixtures/toPrebuild_1.golden index 692827da907f3e..b9e18de5cfca86 100644 --- a/components/public-api/typescript-common/fixtures/toPrebuild_1.golden +++ b/components/public-api/typescript-common/fixtures/toPrebuild_1.golden @@ -22,7 +22,44 @@ "startTime": "2023-11-17T10:42:00Z", "message": "", "logUrl": "https://gitpod-test.preview.gitpod-dev.com/prebuild-logs/5fba7d7c-e740-4339-b928-0e3c5975eb37", - "taskLogs": [], + "taskLogs": [ + { + "taskId": "0", + "taskLabel": "Task [1]", + "taskJson": "{\"init\":\"true\",\"command\":\"npm install\"}", + "logUrl": "https://gitpod-test.preview.gitpod-dev.com/prebuild-logs/5fba7d7c-e740-4339-b928-0e3c5975eb37/0" + }, + { + "taskId": "1", + "taskLabel": "Task [2]", + "taskJson": "{\"command\":\"npm run build\"}", + "logUrl": "" + }, + { + "taskId": "2", + "taskLabel": "Task [3]", + "taskJson": "{\"command\":\"npm run start\"}", + "logUrl": "" + }, + { + "taskId": "jb-warmup-clion-stable", + "taskLabel": "JetBrains Clion warmup (stable)", + "taskJson": "", + "logUrl": "https://gitpod-test.preview.gitpod-dev.com/prebuild-logs/5fba7d7c-e740-4339-b928-0e3c5975eb37/3" + }, + { + "taskId": "jb-warmup-intellij-stable", + "taskLabel": "JetBrains Intellij warmup (stable)", + "taskJson": "", + "logUrl": "https://gitpod-test.preview.gitpod-dev.com/prebuild-logs/5fba7d7c-e740-4339-b928-0e3c5975eb37/4" + }, + { + "taskId": "jb-warmup-intellij-latest", + "taskLabel": "JetBrains Intellij warmup (latest)", + "taskJson": "", + "logUrl": "https://gitpod-test.preview.gitpod-dev.com/prebuild-logs/5fba7d7c-e740-4339-b928-0e3c5975eb37/5" + } + ], "imageBuildLogUrl": "https://gitpod-test.preview.gitpod-dev.com/prebuild-logs/eb276a90-0970-49fb-947f-3cefe856efdc/image-build" }, "configurationName": "parcel-demo" diff --git a/components/public-api/typescript-common/fixtures/toPrebuild_1.json b/components/public-api/typescript-common/fixtures/toPrebuild_1.json index 57308036ea9c66..101d3ba54a21f2 100644 --- a/components/public-api/typescript-common/fixtures/toPrebuild_1.json +++ b/components/public-api/typescript-common/fixtures/toPrebuild_1.json @@ -19,7 +19,33 @@ "changeUrl": "https://github.com/akosyakov/parcel-demo/tree/master" }, "workspace": { - "id": "eb276a90-0970-49fb-947f-3cefe856efdc" + "id": "eb276a90-0970-49fb-947f-3cefe856efdc", + "config": { + "tasks": [ + { + "init": "true", + "command": "npm install" + }, + { + "command": "npm run build" + }, + { + "command": "npm run start" + } + ], + "jetbrains": { + "intellij": { + "prebuilds": { + "version": "both" + } + }, + "clion": { + "prebuilds": { + "version": "stable" + } + } + } + } }, "status": "building" } diff --git a/components/public-api/typescript-common/src/public-api-converter.ts b/components/public-api/typescript-common/src/public-api-converter.ts index a7cd8b35ab9d41..e79b609fe99c38 100644 --- a/components/public-api/typescript-common/src/public-api-converter.ts +++ b/components/public-api/typescript-common/src/public-api-converter.ts @@ -21,6 +21,7 @@ import { EnvVarWithValue, IDESettings, Identity as IdentityProtocol, + JetBrainsProductConfig, NamedWorkspaceFeatureFlag, PrebuiltWorkspaceState, ProjectEnvVar, @@ -35,8 +36,9 @@ import { WithEnvvarsContext, WithPrebuild, WorkspaceAutostartOption, - WorkspaceContext, WorkspaceInfo, - WorkspaceSession as WorkspaceSessionProtocol + WorkspaceContext, + WorkspaceInfo, + WorkspaceSession as WorkspaceSessionProtocol, } from "@gitpod/gitpod-protocol/lib/protocol"; import { OrgMemberInfo, @@ -134,7 +136,8 @@ import { ParseContextURLResponse, PrebuildInitializer, SnapshotInitializer, - UpdateWorkspaceRequest_UpdateTimeout, Workspace, + UpdateWorkspaceRequest_UpdateTimeout, + Workspace, WorkspaceClass, WorkspaceGitStatus, WorkspaceInitializer, @@ -151,7 +154,7 @@ import { WorkspaceSpec_WorkspaceType, WorkspaceStatus, WorkspaceStatus_PrebuildResult, - WorkspaceStatus_WorkspaceConditions + WorkspaceStatus_WorkspaceConditions, } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb"; import { getPrebuildLogPath } from "./prebuild-utils"; import { InvalidGitpodYMLError, RepositoryNotFoundError, UnauthorizedRepositoryAccessError } from "./public-api-errors"; @@ -1194,8 +1197,10 @@ export class PublicAPIConverter { toPrebuildStatus(gitpodHost: string, prebuild: PrebuildWithStatus): PrebuildStatus { const tasks: TaskLog[] = []; + let taskIndex = 0; if (prebuild.workspace?.config?.tasks) { for (let i = 0; i < prebuild.workspace.config.tasks.length; i++) { + taskIndex = i; const task = prebuild.workspace.config.tasks[i]; tasks.push( new TaskLog({ @@ -1211,6 +1216,48 @@ export class PublicAPIConverter { ); } } + + const capitalize = (input: string) => { + return input.charAt(0).toUpperCase() + input.slice(1); + }; + + // This is a hack mimicking the supervisor behavior of adding dynamic IDE tasks https://github.com/gitpod-io/gitpod/blob/e7d79c355e2cd6ac34056ea52d7bdcda45975839/components/ide-service/pkg/server/server.go#L508-L540 + if (prebuild.workspace.config.jetbrains) { + const jetbrainsIdes = Object.entries(prebuild.workspace.config.jetbrains).sort(([a], [b]) => + a.localeCompare(b), + ) as [string, JetBrainsProductConfig][]; + for (const [ide, ideConfig] of jetbrainsIdes) { + if (!ideConfig.prebuilds) { + continue; + } + + if (ideConfig.prebuilds.version !== "latest") { + tasks.push( + new TaskLog({ + taskId: `jb-warmup-${ide}-stable`, + taskLabel: `JetBrains ${capitalize(ide)} warmup (stable)`, + logUrl: new URL( + getPrebuildLogPath(prebuild.info.id, `${++taskIndex}`), + gitpodHost, + ).toString(), + }), + ); + } + if (ideConfig.prebuilds.version !== "stable") { + tasks.push( + new TaskLog({ + taskId: `jb-warmup-${ide}-latest`, + taskLabel: `JetBrains ${capitalize(ide)} warmup (latest)`, + logUrl: new URL( + getPrebuildLogPath(prebuild.info.id, `${++taskIndex}`), + gitpodHost, + ).toString(), + }), + ); + } + } + } + return new PrebuildStatus({ phase: new PrebuildPhase({ name: this.toPrebuildPhase(prebuild.status), diff --git a/components/supervisor/pkg/supervisor/config.go b/components/supervisor/pkg/supervisor/config.go index 686fc29bf76dc0..9f79ba8788ffa8 100644 --- a/components/supervisor/pkg/supervisor/config.go +++ b/components/supervisor/pkg/supervisor/config.go @@ -8,12 +8,13 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "math" "net/http" "net/url" "os" "path/filepath" + "slices" + "strings" "time" env "github.com/Netflix/go-env" @@ -593,7 +594,7 @@ func loadDesktopIDEs(static *StaticConfig) ([]*IDEConfig, error) { uniqueDesktopIDEs[desktopIDE.GetUniqueKey()] = struct{}{} } - files, err := ioutil.ReadDir(static.DesktopIDERoot) + files, err := os.ReadDir(static.DesktopIDERoot) if err != nil { return nil, err } @@ -616,6 +617,10 @@ func loadDesktopIDEs(static *StaticConfig) ([]*IDEConfig, error) { } } + slices.SortFunc(desktopIDEs, func(a, b *IDEConfig) int { + return strings.Compare(a.Name, b.Name) + }) + return desktopIDEs, nil }