diff --git a/Tasks/DotNetCoreCLIV2/Tests/PushTests/skipDuplicate.ts b/Tasks/DotNetCoreCLIV2/Tests/PushTests/skipDuplicate.ts new file mode 100644 index 000000000000..293725276038 --- /dev/null +++ b/Tasks/DotNetCoreCLIV2/Tests/PushTests/skipDuplicate.ts @@ -0,0 +1,63 @@ +import ma = require('azure-pipelines-task-lib/mock-answer'); +import tmrm = require('azure-pipelines-task-lib/mock-run'); +import path = require('path'); +import util = require('../DotnetMockHelper'); + +let taskPath = path.join(__dirname, '../..', 'dotnetcore.js'); +let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +let nmh: util.DotnetMockHelper = new util.DotnetMockHelper(tmr); +nmh.setNugetVersionInputDefault(); +tmr.setInput('command', 'push'); +tmr.setInput('searchPatternPush', 'foo.nupkg'); +tmr.setInput('nuGetFeedType', 'internal'); +tmr.setInput('feedPublish', 'ProjectId/FeedFooId'); +tmr.setInput('arguments', '--skip-duplicate'); + +let a: ma.TaskLibAnswers = { + "osType": {}, + "checkPath": { + "c:\\agent\\home\\directory\\foo.nupkg": true, + "c:\\path\\dotnet.exe": true + }, + "which": { + "dotnet": "c:\\path\\dotnet.exe" + }, + "exec": { + // First push succeeds + "c:\\path\\dotnet.exe nuget push c:\\agent\\home\\directory\\foo.nupkg --source https://vsts/packagesource --api-key VSTS": { + "code": 0, + "stdout": "dotnet output", + "stderr": "" + }, + // Second push (duplicate) also succeeds due to --skip-duplicate + "c:\\path\\dotnet.exe nuget push c:\\agent\\home\\directory\\foo.nupkg --source https://vsts/packagesource --api-key VSTS --skip-duplicate": { + "code": 0, + "stdout": "Package already exists, skipping due to --skip-duplicate", + "stderr": "" + } + }, + "exist": {}, + "stats": { + "c:\\agent\\home\\directory\\foo.nupkg": { + "isFile": true + } + }, + "rmRF": { + "c:\\agent\\home\\directory\\NuGet_1": { + "success": true + } + }, + "findMatch": { + "fromMockedUtility-foo.nupkg": ["c:\\agent\\home\\directory\\foo.nupkg"] + } +}; +nmh.setAnswers(a); +nmh.registerNugetUtilityMock(["c:\\agent\\home\\directory\\foo.nupkg"]); +nmh.registerDefaultNugetVersionMock(); +nmh.registerToolRunnerMock(); +nmh.registerNugetConfigMock(); +nmh.RegisterLocationServiceMocks(); + +// Simulate pushing the same package twice +tmr.run(); +tmr.run(); \ No newline at end of file diff --git a/Tasks/DotNetCoreCLIV2/package-lock.json b/Tasks/DotNetCoreCLIV2/package-lock.json index d7234645f9f9..18672a09b00e 100644 --- a/Tasks/DotNetCoreCLIV2/package-lock.json +++ b/Tasks/DotNetCoreCLIV2/package-lock.json @@ -1,12 +1,12 @@ { "name": "vsts-tasks-dotnetcoreexe", - "version": "2.129.4", + "version": "2.258.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vsts-tasks-dotnetcoreexe", - "version": "2.129.4", + "version": "2.258.0", "license": "MIT", "dependencies": { "@types/mocha": "^5.2.7", diff --git a/Tasks/DotNetCoreCLIV2/package.json b/Tasks/DotNetCoreCLIV2/package.json index df6b5e0a1ffe..da3621624e03 100644 --- a/Tasks/DotNetCoreCLIV2/package.json +++ b/Tasks/DotNetCoreCLIV2/package.json @@ -1,6 +1,6 @@ { "name": "vsts-tasks-dotnetcoreexe", - "version": "2.129.4", + "version": "2.258.0", "description": "Dotnet core exe", "main": "dotnetcore.js", "scripts": { diff --git a/Tasks/DotNetCoreCLIV2/pushcommand.ts b/Tasks/DotNetCoreCLIV2/pushcommand.ts index 7332420c4e47..93af522b806c 100644 --- a/Tasks/DotNetCoreCLIV2/pushcommand.ts +++ b/Tasks/DotNetCoreCLIV2/pushcommand.ts @@ -80,6 +80,9 @@ export async function run(): Promise { tl.debug(`all URL prefixes: ${urlPrefixes}`); } + // Read arguments so users can specify extra arguments like --skip-duplicate + let dotnetArguments: string = tl.getInput('arguments', false) || ''; + // Setting up auth info let accessToken; const isInternalFeed: boolean = nugetFeedType === 'internal'; @@ -164,14 +167,13 @@ export async function run(): Promise { const dotnetPath = tl.which('dotnet', true); try { for (const packageFile of filesList) { - await dotNetNuGetPushAsync(dotnetPath, packageFile, feedUri, apiKey, configFile, tempNuGetConfigDirectory); + await dotNetNuGetPushAsync(dotnetPath, packageFile, feedUri, apiKey, dotnetArguments, configFile, tempNuGetConfigDirectory); } } finally { credCleanup(); } tl.setResult(tl.TaskResult.Succeeded, tl.loc('PackagesPublishedSuccessfully')); - } catch (err) { tl.error(err); @@ -183,7 +185,7 @@ export async function run(): Promise { } } -function dotNetNuGetPushAsync(dotnetPath: string, packageFile: string, feedUri: string, apiKey: string, configFile: string, workingDirectory: string): Q.Promise { +function dotNetNuGetPushAsync(dotnetPath: string, packageFile: string, feedUri: string, apiKey: string, dotnetArguments: string, configFile: string, workingDirectory: string): Q.Promise { const dotnet = tl.tool(dotnetPath); dotnet.arg('nuget'); @@ -197,6 +199,8 @@ function dotNetNuGetPushAsync(dotnetPath: string, packageFile: string, feedUri: dotnet.arg('--api-key'); dotnet.arg(apiKey); + dotnet.line(dotnetArguments); + // dotnet.exe v1 and v2 do not accept the --verbosity parameter for the "nuget push"" command, although it does for other commands const envWithProxy = ngRunner.setNuGetProxyEnvironment(process.env, /*configFile*/ null, feedUri); return dotnet.exec({ cwd: workingDirectory, env: envWithProxy } as IExecOptions);