Skip to content

Commit

Permalink
azp: improve preview + watch debugger (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherHX authored Nov 5, 2023
1 parent 91910a8 commit 443a366
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 17 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ This is experimental and covers a subset of Azure Pipelines.

[Quickstart Guide](./docs/quick-start/azure-pipeline.md)

[Azure Pipelines Tools VSCode Extension](./src/azure-pipelines-vscode-ext/README.md)

run `Runner.Client --event azpipelines -W pipeline.yml` / `gharun --event azpipelines -W pipeline.yml` to run Azure Pipelines locally, _this tool defaults to GitHub Actions and looks by default in `.github/workflows/` for yaml files_.
#### Templating
```yaml
Expand Down
80 changes: 75 additions & 5 deletions src/azure-pipelines-vscode-ext/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Azure Pipelines VSCode Extension
# Azure Pipelines Tools VSCode Extension

This is a minimal Azure Pipelines Extension, the first vscode Extension which can Validate and Expand Azure Pipeline YAML files locally without any REST service.

Expand Down Expand Up @@ -35,18 +35,84 @@ Sample Debugging configuration
"request": "launch",
"name": "Test Pipeline (watch)",
"program": "${workspaceFolder}/azure-pipeline.yml",
"repositories": {},
"parameters": {},
"variables": {},
"repositories": {
"myrepo@windows": "file:///C:/AzurePipelines/myrepo",
"myrepo@unix": "file:///AzurePipelines/myrepo",
"myrepo@github": "vscode-vfs://github/AzurePipelines/myrepo", // Only default branch, url doesn't accept readable ref
"myrepo@azure": "vscode-vfs://azurerepos/AzurePipelines/myrepo/myrepo" // Only default branch, url doesn't accept readable ref
},
"parameters": {
"booleanparam": true,
"numberparam": 12,
"stringparam": "Hello World",
"objectparam": {
"booleanparam": true,
"numberparam": 12,
"stringparam": "Hello World",
},
"arrayparam": [
true,
12,
"Hello World"
]
},
"variables": {
"system.debug": "true"
},
"watch": true,
"preview": true
}
```

Sample Pipeline which dumps the parameters object (legacy parameters syntax)
```yaml
parameters:
booleanparam:
numberparam:
stringparam:
objectparam:
arrayparam:
steps:
- script: echo '${{ converttojson(parameters) }}'
- script: echo '${{ converttojson(variables) }}'
```
Output of the Sample Pipeline
```yaml
stages:
- stage:
jobs:
- job:
steps:
- task: CmdLine@2
inputs:
script: |-
echo '{
"booleanparam": true,
"numberparam": 12,
"stringparam": "Hello World",
"objectparam": {
"booleanparam": true,
"numberparam": 12,
"stringparam": "Hello World"
},
"arrayparam": [
true,
12,
"Hello World"
]
}'
- task: CmdLine@2
inputs:
script: |-
echo '{
"system.debug": "true"
}'
```
## Pros
- Make changes in multiple dependent template files and show a live preview on save
- Everything is done locally
- Whole template engine is open source
- You can run template files with the same template engine locally using the Runner.Client tool using the official Azure Pipelines Agent
- Fast feedback
- Less trial and error commits
Expand All @@ -59,6 +125,10 @@ Sample Debugging configuration
- May not have feature parity with Azure Pipelines
- Missing predefined Variables, feel free to add them manually as needed
## Available in the VSCode Marketplace
[christopherhx.azure-pipelines-vscode-ext](https://marketplace.visualstudio.com/items?itemName=christopherhx.azure-pipelines-vscode-ext)
## Running the Extension
```sh
Expand Down
55 changes: 48 additions & 7 deletions src/azure-pipelines-vscode-ext/azure-pipelines-debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ interface ILaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
program: string;
trace?: boolean;
watch?: boolean;
preview?: boolean;
repositories?: string[];
variables?: string[];
parameters?: string[];
}

interface IAttachRequestArguments extends ILaunchRequestArguments { }
Expand All @@ -22,6 +26,7 @@ export class AzurePipelinesDebugSession extends LoggingDebugSession {
name: string
expandAzurePipeline: any
changed: any
disposables: vscode.Disposable[]

public constructor(virtualFiles: any, name: string, expandAzurePipeline: any, changed: any) {
super("azure-pipelines-debug.yml");
Expand All @@ -31,6 +36,7 @@ export class AzurePipelinesDebugSession extends LoggingDebugSession {
this.name = name;
this.expandAzurePipeline = expandAzurePipeline;
this.changed = changed;
this.disposables = [];
}

protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
Expand Down Expand Up @@ -67,36 +73,65 @@ export class AzurePipelinesDebugSession extends LoggingDebugSession {
return this.launchRequest(response, args);
}

protected async launchRequest(response: DebugProtocol.LaunchResponse, args: any) {
logger.setup(args.trace ? Logger.LogLevel.Verbose : Logger.LogLevel.Stop, false);
protected async launchRequest(response: DebugProtocol.LaunchResponse, args: ILaunchRequestArguments) {
logger.setup(args.trace ? Logger.LogLevel.Verbose : Logger.LogLevel.Warn, false);

var self = this;
var message = null;
var requestReOpen = false;
var assumeIsOpen = false;
if(args.preview) {
self.virtualFiles[self.name] = "";
var uri = vscode.Uri.from({
scheme: "azure-pipelines-vscode-ext",
path: this.name
});
var doc = await vscode.workspace.openTextDocument(uri);
await vscode.window.showTextDocument(doc, { preview: true, viewColumn: vscode.ViewColumn.Beside, preserveFocus: true });
vscode.workspace.onDidCloseTextDocument(adoc => {
await vscode.window.showTextDocument(doc, { preview: true, viewColumn: vscode.ViewColumn.Two, preserveFocus: true });
var previewIsOpen = () => vscode.window.tabGroups.all.some(g => g.tabs.some(t => t.input["uri"] && t.input["uri"].toString() === uri.toString()));
assumeIsOpen = !previewIsOpen();
if(assumeIsOpen) {
logger.error("failed to detect that the textdocument has been opended as a tab, assume that it is open and don't try to show it multiple times");
} else {
this.disposables.push(vscode.window.tabGroups.onDidChangeTabs(e => {
if(!previewIsOpen()) {
if(!requestReOpen) {
console.log(`file closed ${self.name}`);
}
requestReOpen = true;
} else {
if(requestReOpen) {
console.log(`file opened ${self.name}`);
}
requestReOpen = false;
}
}));
}
this.disposables.push(vscode.workspace.onDidCloseTextDocument(adoc => {
if(doc === adoc) {
this.sendEvent(new TerminatedEvent());
delete self.virtualFiles[self.name];
}
});
}));
self.changed(uri);
}
var run = async() => {
await this.expandAzurePipeline(false, args.repositories, args.variables, args.parameters, result => {
await this.expandAzurePipeline(false, args.repositories, args.variables, args.parameters, async result => {
if(args.preview) {
if(requestReOpen) {
await vscode.window.showTextDocument(doc, { preview: true, viewColumn: vscode.ViewColumn.Two, preserveFocus: true });
requestReOpen = false;
}
self.virtualFiles[self.name] = result;
self.changed(uri);
} else {
vscode.window.showInformationMessage("No Issues found");
}
}, args.program, async errmsg => {
if(args.preview) {
if(requestReOpen) {
await vscode.window.showTextDocument(doc, { preview: true, viewColumn: vscode.ViewColumn.Two, preserveFocus: true });
requestReOpen = false;
}
self.virtualFiles[self.name] = errmsg;
self.changed(uri);
} else if(args.watch) {
Expand Down Expand Up @@ -148,6 +183,12 @@ export class AzurePipelinesDebugSession extends LoggingDebugSession {
if (this.watcher) {
this.watcher.dispose();
}
if (this.disposables) {
for(const disposable of this.disposables) {
disposable.dispose();
}
}
delete this.virtualFiles[self.name];
this.sendResponse(response);
}
}
5 changes: 2 additions & 3 deletions src/azure-pipelines-vscode-ext/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function activate(context) {
var uris = [vscode.Uri.parse(fspathname), vscode.Uri.file(fspathname)];
for(var current of uris) {
var rbase = vscode.workspace.getWorkspaceFolder(current);
var name = vscode.workspace.asRelativePath(current);
var name = vscode.workspace.asRelativePath(current, false);
if(rbase && name) {
base = rbase.uri;
filename = name;
Expand All @@ -207,8 +207,7 @@ function activate(context) {
for(var workspace of vscode.workspace.workspaceFolders) {
if(fspathname.startsWith(workspace.uri.fsPath)) {
base = workspace.uri;
filename = vscode.workspace.asRelativePath(workspace.uri.with({path: workspace.uri.path + "/" + fspathname.substring(workspace.uri.fsPath.length).replace(/[\\\/]+/g, "/")
}));
filename = vscode.workspace.asRelativePath(workspace.uri.with({path: workspace.uri.path + "/" + fspathname.substring(workspace.uri.fsPath.length).replace(/[\\\/]+/g, "/")}), false);
break;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/azure-pipelines-vscode-ext/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "azure-pipelines-vscode-ext",
"description": "Azure Pipelines VSCode Tools allows you to make local changes to Azure Pipeline Template Files, while beeing able to check for Syntax errors after expanding all templates into a single file before commit and pushing it to the repository",
"displayName": "Azure Pipelines Tools",
"description": "Azure Pipelines Tools allow you to make local changes to Azure Pipeline Template Files, while beeing able to check for Syntax errors after expanding all templates into a single file before commit and pushing it to the repository",
"categories": [
"Azure",
"Testing",
"Programming Languages"
],
"version": "0.0.6",
"version": "0.0.7",
"publisher": "christopherhx",
"repository": "https://github.com/ChristopherHX/runner.server",
"engines": {
Expand Down

0 comments on commit 443a366

Please sign in to comment.