From 926148321e78687bcf9aa969a0aa965a8a5b2575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Tron=C3=AD=C4=8Dek?= Date: Sun, 23 Apr 2023 17:24:54 +0000 Subject: [PATCH] Helpers --- extensions-schema.json | 4 +++ extensions.json | 1 + helpers/jupyter.js | 75 +++++++++++++++++++++++++++++++++++++++++ lib/resolveExtension.js | 10 +++++- types.d.ts | 3 +- 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 helpers/jupyter.js diff --git a/extensions-schema.json b/extensions-schema.json index 3694b0640..bcdb59155 100644 --- a/extensions-schema.json +++ b/extensions-schema.json @@ -36,6 +36,10 @@ "type": "string", "description": "A property to set a different lookup ID when querying the Microsoft Marketplace. Please do not ever use if not absolutely necessary." }, + "helper": { + "type": "string", + "description": "A helper script to use for building the extension. If not specified, the default resolver will be used. The script must be located in the `helpers` directory of the `open-vsx/publish-extensions` repository." + }, "target": { "type": "array", "description": "A list of platforms to target. If unspecified, a universal extension will be published in case of building from source and if the vsix is resolved from GitHub Releases, all of the attached platform-specific assets will be published.", diff --git a/extensions.json b/extensions.json index 890cca7d5..56e1d9933 100644 --- a/extensions.json +++ b/extensions.json @@ -814,6 +814,7 @@ "custom": [ "source ~/.nvm/nvm.sh && nvm use && nvm install-latest-npm && npm ci --foreground-scripts --prefer-offline && npm run postinstall && python3 -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade -r requirements.txt --no-user && npm run clean && npm run package" ], + "helper": "jupyter", "extensionFile": "ms-toolsai-jupyter-insiders.vsix", "timeout": 30 }, diff --git a/helpers/jupyter.js b/helpers/jupyter.js new file mode 100644 index 000000000..5cc309d3f --- /dev/null +++ b/helpers/jupyter.js @@ -0,0 +1,75 @@ +const Octokit = require('octokit').Octokit; +const path = require('path'); +const fs = require('fs'); + +const readVSIXPackage = require('@vscode/vsce/out/zip').readVSIXPackage; +const download = require('download'); +const exec = require('../lib/exec'); + +const token = process.env.GITHUB_TOKEN; +if (!token) { + throw new Error("GITHUB_TOKEN env var is not set. Cannot lookup from actions"); +} + +const octokit = new Octokit({ auth: token }); + +const repoInfo = { + owner: 'microsoft', + repo: 'vscode-jupyter', +} + +const paths = { + package: 'ms-toolsai-jupyter-insiders.vsix', + folder: "/tmp/download/jupyter" +} + +const resolveVersion = async (version, lastUpdated) => { + const actionRuns = await octokit.rest.actions.listWorkflowRuns( + { + ...repoInfo, + per_page: 100, + workflow_id: 'build-test.yml', + exclude_pull_requests: true, + status: 'success', + } + ); + + const actionRunsForTag = actionRuns.data.workflow_runs.filter(run => new Date(run.run_started_at) < lastUpdated.getTime()); + + console.info(`Found ${actionRunsForTag.length} matching runs for ${version}`) + + // try to find the correct run + for (const run of actionRunsForTag) { + const runArtifacts = await octokit.rest.actions.listWorkflowRunArtifacts({ ...repoInfo, run_id: run.id }); + const runArtifactsForVersion = runArtifacts.data.artifacts.filter(artifact => artifact.name === paths.package); + if (runArtifactsForVersion.length === 1) { + const artifact = runArtifactsForVersion[0]; + const artifactDownload = await octokit.rest.actions.downloadArtifact({ ...repoInfo, artifact_id: artifact.id, archive_format: 'zip' }); + const artifactDownloadUrl = artifactDownload.url; + const file = `/tmp/download/jupyter.zip`; + await download(artifactDownloadUrl, path.dirname(file), { filename: path.basename(file) }); + fs.rmSync(paths.folder, { recursive: true, force: true }); + await exec(`unzip ${file} -d ${paths.folder}`, {quiet: true}); + + const extractedFile = `${paths.folder}/${paths.package}`; + const { manifest, xmlManifest } = (await readVSIXPackage(extractedFile)); + const resolvedVersion = xmlManifest.PackageManifest.Metadata[0].Identity[0].$.Version || manifest.version; + + if (resolvedVersion === version) { + console.log(`Found the correct version: ${resolvedVersion}`); + break; + } else if (version.startsWith(resolvedVersion)) { + console.log(`Found a similar-enough version: ${resolvedVersion}`); + return { version: version, files: {universal: extractedFile}, path: '', resolution: { releaseAsset: 'resolved' } }; + } else { + console.log(`Found non-matching version ${resolvedVersion}`); + } + } + } + + return undefined; +} + +module.exports = { + resolveVersion +}; \ No newline at end of file diff --git a/lib/resolveExtension.js b/lib/resolveExtension.js index eddc6ec61..2a72a6087 100644 --- a/lib/resolveExtension.js +++ b/lib/resolveExtension.js @@ -20,13 +20,21 @@ const octokit = new Octokit({ auth: token }); * @param {{version: string, lastUpdated: Date} | undefined} [ms] * @returns {Promise} */ -exports.resolveExtension = async function ({ id, repository, location }, ms) { +exports.resolveExtension = async function ({ id, repository, location, helper }, ms) { if (!repository) throw TypeError("repository URL not supplied"); const repositoryUrl = new URL(repository); const [owner, repo] = repositoryUrl.pathname.slice(1).split("/"); + if (helper) { + const resolveJupyter = require("../helpers/"+helper).resolveVersion; + const extraLookup = await resolveJupyter(ms.version, ms?.lastUpdated); + if (extraLookup) { + return extraLookup; + } + } + //#region check latest release assets /** @type {string | undefined} */ let releaseTag; diff --git a/types.d.ts b/types.d.ts index e9daa8a8b..1bf69c648 100644 --- a/types.d.ts +++ b/types.d.ts @@ -89,7 +89,8 @@ export interface Extension { custom?: string[] timeout?: number target?: string[] - msMarketplaceIdOverride?: string + msMarketplaceIdOverride?: string, + helper?: string, } export interface ExtensionResolution {