diff --git a/make.ps1 b/make.ps1 index 1752268..17f3f15 100644 --- a/make.ps1 +++ b/make.ps1 @@ -303,7 +303,8 @@ function Build { $json | ConvertTo-Json -Depth 10 | Set-Content .\$vsix } catch { - Write-Host "Error loading the version from Azure DevOps Marketplace" + Write-Host "Error loading the version from Azure DevOps Marketplace, check the [$$env:AZURE_DEVOPS_PAT] setting if it has the right scopes" + return } # build the task @@ -315,6 +316,7 @@ function Build { Set-Location .. # package the whole extension + Write-Host "Packaging the extension" tfx extension create --manifest-globs $vsix --rev-version # get the new version number from the json file diff --git a/vss-extension-dev.json b/vss-extension-dev.json index e2f53cf..665ac4a 100644 --- a/vss-extension-dev.json +++ b/vss-extension-dev.json @@ -1,7 +1,7 @@ { "manifestVersion": 1, "id": "GHAzDoWidget-DEV", - "version": "0.2.415", + "version": "0.2.427", "public": false, "name": "Advanced Security dashboard Widgets [DEV]", "description": "[DEV] GitHub Advanced Security for Azure DevOps dashboard widgets", diff --git a/widgets/build-info/index.html b/widgets/build-info/index.html index d867a70..428a1bd 100644 --- a/widgets/build-info/index.html +++ b/widgets/build-info/index.html @@ -23,7 +23,7 @@ const organization = webContext.account.name; const projectId = project.id; // convert project.name to url encoding - const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26"); + const projectName = handleNames(project.name); // retrieve build id try { // contains: project, collection, account, host, and team info (with their GUID) diff --git a/widgets/library.js b/widgets/library.js index 6af3bfe..206d1ee 100644 --- a/widgets/library.js +++ b/widgets/library.js @@ -89,17 +89,27 @@ function GetAlertTypeFromValue(value) { } } -function fillSelectRepoDropdown(dropDown, repos) { +function fillSelectRepoDropdown(dropDown, repos, showAllRepos = false) { // add a top option to select no repo - dropDown.append(``); - dropDown.append(``); + dropDown.append(``); + if (showAllRepos) { + dropDown.append(``); + } // sort the repo alphabetically repos.sort((a, b) => a.name.localeCompare(b.name)); repos.forEach(r => { - dropDown.append(``); + dropDown.append(``); }); } +function getSelectedRepoIdFromDropdown(dropDown) { + return dropDown.val(); +} + +function getSelectedRepoNameFromDropdown(dropDown) { + return dropDown.find("option:selected").text(); +} + async function getAlerts(organization, projectName, repoId, repos, project, repo) { if (repoId) { // run normally for a single repo @@ -589,6 +599,12 @@ async function showRepoInfo(repos, project, organization, progressDiv, activeCal } } +function handleNames(input) { + // replace spaces with %20 in the input + return input.replace(/ /g, '%20') // space with %20 + .replace(/&/g, "%26") // & with %26 +} + let debugInfo = null function showCallStatus() { if (!debugInfo) { diff --git a/widgets/pr-tab/index.html b/widgets/pr-tab/index.html index 3cd475d..6bc0cb4 100644 --- a/widgets/pr-tab/index.html +++ b/widgets/pr-tab/index.html @@ -21,7 +21,7 @@ const organization = webContext.account.name; const projectId = project.id; // convert project.name to url encoding - const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26"); + const projectName = handleNames(project.name); consoleLog('project id: ' + projectId); consoleLog('project name: ' + projectName); diff --git a/widgets/widgets/chart/chart.html b/widgets/widgets/chart/chart.html index b26badc..c9105b5 100644 --- a/widgets/widgets/chart/chart.html +++ b/widgets/widgets/chart/chart.html @@ -35,7 +35,7 @@ const organization = webContext.account.name const projectId = project.id // convert project.name to url encoding - const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26") + const projectName = handleNames(project.name) consoleLog('project id: ' + projectId) consoleLog('project name: ' + projectName) diff --git a/widgets/widgets/testing_widget/testing.html b/widgets/widgets/testing_widget/testing.html index e3b7c36..77ac65e 100644 --- a/widgets/widgets/testing_widget/testing.html +++ b/widgets/widgets/testing_widget/testing.html @@ -200,7 +200,7 @@ const organization = webContext.account.name; const projectId = project.id; // convert project.name to url encoding - const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26"); + const projectName = handleNames(project.name); consoleLog('project id: ' + projectId); consoleLog('project name: ' + projectName); diff --git a/widgets/widgets/widget_1x1/configuration_1x1.html b/widgets/widgets/widget_1x1/configuration_1x1.html index d189cba..02e1fa4 100644 --- a/widgets/widgets/widget_1x1/configuration_1x1.html +++ b/widgets/widgets/widget_1x1/configuration_1x1.html @@ -17,22 +17,13 @@ var $repoDropdown = $("#repo-dropdown"); var $repoAlertType = $("#repo-alert-type"); var $colorPicker = $("#color-picker"); - const repos = await getRepos(VSS, Service, GitWebApi); - const projects = await getProjects(VSS, Service, RestClient); - - consoleLog(`Found [${repos?.length}] repos and [${projects?.length}] projects`); async function reloadWidget(widgetConfigurationContext) { - let repo; - if (repos) { - // find the repo with this name - repo = repos.find(r => r.name === $repoDropdown.val()); - } var customSettings = { data: JSON.stringify({ - repo: $repoDropdown.val(), - repoId: repo?.id, + repo: getSelectedRepoNameFromDropdown($repoDropdown), + repoId: getSelectedRepoIdFromDropdown($repoDropdown), repoAlertType: $repoAlertType.val(), color: $colorPicker.val() }) @@ -47,6 +38,7 @@ var settings = logWidgetSettings(widgetSettings, VSS, "1x1"); // add all repos as selection options to the dropdown + const repos = await getRepos(VSS, Service, GitWebApi); if (repos) { // todo: use in all other widget locations as well fillSelectRepoDropdown($repoDropdown, repos) @@ -54,7 +46,7 @@ if (settings && settings.repo) { // select the repo that was saved in the settings - $repoDropdown.val(settings.repo); + $repoDropdown.val(settings.repoId); } if (settings && settings.repoAlertType) { @@ -83,15 +75,17 @@ return WidgetHelpers.WidgetStatusHelper.Success(); }, onSave: async function() { - let repo; - if (repos) { - // find the repo with this name - repo = repos.find(r => r.name === $repoDropdown.val()); + let repoId = getSelectedRepoIdFromDropdown($repoDropdown); + if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos + // do not save + console.log(`Not saving the settings because repoId is [${repoId}]`); + return WidgetHelpers.WidgetConfigurationSave.Invalid(); } + var customSettings = { data: JSON.stringify({ - repo: $repoDropdown.val(), - repoId: repo?.id, + repo: getSelectedRepoNameFromDropdown($repoDropdown), + repoId: repoId, repoAlertType: $repoAlertType.val(), color: $colorPicker.val() }) diff --git a/widgets/widgets/widget_1x1/widget_1x1.html b/widgets/widgets/widget_1x1/widget_1x1.html index b6794d4..0d54137 100644 --- a/widgets/widgets/widget_1x1/widget_1x1.html +++ b/widgets/widgets/widget_1x1/widget_1x1.html @@ -23,7 +23,7 @@ const organization = webContext.account.name; const projectId = project.id; // convert project.name to url encoding - const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26"); + const projectName = handleNames(project.name); consoleLog('project id: ' + projectId); consoleLog('project name: ' + projectName); diff --git a/widgets/widgets/widget_1x1/widget_1x1.js b/widgets/widgets/widget_1x1/widget_1x1.js index 79449e8..3ae80d6 100644 --- a/widgets/widgets/widget_1x1/widget_1x1.js +++ b/widgets/widgets/widget_1x1/widget_1x1.js @@ -43,14 +43,9 @@ async function loadWidget(widgetSettings, organization, projectName, VSS, Servic } consoleLog('alerts: ' + JSON.stringify(alerts)); - // remove %20 from the name so that it displays correctly - repoName = repoName.replace(/%20/g, ' '); //todo: support more of these weird characters - // set the title var title = $('h2.ghazdo-title'); title.text(`${repoName}`); - title.attr('title', repoName); - consoleLog(`title set to [${repoName}]`); // set the color const color = data.color ? data.color : '#68217a'; // default to purple @@ -58,6 +53,7 @@ async function loadWidget(widgetSettings, organization, projectName, VSS, Servic widget.style.backgroundColor = `${color}`; // GHAS is only available on the SaaS version, so we can hardcode the domain + repoName = handleNames(repoName); // handle spaces and other characters in the repo name linkBase = `https://dev.azure.com/${organization}/${projectName}/_git/${repoName}/alerts`; } else { diff --git a/widgets/widgets/widget_2x1/configuration_2x1.html b/widgets/widgets/widget_2x1/configuration_2x1.html index 7a567f7..38a93bd 100644 --- a/widgets/widgets/widget_2x1/configuration_2x1.html +++ b/widgets/widgets/widget_2x1/configuration_2x1.html @@ -14,21 +14,21 @@ VSS.require(["VSS/Service", "TFS/Dashboards/WidgetHelpers", "VSS/Context", "TFS/VersionControl/GitRestClient"], function (Service, WidgetHelpers, context, GitWebApi) { VSS.register("GHAzDoWidget.Configuration", async function () { - var $repoDropdown = $("#repo-dropdown") - var $colorPicker = $("#color-picker") - // get a repos in this project - const repos = await getRepos(VSS, Service, GitWebApi); + var $repoDropdown = $("#repo-dropdown"); + var $colorPicker = $("#color-picker"); async function reloadWidget(widgetConfigurationContext) { - let repo; - if (repos) { - // find the repo with this name - repo = repos.find(r => r.name === $repoDropdown.val()); + let repoId = getSelectedRepoIdFromDropdown($repoDropdown); + if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos + // do not reload with errors + console.log(`Not reloading the settings because repoId is [${repoId}]`); + return; } + var customSettings = { data: JSON.stringify({ - repo: $repoDropdown.val(), - repoId: repo.id, + repo: getSelectedRepoNameFromDropdown($repoDropdown), + repoId: getSelectedRepoIdFromDropdown($repoDropdown), color: $colorPicker.val() }) }; @@ -42,26 +42,22 @@ var settings = logWidgetSettings(widgetSettings, VSS, "2x1"); // add all repos as selection options to the dropdown + const repos = await getRepos(VSS, Service, GitWebApi); if (repos) { - // add a top option to select no repo - $repoDropdown.append(``); - // sort the repo alphabetically - repos.sort((a, b) => a.name.localeCompare(b.name)); - repos.forEach(r => { - $repoDropdown.append(``); - }); + fillSelectRepoDropdown($repoDropdown, repos, false); } - if (settings && settings.repo) { + if (settings && settings.repoId) { // select the repo that was saved in the settings - $repoDropdown.val(settings.repo); - } + $repoDropdown.val(settings.repoId); + } if (settings && settings.color) { // select the color that was saved in the settings $colorPicker.val(settings.color); } + // configure events for the dropdowns to call back to the widget $colorPicker.on("change", async function () { await reloadWidget(widgetConfigurationContext); }); @@ -73,16 +69,17 @@ return WidgetHelpers.WidgetStatusHelper.Success(); }, onSave: async function() { - const repos = await getRepos(VSS, Service, GitWebApi); - let repo; - if (repos) { - // find the repo with this name - repo = repos.find(r => r.name === $repoDropdown.val()); + let repoId = getSelectedRepoIdFromDropdown($repoDropdown); + if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos + // do not save + console.log(`Not saving the settings because repoId is [${repoId}]`); + return WidgetHelpers.WidgetConfigurationSave.Invalid(); } + var customSettings = { data: JSON.stringify({ - repo: $repoDropdown.val(), - repoId: repo.id, + repo: getSelectedRepoNameFromDropdown($repoDropdown), + repoId: repoId, color: $colorPicker.val() }) }; diff --git a/widgets/widgets/widget_2x1/widget_2x1.html b/widgets/widgets/widget_2x1/widget_2x1.html index e1f81f8..3750072 100644 --- a/widgets/widgets/widget_2x1/widget_2x1.html +++ b/widgets/widgets/widget_2x1/widget_2x1.html @@ -23,7 +23,7 @@ const organization = webContext.account.name const projectId = project.id // convert project.name to url encoding - const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26") + const projectName = handleNames(project.name) consoleLog('project id: ' + projectId) consoleLog('project name: ' + projectName) @@ -31,6 +31,7 @@ return { load: async function (widgetSettings) { + consoleLog('load with widgetSettings: ' + JSON.stringify(widgetSettings)) await loadWidget(widgetSettings, organization, projectName) return WidgetHelpers.WidgetStatusHelper.Success()