Skip to content

Commit 43c6c84

Browse files
authored
Add support to download a specific version of the AzureDevOps.WikiPDFExport CLI tools (#2167)
* Add option to download specific version of CLI tool * NPM Package Update
1 parent 648aad5 commit 43c6c84

File tree

9 files changed

+583
-935
lines changed

9 files changed

+583
-935
lines changed

Extensions/WikiPDFExport/WikiPDFExportTask/WikiPDFExportTaskV4/package-lock.json

Lines changed: 479 additions & 896 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Extensions/WikiPDFExport/WikiPDFExportTask/WikiPDFExportTaskV4/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
},
1515
"main": "test.js",
1616
"dependencies": {
17+
"axios": "^1.13.2",
1718
"azure-pipelines-task-lib": "^4.10.1",
18-
"download-github-release": "^0.3.2",
1919
"fs": "0.0.1-security",
2020
"ncp": "^2.0.0",
2121
"process": "^0.11.10",

Extensions/WikiPDFExport/WikiPDFExportTask/WikiPDFExportTaskV4/src/ExportFunctions.ts

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as process from "process";
22
import { exec } from "child_process";
33
import * as fs from "fs";
44
import * as path from "path";
5+
import axios from "axios";
56
import {
67
CloneWikiRepo,
78
GetTrimmedUrl,
@@ -16,35 +17,59 @@ import {
1617
import { filePathSupplied } from "azure-pipelines-task-lib";
1718

1819
async function DownloadGitHubArtifact(
19-
user,
20+
owner,
2021
repo,
2122
folder,
22-
usePreRelease,
23+
desiredVersion,
2324
artifactName,
2425
logInfo,
2526
logError) {
2627

27-
var downloadRelease = require("download-github-release");
28-
logInfo(`Starting download ${artifactName} to ${folder}`);
29-
await downloadRelease(
30-
user,
31-
repo,
32-
folder,
33-
function filterRelease(release) {
34-
// Filter out prereleases.
35-
return release.prerelease === usePreRelease;
36-
},
37-
function filterAsset(asset) {
38-
// Select assets that contain the string .
39-
return (asset.name === artifactName);
40-
},
41-
false)
42-
.then(function() {
43-
logInfo("Download done");
44-
})
45-
.catch(function(err) {
46-
logError(err.message);
28+
try {
29+
const apiUrl = desiredVersion
30+
? `https://api.github.com/repos/${owner}/${repo}/releases/tags/${desiredVersion}`
31+
: `https://api.github.com/repos/${owner}/${repo}/releases/latest`;
32+
33+
logInfo(`Fetching release from: ${apiUrl}`);
34+
// Get release info
35+
const response = await axios.get(apiUrl, {
36+
headers: {
37+
"User-Agent": "github-release-downloader",
38+
},
39+
});
40+
const release = response.data;
41+
42+
// Locate the asset
43+
const asset = release.assets.find((a) => a.name === artifactName);
44+
if (!asset) {
45+
logError(`Asset "${artifactName}" not found in release ${release.tag_name}.`);
46+
return;
47+
}
48+
49+
// Download the asset
50+
const downloadResponse = await axios.get(asset.browser_download_url, {
51+
responseType: "stream", // Required for downloading binary files
52+
});
53+
54+
// Stream the asset to a file
55+
if (!fs.existsSync(folder)) {
56+
logInfo(`Creating folder: ${folder}`);
57+
fs.mkdirSync(folder, { recursive: true });
58+
}
59+
const filePath = path.join(folder, artifactName);
60+
const writer = fs.createWriteStream(filePath);
61+
downloadResponse.data.pipe(writer);
62+
63+
writer.on("finish", () => {
64+
logInfo(`Downloaded file at: ${filePath}`);
65+
});
66+
67+
writer.on("error", (err) => {
68+
logError("Error writing file:", err);
4769
});
70+
} catch (error) {
71+
logError("Error downloading release:", error.response ? error.response.data : error.message);
72+
}
4873
}
4974

5075
export async function ExportPDF(
@@ -138,7 +163,7 @@ export async function ExportPDF(
138163
export async function GetExePath (
139164
overrideExePath,
140165
workingFolder,
141-
usePreRelease,
166+
desiredVersion,
142167
os: string
143168
) {
144169
if (overrideExePath && overrideExePath.length > 0) {
@@ -161,7 +186,7 @@ export async function GetExePath (
161186
"MaxMelcher",
162187
"AzureDevOps.WikiPDFExport",
163188
workingFolder,
164-
usePreRelease,
189+
desiredVersion,
165190
artifactName,
166191
logInfo,
167192
logError);

Extensions/WikiPDFExport/WikiPDFExportTask/WikiPDFExportTaskV4/src/WikiPDFExportTask.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var cloneRepo = tl.getBoolInput("cloneRepo");
2727
var overrideExePath = tl.getInput("overrideExePath");
2828
var workingFolder = tl.getInput("downloadPath");
2929
var rootExportPath = tl.getInput("rootExportPath");
30+
var desiredVersion = tl.getInput("desiredVersion");
3031
var usePreRelease = tl.getBoolInput("usePreRelease");
3132

3233
// make sure that we support older configs where these two parameter were a single setting
@@ -46,15 +47,20 @@ console.log(`Variable: OutputFile [${outputFile}]`);
4647
console.log(`Variable: Branch [${branch}]`);
4748
console.log(`Variable: InjectExtraHeader [${injectExtraHeader}]`);
4849
console.log(`Variable: OverrideExePath [${overrideExePath}]`);
49-
console.log(`Variable: UsePreRelease [${usePreRelease}]`);
50+
console.log(`Variable: DesiredVersion [${desiredVersion}]`);
5051
console.log(`Variable: DownloadPath [${workingFolder}]`);
52+
console.log(`Variable: UsePreRelease [${usePreRelease}]`);
53+
54+
if (usePreRelease === true) {
55+
logWarning(`The usePreRelease option is no longer used, it has been replaced by desiredVersion.`);
56+
}
5157

5258
var os = tl.getVariable("AGENT.OS");
5359

5460
GetExePath(
5561
overrideExePath,
5662
workingFolder,
57-
usePreRelease,
63+
desiredVersion,
5864
os
5965
).then((exePath) => {
6066
if (exePath.length > 0) {

Extensions/WikiPDFExport/WikiPDFExportTask/WikiPDFExportTaskV4/task/task.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,19 @@
153153
{
154154
"name": "usePreRelease",
155155
"type": "boolean",
156-
"label": "Use pre-release versions of the export tool",
156+
"label": "Use pre-release versions of the export tool (deprecated)",
157157
"defaultValue": "False",
158158
"required": false,
159-
"helpMarkDown": "If set to true pre-release version of the [AzureDevOps.WikiPDFExport tool](https://github.com/MaxMelcher/AzureDevOps.WikiPDFExport) tool will be used",
159+
"helpMarkDown": "The usePreRelease option is no longer used, it has been replaced by desiredVersion.",
160+
"groupName": "advanced"
161+
},
162+
{
163+
"name": "desiredVersion",
164+
"type": "string",
165+
"label": "Use specific versions of the export tool",
166+
"defaultValue": "",
167+
"required": false,
168+
"helpMarkDown": "Set to a release tag, if not set latest will use version of the [AzureDevOps.WikiPDFExport tool](https://github.com/MaxMelcher/AzureDevOps.WikiPDFExport) tool will be used",
160169
"groupName": "advanced"
161170
}
162171
],

Extensions/WikiPDFExport/WikiPDFExportTask/WikiPDFExportTaskV4/test/getExe.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,32 @@ import * as fse from "fs-extra";
66

77
describe("Get Exe Path ", () => {
88
it("should be able download the pre release", async () => {
9-
var actual = await GetExePath("", "./testdata", true, "Windows_NT");
9+
var actual = await GetExePath("", "./testdata", "4.6.0", "Windows_NT");
1010
expect(actual).to.equal(`testdata\\azuredevops-export-wiki.exe`);
1111
}).timeout(20000); // the default is 2000ms and that is too fast or the download
1212

1313
it("should be able download the latest production windows release", async () => {
14-
var actual = await GetExePath("", "./testdata", false, "Windows_NT");
14+
var actual = await GetExePath("", "./testdata", "", "Windows_NT");
1515
expect(actual).to.equal(`testdata\\azuredevops-export-wiki.exe`);
1616
}).timeout(20000); // the default is 2000ms and that is too fast or the download
1717

1818
it("should be able download the latest production Linux release", async () => {
19-
var actual = await GetExePath("", "./testdata", false, "Linux");
19+
var actual = await GetExePath("", "./testdata", "", "Linux");
2020
expect(actual).to.equal(`testdata\\azuredevops-export-wiki`);
2121
}).timeout(20000); // the default is 2000ms and that is too fast or the download
2222

2323
it("should be able download the latest production MacOS release", async () => {
24-
var actual = await GetExePath("", "./testdata", false, "Darwin");
24+
var actual = await GetExePath("", "./testdata", "", "Darwin");
2525
expect(actual).to.equal(`testdata\\azuredevops-export-wiki-osx`);
2626
}).timeout(20000); // the default is 2000ms and that is too fast or the download
2727

28-
it("should be able to override the release download", async () => {
29-
var actual = await GetExePath(".\\testdata\\dummy.exe.txt", "", true, "Windows_NT");
28+
it("should be able to override the latest release download", async () => {
29+
var actual = await GetExePath(".\\testdata\\dummy.exe.txt", "", "", "Windows_NT");
3030
expect(actual).to.equal(`.\\testdata\\dummy.exe.txt`);
3131
});
3232

33-
it("should be able to override the release download", async () => {
34-
var actual = await GetExePath(".\\testdata\\dummy.exe.txt", "", true, "Windows_NT");
33+
it("should be able to override the desired release download", async () => {
34+
var actual = await GetExePath(".\\testdata\\dummy.exe.txt", "", "4.6.0", "Windows_NT");
3535
expect(actual).to.equal(`.\\testdata\\dummy.exe.txt`);
3636
});
3737

Extensions/WikiPDFExport/azure-pipelines-build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ stages:
142142
deploy:
143143
steps:
144144
- template: test-stage.yml
145+
parameters:
146+
dotnetVersion: '6.0.x'
147+
desiredVersion: '4.6.0'
145148
- deployment: Private_Tests_Mac
146149
timeoutInMinutes: 0
147150
environment: 'Azure DevOps Marketplace (WIKIPDFExport)'

Extensions/WikiPDFExport/test-stage.yml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ parameters:
22
- name: localpath
33
type: string
44
default: $(Agent.TempDirectory)
5+
- name: dotnetVersion
6+
type: string
7+
default: '8.0.x'
8+
- name: desiredVersion
9+
type: string
10+
default: ''
511

612
steps:
713
- checkout: VSTSBuildTaskValidation
@@ -13,7 +19,7 @@ steps:
1319
displayName: 'Use .NET Core runtime'
1420
inputs:
1521
packageType: 'runtime'
16-
version: '6.0.x'
22+
version: '${{parameters.dotnetVersion}}'
1723
includePreviewVersions: false
1824
- task: richardfennellBM.BM-VSTS-XplatGenerateReleaseNotes-DEV1.XplatGenerate-Release-Notes.XplatGenerateReleaseNotes@4
1925
displayName: 'Generate Release Notes based on Release Comparision API'
@@ -42,13 +48,16 @@ steps:
4248
{{/forEach}}
4349
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@3
4450
displayName: 'Export Single File'
51+
enabled: false
4552
inputs:
4653
cloneRepo: false
4754
usePreRelease: false
4855
localpath: '$(System.DefaultWorkingDirectory)'
4956
singleFile: 'inline.md'
5057
outputFile: '$(Build.ArtifactStagingDirectory)/PDF/$(Agent.OS)-singleFileV3.pdf'
5158
downloadPath: '${{parameters.localpath}}'
59+
60+
5261
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
5362
displayName: 'Export Single File'
5463
inputs:
@@ -58,6 +67,8 @@ steps:
5867
singleFile: 'inline.md'
5968
outputFile: '$(Build.ArtifactStagingDirectory)/PDF/$(Agent.OS)-singleFile.pdf'
6069
downloadPath: '${{parameters.localpath}}'
70+
desiredVersion: '${{parameters.desiredVersion}}'
71+
6172
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
6273
displayName: 'Export Single File'
6374
inputs:
@@ -67,6 +78,8 @@ steps:
6778
singleFile: 'inline.md'
6879
outputFile: '$(Build.ArtifactStagingDirectory)/PDF/$(Agent.OS)-singleFile.pdf'
6980
downloadPath: '${{parameters.localpath}}'
81+
desiredVersion: '${{parameters.desiredVersion}}'
82+
7083
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
7184
displayName: 'Export Public GitHub WIKI'
7285
condition: succeededOrFailed()
@@ -77,6 +90,8 @@ steps:
7790
localpath: '$(System.DefaultWorkingDirectory)/GitHubRepo'
7891
outputFile: '$(Build.ArtifactStagingDirectory)/PDF/$(Agent.OS)-publicGitHub.pdf'
7992
downloadPath: '${{parameters.localpath}}'
93+
desiredVersion: '${{parameters.desiredVersion}}'
94+
8095
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
8196
displayName: 'Export Azure DevOps WIKI'
8297
condition: succeededOrFailed()
@@ -86,6 +101,8 @@ steps:
86101
useAgentToken: true
87102
outputFile: '$(Build.ArtifactStagingDirectory)/PDF/$(Agent.OS)-Azrepo.pdf'
88103
downloadPath: '${{parameters.localpath}}'
104+
desiredVersion: '${{parameters.desiredVersion}}'
105+
89106
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
90107
displayName: 'Export part of the Azure DevOps WIKI'
91108
condition: succeededOrFailed()
@@ -97,6 +114,8 @@ steps:
97114
localpath: '$(System.DefaultWorkingDirectory)/repopartial'
98115
rootExportPath: '$(System.DefaultWorkingDirectory)/repopartial/folder'
99116
downloadPath: '${{parameters.localpath}}'
117+
desiredVersion: '${{parameters.desiredVersion}}'
118+
100119
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
101120
displayName: 'Export single part of the Azure DevOps WIKI'
102121
condition: succeededOrFailed()
@@ -109,6 +128,8 @@ steps:
109128
rootExportPath: '$(System.DefaultWorkingDirectory)/repopartial1/folder'
110129
downloadPath: '${{parameters.localpath}}'
111130
singlefile: 'test1.md'
131+
desiredVersion: '${{parameters.desiredVersion}}'
132+
112133
- task: richardfennellBM.BM-VSTS-WikiPDFExport-Tasks-DEV.WikiPDFExportTask.WikiPdfExportTask@4
113134
displayName: 'Export Azure DevOps WIKI without downloading tool'
114135
condition: and(succeededOrFailed(), eq(variables['AGENT.OS'], 'Windows_NT'))
@@ -119,6 +140,8 @@ steps:
119140
useAgentToken: true
120141
outputFile: '$(Build.ArtifactStagingDirectory)/PDF/$(Agent.OS)-Azrepo-nodownload.pdf'
121142
downloadPath: '${{parameters.localpath}}'
143+
desiredVersion: '${{parameters.desiredVersion}}'
144+
122145
- task: PublishPipelineArtifact@0
123146
condition: succeededOrFailed()
124147
inputs:

Extensions/XplatGenerateReleaseNotes/XplatGenerateReleaseNotesTask/testconsole/payload.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)