Skip to content

Commit efd03db

Browse files
committed
added ci-pipeline panel
1 parent 9c7b2be commit efd03db

9 files changed

Lines changed: 607 additions & 16 deletions

File tree

media/codesphere-logo.svg

Lines changed: 4 additions & 0 deletions
Loading

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
"title": "Codesphere",
3030
"icon": "media/codesphere.svg"
3131
}
32+
],
33+
"panel": [
34+
{
35+
"id": "ci-pipeline",
36+
"title": "Ci-Pipeline",
37+
"icon": "media/codesphere.svg",
38+
"order": 10
39+
}
3240
]
3341
},
3442
"views": {
@@ -52,6 +60,15 @@
5260
"icon": "media/Codesphere.svg",
5361
"contextualTitle": "Codesphere"
5462
}
63+
],
64+
"ci-pipeline": [
65+
{
66+
"type": "webview",
67+
"id": "ci-pipeline",
68+
"name": "Ci-Pipeline",
69+
"contextualTitle": "Ci Pipeline",
70+
"when": "codesphere.isLoggedIn && codesphere.workspaceOverview"
71+
}
5572
]
5673
},
5774
"menus": {

src/CiPipelineProvider.ts

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import * as vscode from "vscode";
2+
import { getNonce } from "./ts/getNonce";
3+
import * as wsLib from 'ws';
4+
const { setupWs,
5+
request,
6+
getUaSocket,
7+
checkCiPipelineStructure
8+
} = require('./ts/wsService');
9+
10+
export class CiPipelineProvider implements vscode.WebviewViewProvider {
11+
_view?: vscode.WebviewView;
12+
_doc?: vscode.TextDocument;
13+
14+
constructor(private readonly _extensionUri: vscode.Uri, public extensionContext: vscode.ExtensionContext) {}
15+
16+
17+
18+
public resolveWebviewView(webviewView: vscode.WebviewView) {
19+
this._view = webviewView;
20+
let cache = this.extensionContext.globalState;
21+
22+
webviewView.webview.options = {
23+
// Allow scripts in the webview
24+
enableScripts: true,
25+
26+
localResourceRoots: [this._extensionUri],
27+
};
28+
29+
webviewView.webview.html = this._getHtmlWebview(webviewView.webview);
30+
31+
webviewView.webview.onDidReceiveMessage(async (data) => {
32+
let socket: any;
33+
let uaSocket = getUaSocket();
34+
35+
switch (data.type) {
36+
case "getCiPipelineStages": {
37+
const socketURL = `wss://${data.value.dataCenterId}.codesphere.com/workspace-proxy`;
38+
console.log(socketURL + `socketURL`);
39+
const accessToken = await this.extensionContext.secrets.get("codesphere.accessToken") as string;
40+
const workspaceID: number = parseInt(data.value.workspaceId);
41+
socket = await setupWs(new wsLib.WebSocket(socketURL), "workspace-proxy", accessToken, cache, workspaceID);
42+
43+
uaSocket = getUaSocket();
44+
let ciStructure: any;
45+
const ciPipelineCheck = checkCiPipelineStructure(uaSocket, 324);
46+
ciPipelineCheck.then((ci: any) => {
47+
ciStructure = ci;
48+
console.log('ciStructure: ' + JSON.stringify(ciStructure));
49+
this._view?.webview.postMessage({
50+
type: "CIPipelineStages",
51+
value: {
52+
'CIArray': `${JSON.stringify(ciStructure)}`
53+
}
54+
});
55+
}
56+
);
57+
58+
await request(uaSocket, "pipelineStream", { workspaceId: workspaceID}, "workspace-proxy", 324);
59+
60+
break;
61+
}
62+
63+
case "currentWorkspace": {
64+
const workspace: any = await cache.get("codesphere.workspaceOverview");
65+
66+
const workspaceId = workspace.id;
67+
const teamId = workspace.teamId;
68+
const dataCenterId = workspace.dataCenterId;
69+
70+
this._view?.webview.postMessage({
71+
type: "currentWorkspace",
72+
value: {
73+
'currentWorkspace': `${workspaceId}`,
74+
'teamId': `${teamId}`,
75+
'dcId': `${dataCenterId}`
76+
}
77+
});
78+
79+
break;
80+
}
81+
}
82+
});
83+
}
84+
85+
86+
public updateWebviewContent() {
87+
if (this._view) {
88+
this._view.webview.html = this._getHtmlWebview(this._view.webview);
89+
}
90+
}
91+
92+
public revive(panel: vscode.WebviewView) {
93+
this._view = panel;
94+
}
95+
96+
97+
private _getHtmlWebview(webview: vscode.Webview) {
98+
const styleResetUri = webview.asWebviewUri(
99+
vscode.Uri.joinPath(this._extensionUri, "media", "reset.css")
100+
);
101+
const scriptUri = webview.asWebviewUri(
102+
vscode.Uri.joinPath(this._extensionUri, "out", "compiled/cipipeline.js")
103+
);
104+
const styleMainUri = webview.asWebviewUri(
105+
vscode.Uri.joinPath(this._extensionUri, "out", "compiled/cipipeline.css")
106+
);
107+
const styleVSCodeUri = webview.asWebviewUri(
108+
vscode.Uri.joinPath(this._extensionUri, "media", "vscode.css")
109+
);
110+
111+
// Use a nonce to only allow a specific script to be run.
112+
const nonce = getNonce();
113+
114+
return `<!DOCTYPE html>
115+
<html lang="en">
116+
<head>
117+
<meta charset="UTF-8">
118+
<!--
119+
Use a content security policy to only allow loading images from https or from our extension directory,
120+
and only allow scripts that have a specific nonce.
121+
-->
122+
<meta http-equiv="Content-Security-Policy" content="img-src https: data:; style-src 'unsafe-inline' ${
123+
webview.cspSource
124+
}; script-src 'nonce-${nonce}';">
125+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
126+
<link href="${styleResetUri}" rel="stylesheet">
127+
<link href="${styleVSCodeUri}" rel="stylesheet">
128+
<link href="${styleMainUri}" rel="stylesheet">
129+
<script nonce="${nonce}">
130+
const vscode = acquireVsCodeApi();
131+
</script>
132+
</head>
133+
<body>
134+
<script nonce="${nonce}" src="${scriptUri}"></script>
135+
</body>
136+
</html>`;
137+
}
138+
}

src/SidebarProvider.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
6868
vscode.commands.executeCommand('setContext', 'codesphere.isLoggedIn', true);
6969
cache.update("codesphere.isLoggedIn", true);
7070
webviewView.webview.html = this._getHtmlWebviewOverview(webviewView.webview);
71+
cache.update('codesphere.workspaceOverview', cache.get('codesphere.currentWorkspace'));
72+
vscode.commands.executeCommand('setContext', 'codesphere.workspaceOverview', cache.get('codesphere.currentWorkspace'));
7173
console.log('Congratulations, your extension "codesphere" is now active! You are logged in.');
7274

7375
let currentWorkspace = parseInt(cache.get('codesphere.currentWorkspace') as string);
@@ -128,14 +130,19 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
128130
cache.update("codesphere.activeTunnel", {});
129131
}
130132

133+
if (!cache.get("codesphere.workspaceOverview")) {
134+
cache.update("codesphere.workspaceOverview", '');
135+
}
136+
131137
cache.setKeysForSync(["codesphere.isLoggedIn",
132138
"codesphere.accessTokenCache",
133139
"codesphere.teams",
134140
"codesphere.workspaces",
135141
"codesphere.userData",
136142
"codesphere.lastCode",
137143
"codesphere.activeTunnel",
138-
"codesphere.currentWorkspace"]);
144+
"codesphere.currentWorkspace",
145+
"codesphere.workspaceOverview"]);
139146

140147
webviewView.webview.onDidReceiveMessage(async (data) => {
141148
let socket: any;
@@ -670,6 +677,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
670677
return;
671678
}
672679
webviewView.webview.html = this._getHtmlWebviewOverview(webviewView.webview);
680+
vscode.commands.executeCommand('setContext', 'codesphere.workspaceOverview', data.value.workspaceId);
673681
const workspacesInTeam: any = cache.get("codesphere.workspaces");
674682
const teamId = data.value.teamId;
675683

@@ -679,6 +687,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
679687
);
680688

681689
cache.update("codesphere.currentconnectedWorkspace", selectedWorkspace);
690+
cache.update("codesphere.workspaceOverview", selectedWorkspace);
682691

683692
if (selectedWorkspace === cache.get("codesphere.currentWorkspace")) {
684693
vscode.commands.executeCommand('codesphere.openOverView', selectedWorkspace);
@@ -694,6 +703,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
694703
} else {
695704
console.error("Workspace not found with ID:", data.value.workspaceId);
696705
}
706+
697707
break;
698708
}
699709

@@ -717,8 +727,11 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
717727
if (!data.value) {
718728
return;
719729
}
730+
// todo: check wether it is mandatory to erease the currentWorkspace context. I dont think so but at the moment i dont want to destroy anything
720731
webviewView.webview.html = this._getHtmlForWebviewAfterSignIn(webviewView.webview);
721732
vscode.commands.executeCommand('setContext', 'codesphere.currentWorkspace', "");
733+
vscode.commands.executeCommand('setContext', 'codesphere.workspaceOverview', '');
734+
cache.update('codesphere.workspaceOverview', '');
722735
vscode.commands.executeCommand('codesphere.backToMenu');
723736
break;
724737
}

src/extension.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode';
22
import { SidebarProvider } from './SidebarProvider';
33
import { FileTreeProvider } from './FileTreeProvider';
4+
import { CiPipelineProvider } from './CiPipelineProvider';
45
import { NoCurrentWorkspaceProvider } from './NoCurrentWorkspaceProvider';
56
import { reloadCache } from './ts/reloadCache';
67
import { exec } from 'child_process';
@@ -16,14 +17,12 @@ function getWorkspaceRootPath(): string {
1617
}
1718

1819
export function activate(context: vscode.ExtensionContext) {
19-
20-
vscode.ExtensionKind.UI;
21-
2220
const sidebarProvider = new SidebarProvider(context.extensionUri, context);
2321
const noCurrentWorkspaceProvider = new NoCurrentWorkspaceProvider(context.extensionUri);
2422
const rootPath: string = getWorkspaceRootPath();
2523
const fileTreeProvider = new FileTreeProvider(rootPath);
2624
console.log('roothPath is: ', rootPath);
25+
const ciPipelineProvider = new CiPipelineProvider(context.extensionUri, context);
2726

2827
const remoteName = vscode.env.remoteName;
2928
console.log('remote name ' + remoteName);
@@ -62,6 +61,13 @@ export function activate(context: vscode.ExtensionContext) {
6261
)
6362
);
6463

64+
context.subscriptions.push(
65+
vscode.window.registerWebviewViewProvider(
66+
'ci-pipeline',
67+
ciPipelineProvider
68+
)
69+
);
70+
6571
const userData: any = context.globalState.get("codesphere.userData");
6672
const gitEmail: string = userData.email || "";
6773
let gitFirstName: string = userData.firstName || "";

src/ts/wsService.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,35 @@ const isVSIX = async (deploymentSocket: any) => {
513513
});
514514
};
515515

516+
const checkCiPipelineStructure = async (deploymentSocket: any, endpointId: number) => {
517+
return new Promise((resolve, reject) => {
518+
const messageHandler = (msg: any) => {
519+
try {
520+
let msgTest = msg.toString();
521+
let parsedMsg = JSON.parse(msgTest);
522+
523+
if (msgTest.includes(`"endpointId":${endpointId}`)) {
524+
console.log(`ci-Structure` + msgTest)
525+
deploymentSocket.off("message", messageHandler);
526+
deploymentSocket.off("error", errorHandler);
527+
resolve(parsedMsg.reply);
528+
}
529+
} catch (error) {
530+
console.error("Error parsing message:", error);
531+
reject(error);
532+
}
533+
};
534+
535+
const errorHandler = (err: any) => {
536+
console.log("Socket exited with error:" + err);
537+
reject(err);
538+
};
539+
540+
deploymentSocket.on("message", messageHandler);
541+
deploymentSocket.on("error", errorHandler);
542+
});
543+
};
544+
516545

517546

518547

@@ -535,6 +564,7 @@ module.exports = {
535564
getRemoteURL,
536565
getGitHubToken,
537566
isVSIX,
567+
checkCiPipelineStructure,
538568
getUaSocket: () => uaSocket,
539569
getDsSocket: () => dsSocket
540570
};

0 commit comments

Comments
 (0)