From 8d318411fcbd4497c52bb931ac5937612dfad9f7 Mon Sep 17 00:00:00 2001 From: Jordan Kurtz Date: Mon, 8 Dec 2025 13:46:24 -0600 Subject: [PATCH 1/5] Add task for authenticating with Gradle repositories --- Tasks/GradleAuthenticateV0/.npmrc | 5 + .../resources.resjson/en-US/resources.resjson | 23 + Tasks/GradleAuthenticateV0/Tests/L0.ts | 158 +++ .../Tests/L0AuthGradleProperties.ts | 36 + .../Tests/L0AuthGradlePropertiesExists.ts | 36 + .../Tests/L0EmptyInput.ts | 25 + .../Tests/L0ServiceConnections.ts | 56 ++ .../gradlePropertiesFeedName1.properties | 3 + .../gradlePropertiesOtherFeedName.properties | 3 + .../_buildConfigs/Wif/package.json | 31 + Tasks/GradleAuthenticateV0/cleanup.ts | 25 + Tasks/GradleAuthenticateV0/gradleauth.ts | 120 +++ Tasks/GradleAuthenticateV0/gradleutils.ts | 164 +++ Tasks/GradleAuthenticateV0/make.json | 10 + Tasks/GradleAuthenticateV0/package-lock.json | 948 ++++++++++++++++++ Tasks/GradleAuthenticateV0/package.json | 33 + Tasks/GradleAuthenticateV0/task.json | 94 ++ Tasks/GradleAuthenticateV0/task.loc.json | 94 ++ .../taskJsonOverride.json | 36 + .../taskJsonOverride.loc.json | 36 + Tasks/GradleAuthenticateV0/tsconfig.json | 6 + make-options.json | 2 + 22 files changed, 1944 insertions(+) create mode 100644 Tasks/GradleAuthenticateV0/.npmrc create mode 100644 Tasks/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson create mode 100644 Tasks/GradleAuthenticateV0/Tests/L0.ts create mode 100644 Tasks/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts create mode 100644 Tasks/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts create mode 100644 Tasks/GradleAuthenticateV0/Tests/L0EmptyInput.ts create mode 100644 Tasks/GradleAuthenticateV0/Tests/L0ServiceConnections.ts create mode 100644 Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties create mode 100644 Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties create mode 100644 Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package.json create mode 100644 Tasks/GradleAuthenticateV0/cleanup.ts create mode 100644 Tasks/GradleAuthenticateV0/gradleauth.ts create mode 100644 Tasks/GradleAuthenticateV0/gradleutils.ts create mode 100644 Tasks/GradleAuthenticateV0/make.json create mode 100644 Tasks/GradleAuthenticateV0/package-lock.json create mode 100644 Tasks/GradleAuthenticateV0/package.json create mode 100644 Tasks/GradleAuthenticateV0/task.json create mode 100644 Tasks/GradleAuthenticateV0/task.loc.json create mode 100644 Tasks/GradleAuthenticateV0/taskJsonOverride.json create mode 100644 Tasks/GradleAuthenticateV0/taskJsonOverride.loc.json create mode 100644 Tasks/GradleAuthenticateV0/tsconfig.json diff --git a/Tasks/GradleAuthenticateV0/.npmrc b/Tasks/GradleAuthenticateV0/.npmrc new file mode 100644 index 000000000000..76446dc42b54 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/.npmrc @@ -0,0 +1,5 @@ +scripts-prepend-node-path=true + +registry=https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ + +always-auth=true diff --git a/Tasks/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson b/Tasks/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..37cf72d36a3c --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,23 @@ +{ + "loc.friendlyName": "Gradle Authenticate", + "loc.helpMarkDown": "[Learn more about this task](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate)", + "loc.description": "Provides credentials for Azure Artifacts feeds and external Gradle/Maven repositories", + "loc.instanceNameFormat": "Gradle Authenticate", + "loc.input.label.artifactsFeeds": "Feeds", + "loc.input.label.gradleServiceConnections": "Credentials for repositories outside this organization/collection", + "loc.input.help.gradleServiceConnections": "Credentials to use for external repositories located in the project's build.gradle.", + "loc.messages.Warning_FeedEntryAlreadyExists": "The settings for the feed or repository '%s' already exists in the gradle.properties file.", + "loc.messages.Warning_NoEndpointsToAuth": "No repositories were selected to authenticate, please check your task configuration.", + "loc.messages.Warning_TokenNotGenerated": "Unable to use a federated token", + "loc.messages.Info_GeneratingExternalRepositories": "Generating configs for %s external repositories.", + "loc.messages.Info_GeneratingInternalFeeds": "Generating configs for %s internal feeds.", + "loc.messages.Info_GradleUserHomeFolderDoesntExist": ".gradle folder not found at location %s, creating new folder.", + "loc.messages.Info_GradlePropertiesRead": "Adding authentication to gradle.properties file %s.", + "loc.messages.Info_CreatingGradleProperties": "Creating new gradle.properties at path %s.", + "loc.messages.Info_WritingToGradleProperties": "Writing new gradle.properties with added authentication.", + "loc.messages.Info_AddingFederatedFeedAuth": "Adding auth information from federated service connection %s for feed %s", + "loc.messages.Info_SuccessAddingFederatedFeedAuth": "Successfully added auth for feed %s with federated credentials.", + "loc.messages.Error_InvalidServiceConnection": "The service connection for %s is invalid.", + "loc.messages.Error_FailedCleanupGradle": "Failed to delete credentials from the gradle.properties file: %s", + "loc.messages.Error_FailedToGetServiceConnectionAuth": "Unable to get federated credentials from service connection: %s." +} \ No newline at end of file diff --git a/Tasks/GradleAuthenticateV0/Tests/L0.ts b/Tasks/GradleAuthenticateV0/Tests/L0.ts new file mode 100644 index 000000000000..b56658ce6cdf --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/L0.ts @@ -0,0 +1,158 @@ +import fs = require("fs"); +import assert = require("assert"); +import path = require("path"); +import * as tl from "azure-pipelines-task-lib/task"; +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); +const gradlePropertiesOtherFeedName = path.join(__dirname, "Samples", "gradlePropertiesOtherFeedName.properties"); +const gradlePropertiesFeedName1 = path.join(__dirname, "Samples", "gradlePropertiesFeedName1.properties"); + +const usernameRegex = /Username=/mig; +const passwordRegex = /Password=/mig; + +describe("authenticate azure artifacts feeds for gradle", function() { + this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000); + var env; + + this.beforeAll(async () => { + env = Object.assign({}, process.env); + process.env["USERPROFILE"] = testUserHomeDir; + process.env["HOME"] = testUserHomeDir; + }); + + beforeEach(async () => { + tl.mkdirP(gradleDirPath); + }) + + this.afterAll(async () => { + process.env = env; + }) + + afterEach(async () => { + tl.rmRF(gradleDirPath); + }); + + it("it should create a new gradle.properties in the .gradle folder and add auth for 1 feed.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradleProperties.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be created."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 1, "Only one username entry should be created."); + assert.equal(data.match(passwordRegex).length, 1, "Only one password entry should be created."); + assert(data.includes("feedName1Username="), "feedName1Username entry should be present."); + assert(data.includes("feedName1Password="), "feedName1Password entry should be present."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should read the existing gradle.properties and add auth for 1 new feed", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradlePropertiesExists.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + tl.cp(gradlePropertiesOtherFeedName, gradlePropertiesPath); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be present."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 2, "2 username entries should be present."); + assert.equal(data.match(passwordRegex).length, 2, "2 password entries should be present."); + assert(data.includes("feedName1Username="), "feedName1Username entry should be present."); + assert(data.includes("otherFeedNameUsername="), "otherFeedNameUsername entry should not be deleted."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should read the existing gradle.properties and not add any new entries.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradlePropertiesExists.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + tl.cp(gradlePropertiesFeedName1, gradlePropertiesPath); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be present."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 1, "Only one username entry should be present."); + assert.equal(data.match(passwordRegex).length, 1, "Only one password entry should be present."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.stdOutContained("vso[task.issue type=warning;source=TaskInternal;]loc_mock_Warning_FeedEntryAlreadyExists"), "Entry already exists warning should be displayed"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should create a new gradle.properties in the .gradle folder and add auth for 2 different types of service connections.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0ServiceConnections.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be created."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 2, "2 username entries should be created."); + assert.equal(data.match(passwordRegex).length, 2, "2 password entries should be created."); + + assert(data.includes("tokenBasedUsername=AzureDevOps"), "tokenBased username should be AzureDevOps."); + assert(data.includes("tokenBasedPassword=--token--"), "tokenBased password should be the token."); + + assert(data.includes("usernamePasswordBasedUsername=--testUserName--"), "usernamePasswordBased username should be set."); + assert(data.includes("usernamePasswordBasedPassword=--testPassword--"), "usernamePasswordBased password should be set."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should warn if no inputs are provided.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0EmptyInput.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 0, "gradle.properties file should not be created."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + assert(tr.stdOutContained("vso[task.issue type=warning;source=TaskInternal;]loc_mock_Warning_NoEndpointsToAuth"), "The no endpoints warning should be displayed"); + }); +}); diff --git a/Tasks/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts b/Tasks/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts new file mode 100644 index 000000000000..d54552049149 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts @@ -0,0 +1,36 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", "feedName1"); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: false, + [gradlePropertiesPath]: false + } +}); + +tr.run(); diff --git a/Tasks/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts b/Tasks/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts new file mode 100644 index 000000000000..9af008259a49 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts @@ -0,0 +1,36 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", "feedName1"); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: true, + [gradlePropertiesPath]: true + } +}); + +tr.run(); diff --git a/Tasks/GradleAuthenticateV0/Tests/L0EmptyInput.ts b/Tasks/GradleAuthenticateV0/Tests/L0EmptyInput.ts new file mode 100644 index 000000000000..07118ca600ec --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/L0EmptyInput.ts @@ -0,0 +1,25 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +// Set inputs +tr.setInput("artifactsFeeds", ""); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +tr.setAnswers({ + osType: { + "osType": "Windows NT" + } +}); + +tr.run(); diff --git a/Tasks/GradleAuthenticateV0/Tests/L0ServiceConnections.ts b/Tasks/GradleAuthenticateV0/Tests/L0ServiceConnections.ts new file mode 100644 index 000000000000..b245ad099e91 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/L0ServiceConnections.ts @@ -0,0 +1,56 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", ""); +tr.setInput("gradleServiceConnections", "tokenBased,usernamePasswordBased"); +tr.setInput("verbosity", "verbose"); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +process.env["ENDPOINT_URL_tokenBased"] = "https://endpoint"; +process.env["ENDPOINT_DATA_tokenBased_REPOSITORYID"] = "tokenBased"; +process.env["ENDPOINT_AUTH_SCHEME_tokenBased"] = "token"; +process.env["ENDPOINT_AUTH_tokenBased"] = JSON.stringify({ + "parameters": { + "apitoken": "--token--" + } +}); + +process.env["ENDPOINT_URL_usernamePasswordBased"] = "https://endpoint"; +process.env["ENDPOINT_DATA_usernamePasswordBased_REPOSITORYID"] = "usernamePasswordBased"; +process.env["ENDPOINT_AUTH_SCHEME_usernamePasswordBased"] = "usernamepassword"; +process.env["ENDPOINT_AUTH_usernamePasswordBased"] = JSON.stringify({ + "parameters": { + "username": "--testUserName--", + "password": "--testPassword--" + } +}); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: false, + [gradlePropertiesPath]: false + } +}); + + +tr.run(); diff --git a/Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties b/Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties new file mode 100644 index 000000000000..1649ae03a207 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties @@ -0,0 +1,3 @@ +# Azure Artifacts credentials for feedName1 +feedName1Username=AzureDevOps +feedName1Password=existingToken diff --git a/Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties b/Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties new file mode 100644 index 000000000000..e079032c0599 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties @@ -0,0 +1,3 @@ +# Azure Artifacts credentials for otherFeedName +otherFeedNameUsername=AzureDevOps +otherFeedNamePassword=existingToken diff --git a/Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package.json b/Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package.json new file mode 100644 index 000000000000..6b328bd07aa3 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package.json @@ -0,0 +1,31 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "description": "Azure Pipelines Gradle Authenticate Task", + "main": "gradleauth.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "ISC", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^20.3.1", + "@types/mocha": "^5.2.7", + "@types/uuid": "^8.3.0", + "@types/q": "^1.5.2", + "azure-pipelines-tasks-artifacts-common": "^2.243.1", + "azure-pipelines-task-lib": "^4.15.0", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } +} diff --git a/Tasks/GradleAuthenticateV0/cleanup.ts b/Tasks/GradleAuthenticateV0/cleanup.ts new file mode 100644 index 000000000000..93052513b45b --- /dev/null +++ b/Tasks/GradleAuthenticateV0/cleanup.ts @@ -0,0 +1,25 @@ +import * as path from 'path'; +import * as tl from 'azure-pipelines-task-lib/task'; + +async function run() { + try { + tl.setResourcePath(path.join(__dirname, 'task.json')); + + const userGradlePropertiesPath: string = tl.getTaskVariable('userGradlePropertiesPath'); + const backupUserGradlePropertiesFilePath: string = tl.getTaskVariable('backupUserGradlePropertiesFilePath'); + + if (userGradlePropertiesPath && tl.exist(userGradlePropertiesPath)) { + tl.rmRF(userGradlePropertiesPath); + tl.debug('Deleted user gradle.properties file: ' + userGradlePropertiesPath); + + if (backupUserGradlePropertiesFilePath && tl.exist(backupUserGradlePropertiesFilePath)) { + tl.mv(backupUserGradlePropertiesFilePath, userGradlePropertiesPath); + tl.debug('Restored old user gradle.properties file: ' + backupUserGradlePropertiesFilePath); + } + } + } catch (err) { + tl.warning(tl.loc('Error_FailedCleanupGradle', err)); + } +} + +run(); diff --git a/Tasks/GradleAuthenticateV0/gradleauth.ts b/Tasks/GradleAuthenticateV0/gradleauth.ts new file mode 100644 index 000000000000..a5ff6fb15f9e --- /dev/null +++ b/Tasks/GradleAuthenticateV0/gradleauth.ts @@ -0,0 +1,120 @@ +import tl = require('azure-pipelines-task-lib/task'); +import util = require('./gradleutils'); + +import * as path from 'path'; +import { emitTelemetry } from 'azure-pipelines-tasks-artifacts-common/telemetry'; + +#if WIF +import { getFederatedWorkloadIdentityCredentials, getFeedTenantId } from "azure-pipelines-tasks-artifacts-common/EntraWifUserServiceConnectionUtils"; +#endif + +const GradleFolderName: string = ".gradle"; +const GradlePropertiesName: string = "gradle.properties"; +const backupGradlePropertiesName: string = "_gradle.properties"; + +tl.setResourcePath(path.join(__dirname, 'task.json')); + +async function run(): Promise { + let internalFeedCredentials: any[] = []; + let externalServiceEndpointsCredentials: any[] = []; + let federatedFeedAuthSuccessCount: number = 0; + try { + let userGradleFolderPath: string = ""; + + if (tl.osType().match(/^Win/)) { + userGradleFolderPath = path.join(process.env.USERPROFILE, GradleFolderName); + } else { + userGradleFolderPath = path.join(process.env.HOME, GradleFolderName); + } + + if (!tl.exist(userGradleFolderPath)) { + tl.debug(tl.loc("Info_GradleUserHomeFolderDoesntExist", userGradleFolderPath)); + tl.mkdirP(userGradleFolderPath); + } + + let userGradlePropertiesPath: string = path.join(userGradleFolderPath, GradlePropertiesName); + let backupGradlePropertiesPath: string = path.join(userGradleFolderPath, backupGradlePropertiesName); + let propertiesContent: string = ""; + + tl.setTaskVariable('userGradlePropertiesPath', userGradlePropertiesPath); + + if (tl.exist(userGradlePropertiesPath)) { + tl.debug(tl.loc("Info_GradlePropertiesRead", userGradlePropertiesPath)); + if (!tl.getVariable('FIRST_RUN_GRADLE_PROPERTIES_EXISTS_PATH') && !tl.exist(backupGradlePropertiesPath)) { + tl.cp(userGradlePropertiesPath, backupGradlePropertiesPath); + tl.setTaskVariable("backupUserGradlePropertiesFilePath", backupGradlePropertiesPath); + } + propertiesContent = util.readGradlePropertiesFile(userGradlePropertiesPath); + } + else { + tl.debug(tl.loc("Info_CreatingGradleProperties", userGradlePropertiesPath)); + tl.setVariable('FIRST_RUN_GRADLE_PROPERTIES_EXISTS_PATH', userGradlePropertiesPath); + } + +#if WIF + const entraWifServiceConnectionName = tl.getInput("workloadIdentityServiceConnection"); + const feedIdNames = tl.getDelimitedInput("artifactsFeeds", ','); + + if (entraWifServiceConnectionName) { + + if (feedIdNames.length === 0) { + tl.warning(tl.loc("Warning_NoEndpointsToAuth")); + } + + tl.debug(tl.loc("Info_AddingFederatedFeedAuth", entraWifServiceConnectionName)); + let token = await getFederatedWorkloadIdentityCredentials(entraWifServiceConnectionName); + + if (token) { + + for (let feedName of feedIdNames) { + const credential = { + id: feedName, + username: entraWifServiceConnectionName, + password: token + }; + + propertiesContent = util.addCredentialToGradleProperties(propertiesContent, credential); + federatedFeedAuthSuccessCount++; + console.log(tl.loc("Info_SuccessAddingFederatedFeedAuth", feedName)); + } + + tl.debug(tl.loc("Info_WritingToGradleProperties")); + util.writeGradlePropertiesFile(userGradlePropertiesPath, propertiesContent); + + } + else { + tl.warning(tl.loc("Warning_TokenNotGenerated")); + } + return; + } +#endif + + internalFeedCredentials = util.getInternalFeedsCredentials("artifactsFeeds"); + externalServiceEndpointsCredentials = util.getExternalServiceEndpointsCredentials("gradleServiceConnections"); + const newCredentials = internalFeedCredentials.concat(externalServiceEndpointsCredentials); + + if(newCredentials.length === 0) { + tl.warning(tl.loc("Warning_NoEndpointsToAuth")); + return; + } + + for (let credential of newCredentials) { + propertiesContent = util.addCredentialToGradleProperties(propertiesContent, credential); + }; + + tl.debug(tl.loc("Info_WritingToGradleProperties")); + util.writeGradlePropertiesFile(userGradlePropertiesPath, propertiesContent); + } + catch (err) { + tl.setResult(tl.TaskResult.Failed, err.message); + } + finally { + emitTelemetry("Packaging", "GradleAuthenticate", { + "InternalFeedAuthCount": internalFeedCredentials.length, + "ExternalRepoAuthCount": externalServiceEndpointsCredentials.length, + "FederatedFeedAuthCount": federatedFeedAuthSuccessCount + }); + } +} + +run(); diff --git a/Tasks/GradleAuthenticateV0/gradleutils.ts b/Tasks/GradleAuthenticateV0/gradleutils.ts new file mode 100644 index 000000000000..6cc4bd9ed891 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/gradleutils.ts @@ -0,0 +1,164 @@ +import fs = require('fs'); +import tl = require('azure-pipelines-task-lib/task'); +import path = require('path'); +import { getSystemAccessToken } from 'azure-pipelines-tasks-artifacts-common/webapi' + +import * as os from 'os'; +import * as fse from 'fs-extra'; + +import { getPackagingServiceConnections, ServiceConnectionAuthType, UsernamePasswordServiceConnection, TokenServiceConnection, PrivateKeyServiceConnection } from "azure-pipelines-tasks-artifacts-common/serviceConnectionUtils"; + +export interface GradleCredential { + id: string; + username: string; + password: string; +} + +/** + * Sanitizes a feed/repository name to be used as a Gradle property key + * Gradle properties use alphanumeric, dots, and underscores + */ +export function sanitizePropertyKey(name: string): string { + return name.replace(/[^a-zA-Z0-9._-]/g, '_'); +} + +export function getInternalFeedsCredentials(input: string): GradleCredential[] { + const feeds: string[] = tl.getDelimitedInput(input, ",", false); + var credentials: GradleCredential[] = []; + + if (!feeds || feeds.length === 0) + { + return credentials; + } + + tl.debug(tl.loc('Info_GeneratingInternalFeeds', feeds.length)); + for (let feed of feeds) { + credentials.push({ + id: feed, + username: "AzureDevOps", + password: getSystemAccessToken() + }); + } + + return credentials; +} + +export function getExternalServiceEndpointsCredentials(input: string): GradleCredential[] { + var serviceConnections = getPackagingServiceConnections(input, ["REPOSITORYID"]); + var credentials: GradleCredential[] = []; + if (!serviceConnections || serviceConnections.length === 0) + { + return credentials; + } + + tl.debug(tl.loc("Info_GeneratingExternalRepositories", serviceConnections.length)); + for(let serviceConnection of serviceConnections) { + switch (serviceConnection.authType) { + case (ServiceConnectionAuthType.UsernamePassword): + const usernamePasswordAuthInfo = serviceConnection as UsernamePasswordServiceConnection; + + credentials.push({ + id: serviceConnection.additionalData["REPOSITORYID"], + username: usernamePasswordAuthInfo.username, + password: usernamePasswordAuthInfo.password, + }); + + tl.debug(`Detected username/password credentials for '${serviceConnection.packageSource.uri}'`); + break; + case (ServiceConnectionAuthType.Token): + const tokenAuthInfo = serviceConnection as TokenServiceConnection; + credentials.push({ + id: serviceConnection.additionalData["REPOSITORYID"], + username: "AzureDevOps", + password: tokenAuthInfo.token + }); + tl.debug(`Detected token credentials for '${serviceConnection.packageSource.uri}'`); + break; + case (ServiceConnectionAuthType.PrivateKey): + // Gradle doesn't natively support private key auth like Maven, use as password + const privateKeyAuthInfo = serviceConnection as PrivateKeyServiceConnection; + tl.warning(`Private key authentication is not supported for Gradle. Skipping '${serviceConnection.packageSource.uri}'`); + break; + default: + throw Error(tl.loc('Error_InvalidServiceConnection', serviceConnection.packageSource.uri)); + } + } + + return credentials; +} + +export function readGradlePropertiesFile(filePath: string): string { + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath, 'utf-8'); + } + return ""; +} + +export function writeGradlePropertiesFile(filePath: string, content: string): void { + fse.mkdirpSync(path.dirname(filePath)); + fs.writeFileSync(filePath, content, { encoding: 'utf-8' }); +} + +/** + * Checks if a credential already exists in the gradle.properties content + */ +export function credentialExists(propertiesContent: string, id: string): boolean { + const sanitizedId = sanitizePropertyKey(id); + const usernameKey = `${sanitizedId}Username`; + const passwordKey = `${sanitizedId}Password`; + + // Check if either username or password property already exists + const lines = propertiesContent.split(/\r?\n/); + for (const line of lines) { + const trimmedLine = line.trim(); + if (trimmedLine.startsWith(usernameKey + '=') || trimmedLine.startsWith(passwordKey + '=')) { + return true; + } + } + return false; +} + +/** + * Adds a credential entry to gradle.properties content + * Gradle credentials are stored as properties that can be referenced in build.gradle: + * + * feedNameUsername=AzureDevOps + * feedNamePassword=token_value + * + * In build.gradle, these can be used like: + * repositories { + * maven { + * url "https://pkgs.dev.azure.com/org/project/_packaging/feedName/maven/v1" + * credentials { + * username = project.findProperty("feedNameUsername") ?: "" + * password = project.findProperty("feedNamePassword") ?: "" + * } + * } + * } + */ +export function addCredentialToGradleProperties(propertiesContent: string, credential: GradleCredential): string { + const sanitizedId = sanitizePropertyKey(credential.id); + + // Check if credential already exists + if (credentialExists(propertiesContent, credential.id)) { + tl.warning(tl.loc('Warning_FeedEntryAlreadyExists', credential.id)); + tl.debug('Entry: ' + credential.id); + return propertiesContent; + } + + const usernameEntry = `${sanitizedId}Username=${credential.username}`; + const passwordEntry = `${sanitizedId}Password=${credential.password}`; + + // Add newline if content doesn't end with one + let newContent = propertiesContent; + if (newContent.length > 0 && !newContent.endsWith('\n') && !newContent.endsWith('\r\n')) { + newContent += os.EOL; + } + + // Add a comment and the credentials + newContent += `# Azure Artifacts credentials for ${credential.id}${os.EOL}`; + newContent += `${usernameEntry}${os.EOL}`; + newContent += `${passwordEntry}${os.EOL}`; + + return newContent; +} diff --git a/Tasks/GradleAuthenticateV0/make.json b/Tasks/GradleAuthenticateV0/make.json new file mode 100644 index 000000000000..efbe25eff648 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/make.json @@ -0,0 +1,10 @@ +{ + "rm": [ + { + "items": [ + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ] +} diff --git a/Tasks/GradleAuthenticateV0/package-lock.json b/Tasks/GradleAuthenticateV0/package-lock.json new file mode 100644 index 000000000000..867cbe6bdbf2 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/package-lock.json @@ -0,0 +1,948 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gradleauthenticate", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^20.3.1", + "@types/q": "^1.5.2", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.15.0", + "azure-pipelines-tasks-artifacts-common": "^2.262.0", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/fs-extra/-/fs-extra-8.0.0.tgz", + "integrity": "sha1-0+LDE8op+VBZ8ZjdYNH3dGQtSyU=", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "5.2.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha1-MV1XDMtWxTRS/4Y4c432BybVtuo=", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-20.19.25.tgz", + "integrity": "sha1-Rn2pSi/ZZrV8w5w1ckfWgEdhEZA=", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/q/-/q-1.5.8.tgz", + "integrity": "sha1-lfbGoI8q2Gi6Iw6tHS1/e+PbODc=", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha1-vYakNhffBZR4fTi3NfVcgFvs8bw=", + "license": "MIT" + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha1-C15Md58H3t6lgFzcyxFHBx2UqQk=", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/azure-devops-node-api": { + "version": "14.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-devops-node-api/-/azure-devops-node-api-14.1.0.tgz", + "integrity": "sha1-7FOT3p+hRjmd6qtpBOQdoD7c4YA=", + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "2.1.0" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/azure-pipelines-task-lib": { + "version": "4.17.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.17.3.tgz", + "integrity": "sha1-/VMnGollIKefO6iDOcwLNiv51bk=", + "license": "MIT", + "dependencies": { + "adm-zip": "^0.5.10", + "minimatch": "3.0.5", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.7.2", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common": { + "version": "2.262.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-tasks-artifacts-common/-/azure-pipelines-tasks-artifacts-common-2.262.0.tgz", + "integrity": "sha1-iypOdrS7YH3cMWmUoC5MTcb8yAw=", + "license": "MIT", + "dependencies": { + "@types/fs-extra": "8.0.0", + "@types/mocha": "^5.2.6", + "@types/node": "^16.11.39", + "azure-devops-node-api": "^14.0.2", + "azure-pipelines-task-lib": "^4.13.0", + "fs-extra": "8.1.0", + "node-fetch": "^2.7.0", + "semver": "^6.3.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/@types/node": { + "version": "16.18.126", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-16.18.126.tgz", + "integrity": "sha1-J4dfqikmwPR1s5qLseVGwBdvjUs=", + "license": "MIT" + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha1-VW0u+GiRRuRtzqS/3QlfNDTf/LQ=", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha1-S1QowiK+mF15w9gmV0edvgtZstY=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha1-I43pNdKippKSjFOMfM+pEGf9Bio=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/debug/-/debug-4.4.3.tgz", + "integrity": "sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha1-HTf1dm87v/Tuljjocah2jBc7gdo=", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha1-165mfh3INIL4tw/Q9u78UNow9Yo=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha1-mD6y+aZyTpMD9hrd8BHHLgngsPo=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha1-BfdaJdq5jk+x3NXhRywFRtUFfI8=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha1-HE8sSDcydZfOadLKGQp/3RcjOME=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha1-d31z1yqS+OxNLkEOtHNSpWuOg0A=", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw=", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha1-dD8OO2lkqTpUke0b/6rgVNf5jQE=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha1-FQs/J0OGnvPoUewMSdFbHRTQDuE=", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha1-uN8PuAK7+o6JvR2Ti04WV47UTys=", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha1-ifVrghe9vIgCvSmd9tfxCB1+UaE=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha1-QYPk6L8Iu24Fu7L30uDI9xLKQOM=", + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha1-/JxqeDoISVHQuXH+EBjegTcHozg=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha1-AD6vkb563DcuhOxZ3DclLO24AAM=", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha1-xZ7yJKBP6LdU89sAY6Jeow0ABdY=", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4=", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha1-KpiAGoSfQ+Kt1kT7trxiKbGaTvQ=", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-md4": { + "version": "0.3.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha1-zTs9wEWwxARVbIHdtXVsI+WdfPU=", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha1-oN10voHiqlwvJ+Zc4oNgXuTit/k=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha1-u6vNwChZ9JhzAchW4zh85exDv3A=", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha1-OBqHG2KnNEUGYK497uRIE/cNlZo=", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha1-TajxKQ7g8PjoPWDKafjxNAaGBKM=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha1-0PD6bj4twdJ+/NitmdVQvalNGH0=", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodejs-file-downloader": { + "version": "4.13.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/nodejs-file-downloader/-/nodejs-file-downloader-4.13.0.tgz", + "integrity": "sha1-2ofDAIHeX/TouGQGLJjN7APmatA=", + "license": "ISC", + "dependencies": { + "follow-redirects": "^1.15.6", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha1-g3UmXiG8IND6WCwi4bE0hdbgAhM=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=", + "license": "MIT" + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/qs/-/qs-6.14.0.tgz", + "integrity": "sha1-xj+kBoDSxclBQSoOiZyJr2DAqTA=", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha1-qthXzh/7i/qbCxrCnxFWOD9owmI=", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha1-dV69dSBFkxl34wsgJdNA18kJA3g=", + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-5.7.2.tgz", + "integrity": "sha1-SNVdtzfDKHzUg14X+hP+rOHEHvg=", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha1-3gVUCNg2G+1mxmnS8ABTjO2O4gw=", + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha1-1rtrN5Asb+9RdOX1M/q0xzKib0I=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha1-Ed2hnVNo5Azp7CvcH7DsvAeQ7Oo=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha1-btpL00SjyUrqN21MwxvHcxEDngk=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "license": "MIT" + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=", + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/typed-rest-client": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typed-rest-client/-/typed-rest-client-2.1.0.tgz", + "integrity": "sha1-8Exs/KvGASwtA2uAbqrEVWBPFZg=", + "license": "MIT", + "dependencies": { + "des.js": "^1.1.0", + "js-md4": "^0.3.2", + "qs": "^6.10.3", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha1-AvisICttrSwN1eCRN0W0ejeZgnQ=", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha1-lw4zljr5p92iKPF+voOZ5fvmOhA=", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha1-aR0ArzkJvpOn+qE75hs6W1DvEss=", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha1-+fY5ENFVNu4rLV3UZlOJcV6sXB4=", + "license": "(WTFPL OR MIT)" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "license": "ISC" + } + } +} diff --git a/Tasks/GradleAuthenticateV0/package.json b/Tasks/GradleAuthenticateV0/package.json new file mode 100644 index 000000000000..9d2df69360c0 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/package.json @@ -0,0 +1,33 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "description": "Azure Pipelines Gradle Authenticate Task", + "main": "gradleauth.js", + "scripts": { + "build": "node ../../make.js build --task GradleAuthenticateV0", + "serverBuild": "node ../../make.js serverBuild --task GradleAuthenticateV0", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "ISC", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^20.3.1", + "@types/mocha": "^5.2.7", + "@types/uuid": "^8.3.0", + "@types/q": "^1.5.2", + "azure-pipelines-tasks-artifacts-common": "^2.262.0", + "azure-pipelines-task-lib": "^4.15.0", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } +} diff --git a/Tasks/GradleAuthenticateV0/task.json b/Tasks/GradleAuthenticateV0/task.json new file mode 100644 index 000000000000..3e7b46d3da7f --- /dev/null +++ b/Tasks/GradleAuthenticateV0/task.json @@ -0,0 +1,94 @@ +{ + "id": "A7E1B7E5-4B8D-4F2C-9A1E-3C5D7F9B2E4A", + "name": "GradleAuthenticate", + "friendlyName": "Gradle Authenticate", + "description": "Provides credentials for Azure Artifacts feeds and external Gradle/Maven repositories", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate", + "helpMarkDown": "[Learn more about this task](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate)", + "category": "Package", + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 1, + "Patch": 0 + }, + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "minimumAgentVersion": "2.144.0", + "instanceNameFormat": "Gradle Authenticate", + "inputs": [ + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "Feeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "Credentials for repositories outside this organization/collection", + "helpMarkDown": "Credentials to use for external repositories located in the project's build.gradle.", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ], + "dataSourceBindings": [ + { + "target": "artifactsFeeds", + "endpointId": "tfs:feed", + "endpointUrl": "{{endpoint.url}}/_apis/packaging/feedids", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{name}}}\", \"DisplayValue\" : \"{{{name}}}\" }" + } + ], + "execution": { + "Node10": { + "target": "gradleauth.js" + }, + "Node16": { + "target": "gradleauth.js" + }, + "Node20_1": { + "target": "gradleauth.js", + "argumentFormat": "" + } + }, + "postjobexecution": { + "Node10": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node16": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "cleanup.js", + "argumentFormat": "" + } + }, + "messages": { + "Warning_FeedEntryAlreadyExists": "The settings for the feed or repository '%s' already exists in the gradle.properties file.", + "Warning_NoEndpointsToAuth": "No repositories were selected to authenticate, please check your task configuration.", + "Warning_TokenNotGenerated": "Unable to use a federated token", + "Info_GeneratingExternalRepositories": "Generating configs for %s external repositories.", + "Info_GeneratingInternalFeeds": "Generating configs for %s internal feeds.", + "Info_GradleUserHomeFolderDoesntExist": ".gradle folder not found at location %s, creating new folder.", + "Info_GradlePropertiesRead": "Adding authentication to gradle.properties file %s.", + "Info_CreatingGradleProperties": "Creating new gradle.properties at path %s.", + "Info_WritingToGradleProperties": "Writing new gradle.properties with added authentication.", + "Info_AddingFederatedFeedAuth": "Adding auth information from federated service connection %s for feed %s", + "Info_SuccessAddingFederatedFeedAuth": "Successfully added auth for feed %s with federated credentials.", + "Error_InvalidServiceConnection": "The service connection for %s is invalid.", + "Error_FailedCleanupGradle": "Failed to delete credentials from the gradle.properties file: %s", + "Error_FailedToGetServiceConnectionAuth": "Unable to get federated credentials from service connection: %s." + } +} diff --git a/Tasks/GradleAuthenticateV0/task.loc.json b/Tasks/GradleAuthenticateV0/task.loc.json new file mode 100644 index 000000000000..a482b8caa8f0 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/task.loc.json @@ -0,0 +1,94 @@ +{ + "id": "A7E1B7E5-4B8D-4F2C-9A1E-3C5D7F9B2E4A", + "name": "GradleAuthenticate", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Package", + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 1, + "Patch": 0 + }, + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "minimumAgentVersion": "2.144.0", + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "inputs": [ + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "ms-resource:loc.input.label.artifactsFeeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "ms-resource:loc.input.label.gradleServiceConnections", + "helpMarkDown": "ms-resource:loc.input.help.gradleServiceConnections", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ], + "dataSourceBindings": [ + { + "target": "artifactsFeeds", + "endpointId": "tfs:feed", + "endpointUrl": "{{endpoint.url}}/_apis/packaging/feedids", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{name}}}\", \"DisplayValue\" : \"{{{name}}}\" }" + } + ], + "execution": { + "Node10": { + "target": "gradleauth.js" + }, + "Node16": { + "target": "gradleauth.js" + }, + "Node20_1": { + "target": "gradleauth.js", + "argumentFormat": "" + } + }, + "postjobexecution": { + "Node10": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node16": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "cleanup.js", + "argumentFormat": "" + } + }, + "messages": { + "Warning_FeedEntryAlreadyExists": "ms-resource:loc.messages.Warning_FeedEntryAlreadyExists", + "Warning_NoEndpointsToAuth": "ms-resource:loc.messages.Warning_NoEndpointsToAuth", + "Warning_TokenNotGenerated": "ms-resource:loc.messages.Warning_TokenNotGenerated", + "Info_GeneratingExternalRepositories": "ms-resource:loc.messages.Info_GeneratingExternalRepositories", + "Info_GeneratingInternalFeeds": "ms-resource:loc.messages.Info_GeneratingInternalFeeds", + "Info_GradleUserHomeFolderDoesntExist": "ms-resource:loc.messages.Info_GradleUserHomeFolderDoesntExist", + "Info_GradlePropertiesRead": "ms-resource:loc.messages.Info_GradlePropertiesRead", + "Info_CreatingGradleProperties": "ms-resource:loc.messages.Info_CreatingGradleProperties", + "Info_WritingToGradleProperties": "ms-resource:loc.messages.Info_WritingToGradleProperties", + "Info_AddingFederatedFeedAuth": "ms-resource:loc.messages.Info_AddingFederatedFeedAuth", + "Info_SuccessAddingFederatedFeedAuth": "ms-resource:loc.messages.Info_SuccessAddingFederatedFeedAuth", + "Error_InvalidServiceConnection": "ms-resource:loc.messages.Error_InvalidServiceConnection", + "Error_FailedCleanupGradle": "ms-resource:loc.messages.Error_FailedCleanupGradle", + "Error_FailedToGetServiceConnectionAuth": "ms-resource:loc.messages.Error_FailedToGetServiceConnectionAuth" + } +} \ No newline at end of file diff --git a/Tasks/GradleAuthenticateV0/taskJsonOverride.json b/Tasks/GradleAuthenticateV0/taskJsonOverride.json new file mode 100644 index 000000000000..e75fe24f3c3d --- /dev/null +++ b/Tasks/GradleAuthenticateV0/taskJsonOverride.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": ["azureDevOpsServiceConnection"], + "label": "'Azure DevOps' Service Connection", + "helpMarkDown": "This is an Entra Workload ID-backed Azure DevOps user Service Connection. If this is set, the input gradleServiceConnections will be ignored.", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "Feeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "Credentials for repositories outside this organization/collection", + "helpMarkDown": "Credentials to use for external repositories located in the project's build.gradle.", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ] +} diff --git a/Tasks/GradleAuthenticateV0/taskJsonOverride.loc.json b/Tasks/GradleAuthenticateV0/taskJsonOverride.loc.json new file mode 100644 index 000000000000..2d8691c36274 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/taskJsonOverride.loc.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": ["azureDevOpsServiceConnection"], + "label": "ms-resource:loc.input.label.workloadIdentityServiceConnection", + "helpMarkDown": "ms-resource:loc.input.help.workloadIdentityServiceConnection", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "ms-resource:loc.input.label.artifactsFeeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "ms-resource:loc.input.label.gradleServiceConnections", + "helpMarkDown": "ms-resource:loc.input.help.gradleServiceConnections", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ] +} diff --git a/Tasks/GradleAuthenticateV0/tsconfig.json b/Tasks/GradleAuthenticateV0/tsconfig.json new file mode 100644 index 000000000000..d8739c3f3a75 --- /dev/null +++ b/Tasks/GradleAuthenticateV0/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs" + } +} diff --git a/make-options.json b/make-options.json index 326941b00b3d..a9fb302f326e 100644 --- a/make-options.json +++ b/make-options.json @@ -110,6 +110,7 @@ "GitHubReleaseV1", "GoV0", "GoToolV0", + "GradleAuthenticateV0", "GradleV2", "GradleV3", "GradleV4", @@ -347,6 +348,7 @@ "Not compiling yet: GitHubReleaseV1", "GoToolV0", "GoV0", + "GradleAuthenticateV0", "GradleV2", "GradleV3", "GruntV0", From 3bd5905961267c764d1b473ce7e157a4c8b85f56 Mon Sep 17 00:00:00 2001 From: Jordan Kurtz Date: Mon, 8 Dec 2025 14:08:41 -0600 Subject: [PATCH 2/5] Add WIF task generation for GradleAuthenticate --- .../_buildConfigs/Wif/package-lock.json | 948 ++++++++++++++++++ make-options.json | 3 +- 2 files changed, 950 insertions(+), 1 deletion(-) create mode 100644 Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package-lock.json diff --git a/Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package-lock.json b/Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package-lock.json new file mode 100644 index 000000000000..07d86b44f66e --- /dev/null +++ b/Tasks/GradleAuthenticateV0/_buildConfigs/Wif/package-lock.json @@ -0,0 +1,948 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gradleauthenticate", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^20.3.1", + "@types/q": "^1.5.2", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.15.0", + "azure-pipelines-tasks-artifacts-common": "^2.243.1", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/fs-extra/-/fs-extra-8.0.0.tgz", + "integrity": "sha1-0+LDE8op+VBZ8ZjdYNH3dGQtSyU=", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "5.2.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha1-MV1XDMtWxTRS/4Y4c432BybVtuo=", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-20.19.25.tgz", + "integrity": "sha1-Rn2pSi/ZZrV8w5w1ckfWgEdhEZA=", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/q/-/q-1.5.8.tgz", + "integrity": "sha1-lfbGoI8q2Gi6Iw6tHS1/e+PbODc=", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha1-vYakNhffBZR4fTi3NfVcgFvs8bw=", + "license": "MIT" + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha1-C15Md58H3t6lgFzcyxFHBx2UqQk=", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/azure-devops-node-api": { + "version": "14.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-devops-node-api/-/azure-devops-node-api-14.1.0.tgz", + "integrity": "sha1-7FOT3p+hRjmd6qtpBOQdoD7c4YA=", + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "2.1.0" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/azure-pipelines-task-lib": { + "version": "4.17.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.17.3.tgz", + "integrity": "sha1-/VMnGollIKefO6iDOcwLNiv51bk=", + "license": "MIT", + "dependencies": { + "adm-zip": "^0.5.10", + "minimatch": "3.0.5", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.7.2", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common": { + "version": "2.262.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-tasks-artifacts-common/-/azure-pipelines-tasks-artifacts-common-2.262.0.tgz", + "integrity": "sha1-iypOdrS7YH3cMWmUoC5MTcb8yAw=", + "license": "MIT", + "dependencies": { + "@types/fs-extra": "8.0.0", + "@types/mocha": "^5.2.6", + "@types/node": "^16.11.39", + "azure-devops-node-api": "^14.0.2", + "azure-pipelines-task-lib": "^4.13.0", + "fs-extra": "8.1.0", + "node-fetch": "^2.7.0", + "semver": "^6.3.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/@types/node": { + "version": "16.18.126", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-16.18.126.tgz", + "integrity": "sha1-J4dfqikmwPR1s5qLseVGwBdvjUs=", + "license": "MIT" + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha1-VW0u+GiRRuRtzqS/3QlfNDTf/LQ=", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha1-S1QowiK+mF15w9gmV0edvgtZstY=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha1-I43pNdKippKSjFOMfM+pEGf9Bio=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/debug/-/debug-4.4.3.tgz", + "integrity": "sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha1-HTf1dm87v/Tuljjocah2jBc7gdo=", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha1-165mfh3INIL4tw/Q9u78UNow9Yo=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha1-mD6y+aZyTpMD9hrd8BHHLgngsPo=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha1-BfdaJdq5jk+x3NXhRywFRtUFfI8=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha1-HE8sSDcydZfOadLKGQp/3RcjOME=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha1-d31z1yqS+OxNLkEOtHNSpWuOg0A=", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw=", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha1-dD8OO2lkqTpUke0b/6rgVNf5jQE=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha1-FQs/J0OGnvPoUewMSdFbHRTQDuE=", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha1-uN8PuAK7+o6JvR2Ti04WV47UTys=", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha1-ifVrghe9vIgCvSmd9tfxCB1+UaE=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha1-QYPk6L8Iu24Fu7L30uDI9xLKQOM=", + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha1-/JxqeDoISVHQuXH+EBjegTcHozg=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha1-AD6vkb563DcuhOxZ3DclLO24AAM=", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha1-xZ7yJKBP6LdU89sAY6Jeow0ABdY=", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4=", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha1-KpiAGoSfQ+Kt1kT7trxiKbGaTvQ=", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-md4": { + "version": "0.3.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha1-zTs9wEWwxARVbIHdtXVsI+WdfPU=", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha1-oN10voHiqlwvJ+Zc4oNgXuTit/k=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha1-u6vNwChZ9JhzAchW4zh85exDv3A=", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha1-OBqHG2KnNEUGYK497uRIE/cNlZo=", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha1-TajxKQ7g8PjoPWDKafjxNAaGBKM=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha1-0PD6bj4twdJ+/NitmdVQvalNGH0=", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodejs-file-downloader": { + "version": "4.13.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/nodejs-file-downloader/-/nodejs-file-downloader-4.13.0.tgz", + "integrity": "sha1-2ofDAIHeX/TouGQGLJjN7APmatA=", + "license": "ISC", + "dependencies": { + "follow-redirects": "^1.15.6", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha1-g3UmXiG8IND6WCwi4bE0hdbgAhM=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=", + "license": "MIT" + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/qs/-/qs-6.14.0.tgz", + "integrity": "sha1-xj+kBoDSxclBQSoOiZyJr2DAqTA=", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha1-qthXzh/7i/qbCxrCnxFWOD9owmI=", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha1-dV69dSBFkxl34wsgJdNA18kJA3g=", + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-5.7.2.tgz", + "integrity": "sha1-SNVdtzfDKHzUg14X+hP+rOHEHvg=", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha1-3gVUCNg2G+1mxmnS8ABTjO2O4gw=", + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha1-1rtrN5Asb+9RdOX1M/q0xzKib0I=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha1-Ed2hnVNo5Azp7CvcH7DsvAeQ7Oo=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha1-btpL00SjyUrqN21MwxvHcxEDngk=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "license": "MIT" + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=", + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/typed-rest-client": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typed-rest-client/-/typed-rest-client-2.1.0.tgz", + "integrity": "sha1-8Exs/KvGASwtA2uAbqrEVWBPFZg=", + "license": "MIT", + "dependencies": { + "des.js": "^1.1.0", + "js-md4": "^0.3.2", + "qs": "^6.10.3", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha1-AvisICttrSwN1eCRN0W0ejeZgnQ=", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha1-lw4zljr5p92iKPF+voOZ5fvmOhA=", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha1-aR0ArzkJvpOn+qE75hs6W1DvEss=", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha1-+fY5ENFVNu4rLV3UZlOJcV6sXB4=", + "license": "(WTFPL OR MIT)" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "license": "ISC" + } + } +} diff --git a/make-options.json b/make-options.json index a9fb302f326e..a13a7c997838 100644 --- a/make-options.json +++ b/make-options.json @@ -250,7 +250,8 @@ "CondaAuthenticateV0", "NuGetAuthenticateV1", "MavenAuthenticateV0", - "TwineAuthenticateV1" + "TwineAuthenticateV1", + "GradleAuthenticateV0" ], "LocalPackages": [ "AndroidSigningV2", From 48b5c84e17eb9d689939b3764c7804af19f58fb4 Mon Sep 17 00:00:00 2001 From: Jordan Kurtz Date: Mon, 8 Dec 2025 14:10:30 -0600 Subject: [PATCH 3/5] Add codeowners for GradleAuthenticate --- .github/CODEOWNERS | 2 ++ issue-rules.yml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dbe4984fbaca..587cb83e086a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -474,3 +474,5 @@ Tasks/XamariniOSV2/ @microsoft/azure-pipelines-tasks-and-agent @tarunramsing Tasks/XamarinTestCloudV1/ @microsoft/azure-pipelines-tasks-and-agent @tarunramsinghani Tasks/XcodeV5/ @microsoft/azure-pipelines-tasks-and-agent @tarunramsinghani + +Tasks/MavenAuthenticateV0/ @microsoft/azure-artifacts-packages diff --git a/issue-rules.yml b/issue-rules.yml index c1018619a647..8ed26ada34b5 100644 --- a/issue-rules.yml +++ b/issue-rules.yml @@ -12,6 +12,9 @@ rules: - valueFor: '**Enter Task Name**' contains: 'MavenAuthenticate' addLabels: ['Area: Artifacts'] +- valueFor: '**Enter Task Name**' + contains: 'GradleAuthenticate' + addLabels: ['Area: Artifacts'] - valueFor: '**Enter Task Name**' contains: 'Nuget' addLabels: ['Area: Artifacts'] From 9e6e0c982e88ed44301fe8ee6e33da9985daa605 Mon Sep 17 00:00:00 2001 From: Jordan Kurtz Date: Mon, 8 Dec 2025 14:12:20 -0600 Subject: [PATCH 4/5] Add _generated code for GradleAuthenticate --- .../GradleAuthenticateV0.versionmap.txt | 2 + _generated/GradleAuthenticateV0/.npmrc | 5 + .../resources.resjson/en-US/resources.resjson | 23 + _generated/GradleAuthenticateV0/Tests/L0.ts | 158 +++ .../Tests/L0AuthGradleProperties.ts | 36 + .../Tests/L0AuthGradlePropertiesExists.ts | 36 + .../Tests/L0EmptyInput.ts | 25 + .../Tests/L0ServiceConnections.ts | 56 ++ .../gradlePropertiesFeedName1.properties | 3 + .../gradlePropertiesOtherFeedName.properties | 3 + _generated/GradleAuthenticateV0/cleanup.ts | 25 + _generated/GradleAuthenticateV0/gradleauth.ts | 80 ++ .../GradleAuthenticateV0/gradleutils.ts | 164 +++ _generated/GradleAuthenticateV0/make.json | 10 + .../GradleAuthenticateV0/package-lock.json | 948 ++++++++++++++++++ _generated/GradleAuthenticateV0/package.json | 33 + _generated/GradleAuthenticateV0/task.json | 99 ++ _generated/GradleAuthenticateV0/task.loc.json | 99 ++ .../taskJsonOverride.json | 36 + .../taskJsonOverride.loc.json | 36 + _generated/GradleAuthenticateV0/tsconfig.json | 6 + _generated/GradleAuthenticateV0_Wif/.npmrc | 5 + .../resources.resjson/en-US/resources.resjson | 25 + .../GradleAuthenticateV0_Wif/Tests/L0.ts | 158 +++ .../Tests/L0AuthGradleProperties.ts | 36 + .../Tests/L0AuthGradlePropertiesExists.ts | 36 + .../Tests/L0EmptyInput.ts | 25 + .../Tests/L0ServiceConnections.ts | 56 ++ .../gradlePropertiesFeedName1.properties | 3 + .../gradlePropertiesOtherFeedName.properties | 3 + .../GradleAuthenticateV0_Wif/cleanup.ts | 25 + .../GradleAuthenticateV0_Wif/gradleauth.ts | 116 +++ .../GradleAuthenticateV0_Wif/gradleutils.ts | 164 +++ _generated/GradleAuthenticateV0_Wif/make.json | 10 + .../package-lock.json | 948 ++++++++++++++++++ .../GradleAuthenticateV0_Wif/package.json | 31 + _generated/GradleAuthenticateV0_Wif/task.json | 113 +++ .../GradleAuthenticateV0_Wif/task.loc.json | 113 +++ .../taskJsonOverride.json | 36 + .../taskJsonOverride.loc.json | 36 + .../GradleAuthenticateV0_Wif/tsconfig.json | 6 + 41 files changed, 3828 insertions(+) create mode 100644 _generated/GradleAuthenticateV0.versionmap.txt create mode 100644 _generated/GradleAuthenticateV0/.npmrc create mode 100644 _generated/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson create mode 100644 _generated/GradleAuthenticateV0/Tests/L0.ts create mode 100644 _generated/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts create mode 100644 _generated/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts create mode 100644 _generated/GradleAuthenticateV0/Tests/L0EmptyInput.ts create mode 100644 _generated/GradleAuthenticateV0/Tests/L0ServiceConnections.ts create mode 100644 _generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties create mode 100644 _generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties create mode 100644 _generated/GradleAuthenticateV0/cleanup.ts create mode 100644 _generated/GradleAuthenticateV0/gradleauth.ts create mode 100644 _generated/GradleAuthenticateV0/gradleutils.ts create mode 100644 _generated/GradleAuthenticateV0/make.json create mode 100644 _generated/GradleAuthenticateV0/package-lock.json create mode 100644 _generated/GradleAuthenticateV0/package.json create mode 100644 _generated/GradleAuthenticateV0/task.json create mode 100644 _generated/GradleAuthenticateV0/task.loc.json create mode 100644 _generated/GradleAuthenticateV0/taskJsonOverride.json create mode 100644 _generated/GradleAuthenticateV0/taskJsonOverride.loc.json create mode 100644 _generated/GradleAuthenticateV0/tsconfig.json create mode 100644 _generated/GradleAuthenticateV0_Wif/.npmrc create mode 100644 _generated/GradleAuthenticateV0_Wif/Strings/resources.resjson/en-US/resources.resjson create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/L0.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradleProperties.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradlePropertiesExists.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/L0EmptyInput.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/L0ServiceConnections.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesFeedName1.properties create mode 100644 _generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesOtherFeedName.properties create mode 100644 _generated/GradleAuthenticateV0_Wif/cleanup.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/gradleauth.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/gradleutils.ts create mode 100644 _generated/GradleAuthenticateV0_Wif/make.json create mode 100644 _generated/GradleAuthenticateV0_Wif/package-lock.json create mode 100644 _generated/GradleAuthenticateV0_Wif/package.json create mode 100644 _generated/GradleAuthenticateV0_Wif/task.json create mode 100644 _generated/GradleAuthenticateV0_Wif/task.loc.json create mode 100644 _generated/GradleAuthenticateV0_Wif/taskJsonOverride.json create mode 100644 _generated/GradleAuthenticateV0_Wif/taskJsonOverride.loc.json create mode 100644 _generated/GradleAuthenticateV0_Wif/tsconfig.json diff --git a/_generated/GradleAuthenticateV0.versionmap.txt b/_generated/GradleAuthenticateV0.versionmap.txt new file mode 100644 index 000000000000..8b9de0963a02 --- /dev/null +++ b/_generated/GradleAuthenticateV0.versionmap.txt @@ -0,0 +1,2 @@ +Default|0.1.0 +wif_242|0.267.0 diff --git a/_generated/GradleAuthenticateV0/.npmrc b/_generated/GradleAuthenticateV0/.npmrc new file mode 100644 index 000000000000..76446dc42b54 --- /dev/null +++ b/_generated/GradleAuthenticateV0/.npmrc @@ -0,0 +1,5 @@ +scripts-prepend-node-path=true + +registry=https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ + +always-auth=true diff --git a/_generated/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson b/_generated/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..37cf72d36a3c --- /dev/null +++ b/_generated/GradleAuthenticateV0/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,23 @@ +{ + "loc.friendlyName": "Gradle Authenticate", + "loc.helpMarkDown": "[Learn more about this task](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate)", + "loc.description": "Provides credentials for Azure Artifacts feeds and external Gradle/Maven repositories", + "loc.instanceNameFormat": "Gradle Authenticate", + "loc.input.label.artifactsFeeds": "Feeds", + "loc.input.label.gradleServiceConnections": "Credentials for repositories outside this organization/collection", + "loc.input.help.gradleServiceConnections": "Credentials to use for external repositories located in the project's build.gradle.", + "loc.messages.Warning_FeedEntryAlreadyExists": "The settings for the feed or repository '%s' already exists in the gradle.properties file.", + "loc.messages.Warning_NoEndpointsToAuth": "No repositories were selected to authenticate, please check your task configuration.", + "loc.messages.Warning_TokenNotGenerated": "Unable to use a federated token", + "loc.messages.Info_GeneratingExternalRepositories": "Generating configs for %s external repositories.", + "loc.messages.Info_GeneratingInternalFeeds": "Generating configs for %s internal feeds.", + "loc.messages.Info_GradleUserHomeFolderDoesntExist": ".gradle folder not found at location %s, creating new folder.", + "loc.messages.Info_GradlePropertiesRead": "Adding authentication to gradle.properties file %s.", + "loc.messages.Info_CreatingGradleProperties": "Creating new gradle.properties at path %s.", + "loc.messages.Info_WritingToGradleProperties": "Writing new gradle.properties with added authentication.", + "loc.messages.Info_AddingFederatedFeedAuth": "Adding auth information from federated service connection %s for feed %s", + "loc.messages.Info_SuccessAddingFederatedFeedAuth": "Successfully added auth for feed %s with federated credentials.", + "loc.messages.Error_InvalidServiceConnection": "The service connection for %s is invalid.", + "loc.messages.Error_FailedCleanupGradle": "Failed to delete credentials from the gradle.properties file: %s", + "loc.messages.Error_FailedToGetServiceConnectionAuth": "Unable to get federated credentials from service connection: %s." +} \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0/Tests/L0.ts b/_generated/GradleAuthenticateV0/Tests/L0.ts new file mode 100644 index 000000000000..b56658ce6cdf --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/L0.ts @@ -0,0 +1,158 @@ +import fs = require("fs"); +import assert = require("assert"); +import path = require("path"); +import * as tl from "azure-pipelines-task-lib/task"; +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); +const gradlePropertiesOtherFeedName = path.join(__dirname, "Samples", "gradlePropertiesOtherFeedName.properties"); +const gradlePropertiesFeedName1 = path.join(__dirname, "Samples", "gradlePropertiesFeedName1.properties"); + +const usernameRegex = /Username=/mig; +const passwordRegex = /Password=/mig; + +describe("authenticate azure artifacts feeds for gradle", function() { + this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000); + var env; + + this.beforeAll(async () => { + env = Object.assign({}, process.env); + process.env["USERPROFILE"] = testUserHomeDir; + process.env["HOME"] = testUserHomeDir; + }); + + beforeEach(async () => { + tl.mkdirP(gradleDirPath); + }) + + this.afterAll(async () => { + process.env = env; + }) + + afterEach(async () => { + tl.rmRF(gradleDirPath); + }); + + it("it should create a new gradle.properties in the .gradle folder and add auth for 1 feed.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradleProperties.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be created."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 1, "Only one username entry should be created."); + assert.equal(data.match(passwordRegex).length, 1, "Only one password entry should be created."); + assert(data.includes("feedName1Username="), "feedName1Username entry should be present."); + assert(data.includes("feedName1Password="), "feedName1Password entry should be present."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should read the existing gradle.properties and add auth for 1 new feed", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradlePropertiesExists.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + tl.cp(gradlePropertiesOtherFeedName, gradlePropertiesPath); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be present."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 2, "2 username entries should be present."); + assert.equal(data.match(passwordRegex).length, 2, "2 password entries should be present."); + assert(data.includes("feedName1Username="), "feedName1Username entry should be present."); + assert(data.includes("otherFeedNameUsername="), "otherFeedNameUsername entry should not be deleted."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should read the existing gradle.properties and not add any new entries.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradlePropertiesExists.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + tl.cp(gradlePropertiesFeedName1, gradlePropertiesPath); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be present."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 1, "Only one username entry should be present."); + assert.equal(data.match(passwordRegex).length, 1, "Only one password entry should be present."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.stdOutContained("vso[task.issue type=warning;source=TaskInternal;]loc_mock_Warning_FeedEntryAlreadyExists"), "Entry already exists warning should be displayed"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should create a new gradle.properties in the .gradle folder and add auth for 2 different types of service connections.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0ServiceConnections.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be created."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 2, "2 username entries should be created."); + assert.equal(data.match(passwordRegex).length, 2, "2 password entries should be created."); + + assert(data.includes("tokenBasedUsername=AzureDevOps"), "tokenBased username should be AzureDevOps."); + assert(data.includes("tokenBasedPassword=--token--"), "tokenBased password should be the token."); + + assert(data.includes("usernamePasswordBasedUsername=--testUserName--"), "usernamePasswordBased username should be set."); + assert(data.includes("usernamePasswordBasedPassword=--testPassword--"), "usernamePasswordBased password should be set."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should warn if no inputs are provided.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0EmptyInput.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 0, "gradle.properties file should not be created."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + assert(tr.stdOutContained("vso[task.issue type=warning;source=TaskInternal;]loc_mock_Warning_NoEndpointsToAuth"), "The no endpoints warning should be displayed"); + }); +}); diff --git a/_generated/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts b/_generated/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts new file mode 100644 index 000000000000..d54552049149 --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/L0AuthGradleProperties.ts @@ -0,0 +1,36 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", "feedName1"); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: false, + [gradlePropertiesPath]: false + } +}); + +tr.run(); diff --git a/_generated/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts b/_generated/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts new file mode 100644 index 000000000000..9af008259a49 --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/L0AuthGradlePropertiesExists.ts @@ -0,0 +1,36 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", "feedName1"); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: true, + [gradlePropertiesPath]: true + } +}); + +tr.run(); diff --git a/_generated/GradleAuthenticateV0/Tests/L0EmptyInput.ts b/_generated/GradleAuthenticateV0/Tests/L0EmptyInput.ts new file mode 100644 index 000000000000..07118ca600ec --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/L0EmptyInput.ts @@ -0,0 +1,25 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +// Set inputs +tr.setInput("artifactsFeeds", ""); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +tr.setAnswers({ + osType: { + "osType": "Windows NT" + } +}); + +tr.run(); diff --git a/_generated/GradleAuthenticateV0/Tests/L0ServiceConnections.ts b/_generated/GradleAuthenticateV0/Tests/L0ServiceConnections.ts new file mode 100644 index 000000000000..b245ad099e91 --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/L0ServiceConnections.ts @@ -0,0 +1,56 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", ""); +tr.setInput("gradleServiceConnections", "tokenBased,usernamePasswordBased"); +tr.setInput("verbosity", "verbose"); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +process.env["ENDPOINT_URL_tokenBased"] = "https://endpoint"; +process.env["ENDPOINT_DATA_tokenBased_REPOSITORYID"] = "tokenBased"; +process.env["ENDPOINT_AUTH_SCHEME_tokenBased"] = "token"; +process.env["ENDPOINT_AUTH_tokenBased"] = JSON.stringify({ + "parameters": { + "apitoken": "--token--" + } +}); + +process.env["ENDPOINT_URL_usernamePasswordBased"] = "https://endpoint"; +process.env["ENDPOINT_DATA_usernamePasswordBased_REPOSITORYID"] = "usernamePasswordBased"; +process.env["ENDPOINT_AUTH_SCHEME_usernamePasswordBased"] = "usernamepassword"; +process.env["ENDPOINT_AUTH_usernamePasswordBased"] = JSON.stringify({ + "parameters": { + "username": "--testUserName--", + "password": "--testPassword--" + } +}); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: false, + [gradlePropertiesPath]: false + } +}); + + +tr.run(); diff --git a/_generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties b/_generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties new file mode 100644 index 000000000000..1649ae03a207 --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesFeedName1.properties @@ -0,0 +1,3 @@ +# Azure Artifacts credentials for feedName1 +feedName1Username=AzureDevOps +feedName1Password=existingToken diff --git a/_generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties b/_generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties new file mode 100644 index 000000000000..e079032c0599 --- /dev/null +++ b/_generated/GradleAuthenticateV0/Tests/Samples/gradlePropertiesOtherFeedName.properties @@ -0,0 +1,3 @@ +# Azure Artifacts credentials for otherFeedName +otherFeedNameUsername=AzureDevOps +otherFeedNamePassword=existingToken diff --git a/_generated/GradleAuthenticateV0/cleanup.ts b/_generated/GradleAuthenticateV0/cleanup.ts new file mode 100644 index 000000000000..93052513b45b --- /dev/null +++ b/_generated/GradleAuthenticateV0/cleanup.ts @@ -0,0 +1,25 @@ +import * as path from 'path'; +import * as tl from 'azure-pipelines-task-lib/task'; + +async function run() { + try { + tl.setResourcePath(path.join(__dirname, 'task.json')); + + const userGradlePropertiesPath: string = tl.getTaskVariable('userGradlePropertiesPath'); + const backupUserGradlePropertiesFilePath: string = tl.getTaskVariable('backupUserGradlePropertiesFilePath'); + + if (userGradlePropertiesPath && tl.exist(userGradlePropertiesPath)) { + tl.rmRF(userGradlePropertiesPath); + tl.debug('Deleted user gradle.properties file: ' + userGradlePropertiesPath); + + if (backupUserGradlePropertiesFilePath && tl.exist(backupUserGradlePropertiesFilePath)) { + tl.mv(backupUserGradlePropertiesFilePath, userGradlePropertiesPath); + tl.debug('Restored old user gradle.properties file: ' + backupUserGradlePropertiesFilePath); + } + } + } catch (err) { + tl.warning(tl.loc('Error_FailedCleanupGradle', err)); + } +} + +run(); diff --git a/_generated/GradleAuthenticateV0/gradleauth.ts b/_generated/GradleAuthenticateV0/gradleauth.ts new file mode 100644 index 000000000000..a3e5463ff5e7 --- /dev/null +++ b/_generated/GradleAuthenticateV0/gradleauth.ts @@ -0,0 +1,80 @@ +import tl = require('azure-pipelines-task-lib/task'); +import util = require('./gradleutils'); + +import * as path from 'path'; +import { emitTelemetry } from 'azure-pipelines-tasks-artifacts-common/telemetry'; + + +const GradleFolderName: string = ".gradle"; +const GradlePropertiesName: string = "gradle.properties"; +const backupGradlePropertiesName: string = "_gradle.properties"; + +tl.setResourcePath(path.join(__dirname, 'task.json')); + +async function run(): Promise { + let internalFeedCredentials: any[] = []; + let externalServiceEndpointsCredentials: any[] = []; + let federatedFeedAuthSuccessCount: number = 0; + try { + let userGradleFolderPath: string = ""; + + if (tl.osType().match(/^Win/)) { + userGradleFolderPath = path.join(process.env.USERPROFILE, GradleFolderName); + } else { + userGradleFolderPath = path.join(process.env.HOME, GradleFolderName); + } + + if (!tl.exist(userGradleFolderPath)) { + tl.debug(tl.loc("Info_GradleUserHomeFolderDoesntExist", userGradleFolderPath)); + tl.mkdirP(userGradleFolderPath); + } + + let userGradlePropertiesPath: string = path.join(userGradleFolderPath, GradlePropertiesName); + let backupGradlePropertiesPath: string = path.join(userGradleFolderPath, backupGradlePropertiesName); + let propertiesContent: string = ""; + + tl.setTaskVariable('userGradlePropertiesPath', userGradlePropertiesPath); + + if (tl.exist(userGradlePropertiesPath)) { + tl.debug(tl.loc("Info_GradlePropertiesRead", userGradlePropertiesPath)); + if (!tl.getVariable('FIRST_RUN_GRADLE_PROPERTIES_EXISTS_PATH') && !tl.exist(backupGradlePropertiesPath)) { + tl.cp(userGradlePropertiesPath, backupGradlePropertiesPath); + tl.setTaskVariable("backupUserGradlePropertiesFilePath", backupGradlePropertiesPath); + } + propertiesContent = util.readGradlePropertiesFile(userGradlePropertiesPath); + } + else { + tl.debug(tl.loc("Info_CreatingGradleProperties", userGradlePropertiesPath)); + tl.setVariable('FIRST_RUN_GRADLE_PROPERTIES_EXISTS_PATH', userGradlePropertiesPath); + } + + + internalFeedCredentials = util.getInternalFeedsCredentials("artifactsFeeds"); + externalServiceEndpointsCredentials = util.getExternalServiceEndpointsCredentials("gradleServiceConnections"); + const newCredentials = internalFeedCredentials.concat(externalServiceEndpointsCredentials); + + if(newCredentials.length === 0) { + tl.warning(tl.loc("Warning_NoEndpointsToAuth")); + return; + } + + for (let credential of newCredentials) { + propertiesContent = util.addCredentialToGradleProperties(propertiesContent, credential); + }; + + tl.debug(tl.loc("Info_WritingToGradleProperties")); + util.writeGradlePropertiesFile(userGradlePropertiesPath, propertiesContent); + } + catch (err) { + tl.setResult(tl.TaskResult.Failed, err.message); + } + finally { + emitTelemetry("Packaging", "GradleAuthenticate", { + "InternalFeedAuthCount": internalFeedCredentials.length, + "ExternalRepoAuthCount": externalServiceEndpointsCredentials.length, + "FederatedFeedAuthCount": federatedFeedAuthSuccessCount + }); + } +} + +run(); diff --git a/_generated/GradleAuthenticateV0/gradleutils.ts b/_generated/GradleAuthenticateV0/gradleutils.ts new file mode 100644 index 000000000000..6cc4bd9ed891 --- /dev/null +++ b/_generated/GradleAuthenticateV0/gradleutils.ts @@ -0,0 +1,164 @@ +import fs = require('fs'); +import tl = require('azure-pipelines-task-lib/task'); +import path = require('path'); +import { getSystemAccessToken } from 'azure-pipelines-tasks-artifacts-common/webapi' + +import * as os from 'os'; +import * as fse from 'fs-extra'; + +import { getPackagingServiceConnections, ServiceConnectionAuthType, UsernamePasswordServiceConnection, TokenServiceConnection, PrivateKeyServiceConnection } from "azure-pipelines-tasks-artifacts-common/serviceConnectionUtils"; + +export interface GradleCredential { + id: string; + username: string; + password: string; +} + +/** + * Sanitizes a feed/repository name to be used as a Gradle property key + * Gradle properties use alphanumeric, dots, and underscores + */ +export function sanitizePropertyKey(name: string): string { + return name.replace(/[^a-zA-Z0-9._-]/g, '_'); +} + +export function getInternalFeedsCredentials(input: string): GradleCredential[] { + const feeds: string[] = tl.getDelimitedInput(input, ",", false); + var credentials: GradleCredential[] = []; + + if (!feeds || feeds.length === 0) + { + return credentials; + } + + tl.debug(tl.loc('Info_GeneratingInternalFeeds', feeds.length)); + for (let feed of feeds) { + credentials.push({ + id: feed, + username: "AzureDevOps", + password: getSystemAccessToken() + }); + } + + return credentials; +} + +export function getExternalServiceEndpointsCredentials(input: string): GradleCredential[] { + var serviceConnections = getPackagingServiceConnections(input, ["REPOSITORYID"]); + var credentials: GradleCredential[] = []; + if (!serviceConnections || serviceConnections.length === 0) + { + return credentials; + } + + tl.debug(tl.loc("Info_GeneratingExternalRepositories", serviceConnections.length)); + for(let serviceConnection of serviceConnections) { + switch (serviceConnection.authType) { + case (ServiceConnectionAuthType.UsernamePassword): + const usernamePasswordAuthInfo = serviceConnection as UsernamePasswordServiceConnection; + + credentials.push({ + id: serviceConnection.additionalData["REPOSITORYID"], + username: usernamePasswordAuthInfo.username, + password: usernamePasswordAuthInfo.password, + }); + + tl.debug(`Detected username/password credentials for '${serviceConnection.packageSource.uri}'`); + break; + case (ServiceConnectionAuthType.Token): + const tokenAuthInfo = serviceConnection as TokenServiceConnection; + credentials.push({ + id: serviceConnection.additionalData["REPOSITORYID"], + username: "AzureDevOps", + password: tokenAuthInfo.token + }); + tl.debug(`Detected token credentials for '${serviceConnection.packageSource.uri}'`); + break; + case (ServiceConnectionAuthType.PrivateKey): + // Gradle doesn't natively support private key auth like Maven, use as password + const privateKeyAuthInfo = serviceConnection as PrivateKeyServiceConnection; + tl.warning(`Private key authentication is not supported for Gradle. Skipping '${serviceConnection.packageSource.uri}'`); + break; + default: + throw Error(tl.loc('Error_InvalidServiceConnection', serviceConnection.packageSource.uri)); + } + } + + return credentials; +} + +export function readGradlePropertiesFile(filePath: string): string { + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath, 'utf-8'); + } + return ""; +} + +export function writeGradlePropertiesFile(filePath: string, content: string): void { + fse.mkdirpSync(path.dirname(filePath)); + fs.writeFileSync(filePath, content, { encoding: 'utf-8' }); +} + +/** + * Checks if a credential already exists in the gradle.properties content + */ +export function credentialExists(propertiesContent: string, id: string): boolean { + const sanitizedId = sanitizePropertyKey(id); + const usernameKey = `${sanitizedId}Username`; + const passwordKey = `${sanitizedId}Password`; + + // Check if either username or password property already exists + const lines = propertiesContent.split(/\r?\n/); + for (const line of lines) { + const trimmedLine = line.trim(); + if (trimmedLine.startsWith(usernameKey + '=') || trimmedLine.startsWith(passwordKey + '=')) { + return true; + } + } + return false; +} + +/** + * Adds a credential entry to gradle.properties content + * Gradle credentials are stored as properties that can be referenced in build.gradle: + * + * feedNameUsername=AzureDevOps + * feedNamePassword=token_value + * + * In build.gradle, these can be used like: + * repositories { + * maven { + * url "https://pkgs.dev.azure.com/org/project/_packaging/feedName/maven/v1" + * credentials { + * username = project.findProperty("feedNameUsername") ?: "" + * password = project.findProperty("feedNamePassword") ?: "" + * } + * } + * } + */ +export function addCredentialToGradleProperties(propertiesContent: string, credential: GradleCredential): string { + const sanitizedId = sanitizePropertyKey(credential.id); + + // Check if credential already exists + if (credentialExists(propertiesContent, credential.id)) { + tl.warning(tl.loc('Warning_FeedEntryAlreadyExists', credential.id)); + tl.debug('Entry: ' + credential.id); + return propertiesContent; + } + + const usernameEntry = `${sanitizedId}Username=${credential.username}`; + const passwordEntry = `${sanitizedId}Password=${credential.password}`; + + // Add newline if content doesn't end with one + let newContent = propertiesContent; + if (newContent.length > 0 && !newContent.endsWith('\n') && !newContent.endsWith('\r\n')) { + newContent += os.EOL; + } + + // Add a comment and the credentials + newContent += `# Azure Artifacts credentials for ${credential.id}${os.EOL}`; + newContent += `${usernameEntry}${os.EOL}`; + newContent += `${passwordEntry}${os.EOL}`; + + return newContent; +} diff --git a/_generated/GradleAuthenticateV0/make.json b/_generated/GradleAuthenticateV0/make.json new file mode 100644 index 000000000000..efbe25eff648 --- /dev/null +++ b/_generated/GradleAuthenticateV0/make.json @@ -0,0 +1,10 @@ +{ + "rm": [ + { + "items": [ + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ] +} diff --git a/_generated/GradleAuthenticateV0/package-lock.json b/_generated/GradleAuthenticateV0/package-lock.json new file mode 100644 index 000000000000..867cbe6bdbf2 --- /dev/null +++ b/_generated/GradleAuthenticateV0/package-lock.json @@ -0,0 +1,948 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gradleauthenticate", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^20.3.1", + "@types/q": "^1.5.2", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.15.0", + "azure-pipelines-tasks-artifacts-common": "^2.262.0", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/fs-extra/-/fs-extra-8.0.0.tgz", + "integrity": "sha1-0+LDE8op+VBZ8ZjdYNH3dGQtSyU=", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "5.2.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha1-MV1XDMtWxTRS/4Y4c432BybVtuo=", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-20.19.25.tgz", + "integrity": "sha1-Rn2pSi/ZZrV8w5w1ckfWgEdhEZA=", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/q/-/q-1.5.8.tgz", + "integrity": "sha1-lfbGoI8q2Gi6Iw6tHS1/e+PbODc=", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha1-vYakNhffBZR4fTi3NfVcgFvs8bw=", + "license": "MIT" + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha1-C15Md58H3t6lgFzcyxFHBx2UqQk=", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/azure-devops-node-api": { + "version": "14.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-devops-node-api/-/azure-devops-node-api-14.1.0.tgz", + "integrity": "sha1-7FOT3p+hRjmd6qtpBOQdoD7c4YA=", + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "2.1.0" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/azure-pipelines-task-lib": { + "version": "4.17.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.17.3.tgz", + "integrity": "sha1-/VMnGollIKefO6iDOcwLNiv51bk=", + "license": "MIT", + "dependencies": { + "adm-zip": "^0.5.10", + "minimatch": "3.0.5", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.7.2", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common": { + "version": "2.262.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-tasks-artifacts-common/-/azure-pipelines-tasks-artifacts-common-2.262.0.tgz", + "integrity": "sha1-iypOdrS7YH3cMWmUoC5MTcb8yAw=", + "license": "MIT", + "dependencies": { + "@types/fs-extra": "8.0.0", + "@types/mocha": "^5.2.6", + "@types/node": "^16.11.39", + "azure-devops-node-api": "^14.0.2", + "azure-pipelines-task-lib": "^4.13.0", + "fs-extra": "8.1.0", + "node-fetch": "^2.7.0", + "semver": "^6.3.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/@types/node": { + "version": "16.18.126", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-16.18.126.tgz", + "integrity": "sha1-J4dfqikmwPR1s5qLseVGwBdvjUs=", + "license": "MIT" + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha1-VW0u+GiRRuRtzqS/3QlfNDTf/LQ=", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha1-S1QowiK+mF15w9gmV0edvgtZstY=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha1-I43pNdKippKSjFOMfM+pEGf9Bio=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/debug/-/debug-4.4.3.tgz", + "integrity": "sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha1-HTf1dm87v/Tuljjocah2jBc7gdo=", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha1-165mfh3INIL4tw/Q9u78UNow9Yo=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha1-mD6y+aZyTpMD9hrd8BHHLgngsPo=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha1-BfdaJdq5jk+x3NXhRywFRtUFfI8=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha1-HE8sSDcydZfOadLKGQp/3RcjOME=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha1-d31z1yqS+OxNLkEOtHNSpWuOg0A=", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw=", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha1-dD8OO2lkqTpUke0b/6rgVNf5jQE=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha1-FQs/J0OGnvPoUewMSdFbHRTQDuE=", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha1-uN8PuAK7+o6JvR2Ti04WV47UTys=", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha1-ifVrghe9vIgCvSmd9tfxCB1+UaE=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha1-QYPk6L8Iu24Fu7L30uDI9xLKQOM=", + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha1-/JxqeDoISVHQuXH+EBjegTcHozg=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha1-AD6vkb563DcuhOxZ3DclLO24AAM=", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha1-xZ7yJKBP6LdU89sAY6Jeow0ABdY=", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4=", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha1-KpiAGoSfQ+Kt1kT7trxiKbGaTvQ=", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-md4": { + "version": "0.3.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha1-zTs9wEWwxARVbIHdtXVsI+WdfPU=", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha1-oN10voHiqlwvJ+Zc4oNgXuTit/k=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha1-u6vNwChZ9JhzAchW4zh85exDv3A=", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha1-OBqHG2KnNEUGYK497uRIE/cNlZo=", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha1-TajxKQ7g8PjoPWDKafjxNAaGBKM=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha1-0PD6bj4twdJ+/NitmdVQvalNGH0=", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodejs-file-downloader": { + "version": "4.13.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/nodejs-file-downloader/-/nodejs-file-downloader-4.13.0.tgz", + "integrity": "sha1-2ofDAIHeX/TouGQGLJjN7APmatA=", + "license": "ISC", + "dependencies": { + "follow-redirects": "^1.15.6", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha1-g3UmXiG8IND6WCwi4bE0hdbgAhM=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=", + "license": "MIT" + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/qs/-/qs-6.14.0.tgz", + "integrity": "sha1-xj+kBoDSxclBQSoOiZyJr2DAqTA=", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha1-qthXzh/7i/qbCxrCnxFWOD9owmI=", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha1-dV69dSBFkxl34wsgJdNA18kJA3g=", + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-5.7.2.tgz", + "integrity": "sha1-SNVdtzfDKHzUg14X+hP+rOHEHvg=", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha1-3gVUCNg2G+1mxmnS8ABTjO2O4gw=", + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha1-1rtrN5Asb+9RdOX1M/q0xzKib0I=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha1-Ed2hnVNo5Azp7CvcH7DsvAeQ7Oo=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha1-btpL00SjyUrqN21MwxvHcxEDngk=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "license": "MIT" + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=", + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/typed-rest-client": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typed-rest-client/-/typed-rest-client-2.1.0.tgz", + "integrity": "sha1-8Exs/KvGASwtA2uAbqrEVWBPFZg=", + "license": "MIT", + "dependencies": { + "des.js": "^1.1.0", + "js-md4": "^0.3.2", + "qs": "^6.10.3", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha1-AvisICttrSwN1eCRN0W0ejeZgnQ=", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha1-lw4zljr5p92iKPF+voOZ5fvmOhA=", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha1-aR0ArzkJvpOn+qE75hs6W1DvEss=", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha1-+fY5ENFVNu4rLV3UZlOJcV6sXB4=", + "license": "(WTFPL OR MIT)" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "license": "ISC" + } + } +} diff --git a/_generated/GradleAuthenticateV0/package.json b/_generated/GradleAuthenticateV0/package.json new file mode 100644 index 000000000000..9d2df69360c0 --- /dev/null +++ b/_generated/GradleAuthenticateV0/package.json @@ -0,0 +1,33 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "description": "Azure Pipelines Gradle Authenticate Task", + "main": "gradleauth.js", + "scripts": { + "build": "node ../../make.js build --task GradleAuthenticateV0", + "serverBuild": "node ../../make.js serverBuild --task GradleAuthenticateV0", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "ISC", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^20.3.1", + "@types/mocha": "^5.2.7", + "@types/uuid": "^8.3.0", + "@types/q": "^1.5.2", + "azure-pipelines-tasks-artifacts-common": "^2.262.0", + "azure-pipelines-task-lib": "^4.15.0", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } +} diff --git a/_generated/GradleAuthenticateV0/task.json b/_generated/GradleAuthenticateV0/task.json new file mode 100644 index 000000000000..f5f9e0768d40 --- /dev/null +++ b/_generated/GradleAuthenticateV0/task.json @@ -0,0 +1,99 @@ +{ + "id": "A7E1B7E5-4B8D-4F2C-9A1E-3C5D7F9B2E4A", + "name": "GradleAuthenticate", + "friendlyName": "Gradle Authenticate", + "description": "Provides credentials for Azure Artifacts feeds and external Gradle/Maven repositories", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate", + "helpMarkDown": "[Learn more about this task](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate)", + "category": "Package", + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 1, + "Patch": 0 + }, + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "minimumAgentVersion": "2.144.0", + "instanceNameFormat": "Gradle Authenticate", + "inputs": [ + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "Feeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "Credentials for repositories outside this organization/collection", + "helpMarkDown": "Credentials to use for external repositories located in the project's build.gradle.", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ], + "dataSourceBindings": [ + { + "target": "artifactsFeeds", + "endpointId": "tfs:feed", + "endpointUrl": "{{endpoint.url}}/_apis/packaging/feedids", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{name}}}\", \"DisplayValue\" : \"{{{name}}}\" }" + } + ], + "execution": { + "Node10": { + "target": "gradleauth.js" + }, + "Node16": { + "target": "gradleauth.js" + }, + "Node20_1": { + "target": "gradleauth.js", + "argumentFormat": "" + } + }, + "postjobexecution": { + "Node10": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node16": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "cleanup.js", + "argumentFormat": "" + } + }, + "messages": { + "Warning_FeedEntryAlreadyExists": "The settings for the feed or repository '%s' already exists in the gradle.properties file.", + "Warning_NoEndpointsToAuth": "No repositories were selected to authenticate, please check your task configuration.", + "Warning_TokenNotGenerated": "Unable to use a federated token", + "Info_GeneratingExternalRepositories": "Generating configs for %s external repositories.", + "Info_GeneratingInternalFeeds": "Generating configs for %s internal feeds.", + "Info_GradleUserHomeFolderDoesntExist": ".gradle folder not found at location %s, creating new folder.", + "Info_GradlePropertiesRead": "Adding authentication to gradle.properties file %s.", + "Info_CreatingGradleProperties": "Creating new gradle.properties at path %s.", + "Info_WritingToGradleProperties": "Writing new gradle.properties with added authentication.", + "Info_AddingFederatedFeedAuth": "Adding auth information from federated service connection %s for feed %s", + "Info_SuccessAddingFederatedFeedAuth": "Successfully added auth for feed %s with federated credentials.", + "Error_InvalidServiceConnection": "The service connection for %s is invalid.", + "Error_FailedCleanupGradle": "Failed to delete credentials from the gradle.properties file: %s", + "Error_FailedToGetServiceConnectionAuth": "Unable to get federated credentials from service connection: %s." + }, + "_buildConfigMapping": { + "Default": "0.1.0", + "LocalPackages": "0.249.4", + "wif_242": "0.267.0" + } +} \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0/task.loc.json b/_generated/GradleAuthenticateV0/task.loc.json new file mode 100644 index 000000000000..98a16c342825 --- /dev/null +++ b/_generated/GradleAuthenticateV0/task.loc.json @@ -0,0 +1,99 @@ +{ + "id": "A7E1B7E5-4B8D-4F2C-9A1E-3C5D7F9B2E4A", + "name": "GradleAuthenticate", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Package", + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 1, + "Patch": 0 + }, + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "minimumAgentVersion": "2.144.0", + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "inputs": [ + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "ms-resource:loc.input.label.artifactsFeeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "ms-resource:loc.input.label.gradleServiceConnections", + "helpMarkDown": "ms-resource:loc.input.help.gradleServiceConnections", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ], + "dataSourceBindings": [ + { + "target": "artifactsFeeds", + "endpointId": "tfs:feed", + "endpointUrl": "{{endpoint.url}}/_apis/packaging/feedids", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{name}}}\", \"DisplayValue\" : \"{{{name}}}\" }" + } + ], + "execution": { + "Node10": { + "target": "gradleauth.js" + }, + "Node16": { + "target": "gradleauth.js" + }, + "Node20_1": { + "target": "gradleauth.js", + "argumentFormat": "" + } + }, + "postjobexecution": { + "Node10": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node16": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "cleanup.js", + "argumentFormat": "" + } + }, + "messages": { + "Warning_FeedEntryAlreadyExists": "ms-resource:loc.messages.Warning_FeedEntryAlreadyExists", + "Warning_NoEndpointsToAuth": "ms-resource:loc.messages.Warning_NoEndpointsToAuth", + "Warning_TokenNotGenerated": "ms-resource:loc.messages.Warning_TokenNotGenerated", + "Info_GeneratingExternalRepositories": "ms-resource:loc.messages.Info_GeneratingExternalRepositories", + "Info_GeneratingInternalFeeds": "ms-resource:loc.messages.Info_GeneratingInternalFeeds", + "Info_GradleUserHomeFolderDoesntExist": "ms-resource:loc.messages.Info_GradleUserHomeFolderDoesntExist", + "Info_GradlePropertiesRead": "ms-resource:loc.messages.Info_GradlePropertiesRead", + "Info_CreatingGradleProperties": "ms-resource:loc.messages.Info_CreatingGradleProperties", + "Info_WritingToGradleProperties": "ms-resource:loc.messages.Info_WritingToGradleProperties", + "Info_AddingFederatedFeedAuth": "ms-resource:loc.messages.Info_AddingFederatedFeedAuth", + "Info_SuccessAddingFederatedFeedAuth": "ms-resource:loc.messages.Info_SuccessAddingFederatedFeedAuth", + "Error_InvalidServiceConnection": "ms-resource:loc.messages.Error_InvalidServiceConnection", + "Error_FailedCleanupGradle": "ms-resource:loc.messages.Error_FailedCleanupGradle", + "Error_FailedToGetServiceConnectionAuth": "ms-resource:loc.messages.Error_FailedToGetServiceConnectionAuth" + }, + "_buildConfigMapping": { + "Default": "0.1.0", + "LocalPackages": "0.249.4", + "wif_242": "0.267.0" + } +} \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0/taskJsonOverride.json b/_generated/GradleAuthenticateV0/taskJsonOverride.json new file mode 100644 index 000000000000..e75fe24f3c3d --- /dev/null +++ b/_generated/GradleAuthenticateV0/taskJsonOverride.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": ["azureDevOpsServiceConnection"], + "label": "'Azure DevOps' Service Connection", + "helpMarkDown": "This is an Entra Workload ID-backed Azure DevOps user Service Connection. If this is set, the input gradleServiceConnections will be ignored.", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "Feeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "Credentials for repositories outside this organization/collection", + "helpMarkDown": "Credentials to use for external repositories located in the project's build.gradle.", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ] +} diff --git a/_generated/GradleAuthenticateV0/taskJsonOverride.loc.json b/_generated/GradleAuthenticateV0/taskJsonOverride.loc.json new file mode 100644 index 000000000000..2d8691c36274 --- /dev/null +++ b/_generated/GradleAuthenticateV0/taskJsonOverride.loc.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": ["azureDevOpsServiceConnection"], + "label": "ms-resource:loc.input.label.workloadIdentityServiceConnection", + "helpMarkDown": "ms-resource:loc.input.help.workloadIdentityServiceConnection", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "ms-resource:loc.input.label.artifactsFeeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "ms-resource:loc.input.label.gradleServiceConnections", + "helpMarkDown": "ms-resource:loc.input.help.gradleServiceConnections", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ] +} diff --git a/_generated/GradleAuthenticateV0/tsconfig.json b/_generated/GradleAuthenticateV0/tsconfig.json new file mode 100644 index 000000000000..d8739c3f3a75 --- /dev/null +++ b/_generated/GradleAuthenticateV0/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs" + } +} diff --git a/_generated/GradleAuthenticateV0_Wif/.npmrc b/_generated/GradleAuthenticateV0_Wif/.npmrc new file mode 100644 index 000000000000..d5c7fef620a3 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/.npmrc @@ -0,0 +1,5 @@ +scripts-prepend-node-path=true + +registry=https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ + +always-auth=true \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0_Wif/Strings/resources.resjson/en-US/resources.resjson b/_generated/GradleAuthenticateV0_Wif/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..402004ebcf12 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,25 @@ +{ + "loc.friendlyName": "Gradle Authenticate", + "loc.helpMarkDown": "[Learn more about this task](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate)", + "loc.description": "Provides credentials for Azure Artifacts feeds and external Gradle/Maven repositories", + "loc.instanceNameFormat": "Gradle Authenticate", + "loc.input.label.workloadIdentityServiceConnection": "'Azure DevOps' Service Connection", + "loc.input.help.workloadIdentityServiceConnection": "This is an Entra Workload ID-backed Azure DevOps user Service Connection. If this is set, the input gradleServiceConnections will be ignored.", + "loc.input.label.artifactsFeeds": "Feeds", + "loc.input.label.gradleServiceConnections": "Credentials for repositories outside this organization/collection", + "loc.input.help.gradleServiceConnections": "Credentials to use for external repositories located in the project's build.gradle.", + "loc.messages.Warning_FeedEntryAlreadyExists": "The settings for the feed or repository '%s' already exists in the gradle.properties file.", + "loc.messages.Warning_NoEndpointsToAuth": "No repositories were selected to authenticate, please check your task configuration.", + "loc.messages.Warning_TokenNotGenerated": "Unable to use a federated token", + "loc.messages.Info_GeneratingExternalRepositories": "Generating configs for %s external repositories.", + "loc.messages.Info_GeneratingInternalFeeds": "Generating configs for %s internal feeds.", + "loc.messages.Info_GradleUserHomeFolderDoesntExist": ".gradle folder not found at location %s, creating new folder.", + "loc.messages.Info_GradlePropertiesRead": "Adding authentication to gradle.properties file %s.", + "loc.messages.Info_CreatingGradleProperties": "Creating new gradle.properties at path %s.", + "loc.messages.Info_WritingToGradleProperties": "Writing new gradle.properties with added authentication.", + "loc.messages.Info_AddingFederatedFeedAuth": "Adding auth information from federated service connection %s for feed %s", + "loc.messages.Info_SuccessAddingFederatedFeedAuth": "Successfully added auth for feed %s with federated credentials.", + "loc.messages.Error_InvalidServiceConnection": "The service connection for %s is invalid.", + "loc.messages.Error_FailedCleanupGradle": "Failed to delete credentials from the gradle.properties file: %s", + "loc.messages.Error_FailedToGetServiceConnectionAuth": "Unable to get federated credentials from service connection: %s." +} \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/L0.ts b/_generated/GradleAuthenticateV0_Wif/Tests/L0.ts new file mode 100644 index 000000000000..b56658ce6cdf --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/L0.ts @@ -0,0 +1,158 @@ +import fs = require("fs"); +import assert = require("assert"); +import path = require("path"); +import * as tl from "azure-pipelines-task-lib/task"; +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); +const gradlePropertiesOtherFeedName = path.join(__dirname, "Samples", "gradlePropertiesOtherFeedName.properties"); +const gradlePropertiesFeedName1 = path.join(__dirname, "Samples", "gradlePropertiesFeedName1.properties"); + +const usernameRegex = /Username=/mig; +const passwordRegex = /Password=/mig; + +describe("authenticate azure artifacts feeds for gradle", function() { + this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000); + var env; + + this.beforeAll(async () => { + env = Object.assign({}, process.env); + process.env["USERPROFILE"] = testUserHomeDir; + process.env["HOME"] = testUserHomeDir; + }); + + beforeEach(async () => { + tl.mkdirP(gradleDirPath); + }) + + this.afterAll(async () => { + process.env = env; + }) + + afterEach(async () => { + tl.rmRF(gradleDirPath); + }); + + it("it should create a new gradle.properties in the .gradle folder and add auth for 1 feed.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradleProperties.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be created."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 1, "Only one username entry should be created."); + assert.equal(data.match(passwordRegex).length, 1, "Only one password entry should be created."); + assert(data.includes("feedName1Username="), "feedName1Username entry should be present."); + assert(data.includes("feedName1Password="), "feedName1Password entry should be present."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should read the existing gradle.properties and add auth for 1 new feed", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradlePropertiesExists.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + tl.cp(gradlePropertiesOtherFeedName, gradlePropertiesPath); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be present."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 2, "2 username entries should be present."); + assert.equal(data.match(passwordRegex).length, 2, "2 password entries should be present."); + assert(data.includes("feedName1Username="), "feedName1Username entry should be present."); + assert(data.includes("otherFeedNameUsername="), "otherFeedNameUsername entry should not be deleted."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should read the existing gradle.properties and not add any new entries.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0AuthGradlePropertiesExists.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + tl.cp(gradlePropertiesFeedName1, gradlePropertiesPath); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be present."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 1, "Only one username entry should be present."); + assert.equal(data.match(passwordRegex).length, 1, "Only one password entry should be present."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.stdOutContained("vso[task.issue type=warning;source=TaskInternal;]loc_mock_Warning_FeedEntryAlreadyExists"), "Entry already exists warning should be displayed"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should create a new gradle.properties in the .gradle folder and add auth for 2 different types of service connections.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0ServiceConnections.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 1, "Should have one file."); + const gradlePropertiesStats = tl.stats(gradlePropertiesPath); + assert(gradlePropertiesStats && gradlePropertiesStats.isFile(), "gradle.properties file should be created."); + + const data = fs.readFileSync(gradlePropertiesPath, 'utf-8'); + + assert.equal(data.match(usernameRegex).length, 2, "2 username entries should be created."); + assert.equal(data.match(passwordRegex).length, 2, "2 password entries should be created."); + + assert(data.includes("tokenBasedUsername=AzureDevOps"), "tokenBased username should be AzureDevOps."); + assert(data.includes("tokenBasedPassword=--token--"), "tokenBased password should be the token."); + + assert(data.includes("usernamePasswordBasedUsername=--testUserName--"), "usernamePasswordBased username should be set."); + assert(data.includes("usernamePasswordBasedPassword=--testPassword--"), "usernamePasswordBased password should be set."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + }); + + it("it should warn if no inputs are provided.", async () => { + this.timeout(1000); + + let tp: string = path.join(__dirname, "L0EmptyInput.js"); + + let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); + + await tr.runAsync(); + + assert.equal(tl.ls(null, [gradleDirPath]).length, 0, "gradle.properties file should not be created."); + + assert(tr.stderr.length === 0, "should not have written to stderr"); + assert(tr.succeeded, "task should have succeeded"); + assert(tr.stdOutContained("vso[task.issue type=warning;source=TaskInternal;]loc_mock_Warning_NoEndpointsToAuth"), "The no endpoints warning should be displayed"); + }); +}); diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradleProperties.ts b/_generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradleProperties.ts new file mode 100644 index 000000000000..d54552049149 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradleProperties.ts @@ -0,0 +1,36 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", "feedName1"); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: false, + [gradlePropertiesPath]: false + } +}); + +tr.run(); diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradlePropertiesExists.ts b/_generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradlePropertiesExists.ts new file mode 100644 index 000000000000..9af008259a49 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/L0AuthGradlePropertiesExists.ts @@ -0,0 +1,36 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", "feedName1"); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: true, + [gradlePropertiesPath]: true + } +}); + +tr.run(); diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/L0EmptyInput.ts b/_generated/GradleAuthenticateV0_Wif/Tests/L0EmptyInput.ts new file mode 100644 index 000000000000..07118ca600ec --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/L0EmptyInput.ts @@ -0,0 +1,25 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +// Set inputs +tr.setInput("artifactsFeeds", ""); +tr.setInput("verbosity", "verbose"); +tr.setInput("gradleServiceConnections", ""); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +tr.setAnswers({ + osType: { + "osType": "Windows NT" + } +}); + +tr.run(); diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/L0ServiceConnections.ts b/_generated/GradleAuthenticateV0_Wif/Tests/L0ServiceConnections.ts new file mode 100644 index 000000000000..b245ad099e91 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/L0ServiceConnections.ts @@ -0,0 +1,56 @@ +import tmrm = require("azure-pipelines-task-lib/mock-run"); +import path = require("path"); + +let taskPath = path.join(__dirname, "..", "gradleauth.js"); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +const testUserHomeDir = path.join(__dirname, "USER_HOME"); +const gradleDirName = ".gradle" +const gradleDirPath = path.join(testUserHomeDir, gradleDirName); +const gradlePropertiesName = "gradle.properties"; +const gradlePropertiesPath = path.join(gradleDirPath, gradlePropertiesName); + +// Set inputs +tr.setInput("artifactsFeeds", ""); +tr.setInput("gradleServiceConnections", "tokenBased,usernamePasswordBased"); +tr.setInput("verbosity", "verbose"); + +let mockApi = { + getSystemAccessToken: () => { + return "token"; + } +}; +tr.registerMock('azure-pipelines-tasks-artifacts-common/webapi', mockApi); + +process.env["ENDPOINT_URL_tokenBased"] = "https://endpoint"; +process.env["ENDPOINT_DATA_tokenBased_REPOSITORYID"] = "tokenBased"; +process.env["ENDPOINT_AUTH_SCHEME_tokenBased"] = "token"; +process.env["ENDPOINT_AUTH_tokenBased"] = JSON.stringify({ + "parameters": { + "apitoken": "--token--" + } +}); + +process.env["ENDPOINT_URL_usernamePasswordBased"] = "https://endpoint"; +process.env["ENDPOINT_DATA_usernamePasswordBased_REPOSITORYID"] = "usernamePasswordBased"; +process.env["ENDPOINT_AUTH_SCHEME_usernamePasswordBased"] = "usernamepassword"; +process.env["ENDPOINT_AUTH_usernamePasswordBased"] = JSON.stringify({ + "parameters": { + "username": "--testUserName--", + "password": "--testPassword--" + } +}); + +// provide answers for task mock +tr.setAnswers({ + osType: { + "osType": "Windows NT" + }, + exist: { + [gradleDirPath]: false, + [gradlePropertiesPath]: false + } +}); + + +tr.run(); diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesFeedName1.properties b/_generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesFeedName1.properties new file mode 100644 index 000000000000..1649ae03a207 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesFeedName1.properties @@ -0,0 +1,3 @@ +# Azure Artifacts credentials for feedName1 +feedName1Username=AzureDevOps +feedName1Password=existingToken diff --git a/_generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesOtherFeedName.properties b/_generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesOtherFeedName.properties new file mode 100644 index 000000000000..e079032c0599 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/Tests/Samples/gradlePropertiesOtherFeedName.properties @@ -0,0 +1,3 @@ +# Azure Artifacts credentials for otherFeedName +otherFeedNameUsername=AzureDevOps +otherFeedNamePassword=existingToken diff --git a/_generated/GradleAuthenticateV0_Wif/cleanup.ts b/_generated/GradleAuthenticateV0_Wif/cleanup.ts new file mode 100644 index 000000000000..93052513b45b --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/cleanup.ts @@ -0,0 +1,25 @@ +import * as path from 'path'; +import * as tl from 'azure-pipelines-task-lib/task'; + +async function run() { + try { + tl.setResourcePath(path.join(__dirname, 'task.json')); + + const userGradlePropertiesPath: string = tl.getTaskVariable('userGradlePropertiesPath'); + const backupUserGradlePropertiesFilePath: string = tl.getTaskVariable('backupUserGradlePropertiesFilePath'); + + if (userGradlePropertiesPath && tl.exist(userGradlePropertiesPath)) { + tl.rmRF(userGradlePropertiesPath); + tl.debug('Deleted user gradle.properties file: ' + userGradlePropertiesPath); + + if (backupUserGradlePropertiesFilePath && tl.exist(backupUserGradlePropertiesFilePath)) { + tl.mv(backupUserGradlePropertiesFilePath, userGradlePropertiesPath); + tl.debug('Restored old user gradle.properties file: ' + backupUserGradlePropertiesFilePath); + } + } + } catch (err) { + tl.warning(tl.loc('Error_FailedCleanupGradle', err)); + } +} + +run(); diff --git a/_generated/GradleAuthenticateV0_Wif/gradleauth.ts b/_generated/GradleAuthenticateV0_Wif/gradleauth.ts new file mode 100644 index 000000000000..d0b7ad8d4c7f --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/gradleauth.ts @@ -0,0 +1,116 @@ +import tl = require('azure-pipelines-task-lib/task'); +import util = require('./gradleutils'); + +import * as path from 'path'; +import { emitTelemetry } from 'azure-pipelines-tasks-artifacts-common/telemetry'; + +import { getFederatedWorkloadIdentityCredentials, getFeedTenantId } from "azure-pipelines-tasks-artifacts-common/EntraWifUserServiceConnectionUtils"; + +const GradleFolderName: string = ".gradle"; +const GradlePropertiesName: string = "gradle.properties"; +const backupGradlePropertiesName: string = "_gradle.properties"; + +tl.setResourcePath(path.join(__dirname, 'task.json')); + +async function run(): Promise { + let internalFeedCredentials: any[] = []; + let externalServiceEndpointsCredentials: any[] = []; + let federatedFeedAuthSuccessCount: number = 0; + try { + let userGradleFolderPath: string = ""; + + if (tl.osType().match(/^Win/)) { + userGradleFolderPath = path.join(process.env.USERPROFILE, GradleFolderName); + } else { + userGradleFolderPath = path.join(process.env.HOME, GradleFolderName); + } + + if (!tl.exist(userGradleFolderPath)) { + tl.debug(tl.loc("Info_GradleUserHomeFolderDoesntExist", userGradleFolderPath)); + tl.mkdirP(userGradleFolderPath); + } + + let userGradlePropertiesPath: string = path.join(userGradleFolderPath, GradlePropertiesName); + let backupGradlePropertiesPath: string = path.join(userGradleFolderPath, backupGradlePropertiesName); + let propertiesContent: string = ""; + + tl.setTaskVariable('userGradlePropertiesPath', userGradlePropertiesPath); + + if (tl.exist(userGradlePropertiesPath)) { + tl.debug(tl.loc("Info_GradlePropertiesRead", userGradlePropertiesPath)); + if (!tl.getVariable('FIRST_RUN_GRADLE_PROPERTIES_EXISTS_PATH') && !tl.exist(backupGradlePropertiesPath)) { + tl.cp(userGradlePropertiesPath, backupGradlePropertiesPath); + tl.setTaskVariable("backupUserGradlePropertiesFilePath", backupGradlePropertiesPath); + } + propertiesContent = util.readGradlePropertiesFile(userGradlePropertiesPath); + } + else { + tl.debug(tl.loc("Info_CreatingGradleProperties", userGradlePropertiesPath)); + tl.setVariable('FIRST_RUN_GRADLE_PROPERTIES_EXISTS_PATH', userGradlePropertiesPath); + } + + const entraWifServiceConnectionName = tl.getInput("workloadIdentityServiceConnection"); + const feedIdNames = tl.getDelimitedInput("artifactsFeeds", ','); + + if (entraWifServiceConnectionName) { + + if (feedIdNames.length === 0) { + tl.warning(tl.loc("Warning_NoEndpointsToAuth")); + } + + tl.debug(tl.loc("Info_AddingFederatedFeedAuth", entraWifServiceConnectionName)); + let token = await getFederatedWorkloadIdentityCredentials(entraWifServiceConnectionName); + + if (token) { + + for (let feedName of feedIdNames) { + const credential = { + id: feedName, + username: entraWifServiceConnectionName, + password: token + }; + + propertiesContent = util.addCredentialToGradleProperties(propertiesContent, credential); + federatedFeedAuthSuccessCount++; + console.log(tl.loc("Info_SuccessAddingFederatedFeedAuth", feedName)); + } + + tl.debug(tl.loc("Info_WritingToGradleProperties")); + util.writeGradlePropertiesFile(userGradlePropertiesPath, propertiesContent); + + } + else { + tl.warning(tl.loc("Warning_TokenNotGenerated")); + } + return; + } + + internalFeedCredentials = util.getInternalFeedsCredentials("artifactsFeeds"); + externalServiceEndpointsCredentials = util.getExternalServiceEndpointsCredentials("gradleServiceConnections"); + const newCredentials = internalFeedCredentials.concat(externalServiceEndpointsCredentials); + + if(newCredentials.length === 0) { + tl.warning(tl.loc("Warning_NoEndpointsToAuth")); + return; + } + + for (let credential of newCredentials) { + propertiesContent = util.addCredentialToGradleProperties(propertiesContent, credential); + }; + + tl.debug(tl.loc("Info_WritingToGradleProperties")); + util.writeGradlePropertiesFile(userGradlePropertiesPath, propertiesContent); + } + catch (err) { + tl.setResult(tl.TaskResult.Failed, err.message); + } + finally { + emitTelemetry("Packaging", "GradleAuthenticate", { + "InternalFeedAuthCount": internalFeedCredentials.length, + "ExternalRepoAuthCount": externalServiceEndpointsCredentials.length, + "FederatedFeedAuthCount": federatedFeedAuthSuccessCount + }); + } +} + +run(); diff --git a/_generated/GradleAuthenticateV0_Wif/gradleutils.ts b/_generated/GradleAuthenticateV0_Wif/gradleutils.ts new file mode 100644 index 000000000000..6cc4bd9ed891 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/gradleutils.ts @@ -0,0 +1,164 @@ +import fs = require('fs'); +import tl = require('azure-pipelines-task-lib/task'); +import path = require('path'); +import { getSystemAccessToken } from 'azure-pipelines-tasks-artifacts-common/webapi' + +import * as os from 'os'; +import * as fse from 'fs-extra'; + +import { getPackagingServiceConnections, ServiceConnectionAuthType, UsernamePasswordServiceConnection, TokenServiceConnection, PrivateKeyServiceConnection } from "azure-pipelines-tasks-artifacts-common/serviceConnectionUtils"; + +export interface GradleCredential { + id: string; + username: string; + password: string; +} + +/** + * Sanitizes a feed/repository name to be used as a Gradle property key + * Gradle properties use alphanumeric, dots, and underscores + */ +export function sanitizePropertyKey(name: string): string { + return name.replace(/[^a-zA-Z0-9._-]/g, '_'); +} + +export function getInternalFeedsCredentials(input: string): GradleCredential[] { + const feeds: string[] = tl.getDelimitedInput(input, ",", false); + var credentials: GradleCredential[] = []; + + if (!feeds || feeds.length === 0) + { + return credentials; + } + + tl.debug(tl.loc('Info_GeneratingInternalFeeds', feeds.length)); + for (let feed of feeds) { + credentials.push({ + id: feed, + username: "AzureDevOps", + password: getSystemAccessToken() + }); + } + + return credentials; +} + +export function getExternalServiceEndpointsCredentials(input: string): GradleCredential[] { + var serviceConnections = getPackagingServiceConnections(input, ["REPOSITORYID"]); + var credentials: GradleCredential[] = []; + if (!serviceConnections || serviceConnections.length === 0) + { + return credentials; + } + + tl.debug(tl.loc("Info_GeneratingExternalRepositories", serviceConnections.length)); + for(let serviceConnection of serviceConnections) { + switch (serviceConnection.authType) { + case (ServiceConnectionAuthType.UsernamePassword): + const usernamePasswordAuthInfo = serviceConnection as UsernamePasswordServiceConnection; + + credentials.push({ + id: serviceConnection.additionalData["REPOSITORYID"], + username: usernamePasswordAuthInfo.username, + password: usernamePasswordAuthInfo.password, + }); + + tl.debug(`Detected username/password credentials for '${serviceConnection.packageSource.uri}'`); + break; + case (ServiceConnectionAuthType.Token): + const tokenAuthInfo = serviceConnection as TokenServiceConnection; + credentials.push({ + id: serviceConnection.additionalData["REPOSITORYID"], + username: "AzureDevOps", + password: tokenAuthInfo.token + }); + tl.debug(`Detected token credentials for '${serviceConnection.packageSource.uri}'`); + break; + case (ServiceConnectionAuthType.PrivateKey): + // Gradle doesn't natively support private key auth like Maven, use as password + const privateKeyAuthInfo = serviceConnection as PrivateKeyServiceConnection; + tl.warning(`Private key authentication is not supported for Gradle. Skipping '${serviceConnection.packageSource.uri}'`); + break; + default: + throw Error(tl.loc('Error_InvalidServiceConnection', serviceConnection.packageSource.uri)); + } + } + + return credentials; +} + +export function readGradlePropertiesFile(filePath: string): string { + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath, 'utf-8'); + } + return ""; +} + +export function writeGradlePropertiesFile(filePath: string, content: string): void { + fse.mkdirpSync(path.dirname(filePath)); + fs.writeFileSync(filePath, content, { encoding: 'utf-8' }); +} + +/** + * Checks if a credential already exists in the gradle.properties content + */ +export function credentialExists(propertiesContent: string, id: string): boolean { + const sanitizedId = sanitizePropertyKey(id); + const usernameKey = `${sanitizedId}Username`; + const passwordKey = `${sanitizedId}Password`; + + // Check if either username or password property already exists + const lines = propertiesContent.split(/\r?\n/); + for (const line of lines) { + const trimmedLine = line.trim(); + if (trimmedLine.startsWith(usernameKey + '=') || trimmedLine.startsWith(passwordKey + '=')) { + return true; + } + } + return false; +} + +/** + * Adds a credential entry to gradle.properties content + * Gradle credentials are stored as properties that can be referenced in build.gradle: + * + * feedNameUsername=AzureDevOps + * feedNamePassword=token_value + * + * In build.gradle, these can be used like: + * repositories { + * maven { + * url "https://pkgs.dev.azure.com/org/project/_packaging/feedName/maven/v1" + * credentials { + * username = project.findProperty("feedNameUsername") ?: "" + * password = project.findProperty("feedNamePassword") ?: "" + * } + * } + * } + */ +export function addCredentialToGradleProperties(propertiesContent: string, credential: GradleCredential): string { + const sanitizedId = sanitizePropertyKey(credential.id); + + // Check if credential already exists + if (credentialExists(propertiesContent, credential.id)) { + tl.warning(tl.loc('Warning_FeedEntryAlreadyExists', credential.id)); + tl.debug('Entry: ' + credential.id); + return propertiesContent; + } + + const usernameEntry = `${sanitizedId}Username=${credential.username}`; + const passwordEntry = `${sanitizedId}Password=${credential.password}`; + + // Add newline if content doesn't end with one + let newContent = propertiesContent; + if (newContent.length > 0 && !newContent.endsWith('\n') && !newContent.endsWith('\r\n')) { + newContent += os.EOL; + } + + // Add a comment and the credentials + newContent += `# Azure Artifacts credentials for ${credential.id}${os.EOL}`; + newContent += `${usernameEntry}${os.EOL}`; + newContent += `${passwordEntry}${os.EOL}`; + + return newContent; +} diff --git a/_generated/GradleAuthenticateV0_Wif/make.json b/_generated/GradleAuthenticateV0_Wif/make.json new file mode 100644 index 000000000000..efbe25eff648 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/make.json @@ -0,0 +1,10 @@ +{ + "rm": [ + { + "items": [ + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ] +} diff --git a/_generated/GradleAuthenticateV0_Wif/package-lock.json b/_generated/GradleAuthenticateV0_Wif/package-lock.json new file mode 100644 index 000000000000..07d86b44f66e --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/package-lock.json @@ -0,0 +1,948 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gradleauthenticate", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^20.3.1", + "@types/q": "^1.5.2", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.15.0", + "azure-pipelines-tasks-artifacts-common": "^2.243.1", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/fs-extra/-/fs-extra-8.0.0.tgz", + "integrity": "sha1-0+LDE8op+VBZ8ZjdYNH3dGQtSyU=", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "5.2.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha1-MV1XDMtWxTRS/4Y4c432BybVtuo=", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-20.19.25.tgz", + "integrity": "sha1-Rn2pSi/ZZrV8w5w1ckfWgEdhEZA=", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/q/-/q-1.5.8.tgz", + "integrity": "sha1-lfbGoI8q2Gi6Iw6tHS1/e+PbODc=", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha1-vYakNhffBZR4fTi3NfVcgFvs8bw=", + "license": "MIT" + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha1-C15Md58H3t6lgFzcyxFHBx2UqQk=", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/azure-devops-node-api": { + "version": "14.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-devops-node-api/-/azure-devops-node-api-14.1.0.tgz", + "integrity": "sha1-7FOT3p+hRjmd6qtpBOQdoD7c4YA=", + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "2.1.0" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/azure-pipelines-task-lib": { + "version": "4.17.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.17.3.tgz", + "integrity": "sha1-/VMnGollIKefO6iDOcwLNiv51bk=", + "license": "MIT", + "dependencies": { + "adm-zip": "^0.5.10", + "minimatch": "3.0.5", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.7.2", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common": { + "version": "2.262.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/azure-pipelines-tasks-artifacts-common/-/azure-pipelines-tasks-artifacts-common-2.262.0.tgz", + "integrity": "sha1-iypOdrS7YH3cMWmUoC5MTcb8yAw=", + "license": "MIT", + "dependencies": { + "@types/fs-extra": "8.0.0", + "@types/mocha": "^5.2.6", + "@types/node": "^16.11.39", + "azure-devops-node-api": "^14.0.2", + "azure-pipelines-task-lib": "^4.13.0", + "fs-extra": "8.1.0", + "node-fetch": "^2.7.0", + "semver": "^6.3.1" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/@types/node": { + "version": "16.18.126", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/node/-/node-16.18.126.tgz", + "integrity": "sha1-J4dfqikmwPR1s5qLseVGwBdvjUs=", + "license": "MIT" + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/azure-pipelines-tasks-artifacts-common/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha1-VW0u+GiRRuRtzqS/3QlfNDTf/LQ=", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha1-S1QowiK+mF15w9gmV0edvgtZstY=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha1-I43pNdKippKSjFOMfM+pEGf9Bio=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/debug/-/debug-4.4.3.tgz", + "integrity": "sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha1-HTf1dm87v/Tuljjocah2jBc7gdo=", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha1-165mfh3INIL4tw/Q9u78UNow9Yo=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha1-mD6y+aZyTpMD9hrd8BHHLgngsPo=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha1-BfdaJdq5jk+x3NXhRywFRtUFfI8=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha1-HE8sSDcydZfOadLKGQp/3RcjOME=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha1-d31z1yqS+OxNLkEOtHNSpWuOg0A=", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw=", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha1-dD8OO2lkqTpUke0b/6rgVNf5jQE=", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha1-FQs/J0OGnvPoUewMSdFbHRTQDuE=", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha1-uN8PuAK7+o6JvR2Ti04WV47UTys=", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha1-ifVrghe9vIgCvSmd9tfxCB1+UaE=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha1-QYPk6L8Iu24Fu7L30uDI9xLKQOM=", + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha1-/JxqeDoISVHQuXH+EBjegTcHozg=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha1-AD6vkb563DcuhOxZ3DclLO24AAM=", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha1-xZ7yJKBP6LdU89sAY6Jeow0ABdY=", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4=", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha1-KpiAGoSfQ+Kt1kT7trxiKbGaTvQ=", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-md4": { + "version": "0.3.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha1-zTs9wEWwxARVbIHdtXVsI+WdfPU=", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha1-oN10voHiqlwvJ+Zc4oNgXuTit/k=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha1-u6vNwChZ9JhzAchW4zh85exDv3A=", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha1-OBqHG2KnNEUGYK497uRIE/cNlZo=", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha1-TajxKQ7g8PjoPWDKafjxNAaGBKM=", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/ms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha1-0PD6bj4twdJ+/NitmdVQvalNGH0=", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodejs-file-downloader": { + "version": "4.13.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/nodejs-file-downloader/-/nodejs-file-downloader-4.13.0.tgz", + "integrity": "sha1-2ofDAIHeX/TouGQGLJjN7APmatA=", + "license": "ISC", + "dependencies": { + "follow-redirects": "^1.15.6", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha1-g3UmXiG8IND6WCwi4bE0hdbgAhM=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=", + "license": "MIT" + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/qs/-/qs-6.14.0.tgz", + "integrity": "sha1-xj+kBoDSxclBQSoOiZyJr2DAqTA=", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha1-qthXzh/7i/qbCxrCnxFWOD9owmI=", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha1-dV69dSBFkxl34wsgJdNA18kJA3g=", + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/semver/-/semver-5.7.2.tgz", + "integrity": "sha1-SNVdtzfDKHzUg14X+hP+rOHEHvg=", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha1-3gVUCNg2G+1mxmnS8ABTjO2O4gw=", + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha1-1rtrN5Asb+9RdOX1M/q0xzKib0I=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha1-Ed2hnVNo5Azp7CvcH7DsvAeQ7Oo=", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha1-btpL00SjyUrqN21MwxvHcxEDngk=", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "license": "MIT" + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=", + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/typed-rest-client": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typed-rest-client/-/typed-rest-client-2.1.0.tgz", + "integrity": "sha1-8Exs/KvGASwtA2uAbqrEVWBPFZg=", + "license": "MIT", + "dependencies": { + "des.js": "^1.1.0", + "js-md4": "^0.3.2", + "qs": "^6.10.3", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha1-AvisICttrSwN1eCRN0W0ejeZgnQ=", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha1-lw4zljr5p92iKPF+voOZ5fvmOhA=", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha1-aR0ArzkJvpOn+qE75hs6W1DvEss=", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha1-+fY5ENFVNu4rLV3UZlOJcV6sXB4=", + "license": "(WTFPL OR MIT)" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "license": "ISC" + } + } +} diff --git a/_generated/GradleAuthenticateV0_Wif/package.json b/_generated/GradleAuthenticateV0_Wif/package.json new file mode 100644 index 000000000000..6b328bd07aa3 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/package.json @@ -0,0 +1,31 @@ +{ + "name": "gradleauthenticate", + "version": "0.1.0", + "description": "Azure Pipelines Gradle Authenticate Task", + "main": "gradleauth.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "ISC", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^20.3.1", + "@types/mocha": "^5.2.7", + "@types/uuid": "^8.3.0", + "@types/q": "^1.5.2", + "azure-pipelines-tasks-artifacts-common": "^2.243.1", + "azure-pipelines-task-lib": "^4.15.0", + "fs-extra": "^0.30.0" + }, + "devDependencies": { + "typescript": "5.1.6" + } +} diff --git a/_generated/GradleAuthenticateV0_Wif/task.json b/_generated/GradleAuthenticateV0_Wif/task.json new file mode 100644 index 000000000000..945910eccb6b --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/task.json @@ -0,0 +1,113 @@ +{ + "id": "A7E1B7E5-4B8D-4F2C-9A1E-3C5D7F9B2E4A", + "name": "GradleAuthenticate", + "friendlyName": "Gradle Authenticate", + "description": "Provides credentials for Azure Artifacts feeds and external Gradle/Maven repositories", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate", + "helpMarkDown": "[Learn more about this task](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate)", + "category": "Package", + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 267, + "Patch": 0 + }, + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "minimumAgentVersion": "2.144.0", + "instanceNameFormat": "Gradle Authenticate", + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": [ + "azureDevOpsServiceConnection" + ], + "label": "'Azure DevOps' Service Connection", + "helpMarkDown": "This is an Entra Workload ID-backed Azure DevOps user Service Connection. If this is set, the input gradleServiceConnections will be ignored.", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "Feeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "Credentials for repositories outside this organization/collection", + "helpMarkDown": "Credentials to use for external repositories located in the project's build.gradle.", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ], + "dataSourceBindings": [ + { + "target": "artifactsFeeds", + "endpointId": "tfs:feed", + "endpointUrl": "{{endpoint.url}}/_apis/packaging/feedids", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{name}}}\", \"DisplayValue\" : \"{{{name}}}\" }" + } + ], + "execution": { + "Node10": { + "target": "gradleauth.js" + }, + "Node16": { + "target": "gradleauth.js" + }, + "Node20_1": { + "target": "gradleauth.js", + "argumentFormat": "" + } + }, + "postjobexecution": { + "Node10": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node16": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "cleanup.js", + "argumentFormat": "" + } + }, + "messages": { + "Warning_FeedEntryAlreadyExists": "The settings for the feed or repository '%s' already exists in the gradle.properties file.", + "Warning_NoEndpointsToAuth": "No repositories were selected to authenticate, please check your task configuration.", + "Warning_TokenNotGenerated": "Unable to use a federated token", + "Info_GeneratingExternalRepositories": "Generating configs for %s external repositories.", + "Info_GeneratingInternalFeeds": "Generating configs for %s internal feeds.", + "Info_GradleUserHomeFolderDoesntExist": ".gradle folder not found at location %s, creating new folder.", + "Info_GradlePropertiesRead": "Adding authentication to gradle.properties file %s.", + "Info_CreatingGradleProperties": "Creating new gradle.properties at path %s.", + "Info_WritingToGradleProperties": "Writing new gradle.properties with added authentication.", + "Info_AddingFederatedFeedAuth": "Adding auth information from federated service connection %s for feed %s", + "Info_SuccessAddingFederatedFeedAuth": "Successfully added auth for feed %s with federated credentials.", + "Error_InvalidServiceConnection": "The service connection for %s is invalid.", + "Error_FailedCleanupGradle": "Failed to delete credentials from the gradle.properties file: %s", + "Error_FailedToGetServiceConnectionAuth": "Unable to get federated credentials from service connection: %s." + }, + "_buildConfigMapping": { + "Default": "0.1.0", + "LocalPackages": "0.249.4", + "wif_242": "0.267.0" + } +} \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0_Wif/task.loc.json b/_generated/GradleAuthenticateV0_Wif/task.loc.json new file mode 100644 index 000000000000..61e0e7a794ef --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/task.loc.json @@ -0,0 +1,113 @@ +{ + "id": "A7E1B7E5-4B8D-4F2C-9A1E-3C5D7F9B2E4A", + "name": "GradleAuthenticate", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/package/gradle-authenticate", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Package", + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 267, + "Patch": 0 + }, + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "minimumAgentVersion": "2.144.0", + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": [ + "azureDevOpsServiceConnection" + ], + "label": "ms-resource:loc.input.label.workloadIdentityServiceConnection", + "helpMarkDown": "ms-resource:loc.input.help.workloadIdentityServiceConnection", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "ms-resource:loc.input.label.artifactsFeeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "ms-resource:loc.input.label.gradleServiceConnections", + "helpMarkDown": "ms-resource:loc.input.help.gradleServiceConnections", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ], + "dataSourceBindings": [ + { + "target": "artifactsFeeds", + "endpointId": "tfs:feed", + "endpointUrl": "{{endpoint.url}}/_apis/packaging/feedids", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{name}}}\", \"DisplayValue\" : \"{{{name}}}\" }" + } + ], + "execution": { + "Node10": { + "target": "gradleauth.js" + }, + "Node16": { + "target": "gradleauth.js" + }, + "Node20_1": { + "target": "gradleauth.js", + "argumentFormat": "" + } + }, + "postjobexecution": { + "Node10": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node16": { + "target": "cleanup.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "cleanup.js", + "argumentFormat": "" + } + }, + "messages": { + "Warning_FeedEntryAlreadyExists": "ms-resource:loc.messages.Warning_FeedEntryAlreadyExists", + "Warning_NoEndpointsToAuth": "ms-resource:loc.messages.Warning_NoEndpointsToAuth", + "Warning_TokenNotGenerated": "ms-resource:loc.messages.Warning_TokenNotGenerated", + "Info_GeneratingExternalRepositories": "ms-resource:loc.messages.Info_GeneratingExternalRepositories", + "Info_GeneratingInternalFeeds": "ms-resource:loc.messages.Info_GeneratingInternalFeeds", + "Info_GradleUserHomeFolderDoesntExist": "ms-resource:loc.messages.Info_GradleUserHomeFolderDoesntExist", + "Info_GradlePropertiesRead": "ms-resource:loc.messages.Info_GradlePropertiesRead", + "Info_CreatingGradleProperties": "ms-resource:loc.messages.Info_CreatingGradleProperties", + "Info_WritingToGradleProperties": "ms-resource:loc.messages.Info_WritingToGradleProperties", + "Info_AddingFederatedFeedAuth": "ms-resource:loc.messages.Info_AddingFederatedFeedAuth", + "Info_SuccessAddingFederatedFeedAuth": "ms-resource:loc.messages.Info_SuccessAddingFederatedFeedAuth", + "Error_InvalidServiceConnection": "ms-resource:loc.messages.Error_InvalidServiceConnection", + "Error_FailedCleanupGradle": "ms-resource:loc.messages.Error_FailedCleanupGradle", + "Error_FailedToGetServiceConnectionAuth": "ms-resource:loc.messages.Error_FailedToGetServiceConnectionAuth" + }, + "_buildConfigMapping": { + "Default": "0.1.0", + "LocalPackages": "0.249.4", + "wif_242": "0.267.0" + } +} \ No newline at end of file diff --git a/_generated/GradleAuthenticateV0_Wif/taskJsonOverride.json b/_generated/GradleAuthenticateV0_Wif/taskJsonOverride.json new file mode 100644 index 000000000000..e75fe24f3c3d --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/taskJsonOverride.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": ["azureDevOpsServiceConnection"], + "label": "'Azure DevOps' Service Connection", + "helpMarkDown": "This is an Entra Workload ID-backed Azure DevOps user Service Connection. If this is set, the input gradleServiceConnections will be ignored.", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "Feeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "Credentials for repositories outside this organization/collection", + "helpMarkDown": "Credentials to use for external repositories located in the project's build.gradle.", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ] +} diff --git a/_generated/GradleAuthenticateV0_Wif/taskJsonOverride.loc.json b/_generated/GradleAuthenticateV0_Wif/taskJsonOverride.loc.json new file mode 100644 index 000000000000..2d8691c36274 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/taskJsonOverride.loc.json @@ -0,0 +1,36 @@ +{ + "inputs": [ + { + "name": "workloadIdentityServiceConnection", + "aliases": ["azureDevOpsServiceConnection"], + "label": "ms-resource:loc.input.label.workloadIdentityServiceConnection", + "helpMarkDown": "ms-resource:loc.input.help.workloadIdentityServiceConnection", + "type": "connectedService:workloadidentityuser", + "required": false, + "properties": { + "EditableOptions": "False", + "MultiSelectFlatList": "False" + } + }, + { + "name": "artifactsFeeds", + "type": "pickList", + "label": "ms-resource:loc.input.label.artifactsFeeds", + "defaultValue": "", + "helpMarkdown": "Select one or multiple feeds to authenticate. If workloadIdentityServiceConnection is used, these can be internal or cross-org feed names, otherwise these should just be internal feed names.", + "properties": { + "EditableOptions": "true", + "MultiSelectFlatList": "true" + } + }, + { + "name": "gradleServiceConnections", + "label": "ms-resource:loc.input.label.gradleServiceConnections", + "helpMarkDown": "ms-resource:loc.input.help.gradleServiceConnections", + "type": "connectedService:externalmavenrepository", + "properties": { + "MultiSelectFlatList": "true" + } + } + ] +} diff --git a/_generated/GradleAuthenticateV0_Wif/tsconfig.json b/_generated/GradleAuthenticateV0_Wif/tsconfig.json new file mode 100644 index 000000000000..d8739c3f3a75 --- /dev/null +++ b/_generated/GradleAuthenticateV0_Wif/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs" + } +} From a00bfc0a83f68126e80904fcf8e7e3182009cf52 Mon Sep 17 00:00:00 2001 From: Jordan Kurtz Date: Mon, 8 Dec 2025 14:18:52 -0600 Subject: [PATCH 5/5] Fix codeowner for GradleAuthenticate --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 587cb83e086a..f89c0f26cc0f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -475,4 +475,4 @@ Tasks/XamarinTestCloudV1/ @microsoft/azure-pipelines-tasks-and-agent @tarun Tasks/XcodeV5/ @microsoft/azure-pipelines-tasks-and-agent @tarunramsinghani -Tasks/MavenAuthenticateV0/ @microsoft/azure-artifacts-packages +Tasks/GradleAuthenticateV0/ @microsoft/azure-artifacts-packages