Skip to content

Commit 8612f77

Browse files
committed
gp rebuild hints
1 parent 17b87a1 commit 8612f77

File tree

15 files changed

+267
-397
lines changed

15 files changed

+267
-397
lines changed

.gitpod.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
image: gitpod/workspace-node
12
tasks:
23
- init: |
34
yarn install
@@ -12,6 +13,11 @@ tasks:
1213
cd gitpod-web
1314
gp sync-await shared
1415
yarn watch
16+
- name: Compile gitpod-remote
17+
command: |
18+
cd gitpod-remote
19+
gp sync-await shared
20+
yarn watch
1521
1622
vscode:
1723
extensions:

gitpod-remote/package.json

Lines changed: 15 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -153,51 +153,26 @@
153153
"title": "%tunnelHost%",
154154
"icon": "$(eye-closed)"
155155
},
156-
{
157-
"command": "gitpod.gitpodyml.build",
158-
"title": "%buildGitpodYml%",
159-
"icon": "$(tools)"
160-
},
161156
{
162157
"command": "gitpod.gitpodyml.run",
163158
"title": "%runGitpodYml%",
164159
"icon": "$(play)"
165160
},
166-
{
167-
"command": "gitpod.gitpodyml.editorContext.build",
168-
"title": "%buildGitpodYml%",
169-
"icon": "$(tools)"
170-
},
171161
{
172162
"command": "gitpod.gitpodyml.editorContext.run",
173163
"title": "%runGitpodYml%",
174164
"icon": "$(play)"
175165
},
176-
{
177-
"command": "gitpod.gitpodyml.dockerfile.editorContext.build",
178-
"title": "%buildGitpodYml%",
179-
"icon": "$(tools)"
180-
},
181166
{
182167
"command": "gitpod.gitpodyml.dockerfile.editorContext.run",
183168
"title": "%runGitpodYml%",
184169
"icon": "$(play)"
185170
},
186-
{
187-
"command": "gitpod.gitpodyml.editorTitle.build",
188-
"title": "%buildGitpodYml%",
189-
"icon": "$(tools)"
190-
},
191171
{
192172
"command": "gitpod.gitpodyml.editorTitle.run",
193173
"title": "%runGitpodYml%",
194174
"icon": "$(play)"
195175
},
196-
{
197-
"command": "gitpod.gitpodyml.dockerfile.editorTitle.build",
198-
"title": "%buildGitpodYml%",
199-
"icon": "$(tools)"
200-
},
201176
{
202177
"command": "gitpod.gitpodyml.dockerfile.editorTitle.run",
203178
"title": "%runGitpodYml%",
@@ -283,46 +258,26 @@
283258
}
284259
],
285260
"editor/context": [
286-
{
287-
"command": "gitpod.gitpodyml.editorContext.build",
288-
"when": "gitpod.run-gp.enabled && resourceFilename == '.gitpod.yml' && resourceScheme == file",
289-
"group": "0_navigation@0"
290-
},
291261
{
292262
"command": "gitpod.gitpodyml.editorContext.run",
293-
"when": "gitpod.run-gp.enabled && resourceFilename == '.gitpod.yml' && resourceScheme == file",
294-
"group": "0_navigation@0"
295-
},
296-
{
297-
"command": "gitpod.gitpodyml.dockerfile.editorContext.build",
298-
"when": "gitpod.run-gp.enabled && gitpod.run-gp.dockerfile && resourceFilename =~ /^Dockerfile$|\\.Dockerfile$/ && resourceScheme == file",
263+
"when": "gitpod.rebuild.enabled && resourceFilename == '.gitpod.yml' && resourceScheme == file",
299264
"group": "0_navigation@0"
300265
},
301266
{
302267
"command": "gitpod.gitpodyml.dockerfile.editorContext.run",
303-
"when": "gitpod.run-gp.enabled && gitpod.run-gp.dockerfile && resourceFilename =~ /^Dockerfile$|\\.Dockerfile$/ && resourceScheme == file",
268+
"when": "gitpod.rebuild.enabled && gitpod.rebuild.dockerfile",
304269
"group": "0_navigation@0"
305270
}
306271
],
307272
"editor/title": [
308-
{
309-
"command": "gitpod.gitpodyml.editorTitle.build",
310-
"when": "gitpod.run-gp.enabled && resourceFilename == '.gitpod.yml' && resourceScheme == file",
311-
"group": "navigation"
312-
},
313273
{
314274
"command": "gitpod.gitpodyml.editorTitle.run",
315-
"when": "gitpod.run-gp.enabled && resourceFilename == '.gitpod.yml' && resourceScheme == file",
316-
"group": "navigation"
317-
},
318-
{
319-
"command": "gitpod.gitpodyml.dockerfile.editorTitle.build",
320-
"when": "gitpod.run-gp.enabled && gitpod.run-gp.dockerfile && resourceFilename =~ /^Dockerfile$|\\.Dockerfile$/ && resourceScheme == file",
275+
"when": "gitpod.rebuild.enabled && resourceFilename == '.gitpod.yml' && resourceScheme == file",
321276
"group": "navigation"
322277
},
323278
{
324279
"command": "gitpod.gitpodyml.dockerfile.editorTitle.run",
325-
"when": "gitpod.run-gp.enabled && gitpod.run-gp.dockerfile && resourceFilename =~ /^Dockerfile$|\\.Dockerfile$/ && resourceScheme == file",
280+
"when": "gitpod.rebuild.enabled && gitpod.rebuild.dockerfile",
326281
"group": "navigation"
327282
}
328283
],
@@ -355,48 +310,38 @@
355310
"command": "gitpod.ports.tunnelHost",
356311
"when": "false"
357312
},
358-
{
359-
"command": "gitpod.gitpodyml.build",
360-
"when": "gitpod.run-gp.enabled"
361-
},
362313
{
363314
"command": "gitpod.gitpodyml.run",
364-
"when": "gitpod.run-gp.enabled"
365-
},
366-
{
367-
"command": "gitpod.gitpodyml.editorContext.build",
368-
"when": "false"
315+
"when": "gitpod.rebuild.enabled"
369316
},
370317
{
371318
"command": "gitpod.gitpodyml.editorContext.run",
372319
"when": "false"
373320
},
374-
{
375-
"command": "gitpod.gitpodyml.dockerfile.editorContext.build",
376-
"when": "false"
377-
},
378321
{
379322
"command": "gitpod.gitpodyml.dockerfile.editorContext.run",
380323
"when": "false"
381324
},
382-
{
383-
"command": "gitpod.gitpodyml.editorTitle.build",
384-
"when": "false"
385-
},
386325
{
387326
"command": "gitpod.gitpodyml.editorTitle.run",
388327
"when": "false"
389328
},
390-
{
391-
"command": "gitpod.gitpodyml.dockerfile.editorTitle.build",
392-
"when": "false"
393-
},
394329
{
395330
"command": "gitpod.gitpodyml.dockerfile.editorTitle.run",
396331
"when": "false"
397332
}
398333
]
399334
},
335+
"configuration": {
336+
"title": "Gitpod",
337+
"properties": {
338+
"gitpod.validate.neverPrompt": {
339+
"type": "boolean",
340+
"description": "Control whether to prompt to validate the workspace configuration on change.",
341+
"default": false
342+
}
343+
}
344+
},
400345
"views": {
401346
"portsView": [
402347
{

gitpod-remote/package.nls.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,5 @@
2626
"tunnelHost": "Tunnel on localhost",
2727
"retryAutoExpose": "Retry to expose",
2828
"openWebLinkInBrowser": "Open web link in Browser",
29-
"buildGitpodYml": "Gitpod: Build Gitpod Configuration",
30-
"runGitpodYml": "Gitpod: Test Gitpod Configuration"
29+
"runGitpodYml": "Gitpod: Validate Configuration"
3130
}

gitpod-shared/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"typescript": "^4.6.3"
3030
},
3131
"dependencies": {
32+
"configcat-node": "^8.0.0",
3233
"@gitpod/gitpod-protocol": "main",
3334
"@gitpod/supervisor-api-grpc": "ak-rebuild-debug",
3435
"@vscode/codicons": "^0.0.31",

gitpod-shared/src/analytics.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ export type GitpodAnalyticsEvent =
4949
GAET<'ide_close_signal', {
5050
clientKind: 'vscode';
5151
}> |
52-
GAET<'vscode_execute_command_inner_loop', {
53-
action: 'build' | 'run' | 'feedback' | 'learn';
54-
location: 'codelens' | 'editorContext' | 'editorTitle';
55-
source: 'gitpodYml' | 'dockerfile';
56-
}>;
52+
GitpodValidateAnalytics;
53+
54+
export type GitpodValidateAnalytics = GAET<'vscode_validate', {
55+
action: 'run' | 'feedback' | 'learn' | 'cancel' | 'neverAgain';
56+
location: 'codelens' | 'editorContext' | 'editorTitle' | 'notification';
57+
source: 'gitpodYml' | 'dockerfile';
58+
}>;
5759

5860
export function registerUsageAnalytics(context: GitpodExtensionContext): void {
5961
context.fireAnalyticsEvent({ eventName: 'vscode_session', properties: {} });

gitpod-shared/src/experiments.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Gitpod. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
import * as vscode from 'vscode';
6+
import * as configcat from 'configcat-node';
7+
import * as configcatcommon from 'configcat-common';
8+
import Log from './common/logger';
9+
import { URL } from 'url';
10+
import { Team, User } from '@gitpod/gitpod-protocol';
11+
12+
const experimentsSection = 'gitpod.experiments';
13+
14+
export type EXPERIMENTAL_SETTINGS = 'gitpod.experiments.rebuildHints';
15+
16+
export class ExperimentalSettings {
17+
private configcatClient: configcatcommon.IConfigCatClient;
18+
19+
constructor(
20+
key: string,
21+
context: vscode.ExtensionContext,
22+
private logger: Log,
23+
gitpodHost: string,
24+
private readonly pendingOwner: Promise<User>,
25+
private readonly pendingTeams: Promise<Team[]>,
26+
) {
27+
this.configcatClient = configcat.createClientWithLazyLoad(key, {
28+
baseUrl: new URL('/configcat', context.extensionMode === vscode.ExtensionMode.Production ? gitpodHost : 'https://gitpod-staging.com').href,
29+
logger: {
30+
debug(): void { },
31+
log(): void { },
32+
info(): void { },
33+
warn(message: string): void { logger.warn(`ConfigCat: ${message}`); },
34+
error(message: string): void { logger.error(`ConfigCat: ${message}`); }
35+
},
36+
requestTimeoutMs: 1500,
37+
cacheTimeToLiveSeconds: 60
38+
});
39+
}
40+
41+
async get<T>(key: EXPERIMENTAL_SETTINGS): Promise<T | undefined> {
42+
const config = vscode.workspace.getConfiguration(experimentsSection);
43+
const values = config.inspect<T>(key.substring((experimentsSection + '.').length));
44+
if (!values) {
45+
this.logger.error(`Cannot get invalid experimental setting '${key}'`);
46+
return undefined;
47+
}
48+
if (values.globalValue !== undefined) {
49+
// User setting have priority over configcat so return early
50+
return values.globalValue;
51+
}
52+
const experimentValue = await this.getExperimentValue<T>(key);
53+
return experimentValue ?? values.defaultValue;
54+
}
55+
56+
private async getExperimentValue<T>(key: string): Promise<T | undefined> {
57+
const configcatKey = key.replace(/\./g, '_'); // '.' are not allowed in configcat
58+
const unresolved = '__unressssolved__'
59+
60+
const user = await this.pendingOwner;
61+
const email = User.getPrimaryEmail(user);
62+
const teams = await this.pendingTeams;
63+
if (teams.length) {
64+
for (const team of teams) {
65+
const value = (await this.configcatClient.getValueAsync(configcatKey, unresolved, this.getConfigcatUser(user.id, email, team.id)));
66+
if (value != unresolved) {
67+
return value as T;
68+
}
69+
}
70+
} else {
71+
const value = (await this.configcatClient.getValueAsync(configcatKey, unresolved, this.getConfigcatUser(user.id, email, undefined)));
72+
if (value != unresolved) {
73+
return value as T;
74+
}
75+
}
76+
return undefined;
77+
}
78+
79+
private getConfigcatUser(userId: string, email: string | undefined, teamId: string | undefined): configcatcommon.User {
80+
const attributes: { [key: string]: string } = {
81+
"user_id": userId
82+
}
83+
if (email) {
84+
attributes["user_email"] = email;
85+
}
86+
if (teamId) {
87+
attributes["team_id"] = teamId;
88+
}
89+
return new configcatcommon.User(userId, email, undefined, attributes);
90+
}
91+
92+
dispose(): void {
93+
this.configcatClient.dispose();
94+
}
95+
}

gitpod-shared/src/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import * as vscode from 'vscode';
66
import { registerActiveLanguageAnalytics, registerUsageAnalytics } from './analytics';
77
import { createGitpodExtensionContext, registerDefaultLayout, registerNotifications, registerWorkspaceCommands, registerWorkspaceSharing, registerWorkspaceTimeout } from './features';
8-
import { GitpodCodelens } from './gitpodCodelens';
8+
import { ValidateService } from './validate';
99
import { GitpodExtensionContext } from './gitpodContext';
1010

1111
export { GitpodExtensionContext } from './gitpodContext';
@@ -39,7 +39,7 @@ export async function setupGitpodContext(context: vscode.ExtensionContext): Prom
3939
registerWorkspaceTimeout(gitpodContext);
4040
registerNotifications(gitpodContext);
4141
registerDefaultLayout(gitpodContext);
42-
gitpodContext.subscriptions.push(new GitpodCodelens(gitpodContext));
42+
gitpodContext.subscriptions.push(new ValidateService(gitpodContext));
4343

4444
return gitpodContext;
4545
}

gitpod-shared/src/features.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import WebSocket = require('ws');
2424
import Log from './common/logger';
2525
import { isGRPCErrorStatus } from './common/utils';
2626
import { GitpodConnection, GitpodExtensionContext, SupervisorConnection } from './gitpodContext';
27+
import { ExperimentalSettings } from './experiments';
2728

2829
export async function createGitpodExtensionContext(context: vscode.ExtensionContext): Promise<GitpodExtensionContext | undefined> {
2930
const logger = new Log('Gitpod Workspace');
@@ -103,6 +104,9 @@ export async function createGitpodExtensionContext(context: vscode.ExtensionCont
103104

104105
const ipcHookCli = installCLIProxy(context, logger);
105106

107+
const experiments = new ExperimentalSettings('gitpod', context, logger, gitpodHost, pendingGetOwner, pendingGetUserTeams);
108+
context.subscriptions.push(experiments);
109+
106110
return new GitpodExtensionContext(
107111
context,
108112
devMode,
@@ -116,7 +120,8 @@ export async function createGitpodExtensionContext(context: vscode.ExtensionCont
116120
pendingInstanceListener,
117121
pendingWorkspaceOwned,
118122
logger,
119-
ipcHookCli
123+
ipcHookCli,
124+
experiments
120125
);
121126
}
122127

gitpod-shared/src/gitpodContext.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { GetTokenRequest } from '@gitpod/supervisor-api-grpc/lib/token_pb';
2929
import { PortsStatusRequest, PortsStatusResponse, PortsStatus } from '@gitpod/supervisor-api-grpc/lib/status_pb';
3030
import { isGRPCErrorStatus } from './common/utils';
3131
import { ExposePortRequest } from '@gitpod/supervisor-api-grpc/lib/control_pb';
32+
import { ExperimentalSettings } from './experiments';
3233

3334
// Important:
3435
// This class should performs all supervisor API calls used outside this module.
@@ -212,7 +213,8 @@ export class GitpodExtensionContext implements vscode.ExtensionContext {
212213
readonly instanceListener: Promise<WorkspaceInstanceUpdateListener>,
213214
readonly workspaceOwned: Promise<boolean>,
214215
readonly logger: Log,
215-
readonly ipcHookCli: string | undefined
216+
readonly ipcHookCli: string | undefined,
217+
readonly experiments: ExperimentalSettings
216218
) {
217219
this.workspaceContextUrl = vscode.Uri.parse(info.workspaceContextUrl);
218220

0 commit comments

Comments
 (0)