From 371f353b26a0a3b17df1105acbf7ebe127b05ae2 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 22 Jul 2019 14:09:59 +0200 Subject: [PATCH 01/44] Fix link of Azure DevOps Windows badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c62429c..58510d8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ and for general information about the Cake build automation system see the [Cake | | Develop | Master | |:--:|:--:|:--:| |AppVeyor Windows|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/master)| -|Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8?branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8?branchName=master)| +|Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| ## Code Coverage From 3962908f4952b4753d6a8760c3fe4ce310d6efa9 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 22 Jul 2019 13:52:54 +0200 Subject: [PATCH 02/44] (GH-119) Build on Ubuntu --- README.md | 1 + azure-pipelines.yml | 12 ++++++- build.sh | 85 ++++++++++++++++++++++++++------------------- setup.cake | 1 + 4 files changed, 63 insertions(+), 36 deletions(-) mode change 100644 => 100755 build.sh diff --git a/README.md b/README.md index 58510d8..a4365e3 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ and for general information about the Cake build automation system see the [Cake |:--:|:--:|:--:| |AppVeyor Windows|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/master)| |Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| +|Azure DevOps Ubuntu|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| ## Code Coverage diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8f395df..85854bb 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -12,5 +12,15 @@ jobs: pool: vmImage: 'vs2017-win2016' steps: - - powershell: ./build.ps1 + - powershell: | + $ENV:CAKE_SKIP_GITVERSION=([string]::IsNullOrEmpty($ENV:SYSTEM_PULLREQUEST_PULLREQUESTID) -eq $False).ToString() + .\build.ps1 + exit $LASTEXITCODE + displayName: 'Cake Build' +- job: Ubuntu + pool: + vmImage: 'ubuntu-16.04' + steps: + - bash: | + ./build.sh displayName: 'Cake Build' \ No newline at end of file diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 index a541ec1..2e3718c --- a/build.sh +++ b/build.sh @@ -1,33 +1,35 @@ #!/usr/bin/env bash -############################################################### -# This is the Cake bootstrapper script that is responsible for -# downloading Cake and all specified tools from NuGet. -############################################################### +########################################################################## +# This is the Cake bootstrapper script for Linux and OS X. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## # Define directories. SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) TOOLS_DIR=$SCRIPT_DIR/tools NUGET_EXE=$TOOLS_DIR/nuget.exe -CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe +NUGET_URL=https://dist.nuget.org/win-x86-commandline/latest/nuget.exe +CAKE_VERSION=0.32.1 +CAKE_EXE=$TOOLS_DIR/Cake.$CAKE_VERSION/Cake.exe + +# Temporarily skip verification of addins. +export CAKE_SETTINGS_SKIPVERIFICATION='true' # Define default arguments. -SCRIPT="setup.cake" TARGET="Default" CONFIGURATION="Release" VERBOSITY="verbose" DRYRUN= -SHOW_VERSION=false SCRIPT_ARGUMENTS=() # Parse arguments. for i in "$@"; do case $1 in - -s|--script) SCRIPT="$2"; shift ;; -t|--target) TARGET="$2"; shift ;; -c|--configuration) CONFIGURATION="$2"; shift ;; -v|--verbosity) VERBOSITY="$2"; shift ;; -d|--dryrun) DRYRUN="-dryrun" ;; - --version) SHOW_VERSION=true ;; --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; *) SCRIPT_ARGUMENTS+=("$1") ;; esac @@ -35,48 +37,61 @@ for i in "$@"; do done # Make sure the tools folder exist. -if [ ! -d $TOOLS_DIR ]; then - mkdir $TOOLS_DIR +if [ ! -d "$TOOLS_DIR" ]; then + mkdir "$TOOLS_DIR" fi -# Make sure that packages.config exist. -if [ ! -f $TOOLS_DIR/packages.config ]; then - echo "Downloading packages.config..." - curl -Lsfo $TOOLS_DIR/packages.config http://cakebuild.net/bootstrapper/packages - if [ $? -ne 0 ]; then - echo "An error occured while downloading packages.config." - exit 1 - fi +########################################################################### +# INSTALL .NET CORE CLI +########################################################################### + +echo "Installing .NET CLI..." +if [ ! -d "$SCRIPT_DIR/.dotnet" ]; then + mkdir "$SCRIPT_DIR/.dotnet" fi +curl -Lsfo "$SCRIPT_DIR/.dotnet/dotnet-install.sh" https://dot.net/v1/dotnet-install.sh +sudo bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --version 2.1.400 --install-dir .dotnet --no-path +export PATH="$SCRIPT_DIR/.dotnet":$PATH +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 +"$SCRIPT_DIR/.dotnet/dotnet" --info + +########################################################################### +# INSTALL NUGET +########################################################################### # Download NuGet if it does not exist. -if [ ! -f $NUGET_EXE ]; then +if [ ! -f "$NUGET_EXE" ]; then echo "Downloading NuGet..." - curl -Lsfo $NUGET_EXE https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + curl -Lsfo "$NUGET_EXE" $NUGET_URL if [ $? -ne 0 ]; then - echo "An error occured while downloading nuget.exe." + echo "An error occurred while downloading nuget.exe." exit 1 fi fi -# Restore tools from NuGet. -pushd $TOOLS_DIR >/dev/null -mono $NUGET_EXE install -ExcludeVersion -PreRelease -Source https://www.myget.org/F/cake/api/v3/index.json -if [ $? -ne 0 ]; then - echo "Could not restore NuGet packages." - exit 1 +########################################################################### +# INSTALL CAKE +########################################################################### + +if [ ! -f "$CAKE_EXE" ]; then + mono "$NUGET_EXE" install Cake -Version $CAKE_VERSION -OutputDirectory "$TOOLS_DIR" + if [ $? -ne 0 ]; then + echo "An error occurred while installing Cake." + exit 1 + fi fi -popd >/dev/null # Make sure that Cake has been installed. -if [ ! -f $CAKE_EXE ]; then +if [ ! -f "$CAKE_EXE" ]; then echo "Could not find Cake.exe at '$CAKE_EXE'." exit 1 fi +########################################################################### +# RUN BUILD SCRIPT +########################################################################### + # Start Cake -if $SHOW_VERSION; then - exec mono $CAKE_EXE -version -else - exec mono $CAKE_EXE $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" -fi +exec mono "$CAKE_EXE" setup.cake --verbosity=$VERBOSITY --configuration=$CONFIGURATION --target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" diff --git a/setup.cake b/setup.cake index 13a5083..fc37fca 100644 --- a/setup.cake +++ b/setup.cake @@ -10,6 +10,7 @@ BuildParameters.SetParameters( repositoryOwner: "cake-contrib", repositoryName: "Cake.Issues.PullRequests.Tfs", appVeyorAccountName: "cakecontrib", + shouldRunGitVersion: true, shouldRunCodecov: false, shouldRunDotNetCorePack: true); From a7eaf4da71889ab053b6670ab3461657b160c6b0 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 22 Jul 2019 14:04:33 +0200 Subject: [PATCH 03/44] (GH-120) Build on macOS --- README.md | 1 + azure-pipelines.yml | 12 ++++++++++++ build.sh | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/README.md b/README.md index a4365e3..9ba1107 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ and for general information about the Cake build automation system see the [Cake |:--:|:--:|:--:| |AppVeyor Windows|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/master)| |Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| +|Azure DevOps macOS|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=macOS)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=macOS)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| |Azure DevOps Ubuntu|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| ## Code Coverage diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 85854bb..133a0f8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -17,6 +17,18 @@ jobs: .\build.ps1 exit $LASTEXITCODE displayName: 'Cake Build' +- job: macOS + pool: + vmImage: 'macOS-10.14' + steps: + # To manually select a Xamarin SDK version on the Hosted macOS agent, enable this script with the SDK version you want to target + # https://go.microsoft.com/fwlink/?linkid=871629 + - bash: | + sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_18_1 + displayName: 'Select Mono 5.18.1' + - bash: | + ./build.sh + displayName: 'Cake Build' - job: Ubuntu pool: vmImage: 'ubuntu-16.04' diff --git a/build.sh b/build.sh index 2e3718c..0cab5b8 100755 --- a/build.sh +++ b/build.sh @@ -41,6 +41,11 @@ if [ ! -d "$TOOLS_DIR" ]; then mkdir "$TOOLS_DIR" fi +# Print Mono version. +echo "Mono version:" +mono --version +echo "" + ########################################################################### # INSTALL .NET CORE CLI ########################################################################### From 85c4d7cfc4cbadef66d2e13a22773c5bb919c234 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 26 Jul 2019 21:46:01 +0200 Subject: [PATCH 04/44] Remove Travis settings --- .travis.yml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index eb79eee..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: csharp -script: - - ./build.sh -v diagnostic -os: - - linux - - osx -cache: - directories: - - packages - - tools From 8230508a713c09739be11470ea6d02c66017ac12 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2019 17:19:47 +0000 Subject: [PATCH 05/44] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.9.3 to 2.9.4 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.9.3 to 2.9.4. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Commits](https://github.com/dotnet/roslyn-analyzers/commits) Signed-off-by: dependabot-preview[bot] --- .../Cake.Issues.PullRequests.Tfs.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj b/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj index 286e829..ee17fa3 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj +++ b/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj @@ -46,7 +46,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin - + From 008c97e47d9c4247f2bab49d5c73b212980067f5 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 15 Aug 2019 11:45:11 +0200 Subject: [PATCH 06/44] Add code owner --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..da37e81 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# These owners will be the default owners for everything in the repo and +# will be requested for review when someone opens a pull request. +* @pascalberger @christianbumann @x-jokay @silanosa @georgesgoetz \ No newline at end of file From d408059cf8fe924bb72335133fb63b5f1fe528c7 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Wed, 6 Sep 2017 20:10:58 +0200 Subject: [PATCH 07/44] Initial version --- examples.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ features.md | 33 +++++++++++++++++++++++ index.cshtml | 12 +++++++++ requirements.md | 11 ++++++++ 4 files changed, 128 insertions(+) create mode 100644 examples.md create mode 100644 features.md create mode 100644 index.cshtml create mode 100644 requirements.md diff --git a/examples.md b/examples.md new file mode 100644 index 0000000..82182ae --- /dev/null +++ b/examples.md @@ -0,0 +1,72 @@ +--- +Order: 30 +Title: Examples +Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. +--- + +## Voting for pull requests + +The [Cake.Issues.PullRequests.Tfs addin] also provides an alias for approving or voting for pull requests. + +:::{.alert .alert-info} +The approve functionality can be used without using the [Cake.Issues addin]. +::: + +The following example will approve a pull request on a Team Foundation Server: + +```csharp +#addin "Cake.Issues.PullRequests.Tfs" + +Task("vote-pullrequest").Does(() => +{ + var pullRequestSettings = + new TfsPullRequestSettings( + new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), + "refs/heads/feature/myfeature", + TfsAuthenticationNtlm()); + + TfsVotePullRequest( + pullRequestSettings, + TfsPullRequestVote.Approved); +}); +``` + +You can also vote based on the issues provided to the [Cake.Issues addin]. + +The following example will mark the pull request as waiting for author if any MsBuild warnings have +occurred and approves the pull request otherwise: + +```csharp +#addin "Cake.Issues" +#addin "Cake.Issues.Issues.MsBuild" +#addin "Cake.Issues.PullRequests" +#addin "Cake.Issues.PullRequests.Tfs" + +Task("ReportIssuesToPullRequest").Does(() => +{ + var repoRootFolder = new DirectoryPath(@"c:\repo"); + var pullRequestSettings = + new TfsPullRequestSettings( + new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), + "refs/heads/feature/myfeature", + TfsAuthenticationNtlm()); + + // Write issues as comments to pull request. + var result = + ReportIssuesToPullRequest( + MsBuildIssuesFromFilePath( + @"c:\build\msbuild.log", + @"c:\repo\docs"), + TfsPullRequests(pullRequestSettings), + repoRootFolder); + + // Vote for pull request. + var vote = result.PostedIssues.Any() ? TfsPullRequestVote.WaitingForAuthor : TfsPullRequestVote.Approved; + TfsVotePullRequest( + pullRequestSettings, + vote); +}); +``` + +[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[Cake.Issues addin]: https://www.nuget.org/packages/Cake.Issues \ No newline at end of file diff --git a/features.md b/features.md new file mode 100644 index 0000000..05b6eaa --- /dev/null +++ b/features.md @@ -0,0 +1,33 @@ +--- +Order: 20 +Title: Features +Description: Features of the Cake.Issues.PullRequests.Tfs addin. +--- +The [Cake.Issues.PullRequests.Tfs addin] provides the following features: + +* Writes issues as comments to Team Foundation Server (TFS) or Visual Studio Team Services (VSTS) pull requests. +* Full support for all [Core features]. +* Supported authentication methods: + * NTLM using the [TfsAuthenticationNtlm] alias. + Can only be used for on-premise Team Foundation Server. + * Basic authentication using the [TfsAuthenticationBasic] alias. + Can only be used for on-premise Team Foundation Server [configured for basic authentication]. + * Personal Access Token using the [TfsAuthenticationPersonalAccessToken] alias. + Can be used for Team Foundation Server or Visual Studio Team Services. + * OAuth using the [TfsAuthenticationOAuth] alias. + Can only be used with Visual Studio Team Services. + * Azure Active Directory using the [TfsAuthenticationAzureActiveDirectory] alias. +* Identification of pull requests through source branch or pull request ID. +* Comments written by the addin will be rendered with a specific icon corresponding to the state of the issue. +* Adds rule number and, if provided by the issue provider, link to the rule description to the comment. +* Support for issues messages formatted in Markdown format. +* Alias for approving or voting pull requests. + +[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[Core features]: ../overview/features#supported-core-functionality +[TfsAuthenticationNtlm]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/7DFCE6F3 +[TfsAuthenticationBasic]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3A473143 +[TfsAuthenticationPersonalAccessToken]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B24D89BD +[TfsAuthenticationOAuth]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BEDAF9BF +[TfsAuthenticationAzureActiveDirectory]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/DF54F8F0 +[configured for basic authentication]: https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/tfs-basic-auth diff --git a/index.cshtml b/index.cshtml new file mode 100644 index 0000000..38619fa --- /dev/null +++ b/index.cshtml @@ -0,0 +1,12 @@ +--- +Title: TFS & VSTS +Description: Support for Team Foundation Server and Visual Studio Team Services. +--- +

@Html.Raw(Model.String(DocsKeys.Description))

+ +

+ Support for Team Foundation Server (TFS) and Visual Studio Team Services (VSTS) is implemented in the + Cake.Issues.PullRequests.Tfs addin. +

+ +@Html.Partial("_ChildPages") \ No newline at end of file diff --git a/requirements.md b/requirements.md new file mode 100644 index 0000000..13aefff --- /dev/null +++ b/requirements.md @@ -0,0 +1,11 @@ +--- +Order: 10 +Title: Requirements +Description: Requirements for the Cake.Issues.PullRequests.Tfs addin. +--- +To use the [Cake.Issues.PullRequests.Tfs addin] the following requirements need to be fulfilled: + +* Cake 0.16.2 or newer. +* Team Foundation Server 2017 or newer or Visual Studio Team Services. + +[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs \ No newline at end of file From 622446c127a4df15188f7e271bd2e13c9cb097fe Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Wed, 13 Sep 2017 17:37:50 +0200 Subject: [PATCH 08/44] Update requirement to Cake 0.22.0 --- requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.md b/requirements.md index 13aefff..73df268 100644 --- a/requirements.md +++ b/requirements.md @@ -5,7 +5,7 @@ Description: Requirements for the Cake.Issues.PullRequests.Tfs addin. --- To use the [Cake.Issues.PullRequests.Tfs addin] the following requirements need to be fulfilled: -* Cake 0.16.2 or newer. +* Cake 0.22.0 or newer. * Team Foundation Server 2017 or newer or Visual Studio Team Services. [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs \ No newline at end of file From e8fb1e88ad8cb88ee4f8f737a532c6b1bfd786da Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 17 Sep 2017 23:00:27 +0200 Subject: [PATCH 09/44] Move example to TFS section --- examples.md | 92 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 21 deletions(-) diff --git a/examples.md b/examples.md index 82182ae..764ae0a 100644 --- a/examples.md +++ b/examples.md @@ -4,6 +4,50 @@ Title: Examples Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. --- +## Using with repository remote url and source branch name + +This example shows how to write issues as comments to a Team Foundation Server (TFS) or +Visual Studio Team Services (VSTS) pull request while using repository information. + +For determing the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: + +```csharp +#addin "Cake.Git" +``` + +To write issues as comments to TFS or VSTS pull requests you need to import the core addin, +the core pull request addin, the TFS/VSTS support and one or more issue provider, in this example +for JetBrains InspectCode: + +```csharp +#addin "Cake.Issues" +#addin "Cake.Issues.InspectCode" +#addin "Cake.Issues.PullRequests" +#addin "Cake.Issues.PullRequests.Tfs" +``` + +In the following task we'll first determine the remote repository URL and +source branch of the pull request and with this information call the [TfsPullRequests] alias: + +```csharp +Task("ReportIssuesToPullRequest").Does(() => +{ + var repoRootFolder = MakeAbsolute(Directory("./")); + var currentBranch = GitBranchCurrent(repoRootFolder); + var repoRemoteUrl = new Uri(currentBranch.Remotes.Single(x => x.Name == "origin").Url); + var sourceBranchName = currentBranch.CanonicalName; + + ReportIssuesToPullRequest( + InspectCodeIssuesFromFilePath( + @"C:\build\inspectcode.log"), + TfsPullRequests( + repoRemoteUrl, + sourceBranchName, + TfsAuthenticationNtlm()), + repoRootFolder); +}); +``` + ## Voting for pull requests The [Cake.Issues.PullRequests.Tfs addin] also provides an alias for approving or voting for pull requests. @@ -17,7 +61,7 @@ The following example will approve a pull request on a Team Foundation Server: ```csharp #addin "Cake.Issues.PullRequests.Tfs" -Task("vote-pullrequest").Does(() => +Task("Vote-PullRequest").Does(() => { var pullRequestSettings = new TfsPullRequestSettings( @@ -33,40 +77,46 @@ Task("vote-pullrequest").Does(() => You can also vote based on the issues provided to the [Cake.Issues addin]. -The following example will mark the pull request as waiting for author if any MsBuild warnings have -occurred and approves the pull request otherwise: +The following example will mark the pull request as waiting for author if any JetBrains InspectCode +warnings have occurred and approves the pull request otherwise: ```csharp +#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools" #addin "Cake.Issues" -#addin "Cake.Issues.Issues.MsBuild" -#addin "Cake.Issues.PullRequests" +#addin "Cake.Issues.Issues.InspectCode" #addin "Cake.Issues.PullRequests.Tfs" -Task("ReportIssuesToPullRequest").Does(() => +var logPath = @"c:\build\inspectcode.xml"; +var repoRootPath = @"c:\repo"; + +Task("Analyze-Project").Does(() => { - var repoRootFolder = new DirectoryPath(@"c:\repo"); - var pullRequestSettings = - new TfsPullRequestSettings( - new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), - "refs/heads/feature/myfeature", - TfsAuthenticationNtlm()); + // Run InspectCode. + var settings = new InspectCodeSettings() { + OutputFile = logPath + }; + + InspectCode(repoRootPath.CombineWithFilePath("MySolution.sln"), settings); +}); - // Write issues as comments to pull request. - var result = - ReportIssuesToPullRequest( - MsBuildIssuesFromFilePath( - @"c:\build\msbuild.log", - @"c:\repo\docs"), - TfsPullRequests(pullRequestSettings), - repoRootFolder); +Task("Vote-Pullrequest") +.IsDependentOn("Analyze-Project") +.Does(() => +{ + // Read Issues. + var issues = ReadIssues( + InspectCodeIssuesFromFilePath(logPath), + repoRootPath); // Vote for pull request. - var vote = result.PostedIssues.Any() ? TfsPullRequestVote.WaitingForAuthor : TfsPullRequestVote.Approved; + var vote = issues.Any() ? TfsPullRequestVote.WaitingForAuthor : TfsPullRequestVote.Approved; TfsVotePullRequest( pullRequestSettings, vote); }); ``` +[TfsPullRequests]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/ +[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs [Cake.Issues addin]: https://www.nuget.org/packages/Cake.Issues \ No newline at end of file From eb6dc6409b6a5719d26e10fd0dff2ab16c1319c8 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 25 May 2018 13:15:30 +0200 Subject: [PATCH 10/44] Link requirements to release notes --- requirements.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/requirements.md b/requirements.md index 73df268..31efa10 100644 --- a/requirements.md +++ b/requirements.md @@ -3,9 +3,7 @@ Order: 10 Title: Requirements Description: Requirements for the Cake.Issues.PullRequests.Tfs addin. --- -To use the [Cake.Issues.PullRequests.Tfs addin] the following requirements need to be fulfilled: +The requirements for using the [Cake.Issues.PullRequests.Tfs addin] are listed in the [release notes] for any specific version. -* Cake 0.22.0 or newer. -* Team Foundation Server 2017 or newer or Visual Studio Team Services. - -[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs \ No newline at end of file +[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[release notes]: release-notes \ No newline at end of file From 053fda1017615890d331e3b9e5a9da1f6848bfd2 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 31 May 2018 16:18:07 +0200 Subject: [PATCH 11/44] Start with H1 Otherwise entries won't be added to site TOC --- examples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples.md b/examples.md index 764ae0a..1c31f94 100644 --- a/examples.md +++ b/examples.md @@ -4,7 +4,7 @@ Title: Examples Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. --- -## Using with repository remote url and source branch name +# Using with repository remote url and source branch name This example shows how to write issues as comments to a Team Foundation Server (TFS) or Visual Studio Team Services (VSTS) pull request while using repository information. @@ -48,7 +48,7 @@ Task("ReportIssuesToPullRequest").Does(() => }); ``` -## Voting for pull requests +# Voting for pull requests The [Cake.Issues.PullRequests.Tfs addin] also provides an alias for approving or voting for pull requests. From 8b0b3944eb2c94c6905df51893340cbccc1746d7 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 4 Jun 2018 19:36:08 +0200 Subject: [PATCH 12/44] Fix typos --- examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples.md b/examples.md index 1c31f94..b8cdc44 100644 --- a/examples.md +++ b/examples.md @@ -9,7 +9,7 @@ Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. This example shows how to write issues as comments to a Team Foundation Server (TFS) or Visual Studio Team Services (VSTS) pull request while using repository information. -For determing the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: +To determine the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: ```csharp #addin "Cake.Git" From 0763fd5b372cce44e90a5bbd638f67828280e06e Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Wed, 6 Jun 2018 19:17:23 +0200 Subject: [PATCH 13/44] Fix links --- features.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features.md b/features.md index 05b6eaa..52e1a71 100644 --- a/features.md +++ b/features.md @@ -24,10 +24,10 @@ The [Cake.Issues.PullRequests.Tfs addin] provides the following features: * Alias for approving or voting pull requests. [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs -[Core features]: ../overview/features#supported-core-functionality -[TfsAuthenticationNtlm]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/7DFCE6F3 -[TfsAuthenticationBasic]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3A473143 -[TfsAuthenticationPersonalAccessToken]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B24D89BD -[TfsAuthenticationOAuth]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BEDAF9BF -[TfsAuthenticationAzureActiveDirectory]: ../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/DF54F8F0 +[Core features]: ../../overview/features#supported-core-functionality +[TfsAuthenticationNtlm]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/7DFCE6F3 +[TfsAuthenticationBasic]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3A473143 +[TfsAuthenticationPersonalAccessToken]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B24D89BD +[TfsAuthenticationOAuth]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BEDAF9BF +[TfsAuthenticationAzureActiveDirectory]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/DF54F8F0 [configured for basic authentication]: https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/tfs-basic-auth From 258b081d44bf59b58597fb7fff719bb6fc60c239 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Wed, 6 Jun 2018 21:38:25 +0200 Subject: [PATCH 14/44] Add image for TFS pull request integration --- cake.issues.pullrequests.tfs.png | Bin 0 -> 107013 bytes features.md | 12 +++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 cake.issues.pullrequests.tfs.png diff --git a/cake.issues.pullrequests.tfs.png b/cake.issues.pullrequests.tfs.png new file mode 100644 index 0000000000000000000000000000000000000000..af5eda3c044ccf58e1ad927da9bd0e9fa335b15e GIT binary patch literal 107013 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Ⓢ=i1tBUGR5- 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 ZT)<|cOAHNt*I2#K05oN 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 L)wwd0pCbPWPhKHr literal 0 HcmV?d00001 diff --git a/features.md b/features.md index 52e1a71..c2d33a8 100644 --- a/features.md +++ b/features.md @@ -23,11 +23,13 @@ The [Cake.Issues.PullRequests.Tfs addin] provides the following features: * Support for issues messages formatted in Markdown format. * Alias for approving or voting pull requests. +![Cake.Issues.PullRequests.Tfs](cake.issues.pullrequests.tfs.png "Cake.Issues.PullRequests.Tfs") + [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs [Core features]: ../../overview/features#supported-core-functionality -[TfsAuthenticationNtlm]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/7DFCE6F3 -[TfsAuthenticationBasic]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3A473143 -[TfsAuthenticationPersonalAccessToken]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B24D89BD -[TfsAuthenticationOAuth]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BEDAF9BF -[TfsAuthenticationAzureActiveDirectory]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/DF54F8F0 +[TfsAuthenticationNtlm]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/4E73CD70 +[TfsAuthenticationBasic]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3FA02408 +[TfsAuthenticationPersonalAccessToken]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B7AA9CF6 +[TfsAuthenticationOAuth]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/44032AF4 +[TfsAuthenticationAzureActiveDirectory]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/6826C541 [configured for basic authentication]: https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/tfs-basic-auth From 057434095bf039713377107a4e2c8a014cdd2a18 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 29 Jul 2018 09:50:05 +0200 Subject: [PATCH 15/44] Split examples into separate pages --- examples/index.cshtml | 7 ++++ examples/repository-information.md | 49 ++++++++++++++++++++++++++ examples.md => examples/voting.md | 55 ++---------------------------- 3 files changed, 59 insertions(+), 52 deletions(-) create mode 100644 examples/index.cshtml create mode 100644 examples/repository-information.md rename examples.md => examples/voting.md (53%) diff --git a/examples/index.cshtml b/examples/index.cshtml new file mode 100644 index 0000000..f06460f --- /dev/null +++ b/examples/index.cshtml @@ -0,0 +1,7 @@ +--- +Title: Examples +Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. +--- +

@Html.Raw(Model.String(DocsKeys.Description))

+ +@Html.Partial("_ChildPages") \ No newline at end of file diff --git a/examples/repository-information.md b/examples/repository-information.md new file mode 100644 index 0000000..3ac34a1 --- /dev/null +++ b/examples/repository-information.md @@ -0,0 +1,49 @@ +--- +Order: 10 +Title: Using with repository remote url and source branch name +Description: Examples how to use the Cake.Issues.PullRequests.Tfs addin with repository remote url and source branch name. +--- +This example shows how to write issues as comments to a Team Foundation Server (TFS) or +Visual Studio Team Services (VSTS) pull request while using repository information. + +To determine the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: + +```csharp +#addin "Cake.Git" +``` + +To write issues as comments to TFS or VSTS pull requests you need to import the core addin, +the core pull request addin, the TFS/VSTS support and one or more issue provider, in this example +for JetBrains InspectCode: + +```csharp +#addin "Cake.Issues" +#addin "Cake.Issues.InspectCode" +#addin "Cake.Issues.PullRequests" +#addin "Cake.Issues.PullRequests.Tfs" +``` + +In the following task we'll first determine the remote repository URL and +source branch of the pull request and with this information call the [TfsPullRequests] alias: + +```csharp +Task("ReportIssuesToPullRequest").Does(() => +{ + var repoRootFolder = MakeAbsolute(Directory("./")); + var currentBranch = GitBranchCurrent(repoRootFolder); + var repoRemoteUrl = new Uri(currentBranch.Remotes.Single(x => x.Name == "origin").Url); + var sourceBranchName = currentBranch.CanonicalName; + + ReportIssuesToPullRequest( + InspectCodeIssuesFromFilePath( + @"C:\build\inspectcode.log"), + TfsPullRequests( + repoRemoteUrl, + sourceBranchName, + TfsAuthenticationNtlm()), + repoRootFolder); +}); +``` + +[TfsPullRequests]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/ +[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ \ No newline at end of file diff --git a/examples.md b/examples/voting.md similarity index 53% rename from examples.md rename to examples/voting.md index b8cdc44..a85c89f 100644 --- a/examples.md +++ b/examples/voting.md @@ -1,55 +1,8 @@ --- -Order: 30 -Title: Examples -Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. +Order: 20 +Title: Voting for pull requests +Description: Examples how to approve or vote for pull requests using the Cake.Issues.PullRequests.Tfs addin. --- - -# Using with repository remote url and source branch name - -This example shows how to write issues as comments to a Team Foundation Server (TFS) or -Visual Studio Team Services (VSTS) pull request while using repository information. - -To determine the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: - -```csharp -#addin "Cake.Git" -``` - -To write issues as comments to TFS or VSTS pull requests you need to import the core addin, -the core pull request addin, the TFS/VSTS support and one or more issue provider, in this example -for JetBrains InspectCode: - -```csharp -#addin "Cake.Issues" -#addin "Cake.Issues.InspectCode" -#addin "Cake.Issues.PullRequests" -#addin "Cake.Issues.PullRequests.Tfs" -``` - -In the following task we'll first determine the remote repository URL and -source branch of the pull request and with this information call the [TfsPullRequests] alias: - -```csharp -Task("ReportIssuesToPullRequest").Does(() => -{ - var repoRootFolder = MakeAbsolute(Directory("./")); - var currentBranch = GitBranchCurrent(repoRootFolder); - var repoRemoteUrl = new Uri(currentBranch.Remotes.Single(x => x.Name == "origin").Url); - var sourceBranchName = currentBranch.CanonicalName; - - ReportIssuesToPullRequest( - InspectCodeIssuesFromFilePath( - @"C:\build\inspectcode.log"), - TfsPullRequests( - repoRemoteUrl, - sourceBranchName, - TfsAuthenticationNtlm()), - repoRootFolder); -}); -``` - -# Voting for pull requests - The [Cake.Issues.PullRequests.Tfs addin] also provides an alias for approving or voting for pull requests. :::{.alert .alert-info} @@ -116,7 +69,5 @@ Task("Vote-Pullrequest") }); ``` -[TfsPullRequests]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/ -[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs [Cake.Issues addin]: https://www.nuget.org/packages/Cake.Issues \ No newline at end of file From 7a149b279d61e5a0feac4f026b7fd8478cad8daa Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 18 Aug 2018 19:24:41 +0200 Subject: [PATCH 16/44] Update for pull request system capabilities --- features.md | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/features.md b/features.md index c2d33a8..19bc937 100644 --- a/features.md +++ b/features.md @@ -3,26 +3,37 @@ Order: 20 Title: Features Description: Features of the Cake.Issues.PullRequests.Tfs addin. --- -The [Cake.Issues.PullRequests.Tfs addin] provides the following features: +The [Cake.Issues.PullRequests.Tfs addin] provides the following features. + +# Basic features * Writes issues as comments to Team Foundation Server (TFS) or Visual Studio Team Services (VSTS) pull requests. -* Full support for all [Core features]. -* Supported authentication methods: - * NTLM using the [TfsAuthenticationNtlm] alias. - Can only be used for on-premise Team Foundation Server. - * Basic authentication using the [TfsAuthenticationBasic] alias. - Can only be used for on-premise Team Foundation Server [configured for basic authentication]. - * Personal Access Token using the [TfsAuthenticationPersonalAccessToken] alias. - Can be used for Team Foundation Server or Visual Studio Team Services. - * OAuth using the [TfsAuthenticationOAuth] alias. - Can only be used with Visual Studio Team Services. - * Azure Active Directory using the [TfsAuthenticationAzureActiveDirectory] alias. * Identification of pull requests through source branch or pull request ID. * Comments written by the addin will be rendered with a specific icon corresponding to the state of the issue. * Adds rule number and, if provided by the issue provider, link to the rule description to the comment. * Support for issues messages formatted in Markdown format. * Alias for approving or voting pull requests. +# Supported capabilities + +The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. + +| | Capability | Remarks | +|--------------------------------------------------------------------|--------------------------------|--------------------------------| +| | Checking commit ID | | +| | Discussion threads | | +| | Filtering by modified files | | + +# Supported authentication methods + +| On-Premise Team Foundation Server | Visual Studio Team Services | Authentication method | Alias | Remarks | +|--------------------------------------------------------------------|--------------------------------------------------------------------|--------------------------------|-----------------------------------------|-------------------------------------------------| +| | | NTLM | [TfsAuthenticationNtlm] alias. | | +| | | Basic authentication | [TfsAuthenticationBasic] alias. | See [Configure TFS to use Basic Authentication] | +| | | Personal access token | [TfsAuthenticationPersonalAccessToken] | | +| | | OAuth | [TfsAuthenticationOAuth] | | +| | | Azure Active Directory | [TfsAuthenticationAzureActiveDirectory] | | + ![Cake.Issues.PullRequests.Tfs](cake.issues.pullrequests.tfs.png "Cake.Issues.PullRequests.Tfs") [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs @@ -32,4 +43,4 @@ The [Cake.Issues.PullRequests.Tfs addin] provides the following features: [TfsAuthenticationPersonalAccessToken]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B7AA9CF6 [TfsAuthenticationOAuth]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/44032AF4 [TfsAuthenticationAzureActiveDirectory]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/6826C541 -[configured for basic authentication]: https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/tfs-basic-auth +[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/vsts/integrate/get-started/auth/tfs-basic-auth?view=vsts#configure-tfs-to-use-basic-authentication From 7325dae42b01db35c4feda28db90fb77b021b748 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 24 Aug 2018 12:00:48 +0200 Subject: [PATCH 17/44] Update examples --- examples/pullrequest-id.md | 40 ++++++++++++++++ examples/repository-information.md | 9 ++-- examples/voting.md | 73 ------------------------------ 3 files changed, 45 insertions(+), 77 deletions(-) create mode 100644 examples/pullrequest-id.md delete mode 100644 examples/voting.md diff --git a/examples/pullrequest-id.md b/examples/pullrequest-id.md new file mode 100644 index 0000000..2eb0a5f --- /dev/null +++ b/examples/pullrequest-id.md @@ -0,0 +1,40 @@ +--- +Order: 10 +Title: Using with pull request id +Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with pull request id. +--- +This example shows how to write issues as comments to a Team Foundation Server (TFS) or +Visual Studio Team Services (VSTS) pull request while using pull request id. + +To write issues as comments to TFS or VSTS pull requests you need to import the core addin, +the core pull request addin, the TFS/VSTS support including the Cake TFS addin, and one or more issue providers, +in this example for JetBrains InspectCode: + +```csharp +#addin "Cake.Issues" +#addin "Cake.Issues.InspectCode" +#addin "Cake.Issues.PullRequests" +#addin "Cake.Issues.PullRequests.Tfs" +#addin "Cake.Tfs" +``` + +In the following task we'll first determine the remote repository URL and +source branch of the pull request and with this information call the [TfsPullRequests] alias: + +```csharp +Task("ReportIssuesToPullRequest").Does(() => +{ + var repoRootFolder = MakeAbsolute(Directory("./")); + + ReportIssuesToPullRequest( + InspectCodeIssuesFromFilePath( + @"C:\build\inspectcode.log"), + TfsPullRequests( + repoRemoteUrl, + pullRequestId, + TfsAuthenticationNtlm()), + repoRootFolder); +}); +``` + +[TfsPullRequests]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/ \ No newline at end of file diff --git a/examples/repository-information.md b/examples/repository-information.md index 3ac34a1..bd5e135 100644 --- a/examples/repository-information.md +++ b/examples/repository-information.md @@ -1,7 +1,7 @@ --- -Order: 10 +Order: 20 Title: Using with repository remote url and source branch name -Description: Examples how to use the Cake.Issues.PullRequests.Tfs addin with repository remote url and source branch name. +Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with repository remote url and source branch name. --- This example shows how to write issues as comments to a Team Foundation Server (TFS) or Visual Studio Team Services (VSTS) pull request while using repository information. @@ -13,14 +13,15 @@ To determine the remote repository URL and source branch of the pull request you ``` To write issues as comments to TFS or VSTS pull requests you need to import the core addin, -the core pull request addin, the TFS/VSTS support and one or more issue provider, in this example -for JetBrains InspectCode: +the core pull request addin, the TFS/VSTS support including the Cake TFS addin, and one or more issue providers, +in this example for JetBrains InspectCode: ```csharp #addin "Cake.Issues" #addin "Cake.Issues.InspectCode" #addin "Cake.Issues.PullRequests" #addin "Cake.Issues.PullRequests.Tfs" +#addin "Cake.Tfs" ``` In the following task we'll first determine the remote repository URL and diff --git a/examples/voting.md b/examples/voting.md deleted file mode 100644 index a85c89f..0000000 --- a/examples/voting.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -Order: 20 -Title: Voting for pull requests -Description: Examples how to approve or vote for pull requests using the Cake.Issues.PullRequests.Tfs addin. ---- -The [Cake.Issues.PullRequests.Tfs addin] also provides an alias for approving or voting for pull requests. - -:::{.alert .alert-info} -The approve functionality can be used without using the [Cake.Issues addin]. -::: - -The following example will approve a pull request on a Team Foundation Server: - -```csharp -#addin "Cake.Issues.PullRequests.Tfs" - -Task("Vote-PullRequest").Does(() => -{ - var pullRequestSettings = - new TfsPullRequestSettings( - new Uri("http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository"), - "refs/heads/feature/myfeature", - TfsAuthenticationNtlm()); - - TfsVotePullRequest( - pullRequestSettings, - TfsPullRequestVote.Approved); -}); -``` - -You can also vote based on the issues provided to the [Cake.Issues addin]. - -The following example will mark the pull request as waiting for author if any JetBrains InspectCode -warnings have occurred and approves the pull request otherwise: - -```csharp -#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools" -#addin "Cake.Issues" -#addin "Cake.Issues.Issues.InspectCode" -#addin "Cake.Issues.PullRequests.Tfs" - -var logPath = @"c:\build\inspectcode.xml"; -var repoRootPath = @"c:\repo"; - -Task("Analyze-Project").Does(() => -{ - // Run InspectCode. - var settings = new InspectCodeSettings() { - OutputFile = logPath - }; - - InspectCode(repoRootPath.CombineWithFilePath("MySolution.sln"), settings); -}); - -Task("Vote-Pullrequest") -.IsDependentOn("Analyze-Project") -.Does(() => -{ - // Read Issues. - var issues = ReadIssues( - InspectCodeIssuesFromFilePath(logPath), - repoRootPath); - - // Vote for pull request. - var vote = issues.Any() ? TfsPullRequestVote.WaitingForAuthor : TfsPullRequestVote.Approved; - TfsVotePullRequest( - pullRequestSettings, - vote); -}); -``` - -[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs -[Cake.Issues addin]: https://www.nuget.org/packages/Cake.Issues \ No newline at end of file From 003fce3918ec5708356fd8e1393c8522cb6b26fd Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 24 Aug 2018 12:09:51 +0200 Subject: [PATCH 18/44] Remove alias for voting which is now part of Cake.Tfs --- features.md | 1 - 1 file changed, 1 deletion(-) diff --git a/features.md b/features.md index 19bc937..b38a5ce 100644 --- a/features.md +++ b/features.md @@ -12,7 +12,6 @@ The [Cake.Issues.PullRequests.Tfs addin] provides the following features. * Comments written by the addin will be rendered with a specific icon corresponding to the state of the issue. * Adds rule number and, if provided by the issue provider, link to the rule description to the comment. * Support for issues messages formatted in Markdown format. -* Alias for approving or voting pull requests. # Supported capabilities From b416dd7fe3b5dfa05929aa44629c44ee2b8f6d5f Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 26 Aug 2018 14:59:38 +0200 Subject: [PATCH 19/44] Add documentation for AppVeyor integration --- index.cshtml | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.cshtml b/index.cshtml index 38619fa..a1c26ce 100644 --- a/index.cshtml +++ b/index.cshtml @@ -2,8 +2,6 @@ Title: TFS & VSTS Description: Support for Team Foundation Server and Visual Studio Team Services. --- -

@Html.Raw(Model.String(DocsKeys.Description))

-

Support for Team Foundation Server (TFS) and Visual Studio Team Services (VSTS) is implemented in the Cake.Issues.PullRequests.Tfs addin. From 3819f01b02dffa21bad7dd683957f0f112a25e7f Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 15 Sep 2018 11:35:48 +0200 Subject: [PATCH 20/44] Change VSTS to Azure DevOps --- examples/pullrequest-id.md | 6 +++--- examples/repository-information.md | 6 +++--- features.md | 7 ++++--- index.cshtml | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/examples/pullrequest-id.md b/examples/pullrequest-id.md index 2eb0a5f..4cc4ebc 100644 --- a/examples/pullrequest-id.md +++ b/examples/pullrequest-id.md @@ -4,10 +4,10 @@ Title: Using with pull request id Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with pull request id. --- This example shows how to write issues as comments to a Team Foundation Server (TFS) or -Visual Studio Team Services (VSTS) pull request while using pull request id. +Azure DevOps pull request while using pull request id. -To write issues as comments to TFS or VSTS pull requests you need to import the core addin, -the core pull request addin, the TFS/VSTS support including the Cake TFS addin, and one or more issue providers, +To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, +the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, in this example for JetBrains InspectCode: ```csharp diff --git a/examples/repository-information.md b/examples/repository-information.md index bd5e135..adb51a4 100644 --- a/examples/repository-information.md +++ b/examples/repository-information.md @@ -4,7 +4,7 @@ Title: Using with repository remote url and source branch name Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with repository remote url and source branch name. --- This example shows how to write issues as comments to a Team Foundation Server (TFS) or -Visual Studio Team Services (VSTS) pull request while using repository information. +Azure DevOps pull request while using repository information. To determine the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: @@ -12,8 +12,8 @@ To determine the remote repository URL and source branch of the pull request you #addin "Cake.Git" ``` -To write issues as comments to TFS or VSTS pull requests you need to import the core addin, -the core pull request addin, the TFS/VSTS support including the Cake TFS addin, and one or more issue providers, +To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, +the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, in this example for JetBrains InspectCode: ```csharp diff --git a/features.md b/features.md index b38a5ce..ab3f7ba 100644 --- a/features.md +++ b/features.md @@ -7,7 +7,7 @@ The [Cake.Issues.PullRequests.Tfs addin] provides the following features. # Basic features -* Writes issues as comments to Team Foundation Server (TFS) or Visual Studio Team Services (VSTS) pull requests. +* Writes issues as comments to Team Foundation Server (TFS) or [Azure DevOps] pull requests. * Identification of pull requests through source branch or pull request ID. * Comments written by the addin will be rendered with a specific icon corresponding to the state of the issue. * Adds rule number and, if provided by the issue provider, link to the rule description to the comment. @@ -25,7 +25,7 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. # Supported authentication methods -| On-Premise Team Foundation Server | Visual Studio Team Services | Authentication method | Alias | Remarks | +| On-Premise Team Foundation Server | Azure DevOps | Authentication method | Alias | Remarks | |--------------------------------------------------------------------|--------------------------------------------------------------------|--------------------------------|-----------------------------------------|-------------------------------------------------| | | | NTLM | [TfsAuthenticationNtlm] alias. | | | | | Basic authentication | [TfsAuthenticationBasic] alias. | See [Configure TFS to use Basic Authentication] | @@ -36,10 +36,11 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. ![Cake.Issues.PullRequests.Tfs](cake.issues.pullrequests.tfs.png "Cake.Issues.PullRequests.Tfs") [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[Azure DevOps]: https://azure.microsoft.com/en-us/services/devops/ [Core features]: ../../overview/features#supported-core-functionality [TfsAuthenticationNtlm]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/4E73CD70 [TfsAuthenticationBasic]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3FA02408 [TfsAuthenticationPersonalAccessToken]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B7AA9CF6 [TfsAuthenticationOAuth]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/44032AF4 [TfsAuthenticationAzureActiveDirectory]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/6826C541 -[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/vsts/integrate/get-started/auth/tfs-basic-auth?view=vsts#configure-tfs-to-use-basic-authentication +[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/auth/tfs-basic-auth?view=tfs-2018#configure-tfs-to-use-basic-authentication diff --git a/index.cshtml b/index.cshtml index a1c26ce..4fa97ba 100644 --- a/index.cshtml +++ b/index.cshtml @@ -1,9 +1,9 @@ --- -Title: TFS & VSTS -Description: Support for Team Foundation Server and Visual Studio Team Services. +Title: TFS & Azure DevOps +Description: Support for Team Foundation Server and Azure DevOps. ---

- Support for Team Foundation Server (TFS) and Visual Studio Team Services (VSTS) is implemented in the + Support for Team Foundation Server (TFS) and Azure DevOps is implemented in the Cake.Issues.PullRequests.Tfs addin.

From f96817b89680f3a5707b6eefa7b905e448bae6fe Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 15 Sep 2018 12:07:36 +0200 Subject: [PATCH 21/44] (GH-86) Add link to demo repositories --- examples/index.cshtml | 5 +++++ features.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/examples/index.cshtml b/examples/index.cshtml index f06460f..31b5f6c 100644 --- a/examples/index.cshtml +++ b/examples/index.cshtml @@ -4,4 +4,9 @@ Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. ---

@Html.Raw(Model.String(DocsKeys.Description))

+
+There's a demo repository +available which you can fork and to which you can create pull requests to test the integration functionality. +
+ @Html.Partial("_ChildPages") \ No newline at end of file diff --git a/features.md b/features.md index ab3f7ba..f34d8b1 100644 --- a/features.md +++ b/features.md @@ -5,6 +5,10 @@ Description: Features of the Cake.Issues.PullRequests.Tfs addin. --- The [Cake.Issues.PullRequests.Tfs addin] provides the following features. +:::{.alert .alert-info} +There's a [demo repository] available which you can fork and to which you can create pull requests to test the integration functionality. +::: + # Basic features * Writes issues as comments to Team Foundation Server (TFS) or [Azure DevOps] pull requests. @@ -35,6 +39,7 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. ![Cake.Issues.PullRequests.Tfs](cake.issues.pullrequests.tfs.png "Cake.Issues.PullRequests.Tfs") +[demo repository]: https://dev.azure.com/pberger/Cake.Issues-Demo [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs [Azure DevOps]: https://azure.microsoft.com/en-us/services/devops/ [Core features]: ../../overview/features#supported-core-functionality From 4f25a2f70ac66985d2792134743dfd5a004e0a6b Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 21 Sep 2018 20:34:51 +0200 Subject: [PATCH 22/44] Add instructions how to setup Cake.Issues.PullRequests.Tfs authentication --- features.md | 23 +++++++--------- setup.md | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 setup.md diff --git a/features.md b/features.md index f34d8b1..2502c1b 100644 --- a/features.md +++ b/features.md @@ -29,13 +29,15 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. # Supported authentication methods -| On-Premise Team Foundation Server | Azure DevOps | Authentication method | Alias | Remarks | -|--------------------------------------------------------------------|--------------------------------------------------------------------|--------------------------------|-----------------------------------------|-------------------------------------------------| -| | | NTLM | [TfsAuthenticationNtlm] alias. | | -| | | Basic authentication | [TfsAuthenticationBasic] alias. | See [Configure TFS to use Basic Authentication] | -| | | Personal access token | [TfsAuthenticationPersonalAccessToken] | | -| | | OAuth | [TfsAuthenticationOAuth] | | -| | | Azure Active Directory | [TfsAuthenticationAzureActiveDirectory] | | +| On-Premise Team Foundation Server | Azure DevOps | Authentication method | +|--------------------------------------------------------------------|--------------------------------------------------------------------|--------------------------------| +| | | NTLM | +| | | Basic authentication | +| | | Personal access token | +| | | OAuth | +| | | Azure Active Directory | + +For detailed instructions how to connect using the different methods see [Setup instructions]. ![Cake.Issues.PullRequests.Tfs](cake.issues.pullrequests.tfs.png "Cake.Issues.PullRequests.Tfs") @@ -43,9 +45,4 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs [Azure DevOps]: https://azure.microsoft.com/en-us/services/devops/ [Core features]: ../../overview/features#supported-core-functionality -[TfsAuthenticationNtlm]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/4E73CD70 -[TfsAuthenticationBasic]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/3FA02408 -[TfsAuthenticationPersonalAccessToken]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/B7AA9CF6 -[TfsAuthenticationOAuth]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/44032AF4 -[TfsAuthenticationAzureActiveDirectory]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/6826C541 -[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/auth/tfs-basic-auth?view=tfs-2018#configure-tfs-to-use-basic-authentication +[Setup instructions]: setup \ No newline at end of file diff --git a/setup.md b/setup.md new file mode 100644 index 0000000..8039c0a --- /dev/null +++ b/setup.md @@ -0,0 +1,78 @@ +--- +Order: 30 +Title: Setup +Description: Instructions how to setup the Cake.Issues.PullRequests.Tfs addin. +--- +This page describes the different ways how the [Cake.Issues.PullRequests.Tfs addin] can be setup. + +# NTLM authentication + +:::{.alert .alert-info} +NTLM authentication is only available for on-premise Team Foundation Server. +::: + +To authenticate with NTLM you can use the [TfsAuthenticationNtlm] alias from the [Cake.Tfs addin]. + +The user needs to have `Contribute to pull requests` permission for the specific repository to +allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. + +# Basic authentication + +:::{.alert .alert-info} +Basic authentication is only available for on-premise Team Foundation Server. +::: + +To authenticate with basic authentication you can use the [TfsAuthenticationBasic] alias from the [Cake.Tfs addin] and +need to [Configure TFS to use Basic Authentication]. + +The user needs to have `Contribute to pull requests` permission for the specific repository to +allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. + +# Personal access token + +To authenticate with an personal access token you can use the [TfsAuthenticationPersonalAccessToken] alias from the [Cake.Tfs addin]. + +If you want to use the [Cake.Issues.PullRequests.Tfs addin] with an personal access token see +[Authenticate access with personal access tokens for Azure DevOps Services and TFS] for instructions how to create +a personal access token. + +The access token needs to have the scope `Code (read and write)` set and the user needs to have `Contribute to pull requests` +permission for the specific repository to allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. + +# OAuth authentication from Azure Pipelines + +:::{.alert .alert-info} +OAuth authentication is only available for Azure DevOps. +::: + +If you want to use the [Cake.Issues.PullRequests.Tfs addin] from an Azure Pipelines you can authenticate using the +OAuth token provided to the build. +For this you need to enable the [Allow scripts to access the OAuth token] option on the build definition. + +To authenticate you can use the [TfsAuthenticationOAuth] alias from the [Cake.Tfs addin]. + +The user under which the build runs, named ` Build Service ()` (e.g. `Cake.Issues-Demo Build Service (cake-contrib)`), +needs to have `Contribute to pull requests` permission for the specific repository to allow [Cake.Issues.PullRequests.Tfs addin] +to post issues as comments to pull requests. + +# Azure Active Directory + +:::{.alert .alert-info} +OAuth authentication is only available for Azure DevOps. +::: + +To authenticate with Azure Active Directory you can use the [TfsAuthenticationAzureActiveDirectory] alias from the [Cake.Tfs addin]. + +The user needs to have `Contribute to pull requests` permission for the specific repository to +allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. + +[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[Cake.Tfs addin]: https://www.nuget.org/packages/Cake.Tfs +[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/auth/tfs-basic-auth?view=tfs-2018#configure-tfs-to-use-basic-authentication +[Authenticate access with personal access tokens for Azure DevOps Services and TFS]: https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=vsts +[Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options?view=vsts&tabs=yaml#allow-scripts-to-access-the-oauth-token +[TfsAuthenticationNtlm]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/6989592E +[TfsAuthenticationBasic]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/86407B1D +[TfsAuthenticationPersonalAccessToken]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E4AC3E3 +[TfsAuthenticationOAuth]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/B5D45B5D +[TfsAuthenticationAzureActiveDirectory]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E787800 \ No newline at end of file From 1f4b7a10eb3d1255ec066c54b2434adc49b4f0a5 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 30 Sep 2018 13:47:11 +0200 Subject: [PATCH 23/44] Fix link to TfsPullRequests alias --- examples/repository-information.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/repository-information.md b/examples/repository-information.md index adb51a4..21eda1c 100644 --- a/examples/repository-information.md +++ b/examples/repository-information.md @@ -46,5 +46,5 @@ Task("ReportIssuesToPullRequest").Does(() => }); ``` -[TfsPullRequests]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/ -[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ \ No newline at end of file +[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/8B150084 +[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ From 5f2a9effd2c2cdeb70e524eb2deca0d8e18641d2 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 30 Sep 2018 13:42:47 +0200 Subject: [PATCH 24/44] Complete sample for writing issues to TFS pullrequest using ID --- examples/pullrequest-id.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/pullrequest-id.md b/examples/pullrequest-id.md index 4cc4ebc..00b9e8d 100644 --- a/examples/pullrequest-id.md +++ b/examples/pullrequest-id.md @@ -6,6 +6,12 @@ Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with pull This example shows how to write issues as comments to a Team Foundation Server (TFS) or Azure DevOps pull request while using pull request id. +To determine the remote repository URL you need the [Cake.Git] addin: + +```csharp +#addin "Cake.Git" +``` + To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, in this example for JetBrains InspectCode: @@ -19,12 +25,14 @@ in this example for JetBrains InspectCode: ``` In the following task we'll first determine the remote repository URL and -source branch of the pull request and with this information call the [TfsPullRequests] alias: +with this information call the [TfsPullRequests] alias: ```csharp Task("ReportIssuesToPullRequest").Does(() => { var repoRootFolder = MakeAbsolute(Directory("./")); + var repoRemoteUrl = new Uri(currentBranch.Remotes.Single(x => x.Name == "origin").Url); + var pullRequestId = 123; ReportIssuesToPullRequest( InspectCodeIssuesFromFilePath( @@ -37,4 +45,4 @@ Task("ReportIssuesToPullRequest").Does(() => }); ``` -[TfsPullRequests]: ../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/ \ No newline at end of file +[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C \ No newline at end of file From 4fcb783e71bdca5d91720225cb69061aaffb7e43 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 30 Sep 2018 14:15:15 +0200 Subject: [PATCH 25/44] Add example how to use with Azure Pipelines --- examples/azure-pipelines.md | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 examples/azure-pipelines.md diff --git a/examples/azure-pipelines.md b/examples/azure-pipelines.md new file mode 100644 index 0000000..fd63a5b --- /dev/null +++ b/examples/azure-pipelines.md @@ -0,0 +1,79 @@ +--- +Order: 30 +Title: Using with Azure Pipelines +Description: Example how to use the Cake.Issues.PullRequests.Tfs addin from an Azure Pipelines build. +--- +This example shows how to write issues as comments to a Team Foundation Server (TFS) or +Azure DevOps pull request from an Azure Pipelines build. + +To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, +the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, +in this example for JetBrains InspectCode: + +```csharp +#addin "Cake.Issues" +#addin "Cake.Issues.InspectCode" +#addin "Cake.Issues.PullRequests" +#addin "Cake.Issues.PullRequests.Tfs" +#addin "Cake.Tfs" +``` + +In the following task we'll first determine if the build is running on Azure DevOps and for a pull request, +then read the remote repository URL and pull request id from environment variables set by the Azure Pipelines build +and finally call the [TfsPullRequests] alias using the OAuth token provided by the Azure Pipeline build. + +:::{.alert .alert-info} +Please note that you'll need to setup your Azure Pipelines build to allow scripts to +access the OAuth token and need to setup proper permissions. + +See [OAuth authentication from Azure Pipelines] for details. +::: + +```csharp +Task("ReportIssuesToPullRequest").Does(() => +{ + var isRunningOnAzureDevOps = + !string.IsNullOrWhiteSpace(context.EnvironmentVariable("TF_BUILD")) && + !string.IsNullOrWhiteSpace(context.EnvironmentVariable("SYSTEM_COLLECTIONURI")) && + ( + new Uri(context.EnvironmentVariable("SYSTEM_COLLECTIONURI")).Host == "dev.azure.com" || + new Uri(context.EnvironmentVariable("SYSTEM_COLLECTIONURI")).Host.EndsWith("visualstudio.com") + ); + + var isPullRequestBuild = + !string.IsNullOrWhiteSpace(context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID")); + + if (isRunningOnAzureDevOps) + { + var repositoryUrl = new Uri(context.EnvironmentVariable("BUILD_REPOSITORY_URI")); + + if (isPullRequestBuild) + { + if (!Int32.TryParse(context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID"), out var pullRequestId)) + { + throw new Exception( + string.Format( + "Invalid pull request ID: {0}", + context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID"))); + } + else + { + var repoRootFolder = MakeAbsolute(Directory("./")); + + ReportIssuesToPullRequest( + InspectCodeIssuesFromFilePath( + @"C:\build\inspectcode.log"), + TfsPullRequests( + repositoryUrl, + pullRequestId, + TfsAuthenticationOAuth(EnvironmentVariable("SYSTEM_ACCESSTOKEN"))), + repoRootFolder); + } + } + } +}); +``` + +[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C +[Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options?view=vsts&tabs=yaml#allow-scripts-to-access-the-oauth-token +[OAuth authentication from Azure Pipelines]: ../setup#oauth-authentication-from-azure-pipelines \ No newline at end of file From 81da8a624f89ceb745b09df54cd797db4430a8b3 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 30 Sep 2018 14:48:53 +0200 Subject: [PATCH 26/44] Add note about addin pinning --- examples/azure-pipelines.md | 7 +++++++ examples/pullrequest-id.md | 7 +++++++ examples/repository-information.md | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/examples/azure-pipelines.md b/examples/azure-pipelines.md index fd63a5b..7b04183 100644 --- a/examples/azure-pipelines.md +++ b/examples/azure-pipelines.md @@ -18,6 +18,13 @@ in this example for JetBrains InspectCode: #addin "Cake.Tfs" ``` +:::{.alert .alert-warning} +Please note that you always should pin addins to a specific version to make sure your builds are deterministic and +won't break due to updates to one of the addins. + +See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-version#pinning-addin-version) for details. +::: + In the following task we'll first determine if the build is running on Azure DevOps and for a pull request, then read the remote repository URL and pull request id from environment variables set by the Azure Pipelines build and finally call the [TfsPullRequests] alias using the OAuth token provided by the Azure Pipeline build. diff --git a/examples/pullrequest-id.md b/examples/pullrequest-id.md index 00b9e8d..36c31e5 100644 --- a/examples/pullrequest-id.md +++ b/examples/pullrequest-id.md @@ -24,6 +24,13 @@ in this example for JetBrains InspectCode: #addin "Cake.Tfs" ``` +:::{.alert .alert-warning} +Please note that you always should pin addins to a specific version to make sure your builds are deterministic and +won't break due to updates to one of the addins. + +See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-version#pinning-addin-version) for details. +::: + In the following task we'll first determine the remote repository URL and with this information call the [TfsPullRequests] alias: diff --git a/examples/repository-information.md b/examples/repository-information.md index 21eda1c..74a7aba 100644 --- a/examples/repository-information.md +++ b/examples/repository-information.md @@ -24,6 +24,13 @@ in this example for JetBrains InspectCode: #addin "Cake.Tfs" ``` +:::{.alert .alert-warning} +Please note that you always should pin addins to a specific version to make sure your builds are deterministic and +won't break due to updates to one of the addins. + +See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-version#pinning-addin-version) for details. +::: + In the following task we'll first determine the remote repository URL and source branch of the pull request and with this information call the [TfsPullRequests] alias: From d5baf7ad0ccff5db35088d66cb3cb02e9b8b7664 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 30 Sep 2018 18:58:43 +0200 Subject: [PATCH 27/44] Make clear that some examples are for on-premise TFS --- examples/pullrequest-id.md | 3 ++- examples/repository-information.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/pullrequest-id.md b/examples/pullrequest-id.md index 36c31e5..c5d99a3 100644 --- a/examples/pullrequest-id.md +++ b/examples/pullrequest-id.md @@ -32,7 +32,8 @@ See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-v ::: In the following task we'll first determine the remote repository URL and -with this information call the [TfsPullRequests] alias: +with this information call the [TfsPullRequests] alias, +which will authenticate through NTLM to a on-premise TFS instance: ```csharp Task("ReportIssuesToPullRequest").Does(() => diff --git a/examples/repository-information.md b/examples/repository-information.md index 74a7aba..a31c159 100644 --- a/examples/repository-information.md +++ b/examples/repository-information.md @@ -32,7 +32,8 @@ See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-v ::: In the following task we'll first determine the remote repository URL and -source branch of the pull request and with this information call the [TfsPullRequests] alias: +source branch of the pull request and with this information call the [TfsPullRequests] alias, +which will authenticate through NTLM to a on-premise TFS instance: ```csharp Task("ReportIssuesToPullRequest").Does(() => From 1327b39eb45e29caae3466e138c7d2c6b1f266db Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Wed, 6 Feb 2019 12:17:32 +0100 Subject: [PATCH 28/44] Add missing link to Cake.Git package --- examples/pullrequest-id.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/pullrequest-id.md b/examples/pullrequest-id.md index c5d99a3..0da1bdf 100644 --- a/examples/pullrequest-id.md +++ b/examples/pullrequest-id.md @@ -53,4 +53,5 @@ Task("ReportIssuesToPullRequest").Does(() => }); ``` -[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C \ No newline at end of file +[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C +[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ \ No newline at end of file From 3753a9dcc82ba8de017ee27ab3701945fc6c113d Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 15 Aug 2019 18:27:45 +0200 Subject: [PATCH 29/44] Move documentation to docs folder --- .../cake.issues.pullrequests.tfs.png | Bin {examples => docs/examples}/azure-pipelines.md | 0 {examples => docs/examples}/index.cshtml | 0 {examples => docs/examples}/pullrequest-id.md | 0 .../examples}/repository-information.md | 0 features.md => docs/features.md | 0 index.cshtml => docs/index.cshtml | 0 requirements.md => docs/requirements.md | 0 setup.md => docs/setup.md | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename cake.issues.pullrequests.tfs.png => docs/cake.issues.pullrequests.tfs.png (100%) rename {examples => docs/examples}/azure-pipelines.md (100%) rename {examples => docs/examples}/index.cshtml (100%) rename {examples => docs/examples}/pullrequest-id.md (100%) rename {examples => docs/examples}/repository-information.md (100%) rename features.md => docs/features.md (100%) rename index.cshtml => docs/index.cshtml (100%) rename requirements.md => docs/requirements.md (100%) rename setup.md => docs/setup.md (100%) diff --git a/cake.issues.pullrequests.tfs.png b/docs/cake.issues.pullrequests.tfs.png similarity index 100% rename from cake.issues.pullrequests.tfs.png rename to docs/cake.issues.pullrequests.tfs.png diff --git a/examples/azure-pipelines.md b/docs/examples/azure-pipelines.md similarity index 100% rename from examples/azure-pipelines.md rename to docs/examples/azure-pipelines.md diff --git a/examples/index.cshtml b/docs/examples/index.cshtml similarity index 100% rename from examples/index.cshtml rename to docs/examples/index.cshtml diff --git a/examples/pullrequest-id.md b/docs/examples/pullrequest-id.md similarity index 100% rename from examples/pullrequest-id.md rename to docs/examples/pullrequest-id.md diff --git a/examples/repository-information.md b/docs/examples/repository-information.md similarity index 100% rename from examples/repository-information.md rename to docs/examples/repository-information.md diff --git a/features.md b/docs/features.md similarity index 100% rename from features.md rename to docs/features.md diff --git a/index.cshtml b/docs/index.cshtml similarity index 100% rename from index.cshtml rename to docs/index.cshtml diff --git a/requirements.md b/docs/requirements.md similarity index 100% rename from requirements.md rename to docs/requirements.md diff --git a/setup.md b/docs/setup.md similarity index 100% rename from setup.md rename to docs/setup.md From 3811d16548ce56a9032cda88ed109c1b2a3b710c Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 15 Aug 2019 18:29:29 +0200 Subject: [PATCH 30/44] Disable generation of documentation --- setup.cake | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cake b/setup.cake index fc37fca..4b6048c 100644 --- a/setup.cake +++ b/setup.cake @@ -10,6 +10,7 @@ BuildParameters.SetParameters( repositoryOwner: "cake-contrib", repositoryName: "Cake.Issues.PullRequests.Tfs", appVeyorAccountName: "cakecontrib", + shouldGenerateDocumentation: false, shouldRunGitVersion: true, shouldRunCodecov: false, shouldRunDotNetCorePack: true); From b3d9e93d0e93397a0b30d9bca1333a2f5e827335 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 16 Aug 2019 17:51:10 +0200 Subject: [PATCH 31/44] Fix documentation --- docs/examples/azure-pipelines.md | 10 ++++------ docs/examples/pullrequest-id.md | 2 +- docs/features.md | 2 +- docs/requirements.md | 2 +- docs/setup.md | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/examples/azure-pipelines.md b/docs/examples/azure-pipelines.md index 7b04183..662754b 100644 --- a/docs/examples/azure-pipelines.md +++ b/docs/examples/azure-pipelines.md @@ -56,12 +56,10 @@ Task("ReportIssuesToPullRequest").Does(() => if (isPullRequestBuild) { - if (!Int32.TryParse(context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID"), out var pullRequestId)) + var pullRequestIdVariable = context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID"); + if (!Int32.TryParse(pullRequestIdVariable, out var pullRequestId)) { - throw new Exception( - string.Format( - "Invalid pull request ID: {0}", - context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID"))); + throw new Exception($"Invalid pull request ID: {pullRequestIdVariable}"); } else { @@ -83,4 +81,4 @@ Task("ReportIssuesToPullRequest").Does(() => [TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C [Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options?view=vsts&tabs=yaml#allow-scripts-to-access-the-oauth-token -[OAuth authentication from Azure Pipelines]: ../setup#oauth-authentication-from-azure-pipelines \ No newline at end of file +[OAuth authentication from Azure Pipelines]: ../setup#oauth-authentication-from-azure-pipelines diff --git a/docs/examples/pullrequest-id.md b/docs/examples/pullrequest-id.md index 0da1bdf..d37eaa3 100644 --- a/docs/examples/pullrequest-id.md +++ b/docs/examples/pullrequest-id.md @@ -54,4 +54,4 @@ Task("ReportIssuesToPullRequest").Does(() => ``` [TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C -[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ \ No newline at end of file +[Cake.Git]: https://www.nuget.org/packages/Cake.Git/ diff --git a/docs/features.md b/docs/features.md index 2502c1b..b2ff694 100644 --- a/docs/features.md +++ b/docs/features.md @@ -45,4 +45,4 @@ For detailed instructions how to connect using the different methods see [Setup [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs [Azure DevOps]: https://azure.microsoft.com/en-us/services/devops/ [Core features]: ../../overview/features#supported-core-functionality -[Setup instructions]: setup \ No newline at end of file +[Setup instructions]: setup diff --git a/docs/requirements.md b/docs/requirements.md index 31efa10..bfe4a82 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -6,4 +6,4 @@ Description: Requirements for the Cake.Issues.PullRequests.Tfs addin. The requirements for using the [Cake.Issues.PullRequests.Tfs addin] are listed in the [release notes] for any specific version. [Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs -[release notes]: release-notes \ No newline at end of file +[release notes]: release-notes diff --git a/docs/setup.md b/docs/setup.md index 8039c0a..17aced5 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -75,4 +75,4 @@ allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull re [TfsAuthenticationBasic]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/86407B1D [TfsAuthenticationPersonalAccessToken]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E4AC3E3 [TfsAuthenticationOAuth]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/B5D45B5D -[TfsAuthenticationAzureActiveDirectory]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E787800 \ No newline at end of file +[TfsAuthenticationAzureActiveDirectory]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E787800 From 568289a0d530c15ba051e0c79b0da6adc603ae26 Mon Sep 17 00:00:00 2001 From: Gary Ewan Park Date: Tue, 10 Sep 2019 21:10:33 +0100 Subject: [PATCH 32/44] (GH-134) Switch to recipe.cake file This provides some immediate information that a repository is using Cake.Recipe, and it is a convention now followed by a number of other repositories. --- .appveyor.yml | 2 +- build.ps1 | 4 ++-- build.sh | 2 +- setup.cake => recipe.cake | 0 src/Cake.Issues.PullRequests.Tfs.sln | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename setup.cake => recipe.cake (100%) diff --git a/.appveyor.yml b/.appveyor.yml index 2b5f541..0d21fc4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -27,4 +27,4 @@ branches: # Build Cache # #---------------------------------# cache: -- tools -> setup.cake \ No newline at end of file +- tools -> recipe.cake diff --git a/build.ps1 b/build.ps1 index bdfb32b..a6d30c4 100644 --- a/build.ps1 +++ b/build.ps1 @@ -35,7 +35,7 @@ http://cakebuild.net [CmdletBinding()] Param( - [string]$Script = "setup.cake", + [string]$Script = "recipe.cake", [string]$Target = "Default", [ValidateSet("Release", "Debug")] [string]$Configuration = "Release", @@ -181,4 +181,4 @@ if (!(Test-Path $CAKE_EXE)) { # Start Cake Write-Host "Running build script..." Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" -exit $LASTEXITCODE \ No newline at end of file +exit $LASTEXITCODE diff --git a/build.sh b/build.sh index 0cab5b8..68d388f 100755 --- a/build.sh +++ b/build.sh @@ -99,4 +99,4 @@ fi ########################################################################### # Start Cake -exec mono "$CAKE_EXE" setup.cake --verbosity=$VERBOSITY --configuration=$CONFIGURATION --target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" +exec mono "$CAKE_EXE" recipe.cake --verbosity=$VERBOSITY --configuration=$CONFIGURATION --target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" diff --git a/setup.cake b/recipe.cake similarity index 100% rename from setup.cake rename to recipe.cake diff --git a/src/Cake.Issues.PullRequests.Tfs.sln b/src/Cake.Issues.PullRequests.Tfs.sln index bd4878a..818fc58 100644 --- a/src/Cake.Issues.PullRequests.Tfs.sln +++ b/src/Cake.Issues.PullRequests.Tfs.sln @@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Issues.PullRequests.Tf EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{AAD732D5-4A2D-4A67-B571-7CD931983393}" ProjectSection(SolutionItems) = preProject - ..\setup.cake = ..\setup.cake + ..\recipe.cake = ..\recipe.cake EndProjectSection EndProject Global From 2cbcaa7f9d5a9dadd0301c5785ff8335dec830f5 Mon Sep 17 00:00:00 2001 From: Gary Ewan Park Date: Tue, 10 Sep 2019 21:10:48 +0100 Subject: [PATCH 33/44] (maint) Add .dotnet folder to .gitignore file --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a9e78cf..ad84880 100644 --- a/.gitignore +++ b/.gitignore @@ -276,4 +276,6 @@ __pycache__/ # Cake - Uncomment if you are using it tools/** !tools/packages.config -BuildArtifacts/ \ No newline at end of file +BuildArtifacts/ + +.dotnet From 458a644f980064bb4d00ffe9b05e820e02b4c7db Mon Sep 17 00:00:00 2001 From: "D. Domig" Date: Tue, 1 Oct 2019 21:39:31 +0200 Subject: [PATCH 34/44] Fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 15d63ab..792c72d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ analyzer or linter to Team Foundation Server or Azure DevOps pull requests using the [Cake Issues addin](https://github.com/cake-contrib/Cake.Issues). For more information about this add-in see the [Cake.Issues website](https://cakeissues.net) -and for general information about the Cake build automation system see the [Cake website](http://cakebuild.net) +and for general information about the Cake build automation system see the [Cake website](http://cakebuild.net). [![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/cake-contrib/Cake.Issues.PullRequests.Tfs/blob/feature/build/LICENSE) @@ -35,7 +35,7 @@ and for general information about the Cake build automation system see the [Cake ## Chat Room -Come join in the conversation about this addin in our Gitter Chat Room +Come join in the conversation about this addin in our Gitter Chat Room. [![Join the chat at https://gitter.im/cake-contrib/Lobby](https://badges.gitter.im/cake-contrib/Lobby.svg)](https://gitter.im/cake-contrib/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From fcbebb517c830e417f9983a8351fe2d8e417044a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2019 00:51:08 +0000 Subject: [PATCH 35/44] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.9.4 to 2.9.5 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.9.4 to 2.9.5. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Changelog](https://github.com/dotnet/roslyn-analyzers/blob/master/PostReleaseActivities.md) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v2.9.4...v2.9.5) Signed-off-by: dependabot-preview[bot] --- .../Cake.Issues.PullRequests.Tfs.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj b/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj index 73a4f27..8edf311 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj +++ b/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj @@ -46,7 +46,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin - + From 2daec88993be80d1b1defc28a6be891a26d4314d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2019 23:59:19 +0000 Subject: [PATCH 36/44] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.9.5 to 2.9.6 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.9.5 to 2.9.6. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Changelog](https://github.com/dotnet/roslyn-analyzers/blob/master/PostReleaseActivities.md) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v2.9.5...v2.9.6) Signed-off-by: dependabot-preview[bot] --- .../Cake.Issues.PullRequests.Tfs.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj b/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj index 8edf311..749a26d 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj +++ b/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj @@ -46,7 +46,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin - + From 35b4b4cbfbf8b53e1e1fdf0ec10fa078bf36bc38 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 11 Oct 2019 21:40:53 +0200 Subject: [PATCH 37/44] (GH-118) Rename to Cake.Issues.PullRequests.AzureDevOps --- README.md | 21 ++- recipe.cake | 8 +- ...es.PullRequests.AzureDevOps.Tests.ruleset} | 4 +- ...reDevOpsPullRequestSystemSettingsTests.cs} | 18 +- .../AzureDevOpsPullRequestSystemTests.cs} | 16 +- ...ues.PullRequests.AzureDevOps.Tests.csproj} | 10 +- ...eDevOpsCheckingCommitIdCapabilityTests.cs} | 14 +- ...DevOpsDiscussionThreadsCapabilityTests.cs} | 14 +- ...ilteringByModifiedFilesCapabilityTests.cs} | 14 +- .../Capabilities/CommentExtensionsTests.cs | 12 +- .../CommentThreadStatusExtensionsTests.cs | 38 ++-- ...PullRequestCommentThreadExtensionsTests.cs | 166 +++++++++--------- .../ContentProviderTests.cs | 2 +- .../Properties/AssemblyInfo.cs | 0 .../app.config | 0 ...e.Issues.PullRequests.AzureDevOps.ruleset} | 2 +- ... Cake.Issues.PullRequests.AzureDevOps.sln} | 4 +- ....PullRequests.AzureDevOps.sln.DotSettings} | 0 .../AzureDevOpsPullRequestSystem.cs} | 81 +++++---- ...RequestSystemAliases.PullRequestSystem.cs} | 103 ++++++----- .../AzureDevOpsPullRequestSystemAliases.cs} | 7 +- .../AzureDevOpsPullRequestSystemSettings.cs} | 48 +++-- ...ke.Issues.PullRequests.AzureDevOps.csproj} | 20 +-- .../AzureDevOpsCheckingCommitIdCapability.cs} | 12 +- .../AzureDevOpsCommentExtensions.cs | 26 +++ ...zureDevOpsCommentThreadStatusExtensions.cs | 58 ++++++ ...AzureDevOpsDiscussionThreadsCapability.cs} | 16 +- ...vOpsFilteringByModifiedFilesCapability.cs} | 12 +- ...vOpsPullRequestCommentThreadExtensions.cs} | 24 +-- .../ContentProvider.cs | 2 +- .../IAzureDevOpsPullRequestSystem.cs} | 12 +- .../Properties/AssemblyInfo.cs | 2 +- .../app.config | 0 .../Capabilities/TfsCommentExtensions.cs | 26 --- .../TfsCommentThreadStatusExtensions.cs | 58 ------ 35 files changed, 419 insertions(+), 431 deletions(-) rename src/{Cake.Issues.PullRequests.Tfs.Tests.ruleset => Cake.Issues.PullRequests.AzureDevOps.Tests.ruleset} (53%) rename src/{Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemSettingsTests.cs => Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemSettingsTests.cs} (64%) rename src/{Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemTests.cs => Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemTests.cs} (60%) rename src/{Cake.Issues.PullRequests.Tfs.Tests/Cake.Issues.PullRequests.Tfs.Tests.csproj => Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj} (71%) rename src/{Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsFilteringByModifiedFilesCapabilityTests.cs => Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsCheckingCommitIdCapabilityTests.cs} (56%) rename src/{Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsDiscussionThreadsCapabilityTests.cs => Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsDiscussionThreadsCapabilityTests.cs} (56%) rename src/{Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsCheckingCommitIdCapabilityTests.cs => Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsFilteringByModifiedFilesCapabilityTests.cs} (55%) rename src/{Cake.Issues.PullRequests.Tfs.Tests => Cake.Issues.PullRequests.AzureDevOps.Tests}/Capabilities/CommentExtensionsTests.cs (82%) rename src/{Cake.Issues.PullRequests.Tfs.Tests => Cake.Issues.PullRequests.AzureDevOps.Tests}/Capabilities/CommentThreadStatusExtensionsTests.cs (66%) rename src/{Cake.Issues.PullRequests.Tfs.Tests => Cake.Issues.PullRequests.AzureDevOps.Tests}/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs (75%) rename src/{Cake.Issues.PullRequests.Tfs.Tests => Cake.Issues.PullRequests.AzureDevOps.Tests}/ContentProviderTests.cs (97%) rename src/{Cake.Issues.PullRequests.Tfs.Tests => Cake.Issues.PullRequests.AzureDevOps.Tests}/Properties/AssemblyInfo.cs (100%) rename src/{Cake.Issues.PullRequests.Tfs.Tests => Cake.Issues.PullRequests.AzureDevOps.Tests}/app.config (100%) rename src/{Cake.Issues.PullRequests.Tfs.ruleset => Cake.Issues.PullRequests.AzureDevOps.ruleset} (98%) rename src/{Cake.Issues.PullRequests.Tfs.sln => Cake.Issues.PullRequests.AzureDevOps.sln} (83%) rename src/{Cake.Issues.PullRequests.Tfs.sln.DotSettings => Cake.Issues.PullRequests.AzureDevOps.sln.DotSettings} (100%) rename src/{Cake.Issues.PullRequests.Tfs/TfsPullRequestSystem.cs => Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs} (74%) rename src/{Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.PullRequestSystem.cs => Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.PullRequestSystem.cs} (62%) rename src/{Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.cs => Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.cs} (55%) rename src/{Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemSettings.cs => Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemSettings.cs} (61%) rename src/{Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj => Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj} (76%) rename src/{Cake.Issues.PullRequests.Tfs/Capabilities/TfsCheckingCommitIdCapability.cs => Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCheckingCommitIdCapability.cs} (54%) create mode 100644 src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentExtensions.cs create mode 100644 src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentThreadStatusExtensions.cs rename src/{Cake.Issues.PullRequests.Tfs/Capabilities/TfsDiscussionThreadsCapability.cs => Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsDiscussionThreadsCapability.cs} (76%) rename src/{Cake.Issues.PullRequests.Tfs/Capabilities/TfsFilteringByModifiedFilesCapability.cs => Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsFilteringByModifiedFilesCapability.cs} (54%) rename src/{Cake.Issues.PullRequests.Tfs/Capabilities/TfsPullRequestCommentThreadExtensions.cs => Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsPullRequestCommentThreadExtensions.cs} (74%) rename src/{Cake.Issues.PullRequests.Tfs => Cake.Issues.PullRequests.AzureDevOps}/ContentProvider.cs (94%) rename src/{Cake.Issues.PullRequests.Tfs/ITfsPullRequestSystem.cs => Cake.Issues.PullRequests.AzureDevOps/IAzureDevOpsPullRequestSystem.cs} (51%) rename src/{Cake.Issues.PullRequests.Tfs => Cake.Issues.PullRequests.AzureDevOps}/Properties/AssemblyInfo.cs (88%) rename src/{Cake.Issues.PullRequests.Tfs => Cake.Issues.PullRequests.AzureDevOps}/app.config (100%) delete mode 100644 src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentExtensions.cs delete mode 100644 src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentThreadStatusExtensions.cs diff --git a/README.md b/README.md index 792c72d..895b807 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,32 @@ -# TFS / Azure DevOps support for Cake Issues Addin +# Azure DevOps support for Cake Issues Addin This addin for the Cake Build Automation System allows you to write issues found using any code -analyzer or linter to Team Foundation Server or Azure DevOps pull requests using -the [Cake Issues addin](https://github.com/cake-contrib/Cake.Issues). +analyzer or linter to Azure DevOps pull requests using the [Cake Issues addin](https://github.com/cake-contrib/Cake.Issues). For more information about this add-in see the [Cake.Issues website](https://cakeissues.net) and for general information about the Cake build automation system see the [Cake website](http://cakebuild.net). -[![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/cake-contrib/Cake.Issues.PullRequests.Tfs/blob/feature/build/LICENSE) +[![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/blob/feature/build/LICENSE) ## Information | | Stable | Pre-release | |:--:|:--:|:--:| -|GitHub Release|-|[![GitHub release](https://img.shields.io/github/release/cake-contrib/Cake.Issues.PullRequests.Tfs.svg)](https://github.com/cake-contrib/Cake.Issues.PullRequests.Tfs/releases/latest)| -|NuGet|[![NuGet](https://img.shields.io/nuget/v/Cake.Issues.PullRequests.Tfs.svg)](https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs)|[![NuGet](https://img.shields.io/nuget/vpre/Cake.Issues.PullRequests.Tfs.svg)](https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs)| +|GitHub Release|-|[![GitHub release](https://img.shields.io/github/release/cake-contrib/Cake.Issues.PullRequests.AzureDevOps.svg)](https://github.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/releases/latest)| +|NuGet|[![NuGet](https://img.shields.io/nuget/v/Cake.Issues.PullRequests.AzureDevOps.svg)](https://www.nuget.org/packages/Cake.Issues.PullRequests.AzureDevOps)|[![NuGet](https://img.shields.io/nuget/vpre/Cake.Issues.PullRequests.AzureDevOps.svg)](https://www.nuget.org/packages/Cake.Issues.PullRequests.AzureDevOps)| ## Build Status | | Develop | Master | |:--:|:--:|:--:| -|AppVeyor Windows|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/s8t8j2gh6icynkod/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-tfs/branch/master)| -|Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| -|Azure DevOps macOS|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=macOS)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=macOS)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| -|Azure DevOps Ubuntu|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=develop&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.Tfs?branchName=master&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.Tfs/_build/latest?definitionId=8&branchName=master)| +|AppVeyor Windows|[![Build status](https://ci.appveyor.com/api/projects/status/6t6m39enwkvkhk80/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-azuredevops/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/6t6m39enwkvkhk80/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues-pullrequests-azuredevops/branch/master)| +|Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.AzureDevOps?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.AzureDevOps?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_build/latest?definitionId=8&branchName=master)| +|Azure DevOps macOS|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.AzureDevOps?branchName=develop&jobName=macOS)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.AzureDevOps?branchName=master&jobName=macOS)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_build/latest?definitionId=8&branchName=master)| +|Azure DevOps Ubuntu|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.AzureDevOps?branchName=develop&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_build/latest?definitionId=8&branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_apis/build/status/cake-contrib.Cake.Issues.PullRequests.AzureDevOps?branchName=master&jobName=Ubuntu)](https://dev.azure.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/_build/latest?definitionId=8&branchName=master)| ## Code Coverage -[![Coverage Status](https://coveralls.io/repos/github/cake-contrib/Cake.Issues.PullRequests.Tfs/badge.svg?branch=develop)](https://coveralls.io/github/cake-contrib/Cake.Issues.PullRequests.Tfs?branch=develop) +[![Coverage Status](https://coveralls.io/repos/github/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/badge.svg?branch=develop)](https://coveralls.io/github/cake-contrib/Cake.Issues.PullRequests.AzureDevOps?branch=develop) ## Quick Links diff --git a/recipe.cake b/recipe.cake index 4b6048c..2d2228b 100644 --- a/recipe.cake +++ b/recipe.cake @@ -6,9 +6,9 @@ BuildParameters.SetParameters( context: Context, buildSystem: BuildSystem, sourceDirectoryPath: "./src", - title: "Cake.Issues.PullRequests.Tfs", + title: "Cake.Issues.PullRequests.AzureDevOps", repositoryOwner: "cake-contrib", - repositoryName: "Cake.Issues.PullRequests.Tfs", + repositoryName: "Cake.Issues.PullRequests.AzureDevOps", appVeyorAccountName: "cakecontrib", shouldGenerateDocumentation: false, shouldRunGitVersion: true, @@ -19,8 +19,8 @@ BuildParameters.PrintParameters(Context); ToolSettings.SetToolSettings( context: Context, - dupFinderExcludePattern: new string[] { BuildParameters.RootDirectoryPath + "/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/*.cs" }, - testCoverageFilter: "+[*]* -[xunit.*]* -[Cake.Core]* -[Cake.Testing]* -[*.Tests]* -[Cake.Issues]* -[Cake.Issues.Testing]* -[Cake.Issues.PullRequests]* -[Cake.Tfs]* -[Shouldly]*", + dupFinderExcludePattern: new string[] { BuildParameters.RootDirectoryPath + "/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/*.cs" }, + testCoverageFilter: "+[*]* -[xunit.*]* -[Cake.Core]* -[Cake.Testing]* -[*.Tests]* -[Cake.Issues]* -[Cake.Issues.Testing]* -[Cake.Issues.PullRequests]* -[Cake.AzureDevOps]* -[Shouldly]*", testCoverageExcludeByAttribute: "*.ExcludeFromCodeCoverage*", testCoverageExcludeByFile: "*/*Designer.cs;*/*.g.cs;*/*.g.i.cs"); diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests.ruleset b/src/Cake.Issues.PullRequests.AzureDevOps.Tests.ruleset similarity index 53% rename from src/Cake.Issues.PullRequests.Tfs.Tests.ruleset rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests.ruleset index dccc7b5..ca8c3a4 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests.ruleset +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests.ruleset @@ -1,6 +1,6 @@  - - + + diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemSettingsTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemSettingsTests.cs similarity index 64% rename from src/Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemSettingsTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemSettingsTests.cs index a622f2b..e8b40d1 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemSettingsTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemSettingsTests.cs @@ -1,10 +1,10 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests +namespace Cake.Issues.PullRequests.AzureDevOps.Tests { using System; using Cake.Issues.Testing; using Xunit; - public sealed class TfsPullRequestSystemSettingsTests + public sealed class AzureDevOpsPullRequestSystemSettingsTests { public sealed class TheCtor { @@ -12,7 +12,7 @@ public sealed class TheCtor public void Should_Throw_If_RepositoryUrl_For_SourceRefName_Is_Null() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(null, "foo", null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(null, "foo", null)); // Then result.IsArgumentNullException("repositoryUrl"); @@ -22,7 +22,7 @@ public void Should_Throw_If_RepositoryUrl_For_SourceRefName_Is_Null() public void Should_Throw_If_SourceRefName_Is_Null() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(new Uri("http://example.com"), null, null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(new Uri("http://example.com"), null, null)); // Then result.IsArgumentNullException("sourceRefName"); @@ -32,7 +32,7 @@ public void Should_Throw_If_SourceRefName_Is_Null() public void Should_Throw_If_SourceRefName_Is_Empty() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(new Uri("http://example.com"), string.Empty, null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(new Uri("http://example.com"), string.Empty, null)); // Then result.IsArgumentOutOfRangeException("sourceRefName"); @@ -42,7 +42,7 @@ public void Should_Throw_If_SourceRefName_Is_Empty() public void Should_Throw_If_SourceRefName_Is_WhiteSpace() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(new Uri("http://example.com"), " ", null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(new Uri("http://example.com"), " ", null)); // Then result.IsArgumentOutOfRangeException("sourceRefName"); @@ -52,7 +52,7 @@ public void Should_Throw_If_SourceRefName_Is_WhiteSpace() public void Should_Throw_If_RepositoryUrl_For_PullRequestId_Is_Null() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(null, 0, null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(null, 0, null)); // Then result.IsArgumentNullException("repositoryUrl"); @@ -62,7 +62,7 @@ public void Should_Throw_If_RepositoryUrl_For_PullRequestId_Is_Null() public void Should_Throw_If_Credentials_For_PullRequestId_Are_Null() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(new Uri("http://example.com"), 42, null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(new Uri("http://example.com"), 42, null)); // Then result.IsArgumentNullException("credentials"); @@ -72,7 +72,7 @@ public void Should_Throw_If_Credentials_For_PullRequestId_Are_Null() public void Should_Throw_If_Credentials_For_SourceBranch_Are_Null() { // Given / When - var result = Record.Exception(() => new TfsPullRequestSystemSettings(new Uri("http://example.com"), "feature/foo", null)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystemSettings(new Uri("http://example.com"), "feature/foo", null)); // Then result.IsArgumentNullException("credentials"); diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemTests.cs similarity index 60% rename from src/Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemTests.cs index d73c253..9e68d3a 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/TfsPullRequestSystemTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/AzureDevOpsPullRequestSystemTests.cs @@ -1,13 +1,13 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests +namespace Cake.Issues.PullRequests.AzureDevOps.Tests { using System; + using Cake.AzureDevOps.Authentication; using Cake.Core.Diagnostics; using Cake.Issues.Testing; using Cake.Testing; - using Cake.Tfs.Authentication; using Xunit; - public sealed class TfsPullRequestSystemTests + public sealed class AzureDevOpsPullRequestSystemTests { public sealed class TheCtor { @@ -17,13 +17,13 @@ public void Should_Throw_If_Log_Is_Null() // Given ICakeLog log = null; var settings = - new TfsPullRequestSystemSettings( + new AzureDevOpsPullRequestSystemSettings( new Uri("https://google.com"), 123, - new TfsNtlmCredentials()); + new AzureDevOpsNtlmCredentials()); // When - var result = Record.Exception(() => new TfsPullRequestSystem(log, settings)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystem(log, settings)); // Then result.IsArgumentNullException("log"); @@ -34,10 +34,10 @@ public void Should_Throw_If_Settings_Are_Null() { // Given var log = new FakeLog(); - TfsPullRequestSystemSettings settings = null; + AzureDevOpsPullRequestSystemSettings settings = null; // When - var result = Record.Exception(() => new TfsPullRequestSystem(log, settings)); + var result = Record.Exception(() => new AzureDevOpsPullRequestSystem(log, settings)); // Then result.IsArgumentNullException("settings"); diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Cake.Issues.PullRequests.Tfs.Tests.csproj b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj similarity index 71% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Cake.Issues.PullRequests.Tfs.Tests.csproj rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj index 310f480..0e3ca19 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Cake.Issues.PullRequests.Tfs.Tests.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj @@ -3,14 +3,14 @@ netcoreapp2.0 false - Cake.Issues.PullRequests.Tfs + Cake.Issues.PullRequests.AzureDevOps Copyright © BBT Software AG and contributors - Tests for the Cake.Issues.PullRequests.Tfs addin + Tests for the Cake.Issues.PullRequests.AzureDevOps addin BBT Software AG and contributors - ..\Cake.Issues.PullRequests.Tfs.Tests.ruleset + ..\Cake.Issues.PullRequests.AzureDevOps.Tests.ruleset latest @@ -20,7 +20,7 @@ - + @@ -29,7 +29,7 @@ - + \ No newline at end of file diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsFilteringByModifiedFilesCapabilityTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsCheckingCommitIdCapabilityTests.cs similarity index 56% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsFilteringByModifiedFilesCapabilityTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsCheckingCommitIdCapabilityTests.cs index ed988f4..f433063 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsFilteringByModifiedFilesCapabilityTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsCheckingCommitIdCapabilityTests.cs @@ -1,13 +1,13 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Tests.Capabilities { using Cake.Core.Diagnostics; - using Cake.Issues.PullRequests.Tfs.Capabilities; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; using Cake.Issues.Testing; using Cake.Testing; using NSubstitute; using Xunit; - public sealed class TfsFilteringByModifiedFilesCapabilityTests + public sealed class AzureDevOpsCheckingCommitIdCapabilityTests { public sealed class TheCtor { @@ -16,10 +16,10 @@ public void Should_Throw_If_Log_Is_Null() { // Given ICakeLog log = null; - var pullRequestSystem = Substitute.For(); + var pullRequestSystem = Substitute.For(); // When - var result = Record.Exception(() => new TfsFilteringByModifiedFilesCapability(log, pullRequestSystem)); + var result = Record.Exception(() => new AzureDevOpsCheckingCommitIdCapability(log, pullRequestSystem)); // Then result.IsArgumentNullException("log"); @@ -30,10 +30,10 @@ public void Should_Throw_If_PullRequestSystem_Is_Null() { // Given var log = new FakeLog(); - TfsPullRequestSystem pullRequestSystem = null; + AzureDevOpsPullRequestSystem pullRequestSystem = null; // When - var result = Record.Exception(() => new TfsFilteringByModifiedFilesCapability(log, pullRequestSystem)); + var result = Record.Exception(() => new AzureDevOpsCheckingCommitIdCapability(log, pullRequestSystem)); // Then result.IsArgumentNullException("pullRequestSystem"); diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsDiscussionThreadsCapabilityTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsDiscussionThreadsCapabilityTests.cs similarity index 56% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsDiscussionThreadsCapabilityTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsDiscussionThreadsCapabilityTests.cs index f79bb18..2a04fd4 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsDiscussionThreadsCapabilityTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsDiscussionThreadsCapabilityTests.cs @@ -1,13 +1,13 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Tests.Capabilities { using Cake.Core.Diagnostics; - using Cake.Issues.PullRequests.Tfs.Capabilities; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; using Cake.Issues.Testing; using Cake.Testing; using NSubstitute; using Xunit; - public sealed class TfsDiscussionThreadsCapabilityTests + public sealed class AzureDevOpsDiscussionThreadsCapabilityTests { public sealed class TheCtor { @@ -16,10 +16,10 @@ public void Should_Throw_If_Log_Is_Null() { // Given ICakeLog log = null; - var pullRequestSystem = Substitute.For(); + var pullRequestSystem = Substitute.For(); // When - var result = Record.Exception(() => new TfsDiscussionThreadsCapability(log, pullRequestSystem)); + var result = Record.Exception(() => new AzureDevOpsDiscussionThreadsCapability(log, pullRequestSystem)); // Then result.IsArgumentNullException("log"); @@ -30,10 +30,10 @@ public void Should_Throw_If_PullRequestSystem_Is_Null() { // Given var log = new FakeLog(); - TfsPullRequestSystem pullRequestSystem = null; + AzureDevOpsPullRequestSystem pullRequestSystem = null; // When - var result = Record.Exception(() => new TfsDiscussionThreadsCapability(log, pullRequestSystem)); + var result = Record.Exception(() => new AzureDevOpsDiscussionThreadsCapability(log, pullRequestSystem)); // Then result.IsArgumentNullException("pullRequestSystem"); diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsCheckingCommitIdCapabilityTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsFilteringByModifiedFilesCapabilityTests.cs similarity index 55% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsCheckingCommitIdCapabilityTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsFilteringByModifiedFilesCapabilityTests.cs index ee38adb..f6172e6 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/TfsCheckingCommitIdCapabilityTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/AzureDevOpsFilteringByModifiedFilesCapabilityTests.cs @@ -1,13 +1,13 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Tests.Capabilities { using Cake.Core.Diagnostics; - using Cake.Issues.PullRequests.Tfs.Capabilities; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; using Cake.Issues.Testing; using Cake.Testing; using NSubstitute; using Xunit; - public sealed class TfsCheckingCommitIdCapabilityTests + public sealed class AzureDevOpsFilteringByModifiedFilesCapabilityTests { public sealed class TheCtor { @@ -16,10 +16,10 @@ public void Should_Throw_If_Log_Is_Null() { // Given ICakeLog log = null; - var pullRequestSystem = Substitute.For(); + var pullRequestSystem = Substitute.For(); // When - var result = Record.Exception(() => new TfsCheckingCommitIdCapability(log, pullRequestSystem)); + var result = Record.Exception(() => new AzureDevOpsFilteringByModifiedFilesCapability(log, pullRequestSystem)); // Then result.IsArgumentNullException("log"); @@ -30,10 +30,10 @@ public void Should_Throw_If_PullRequestSystem_Is_Null() { // Given var log = new FakeLog(); - TfsPullRequestSystem pullRequestSystem = null; + AzureDevOpsPullRequestSystem pullRequestSystem = null; // When - var result = Record.Exception(() => new TfsCheckingCommitIdCapability(log, pullRequestSystem)); + var result = Record.Exception(() => new AzureDevOpsFilteringByModifiedFilesCapability(log, pullRequestSystem)); // Then result.IsArgumentNullException("pullRequestSystem"); diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/CommentExtensionsTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/CommentExtensionsTests.cs similarity index 82% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/CommentExtensionsTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/CommentExtensionsTests.cs index d4672d9..d526150 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/CommentExtensionsTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/CommentExtensionsTests.cs @@ -1,8 +1,8 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Tests.Capabilities { - using Cake.Issues.PullRequests.Tfs.Capabilities; + using Cake.AzureDevOps.PullRequest.CommentThread; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; using Cake.Issues.Testing; - using Cake.Tfs.PullRequest.CommentThread; using Shouldly; using Xunit; @@ -14,7 +14,7 @@ public sealed class TheToPullRequestDiscussionCommentExtension public void Should_Throw_If_Comment_Is_Null() { // Given - TfsComment comment = null; + AzureDevOpsComment comment = null; // When var result = Record.Exception(() => comment.ToPullRequestDiscussionComment()); @@ -29,7 +29,7 @@ public void Should_Set_Correct_Content() // Given var content = "foo"; var comment = - new TfsComment + new AzureDevOpsComment { Content = content, }; @@ -48,7 +48,7 @@ public void Should_Set_Correct_IsDeleted(bool isDeleted) { // Given var comment = - new TfsComment + new AzureDevOpsComment { IsDeleted = isDeleted, }; diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/CommentThreadStatusExtensionsTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/CommentThreadStatusExtensionsTests.cs similarity index 66% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/CommentThreadStatusExtensionsTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/CommentThreadStatusExtensionsTests.cs index 50ac583..b9ad454 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/CommentThreadStatusExtensionsTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/CommentThreadStatusExtensionsTests.cs @@ -1,7 +1,7 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Tests.Capabilities { - using Cake.Issues.PullRequests.Tfs.Capabilities; - using Cake.Tfs.PullRequest.CommentThread; + using Cake.AzureDevOps.PullRequest.CommentThread; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; using Shouldly; using Xunit; @@ -11,28 +11,28 @@ public sealed class TheToPullRequestDiscussionStatusExtension { [Theory] [InlineData( - TfsCommentThreadStatus.Unknown, + AzureDevOpsCommentThreadStatus.Unknown, PullRequestDiscussionStatus.Unknown)] [InlineData( - TfsCommentThreadStatus.Active, + AzureDevOpsCommentThreadStatus.Active, PullRequestDiscussionStatus.Active)] [InlineData( - TfsCommentThreadStatus.Pending, + AzureDevOpsCommentThreadStatus.Pending, PullRequestDiscussionStatus.Active)] [InlineData( - TfsCommentThreadStatus.Fixed, + AzureDevOpsCommentThreadStatus.Fixed, PullRequestDiscussionStatus.Resolved)] [InlineData( - TfsCommentThreadStatus.WontFix, + AzureDevOpsCommentThreadStatus.WontFix, PullRequestDiscussionStatus.Resolved)] [InlineData( - TfsCommentThreadStatus.Closed, + AzureDevOpsCommentThreadStatus.Closed, PullRequestDiscussionStatus.Resolved)] [InlineData( - TfsCommentThreadStatus.ByDesign, + AzureDevOpsCommentThreadStatus.ByDesign, PullRequestDiscussionStatus.Resolved)] public void Should_Return_Correct_Value( - TfsCommentThreadStatus status, + AzureDevOpsCommentThreadStatus status, PullRequestDiscussionStatus expectedResult) { // Given @@ -49,28 +49,28 @@ public sealed class TheToPullRequestDiscussionResolutionExtension { [Theory] [InlineData( - TfsCommentThreadStatus.Unknown, + AzureDevOpsCommentThreadStatus.Unknown, PullRequestDiscussionResolution.Unknown)] [InlineData( - TfsCommentThreadStatus.Active, + AzureDevOpsCommentThreadStatus.Active, PullRequestDiscussionResolution.Unknown)] [InlineData( - TfsCommentThreadStatus.Pending, + AzureDevOpsCommentThreadStatus.Pending, PullRequestDiscussionResolution.Unknown)] [InlineData( - TfsCommentThreadStatus.Fixed, + AzureDevOpsCommentThreadStatus.Fixed, PullRequestDiscussionResolution.Resolved)] [InlineData( - TfsCommentThreadStatus.WontFix, + AzureDevOpsCommentThreadStatus.WontFix, PullRequestDiscussionResolution.WontFix)] [InlineData( - TfsCommentThreadStatus.Closed, + AzureDevOpsCommentThreadStatus.Closed, PullRequestDiscussionResolution.Resolved)] [InlineData( - TfsCommentThreadStatus.ByDesign, + AzureDevOpsCommentThreadStatus.ByDesign, PullRequestDiscussionResolution.Resolved)] public void Should_Return_Correct_Value( - TfsCommentThreadStatus status, + AzureDevOpsCommentThreadStatus status, PullRequestDiscussionResolution expectedResult) { // Given diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs similarity index 75% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs index d272204..9976b7f 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Capabilities/GitPullRequestCommentThreadExtensionsTests.cs @@ -1,10 +1,10 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Tests.Capabilities { using System.Collections.Generic; using System.Linq; - using Cake.Issues.PullRequests.Tfs.Capabilities; + using Cake.AzureDevOps.PullRequest.CommentThread; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; using Cake.Issues.Testing; - using Cake.Tfs.PullRequest.CommentThread; using Shouldly; using Xunit; @@ -16,7 +16,7 @@ public sealed class TheToPullRequestDiscussionThreadExtension public void Should_Throw_If_Thread_Is_Null() { // Given - TfsPullRequestCommentThread thread = null; + AzureDevOpsPullRequestCommentThread thread = null; // When var result = Record.Exception(() => thread.ToPullRequestDiscussionThread()); @@ -30,10 +30,10 @@ public void Should_Throw_If_Comments_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", Comments = null, Properties = new Dictionary(), @@ -51,12 +51,12 @@ public void Should_Not_Throw_If_Properties_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = null, }; @@ -72,15 +72,15 @@ public void Should_Set_Correct_Id() { // Given var id = 123; - var status = TfsCommentThreadStatus.Active; + var status = AzureDevOpsCommentThreadStatus.Active; var filePath = "/foo.cs"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = id, Status = status, FilePath = filePath, - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; @@ -93,40 +93,40 @@ public void Should_Set_Correct_Id() [Theory] [InlineData( - TfsCommentThreadStatus.Unknown, + AzureDevOpsCommentThreadStatus.Unknown, PullRequestDiscussionStatus.Unknown)] [InlineData( - TfsCommentThreadStatus.Active, + AzureDevOpsCommentThreadStatus.Active, PullRequestDiscussionStatus.Active)] [InlineData( - TfsCommentThreadStatus.Pending, + AzureDevOpsCommentThreadStatus.Pending, PullRequestDiscussionStatus.Active)] [InlineData( - TfsCommentThreadStatus.Fixed, + AzureDevOpsCommentThreadStatus.Fixed, PullRequestDiscussionStatus.Resolved)] [InlineData( - TfsCommentThreadStatus.WontFix, + AzureDevOpsCommentThreadStatus.WontFix, PullRequestDiscussionStatus.Resolved)] [InlineData( - TfsCommentThreadStatus.Closed, + AzureDevOpsCommentThreadStatus.Closed, PullRequestDiscussionStatus.Resolved)] [InlineData( - TfsCommentThreadStatus.ByDesign, + AzureDevOpsCommentThreadStatus.ByDesign, PullRequestDiscussionStatus.Resolved)] public void Should_Set_Correct_Status( - TfsCommentThreadStatus status, + AzureDevOpsCommentThreadStatus status, PullRequestDiscussionStatus expectedResult) { // Given var id = 123; var filePath = "/foo.cs"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = id, Status = status, FilePath = filePath, - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; @@ -143,14 +143,14 @@ public void Should_Set_Correct_FilePath(string filePath, string expectedResult) { // Given var id = 123; - var status = TfsCommentThreadStatus.Active; + var status = AzureDevOpsCommentThreadStatus.Active; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = id, Status = status, FilePath = filePath, - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; @@ -166,11 +166,11 @@ public void Should_Set_Correct_FilePath_If_ThreadContext_Is_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, - Comments = new List(), + Status = AzureDevOpsCommentThreadStatus.Active, + Comments = new List(), Properties = new Dictionary(), }; @@ -186,19 +186,19 @@ public void Should_Set_Correct_Comments() { // Given var id = 123; - var status = TfsCommentThreadStatus.Active; + var status = AzureDevOpsCommentThreadStatus.Active; var filePath = "/foo.cs"; var commentContent = "foo"; var commentIsDeleted = false; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = id, Status = status, FilePath = filePath, - Comments = new List + Comments = new List { - new TfsComment() + new AzureDevOpsComment() { Content = commentContent, IsDeleted = commentIsDeleted, @@ -221,16 +221,16 @@ public void Should_Set_Correct_CommentSource() { // Given var id = 123; - var status = TfsCommentThreadStatus.Active; + var status = AzureDevOpsCommentThreadStatus.Active; var filePath = "/foo.cs"; var commentSource = "foo"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = id, Status = status, FilePath = filePath, - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; thread.SetCommentSource(commentSource); @@ -244,40 +244,40 @@ public void Should_Set_Correct_CommentSource() [Theory] [InlineData( - TfsCommentThreadStatus.Unknown, + AzureDevOpsCommentThreadStatus.Unknown, PullRequestDiscussionResolution.Unknown)] [InlineData( - TfsCommentThreadStatus.Active, + AzureDevOpsCommentThreadStatus.Active, PullRequestDiscussionResolution.Unknown)] [InlineData( - TfsCommentThreadStatus.Pending, + AzureDevOpsCommentThreadStatus.Pending, PullRequestDiscussionResolution.Unknown)] [InlineData( - TfsCommentThreadStatus.Fixed, + AzureDevOpsCommentThreadStatus.Fixed, PullRequestDiscussionResolution.Resolved)] [InlineData( - TfsCommentThreadStatus.WontFix, + AzureDevOpsCommentThreadStatus.WontFix, PullRequestDiscussionResolution.WontFix)] [InlineData( - TfsCommentThreadStatus.Closed, + AzureDevOpsCommentThreadStatus.Closed, PullRequestDiscussionResolution.Resolved)] [InlineData( - TfsCommentThreadStatus.ByDesign, + AzureDevOpsCommentThreadStatus.ByDesign, PullRequestDiscussionResolution.Resolved)] public void Should_Set_Correct_Resolution( - TfsCommentThreadStatus status, + AzureDevOpsCommentThreadStatus status, PullRequestDiscussionResolution expectedResult) { // Given var id = 123; var filePath = "/foo.cs"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = id, Status = status, FilePath = filePath, - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; @@ -295,7 +295,7 @@ public sealed class TheGetCommentSourceExtension public void Should_Throw_If_Thread_Is_Null() { // Given - TfsPullRequestCommentThread thread = null; + AzureDevOpsPullRequestCommentThread thread = null; // When var result = Record.Exception(() => thread.GetCommentSource()); @@ -309,12 +309,12 @@ public void Should_Not_Throw_If_Properties_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = null, }; @@ -331,12 +331,12 @@ public void Should_Return_Comment_Source() // Given var commentSource = "foo"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; thread.SetCommentSource(commentSource); @@ -355,7 +355,7 @@ public sealed class TheSetCommentSourceExtension public void Should_Throw_If_Thread_Is_Null() { // Given - TfsPullRequestCommentThread thread = null; + AzureDevOpsPullRequestCommentThread thread = null; var value = "foo"; // When @@ -370,12 +370,12 @@ public void Should_Throw_If_Properties_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = null, }; var value = "foo"; @@ -393,12 +393,12 @@ public void Should_Set_Comment_Source() // Given var commentSource = "foo"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; @@ -416,7 +416,7 @@ public sealed class TheIsCommentSourceExtension public void Should_Throw_If_Thread_Is_Null() { // Given - TfsPullRequestCommentThread thread = null; + AzureDevOpsPullRequestCommentThread thread = null; var value = "foo"; // When @@ -431,12 +431,12 @@ public void Should_Not_Throw_If_Properties_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = null, }; var value = "foo"; @@ -454,12 +454,12 @@ public void Should_Return_True_For_Existing_Comment_Source() // Given var commentSource = "foo"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; thread.SetCommentSource(commentSource); @@ -476,12 +476,12 @@ public void Should_Return_False_For_Non_Existing_Comment_Source() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; thread.SetCommentSource("foo"); @@ -500,7 +500,7 @@ public sealed class TheGetIssueMessageExtension public void Should_Throw_If_Thread_Is_Null() { // Given - TfsPullRequestCommentThread thread = null; + AzureDevOpsPullRequestCommentThread thread = null; // When var result = Record.Exception(() => thread.GetIssueMessage()); @@ -514,12 +514,12 @@ public void Should_Not_Throw_If_Properties_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = null, }; @@ -536,12 +536,12 @@ public void Should_Return_Message() // Given var message = "foo"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; thread.SetIssueMessage(message); @@ -560,7 +560,7 @@ public sealed class TheSetIssueMessageExtension public void Should_Throw_If_Thread_Is_Null() { // Given - TfsPullRequestCommentThread thread = null; + AzureDevOpsPullRequestCommentThread thread = null; var value = "foo"; // When @@ -575,12 +575,12 @@ public void Should_Throw_If_Properties_Are_Null() { // Given var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = null, }; var value = "foo"; @@ -598,12 +598,12 @@ public void Should_Return_Message() // Given var message = "foo"; var thread = - new TfsPullRequestCommentThread + new AzureDevOpsPullRequestCommentThread { Id = 123, - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, FilePath = "/foo.cs", - Comments = new List(), + Comments = new List(), Properties = new Dictionary(), }; diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/ContentProviderTests.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/ContentProviderTests.cs similarity index 97% rename from src/Cake.Issues.PullRequests.Tfs.Tests/ContentProviderTests.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/ContentProviderTests.cs index e58b2e1..d727869 100644 --- a/src/Cake.Issues.PullRequests.Tfs.Tests/ContentProviderTests.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/ContentProviderTests.cs @@ -1,4 +1,4 @@ -namespace Cake.Issues.PullRequests.Tfs.Tests +namespace Cake.Issues.PullRequests.AzureDevOps.Tests { using System; using Shouldly; diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/Properties/AssemblyInfo.cs b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Properties/AssemblyInfo.cs similarity index 100% rename from src/Cake.Issues.PullRequests.Tfs.Tests/Properties/AssemblyInfo.cs rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/Properties/AssemblyInfo.cs diff --git a/src/Cake.Issues.PullRequests.Tfs.Tests/app.config b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/app.config similarity index 100% rename from src/Cake.Issues.PullRequests.Tfs.Tests/app.config rename to src/Cake.Issues.PullRequests.AzureDevOps.Tests/app.config diff --git a/src/Cake.Issues.PullRequests.Tfs.ruleset b/src/Cake.Issues.PullRequests.AzureDevOps.ruleset similarity index 98% rename from src/Cake.Issues.PullRequests.Tfs.ruleset rename to src/Cake.Issues.PullRequests.AzureDevOps.ruleset index f3985ae..66c8bf4 100644 --- a/src/Cake.Issues.PullRequests.Tfs.ruleset +++ b/src/Cake.Issues.PullRequests.AzureDevOps.ruleset @@ -1,5 +1,5 @@  - + diff --git a/src/Cake.Issues.PullRequests.Tfs.sln b/src/Cake.Issues.PullRequests.AzureDevOps.sln similarity index 83% rename from src/Cake.Issues.PullRequests.Tfs.sln rename to src/Cake.Issues.PullRequests.AzureDevOps.sln index 818fc58..34a4c57 100644 --- a/src/Cake.Issues.PullRequests.Tfs.sln +++ b/src/Cake.Issues.PullRequests.AzureDevOps.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28922.388 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Issues.PullRequests.Tfs", "Cake.Issues.PullRequests.Tfs\Cake.Issues.PullRequests.Tfs.csproj", "{1D046545-035B-4D7E-98C8-8AE6F5D0D289}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Issues.PullRequests.AzureDevOps", "Cake.Issues.PullRequests.AzureDevOps\Cake.Issues.PullRequests.AzureDevOps.csproj", "{1D046545-035B-4D7E-98C8-8AE6F5D0D289}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Issues.PullRequests.Tfs.Tests", "Cake.Issues.PullRequests.Tfs.Tests\Cake.Issues.PullRequests.Tfs.Tests.csproj", "{E938CD33-F1C7-45ED-A12C-7F18934AD131}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Issues.PullRequests.AzureDevOps.Tests", "Cake.Issues.PullRequests.AzureDevOps.Tests\Cake.Issues.PullRequests.AzureDevOps.Tests.csproj", "{E938CD33-F1C7-45ED-A12C-7F18934AD131}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{AAD732D5-4A2D-4A67-B571-7CD931983393}" ProjectSection(SolutionItems) = preProject diff --git a/src/Cake.Issues.PullRequests.Tfs.sln.DotSettings b/src/Cake.Issues.PullRequests.AzureDevOps.sln.DotSettings similarity index 100% rename from src/Cake.Issues.PullRequests.Tfs.sln.DotSettings rename to src/Cake.Issues.PullRequests.AzureDevOps.sln.DotSettings diff --git a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystem.cs b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs similarity index 74% rename from src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystem.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs index 9b71134..13133d6 100644 --- a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystem.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs @@ -1,31 +1,30 @@ -namespace Cake.Issues.PullRequests.Tfs +namespace Cake.Issues.PullRequests.AzureDevOps { using System; using System.Collections.Generic; using System.Globalization; using System.Linq; - using System.Threading; + using Cake.AzureDevOps.PullRequest; + using Cake.AzureDevOps.PullRequest.CommentThread; using Cake.Core.Diagnostics; using Cake.Core.IO; - using Cake.Issues.PullRequests.Tfs.Capabilities; - using Cake.Tfs.PullRequest; - using Cake.Tfs.PullRequest.CommentThread; + using Cake.Issues.PullRequests.AzureDevOps.Capabilities; /// - /// Class for writing issues to Team Foundation Server or Azure DevOps pull requests. + /// Class for writing issues to Azure DevOps pull requests. /// - internal sealed class TfsPullRequestSystem : BasePullRequestSystem, ITfsPullRequestSystem + internal sealed class AzureDevOpsPullRequestSystem : BasePullRequestSystem, IAzureDevOpsPullRequestSystem { - private readonly TfsPullRequestSystemSettings settings; - private readonly TfsPullRequest tfsPullRequest; + private readonly AzureDevOpsPullRequestSystemSettings settings; + private readonly AzureDevOpsPullRequest azureDevOpsPullRequest; /// - /// Initializes a new instance of the class. - /// Connects to the TFS server using NTLM authentication. + /// Initializes a new instance of the class. + /// Connects to the Azure DevOps server using NTLM authentication. /// /// The Cake log context. - /// Settings for accessing TFS. - public TfsPullRequestSystem(ICakeLog log, TfsPullRequestSystemSettings settings) + /// Settings for accessing Azure DevOps Server. + public AzureDevOpsPullRequestSystem(ICakeLog log, AzureDevOpsPullRequestSystemSettings settings) : base(log) { settings.NotNull(nameof(settings)); @@ -34,7 +33,7 @@ public TfsPullRequestSystem(ICakeLog log, TfsPullRequestSystemSettings settings) if (settings.CheckCommitId) { - this.AddCapability(new TfsCheckingCommitIdCapability(log, this)); + this.AddCapability(new AzureDevOpsCheckingCommitIdCapability(log, this)); this.Log.Information("Commit ID check capability is enabled."); } else @@ -44,7 +43,7 @@ public TfsPullRequestSystem(ICakeLog log, TfsPullRequestSystemSettings settings) if (settings.ManageDiscussionThreadStatus) { - this.AddCapability(new TfsDiscussionThreadsCapability(log, this)); + this.AddCapability(new AzureDevOpsDiscussionThreadsCapability(log, this)); this.Log.Information("Discussion thread status management capability is enabled."); } else @@ -54,20 +53,20 @@ public TfsPullRequestSystem(ICakeLog log, TfsPullRequestSystemSettings settings) // Filtering by modified files is always required as we otherwise no longer can compare issues // in a subsequent run as we lose information about file and line. - // See https://github.com/cake-contrib/Cake.Issues.PullRequests.Tfs/issues/46#issuecomment-419149355 - this.AddCapability(new TfsFilteringByModifiedFilesCapability(log, this)); + // See https://github.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/issues/46#issuecomment-419149355 + this.AddCapability(new AzureDevOpsFilteringByModifiedFilesCapability(log, this)); - this.tfsPullRequest = new TfsPullRequest(log, settings); + this.azureDevOpsPullRequest = new AzureDevOpsPullRequest(log, settings); } /// - TfsPullRequest ITfsPullRequestSystem.TfsPullRequest => this.tfsPullRequest; + AzureDevOpsPullRequest IAzureDevOpsPullRequestSystem.AzureDevOpsPullRequest => this.azureDevOpsPullRequest; /// public override bool Initialize(ReportIssuesToPullRequestSettings settings) { // Fail initialization if no pull request could be found. - return base.Initialize(settings) && this.tfsPullRequest.HasPullRequestLoaded; + return base.Initialize(settings) && this.azureDevOpsPullRequest.HasPullRequestLoaded; } /// @@ -77,7 +76,7 @@ public override IssueCommentFormat GetPreferredCommentFormat() } /// - bool ITfsPullRequestSystem.ValidatePullRequest() + bool IAzureDevOpsPullRequestSystem.ValidatePullRequest() { return this.ValidatePullRequest(); } @@ -104,7 +103,7 @@ protected override void InternalPostDiscussionThreads(IEnumerable issues foreach (var thread in threads) { - this.tfsPullRequest.CreateCommentThread(thread); + this.azureDevOpsPullRequest.CreateCommentThread(thread); } this.Log.Information("Posted {0} discussion threads", threads.Count); @@ -131,13 +130,13 @@ private static void AddCodeFlowProperties( /// /// Validates if a pull request could be found. - /// Depending on + /// Depending on /// the pull request instance can not be successfully loaded. /// /// True if a valid pull request instance exists. private bool ValidatePullRequest() { - if (this.tfsPullRequest.HasPullRequestLoaded) + if (this.azureDevOpsPullRequest.HasPullRequestLoaded) { return true; } @@ -146,7 +145,7 @@ private bool ValidatePullRequest() return false; } - private IEnumerable CreateDiscussionThreads( + private IEnumerable CreateDiscussionThreads( IEnumerable issues, string commentSource) { @@ -154,19 +153,19 @@ private IEnumerable CreateDiscussionThreads( issues.NotNull(nameof(issues)); this.Log.Verbose("Creating new discussion threads"); - var result = new List(); + var result = new List(); // Code flow properties var iterationId = 0; - IEnumerable changes = null; + IEnumerable changes = null; - if (this.tfsPullRequest.CodeReviewId > 0) + if (this.azureDevOpsPullRequest.CodeReviewId > 0) { iterationId = this.GetCodeFlowLatestIterationId(); changes = this.GetCodeFlowChanges(iterationId); } - // Filter isues not related to a file. + // Filter issues not related to a file. if (!this.settings.ReportIssuesNotRelatedToAFile) { issues = issues.Where(x => x.AffectedFileRelativePath != null); @@ -180,14 +179,14 @@ private IEnumerable CreateDiscussionThreads( issue.Line, issue.AffectedFileRelativePath); - var newThread = new TfsPullRequestCommentThread() + var newThread = new AzureDevOpsPullRequestCommentThread() { - Status = TfsCommentThreadStatus.Active, + Status = AzureDevOpsCommentThreadStatus.Active, }; - var discussionComment = new TfsComment + var discussionComment = new AzureDevOpsComment { - CommentType = TfsCommentType.System, + CommentType = AzureDevOpsCommentType.System, IsDeleted = false, Content = ContentProvider.GetContent(issue), }; @@ -197,7 +196,7 @@ private IEnumerable CreateDiscussionThreads( continue; } - newThread.Comments = new List { discussionComment }; + newThread.Comments = new List { discussionComment }; result.Add(newThread); } @@ -205,8 +204,8 @@ private IEnumerable CreateDiscussionThreads( } private bool AddThreadProperties( - TfsPullRequestCommentThread thread, - IEnumerable changes, + AzureDevOpsPullRequestCommentThread thread, + IEnumerable changes, IIssue issue, int iterationId, string commentSource) @@ -219,7 +218,7 @@ private bool AddThreadProperties( if (issue.AffectedFileRelativePath != null) { - if (this.tfsPullRequest.CodeReviewId > 0) + if (this.azureDevOpsPullRequest.CodeReviewId > 0) { var changeTrackingId = this.TryGetCodeFlowChangeTrackingId(changes, issue.AffectedFileRelativePath); @@ -254,14 +253,14 @@ private bool AddThreadProperties( private int GetCodeFlowLatestIterationId() { - var iterationId = this.tfsPullRequest.GetLatestIterationId(); + var iterationId = this.azureDevOpsPullRequest.GetLatestIterationId(); this.Log.Verbose("Determined iteration ID: {0}", iterationId); return iterationId; } - private IEnumerable GetCodeFlowChanges(int iterationId) + private IEnumerable GetCodeFlowChanges(int iterationId) { - var changes = this.tfsPullRequest.GetIterationChanges(iterationId); + var changes = this.azureDevOpsPullRequest.GetIterationChanges(iterationId); if (changes != null) { @@ -271,7 +270,7 @@ private IEnumerable GetCodeFlowChanges(int iterat return changes; } - private int TryGetCodeFlowChangeTrackingId(IEnumerable changes, FilePath path) + private int TryGetCodeFlowChangeTrackingId(IEnumerable changes, FilePath path) { changes.NotNull(nameof(changes)); path.NotNull(nameof(path)); diff --git a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.PullRequestSystem.cs b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.PullRequestSystem.cs similarity index 62% rename from src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.PullRequestSystem.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.PullRequestSystem.cs index da69a61..acf2ce0 100644 --- a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.PullRequestSystem.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.PullRequestSystem.cs @@ -1,18 +1,18 @@ -namespace Cake.Issues.PullRequests.Tfs +namespace Cake.Issues.PullRequests.AzureDevOps { using System; + using Cake.AzureDevOps.Authentication; using Cake.Core; using Cake.Core.Annotations; - using Cake.Tfs.Authentication; /// - /// Contains functionality related to . + /// Contains functionality related to . /// - public static partial class TfsPullRequestSystemAliases + public static partial class AzureDevOpsPullRequestSystemAliases { /// - /// Gets an object for writing issues to Team Foundation Server or Azure DevOps pull request - /// in a specific repository and for a specific source branch. + /// Gets an object for writing issues to Azure DevOps pull request in a specific repository and for a + /// specific source branch. /// /// The context. /// Full URL of the Git repository, @@ -20,44 +20,42 @@ public static partial class TfsPullRequestSystemAliases /// Supported URL schemes are HTTP, HTTPS and SSH. /// URLs using SSH scheme are converted to HTTPS. /// Branch for which the pull request is made. - /// Credentials to use to authenticate against Team Foundation Server or - /// Azure DevOps. - /// Object for writing issues to Team Foundation Server or Azure DevOps pull request. + /// Credentials to use to authenticate against Azure DevOps. + /// Object for writing issues to Azure DevOps pull request. /// - /// Report code analysis issues reported as MsBuild warnings to a TFS pull request: + /// Report code analysis issues reported as MsBuild warnings to an Azure DevOps pull request: /// /// /// /// [CakeMethodAlias] [CakeAliasCategory(PullRequestsAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPullRequestSystem TfsPullRequests( + public static IPullRequestSystem AzureDevOpsPullRequests( this ICakeContext context, Uri repositoryUrl, string sourceBranch, - ITfsCredentials credentials) + IAzureDevOpsCredentials credentials) { context.NotNull(nameof(context)); repositoryUrl.NotNull(nameof(repositoryUrl)); sourceBranch.NotNullOrWhiteSpace(nameof(sourceBranch)); credentials.NotNull(nameof(credentials)); - return context.TfsPullRequests(new TfsPullRequestSystemSettings(repositoryUrl, sourceBranch, credentials)); + return context.AzureDevOpsPullRequests(new AzureDevOpsPullRequestSystemSettings(repositoryUrl, sourceBranch, credentials)); } /// - /// Gets an object for writing issues to Team Foundation Server or Azure DevOps pull request - /// in a specific repository and with a specific ID. + /// Gets an object for writing issues to Azure DevOps pull request in a specific repository and with a specific ID. /// /// The context. /// Full URL of the Git repository, @@ -65,139 +63,136 @@ public static IPullRequestSystem TfsPullRequests( /// Supported URL schemes are HTTP, HTTPS and SSH. /// URLs using SSH scheme are converted to HTTPS. /// ID of the pull request. - /// Credentials to use to authenticate against Team Foundation Server or - /// Azure DevOps. - /// Object for writing issues to Team Foundation Server or Azure DevOps pull request. + /// Credentials to use to authenticate against Azure DevOps. + /// Object for writing issues to Azure DevOps pull request. /// - /// Report code analysis issues reported as MsBuild warnings to a TFS pull request: + /// Report code analysis issues reported as MsBuild warnings to an Azure DevOps Server pull request: /// /// /// /// [CakeMethodAlias] [CakeAliasCategory(PullRequestsAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPullRequestSystem TfsPullRequests( + public static IPullRequestSystem AzureDevOpsPullRequests( this ICakeContext context, Uri repositoryUrl, int pullRequestId, - ITfsCredentials credentials) + IAzureDevOpsCredentials credentials) { context.NotNull(nameof(context)); repositoryUrl.NotNull(nameof(repositoryUrl)); credentials.NotNull(nameof(credentials)); - return context.TfsPullRequests(new TfsPullRequestSystemSettings(repositoryUrl, pullRequestId, credentials)); + return context.AzureDevOpsPullRequests(new AzureDevOpsPullRequestSystemSettings(repositoryUrl, pullRequestId, credentials)); } /// - /// Gets an object for writing issues to Team Foundation Server or Azure DevOps pull request - /// where all required data is taken from the environment variables set by the Azure Pipelines / TFS build. + /// Gets an object for writing issues to Azure DevOps pull request where all required data is taken + /// from the environment variables set by Azure Pipelines. /// /// The context. - /// Credentials to use to authenticate against Team Foundation Server or - /// Azure DevOps. - /// Object for writing issues to Team Foundation Server or Azure DevOps pull request. + /// Credentials to use to authenticate against Azure DevOps. + /// Object for writing issues to Azure DevOps pull request. /// - /// Report code analysis issues reported as MsBuild warnings to a TFS pull request: + /// Report code analysis issues reported as MsBuild warnings to an Azure DevOps Server pull request: /// /// /// /// [CakeMethodAlias] [CakeAliasCategory(PullRequestsAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPullRequestSystem TfsPullRequests( + public static IPullRequestSystem AzureDevOpsPullRequests( this ICakeContext context, - ITfsCredentials credentials) + IAzureDevOpsCredentials credentials) { context.NotNull(nameof(context)); credentials.NotNull(nameof(credentials)); - return context.TfsPullRequests(new TfsPullRequestSystemSettings(credentials)); + return context.AzureDevOpsPullRequests(new AzureDevOpsPullRequestSystemSettings(credentials)); } /// - /// Gets an object for writing issues to Team Foundation Server or Azure DevOps pull request - /// where all required data (including authentication token) is taken from the environment variables set by the Azure Pipelines / TFS build. + /// Gets an object for writing issues to Azure DevOps pull request where all required data (including authentication token) + /// is taken from the environment variables set by Azure Pipelines. /// /// The context. - /// Object for writing issues to Team Foundation Server or Azure DevOps pull request. + /// Object for writing issues to Azure DevOps pull request. /// - /// Report code analysis issues reported as MsBuild warnings to a TFS pull request: + /// Report code analysis issues reported as MsBuild warnings to an Azure DevOps pull request: /// /// /// /// [CakeMethodAlias] [CakeAliasCategory(PullRequestsAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPullRequestSystem TfsPullRequests( + public static IPullRequestSystem AzureDevOpsPullRequests( this ICakeContext context) { context.NotNull(nameof(context)); - return context.TfsPullRequests(new TfsPullRequestSystemSettings()); + return context.AzureDevOpsPullRequests(new AzureDevOpsPullRequestSystemSettings()); } /// - /// Gets an object for writing issues to Team Foundation Server or Visual Studio Team Services pull request - /// using the specified settings. + /// Gets an object for writing issues to Azure DevOps pull request using the specified settings. /// /// The context. /// Settings for accessing the pull request system. - /// Object for writing issues to Team Foundation Server or Azure DevOps pull request. + /// Object for writing issues to Azure DevOps pull request. /// - /// Report code analysis issues reported as MsBuild warnings to a TFS pull request: + /// Report code analysis issues reported as MsBuild warnings to an Azure DevOps Server pull request: /// /// /// /// [CakeMethodAlias] [CakeAliasCategory(PullRequestsAliasConstants.PullRequestSystemCakeAliasCategory)] - public static IPullRequestSystem TfsPullRequests( + public static IPullRequestSystem AzureDevOpsPullRequests( this ICakeContext context, - TfsPullRequestSystemSettings settings) + AzureDevOpsPullRequestSystemSettings settings) { context.NotNull(nameof(context)); settings.NotNull(nameof(settings)); - return new TfsPullRequestSystem(context.Log, settings); + return new AzureDevOpsPullRequestSystem(context.Log, settings); } } } diff --git a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.cs b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.cs similarity index 55% rename from src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.cs index 518c7d3..5ac2340 100644 --- a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases.cs @@ -1,13 +1,12 @@ -namespace Cake.Issues.PullRequests.Tfs +namespace Cake.Issues.PullRequests.AzureDevOps { using Cake.Core.Annotations; /// - /// Contains functionality related to writing code analysis issues to Team Foundation Server or - /// Azure DevOps pull requests. + /// Contains functionality related to writing code analysis issues to Azure DevOps pull requests. /// [CakeAliasCategory(IssuesAliasConstants.MainCakeAliasCategory)] - public static partial class TfsPullRequestSystemAliases + public static partial class AzureDevOpsPullRequestSystemAliases { } } diff --git a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemSettings.cs b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemSettings.cs similarity index 61% rename from src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemSettings.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemSettings.cs index 12ebd5d..ac5c3eb 100644 --- a/src/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemSettings.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemSettings.cs @@ -1,72 +1,68 @@ -namespace Cake.Issues.PullRequests.Tfs +namespace Cake.Issues.PullRequests.AzureDevOps { using System; - using Cake.Tfs.Authentication; - using Cake.Tfs.PullRequest; + using Cake.AzureDevOps.Authentication; + using Cake.AzureDevOps.PullRequest; /// - /// Settings for . + /// Settings for . /// - public class TfsPullRequestSystemSettings : TfsPullRequestSettings + public class AzureDevOpsPullRequestSystemSettings : AzureDevOpsPullRequestSettings { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Full URL of the Git repository, /// eg. http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository. /// Supported URL schemes are HTTP, HTTPS and SSH. /// URLs using SSH scheme are converted to HTTPS. /// Branch for which the pull request is made. - /// Credentials to use to authenticate against Team Foundation Server or - /// Azure DevOps. - public TfsPullRequestSystemSettings(Uri repositoryUrl, string sourceBranch, ITfsCredentials credentials) + /// Credentials to use to authenticate against Azure DevOps. + public AzureDevOpsPullRequestSystemSettings(Uri repositoryUrl, string sourceBranch, IAzureDevOpsCredentials credentials) : base(repositoryUrl, sourceBranch, credentials) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Full URL of the Git repository, /// eg. http://myserver:8080/tfs/defaultcollection/myproject/_git/myrepository. /// Supported URL schemes are HTTP, HTTPS and SSH. /// URLs using SSH scheme are converted to HTTPS. /// ID of the pull request. - /// Credentials to use to authenticate against Team Foundation Server or - /// Azure DevOps. - public TfsPullRequestSystemSettings(Uri repositoryUrl, int pullRequestId, ITfsCredentials credentials) + /// Credentials to use to authenticate against Azure DevOps. + public AzureDevOpsPullRequestSystemSettings(Uri repositoryUrl, int pullRequestId, IAzureDevOpsCredentials credentials) : base(repositoryUrl, pullRequestId, credentials) { } /// - /// Initializes a new instance of the class - /// based on the instance of a class. + /// Initializes a new instance of the class + /// based on the instance of a class. /// /// Settings containing the parameters. - public TfsPullRequestSystemSettings(TfsPullRequestSettings settings) + public AzureDevOpsPullRequestSystemSettings(AzureDevOpsPullRequestSettings settings) : base(settings) { } /// - /// Initializes a new instance of the class - /// based on the environment variables set by the Azure Pipelines / TFS build. + /// Initializes a new instance of the class + /// based on the environment variables set by the Azure Pipelines. /// - /// Credentials to use to authenticate against Team Foundation Server or - /// Azure DevOps. - public TfsPullRequestSystemSettings(ITfsCredentials credentials) + /// Credentials to use to authenticate against Azure DevOps. + public AzureDevOpsPullRequestSystemSettings(IAzureDevOpsCredentials credentials) : base(credentials) { } /// - /// Initializes a new instance of the class - /// based on the environment variables set by the Azure Pipelines / TFS build - /// using the build authentication token. + /// Initializes a new instance of the class + /// based on the environment variables set by the Azure Pipelines using the build authentication token. /// - public TfsPullRequestSystemSettings() - : base(UsingTfsBuildOAuthToken()) + public AzureDevOpsPullRequestSystemSettings() + : base(UsingAzurePipelinesOAuthToken()) { } diff --git a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj similarity index 76% rename from src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj rename to src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj index 749a26d..d837bb4 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Cake.Issues.PullRequests.Tfs.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj @@ -7,17 +7,17 @@ full true - ..\Cake.Issues.PullRequests.Tfs.ruleset + ..\Cake.Issues.PullRequests.AzureDevOps.ruleset latest - Cake.Issues.PullRequests.Tfs + Cake.Issues.PullRequests.AzureDevOps -The Azure DevOps / Azure DevOps Server support for the Cake.Issues addin for Cake allows you to -write found issues as comments to Azure DevOps or Azure DevOps Server pull requests. +The Azure DevOps support for the Cake.Issues addin for Cake allows you to +write found issues as comments to Azure DevOps pull requests. -This addin provides the aliases for writing to Azure DevOps or Azure DevOps Server pull requests. +This addin provides the aliases for writing to Azure DevOps pull requests. It also requires the core Cake.Issues and Cake.Issues.PullRequests addins and one or more issue providers. See the Project Site for an overview of the whole ecosystem of addins for working with issues in Cake scripts. @@ -29,23 +29,23 @@ See the Project Site for an overview of the whole ecosystem of addins for workin https://cakeissues.net MIT git - https://github.com/cake-contrib/Cake.Issues.PullRequests.Tfs.git - https://github.com/cake-contrib/Cake.Issues.PullRequests.Tfs/releases/tag/0.7.2 + https://github.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps.git + https://github.com/cake-contrib/Cake.Issues.PullRequests.AzureDevOps/releases/tag/0.8.0 - bin\Debug\netstandard2.0\Cake.Issues.PullRequests.Tfs.xml + bin\Debug\netstandard2.0\Cake.Issues.PullRequests.AzureDevOps.xml - bin\Release\netstandard2.0\Cake.Issues.PullRequests.Tfs.xml + bin\Release\netstandard2.0\Cake.Issues.PullRequests.AzureDevOps.xml - + diff --git a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCheckingCommitIdCapability.cs b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCheckingCommitIdCapability.cs similarity index 54% rename from src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCheckingCommitIdCapability.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCheckingCommitIdCapability.cs index 6af80f4..3517f23 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCheckingCommitIdCapability.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCheckingCommitIdCapability.cs @@ -1,18 +1,18 @@ -namespace Cake.Issues.PullRequests.Tfs.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Capabilities { using Cake.Core.Diagnostics; /// - /// Implementation of a for . + /// Implementation of a for . /// - internal class TfsCheckingCommitIdCapability : BaseCheckingCommitIdCapability + internal class AzureDevOpsCheckingCommitIdCapability : BaseCheckingCommitIdCapability { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The Cake log context. /// Pull request system to which this capability belongs. - public TfsCheckingCommitIdCapability(ICakeLog log, ITfsPullRequestSystem pullRequestSystem) + public AzureDevOpsCheckingCommitIdCapability(ICakeLog log, IAzureDevOpsPullRequestSystem pullRequestSystem) : base(log, pullRequestSystem) { } @@ -25,7 +25,7 @@ public override string GetLastSourceCommitId() return string.Empty; } - return this.PullRequestSystem.TfsPullRequest.LastSourceCommitId; + return this.PullRequestSystem.AzureDevOpsPullRequest.LastSourceCommitId; } } } diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentExtensions.cs b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentExtensions.cs new file mode 100644 index 0000000..a687e82 --- /dev/null +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentExtensions.cs @@ -0,0 +1,26 @@ +namespace Cake.Issues.PullRequests.AzureDevOps.Capabilities +{ + using Cake.AzureDevOps.PullRequest.CommentThread; + + /// + /// Extensions for . + /// + internal static class AzureDevOpsCommentExtensions + { + /// + /// Converts a from Azure DevOps to a as used in this addin. + /// + /// Azure DevOps comment to convert. + /// Converted comment. + public static IPullRequestDiscussionComment ToPullRequestDiscussionComment(this AzureDevOpsComment comment) + { + comment.NotNull(nameof(comment)); + + return new PullRequestDiscussionComment() + { + Content = comment.Content, + IsDeleted = comment.IsDeleted, + }; + } + } +} diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentThreadStatusExtensions.cs b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentThreadStatusExtensions.cs new file mode 100644 index 0000000..60571ad --- /dev/null +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsCommentThreadStatusExtensions.cs @@ -0,0 +1,58 @@ +namespace Cake.Issues.PullRequests.AzureDevOps.Capabilities +{ + using Cake.AzureDevOps.PullRequest.CommentThread; + + /// + /// Extensions for enumeration. + /// + internal static class AzureDevOpsCommentThreadStatusExtensions + { + /// + /// Converts a from Azure DevOps to a as used in this addin. + /// + /// Azure DevOps status to convert. + /// Converted status. + public static PullRequestDiscussionStatus ToPullRequestDiscussionStatus(this AzureDevOpsCommentThreadStatus status) + { + switch (status) + { + case AzureDevOpsCommentThreadStatus.Unknown: + return PullRequestDiscussionStatus.Unknown; + case AzureDevOpsCommentThreadStatus.Active: + case AzureDevOpsCommentThreadStatus.Pending: + return PullRequestDiscussionStatus.Active; + case AzureDevOpsCommentThreadStatus.Fixed: + case AzureDevOpsCommentThreadStatus.WontFix: + case AzureDevOpsCommentThreadStatus.Closed: + case AzureDevOpsCommentThreadStatus.ByDesign: + return PullRequestDiscussionStatus.Resolved; + default: + throw new PullRequestIssuesException("Unknown enumeration value"); + } + } + + /// + /// Converts a from Azure DevOps to a as used in this addin. + /// + /// Azure DevOps status to convert. + /// Converted status. + public static PullRequestDiscussionResolution ToPullRequestDiscussionResolution(this AzureDevOpsCommentThreadStatus status) + { + switch (status) + { + case AzureDevOpsCommentThreadStatus.Unknown: + case AzureDevOpsCommentThreadStatus.Active: + case AzureDevOpsCommentThreadStatus.Pending: + return PullRequestDiscussionResolution.Unknown; + case AzureDevOpsCommentThreadStatus.Fixed: + case AzureDevOpsCommentThreadStatus.Closed: + case AzureDevOpsCommentThreadStatus.ByDesign: + return PullRequestDiscussionResolution.Resolved; + case AzureDevOpsCommentThreadStatus.WontFix: + return PullRequestDiscussionResolution.WontFix; + default: + throw new PullRequestIssuesException("Unknown enumeration value"); + } + } + } +} diff --git a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsDiscussionThreadsCapability.cs b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsDiscussionThreadsCapability.cs similarity index 76% rename from src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsDiscussionThreadsCapability.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsDiscussionThreadsCapability.cs index c6e758c..ec22c9c 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsDiscussionThreadsCapability.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsDiscussionThreadsCapability.cs @@ -1,20 +1,20 @@ -namespace Cake.Issues.PullRequests.Tfs.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Capabilities { using System.Collections.Generic; using System.Linq; using Cake.Core.Diagnostics; /// - /// Implementation of a for . + /// Implementation of a for . /// - internal class TfsDiscussionThreadsCapability : BaseDiscussionThreadsCapability + internal class AzureDevOpsDiscussionThreadsCapability : BaseDiscussionThreadsCapability { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The Cake log context. /// Pull request system to which this capability belongs. - public TfsDiscussionThreadsCapability(ICakeLog log, ITfsPullRequestSystem pullRequestSystem) + public AzureDevOpsDiscussionThreadsCapability(ICakeLog log, IAzureDevOpsPullRequestSystem pullRequestSystem) : base(log, pullRequestSystem) { } @@ -22,7 +22,7 @@ public TfsDiscussionThreadsCapability(ICakeLog log, ITfsPullRequestSystem pullRe /// protected override IEnumerable InternalFetchDiscussionThreads(string commentSource) { - var threads = this.PullRequestSystem.TfsPullRequest.GetCommentThreads(); + var threads = this.PullRequestSystem.AzureDevOpsPullRequest.GetCommentThreads(); var threadList = new List(); foreach (var thread in threads) @@ -55,7 +55,7 @@ protected override void InternalResolveDiscussionThreads(IEnumerable - /// Implementation of a for . + /// Implementation of a for . /// - internal class TfsFilteringByModifiedFilesCapability : BaseFilteringByModifiedFilesCapability + internal class AzureDevOpsFilteringByModifiedFilesCapability : BaseFilteringByModifiedFilesCapability { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The Cake log context. /// Pull request system to which this capability belongs. - public TfsFilteringByModifiedFilesCapability(ICakeLog log, ITfsPullRequestSystem pullRequestSystem) + public AzureDevOpsFilteringByModifiedFilesCapability(ICakeLog log, IAzureDevOpsPullRequestSystem pullRequestSystem) : base(log, pullRequestSystem) { } @@ -24,7 +24,7 @@ protected override IEnumerable InternalGetModifiedFilesInPullRequest() { this.Log.Verbose("Computing the list of files changed in this pull request..."); - return this.PullRequestSystem.TfsPullRequest.GetModifiedFiles(); + return this.PullRequestSystem.AzureDevOpsPullRequest.GetModifiedFiles(); } } } diff --git a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsPullRequestCommentThreadExtensions.cs b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsPullRequestCommentThreadExtensions.cs similarity index 74% rename from src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsPullRequestCommentThreadExtensions.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsPullRequestCommentThreadExtensions.cs index f89119f..eb2fe0f 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsPullRequestCommentThreadExtensions.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Capabilities/AzureDevOpsPullRequestCommentThreadExtensions.cs @@ -1,22 +1,22 @@ -namespace Cake.Issues.PullRequests.Tfs.Capabilities +namespace Cake.Issues.PullRequests.AzureDevOps.Capabilities { using System.Linq; - using Cake.Tfs.PullRequest.CommentThread; + using Cake.AzureDevOps.PullRequest.CommentThread; /// - /// Extensions for . + /// Extensions for . /// - internal static class TfsPullRequestCommentThreadExtensions + internal static class AzureDevOpsPullRequestCommentThreadExtensions { private const string CommentSourcePropertyName = "CakeIssuesCommentSource"; private const string IssueMessagePropertyName = "CakeIssuesIssueMessage"; /// - /// Converts a from TFS to a as used in this addin. + /// Converts a from Azure DevOps to a as used in this addin. /// - /// TFS thread to convert. + /// Azure DevOps thread to convert. /// Converted thread. - public static IPullRequestDiscussionThread ToPullRequestDiscussionThread(this TfsPullRequestCommentThread thread) + public static IPullRequestDiscussionThread ToPullRequestDiscussionThread(this AzureDevOpsPullRequestCommentThread thread) { thread.NotNull(nameof(thread)); @@ -36,7 +36,7 @@ public static IPullRequestDiscussionThread ToPullRequestDiscussionThread(this Tf /// /// Thread to get the value from. /// Comment source value. - public static string GetCommentSource(this TfsPullRequestCommentThread thread) + public static string GetCommentSource(this AzureDevOpsPullRequestCommentThread thread) { thread.NotNull(nameof(thread)); @@ -48,7 +48,7 @@ public static string GetCommentSource(this TfsPullRequestCommentThread thread) /// /// Thread for which the value should be set. /// Value to set as comment source. - public static void SetCommentSource(this TfsPullRequestCommentThread thread, string value) + public static void SetCommentSource(this AzureDevOpsPullRequestCommentThread thread, string value) { thread.NotNull(nameof(thread)); @@ -62,7 +62,7 @@ public static void SetCommentSource(this TfsPullRequestCommentThread thread, str /// Thread to check. /// Value to check for. /// True if the value is identical, False otherwise. - public static bool IsCommentSource(this TfsPullRequestCommentThread thread, string value) + public static bool IsCommentSource(this AzureDevOpsPullRequestCommentThread thread, string value) { thread.NotNull(nameof(thread)); @@ -75,7 +75,7 @@ public static bool IsCommentSource(this TfsPullRequestCommentThread thread, stri /// /// Thread to get the value from. /// Original message of the issue. - public static string GetIssueMessage(this TfsPullRequestCommentThread thread) + public static string GetIssueMessage(this AzureDevOpsPullRequestCommentThread thread) { thread.NotNull(nameof(thread)); @@ -87,7 +87,7 @@ public static string GetIssueMessage(this TfsPullRequestCommentThread thread) /// /// Thread for which the value should be set. /// Value to set as the original message. - public static void SetIssueMessage(this TfsPullRequestCommentThread thread, string value) + public static void SetIssueMessage(this AzureDevOpsPullRequestCommentThread thread, string value) { thread.NotNull(nameof(thread)); diff --git a/src/Cake.Issues.PullRequests.Tfs/ContentProvider.cs b/src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs similarity index 94% rename from src/Cake.Issues.PullRequests.Tfs/ContentProvider.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs index 2fe6b49..35975dc 100644 --- a/src/Cake.Issues.PullRequests.Tfs/ContentProvider.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs @@ -1,4 +1,4 @@ -namespace Cake.Issues.PullRequests.Tfs +namespace Cake.Issues.PullRequests.AzureDevOps { /// /// Class for providing the content for a pull request comment. diff --git a/src/Cake.Issues.PullRequests.Tfs/ITfsPullRequestSystem.cs b/src/Cake.Issues.PullRequests.AzureDevOps/IAzureDevOpsPullRequestSystem.cs similarity index 51% rename from src/Cake.Issues.PullRequests.Tfs/ITfsPullRequestSystem.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/IAzureDevOpsPullRequestSystem.cs index bcec27d..96887cf 100644 --- a/src/Cake.Issues.PullRequests.Tfs/ITfsPullRequestSystem.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/IAzureDevOpsPullRequestSystem.cs @@ -1,20 +1,20 @@ -namespace Cake.Issues.PullRequests.Tfs +namespace Cake.Issues.PullRequests.AzureDevOps { - using Cake.Tfs.PullRequest; + using Cake.AzureDevOps.PullRequest; /// - /// Interface for writing issues to Team Foundation Server or Azure DevOps pull requests. + /// Interface for writing issues to Azure DevOps pull requests. /// - internal interface ITfsPullRequestSystem : IPullRequestSystem + internal interface IAzureDevOpsPullRequestSystem : IPullRequestSystem { /// /// Gets information about the pull request. /// - TfsPullRequest TfsPullRequest { get; } + AzureDevOpsPullRequest AzureDevOpsPullRequest { get; } /// /// Validates if a pull request could be found. - /// Depending on + /// Depending on /// the pull request instance can be null for subsequent calls. /// /// True if a valid pull request instance exists. diff --git a/src/Cake.Issues.PullRequests.Tfs/Properties/AssemblyInfo.cs b/src/Cake.Issues.PullRequests.AzureDevOps/Properties/AssemblyInfo.cs similarity index 88% rename from src/Cake.Issues.PullRequests.Tfs/Properties/AssemblyInfo.cs rename to src/Cake.Issues.PullRequests.AzureDevOps/Properties/AssemblyInfo.cs index 8a2d63f..8467724 100644 --- a/src/Cake.Issues.PullRequests.Tfs/Properties/AssemblyInfo.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Properties/AssemblyInfo.cs @@ -11,5 +11,5 @@ [assembly: Guid("1d046545-035b-4d7e-98c8-8ae6f5d0d289")] [assembly: CLSCompliant(true)] -[assembly: InternalsVisibleTo("Cake.Issues.PullRequests.Tfs.Tests")] +[assembly: InternalsVisibleTo("Cake.Issues.PullRequests.AzureDevOps.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Required for NSubstitute \ No newline at end of file diff --git a/src/Cake.Issues.PullRequests.Tfs/app.config b/src/Cake.Issues.PullRequests.AzureDevOps/app.config similarity index 100% rename from src/Cake.Issues.PullRequests.Tfs/app.config rename to src/Cake.Issues.PullRequests.AzureDevOps/app.config diff --git a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentExtensions.cs b/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentExtensions.cs deleted file mode 100644 index a963e57..0000000 --- a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Cake.Issues.PullRequests.Tfs.Capabilities -{ - using Cake.Tfs.PullRequest.CommentThread; - - /// - /// Extensions for . - /// - internal static class TfsCommentExtensions - { - /// - /// Converts a from TFS to a as used in this addin. - /// - /// TFS comment to convert. - /// Converted comment. - public static IPullRequestDiscussionComment ToPullRequestDiscussionComment(this TfsComment comment) - { - comment.NotNull(nameof(comment)); - - return new PullRequestDiscussionComment() - { - Content = comment.Content, - IsDeleted = comment.IsDeleted, - }; - } - } -} diff --git a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentThreadStatusExtensions.cs b/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentThreadStatusExtensions.cs deleted file mode 100644 index 2618276..0000000 --- a/src/Cake.Issues.PullRequests.Tfs/Capabilities/TfsCommentThreadStatusExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Cake.Issues.PullRequests.Tfs.Capabilities -{ - using Cake.Tfs.PullRequest.CommentThread; - - /// - /// Extensions for enumeration. - /// - internal static class TfsCommentThreadStatusExtensions - { - /// - /// Converts a from TFS to a as used in this addin. - /// - /// TFS status to convert. - /// Converted status. - public static PullRequestDiscussionStatus ToPullRequestDiscussionStatus(this TfsCommentThreadStatus status) - { - switch (status) - { - case TfsCommentThreadStatus.Unknown: - return PullRequestDiscussionStatus.Unknown; - case TfsCommentThreadStatus.Active: - case TfsCommentThreadStatus.Pending: - return PullRequestDiscussionStatus.Active; - case TfsCommentThreadStatus.Fixed: - case TfsCommentThreadStatus.WontFix: - case TfsCommentThreadStatus.Closed: - case TfsCommentThreadStatus.ByDesign: - return PullRequestDiscussionStatus.Resolved; - default: - throw new PullRequestIssuesException("Unknown enumeration value"); - } - } - - /// - /// Converts a from TFS to a as used in this addin. - /// - /// TFS status to convert. - /// Converted status. - public static PullRequestDiscussionResolution ToPullRequestDiscussionResolution(this TfsCommentThreadStatus status) - { - switch (status) - { - case TfsCommentThreadStatus.Unknown: - case TfsCommentThreadStatus.Active: - case TfsCommentThreadStatus.Pending: - return PullRequestDiscussionResolution.Unknown; - case TfsCommentThreadStatus.Fixed: - case TfsCommentThreadStatus.Closed: - case TfsCommentThreadStatus.ByDesign: - return PullRequestDiscussionResolution.Resolved; - case TfsCommentThreadStatus.WontFix: - return PullRequestDiscussionResolution.WontFix; - default: - throw new PullRequestIssuesException("Unknown enumeration value"); - } - } - } -} From 15b7191f8b423d5f9bd5815a470708a10a4e8c55 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 5 Oct 2019 19:57:22 +0200 Subject: [PATCH 38/44] (GH-142) Update to Cake.Issues 0.8.0 --- .../Cake.Issues.PullRequests.AzureDevOps.Tests.csproj | 6 +++--- .../AzureDevOpsPullRequestSystem.cs | 8 +------- .../Cake.Issues.PullRequests.AzureDevOps.csproj | 4 ++-- .../ContentProvider.cs | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj index 0e3ca19..0b23fff 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj @@ -16,9 +16,9 @@ - - - + + + diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs index 13133d6..365a417 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystem.cs @@ -69,12 +69,6 @@ public override bool Initialize(ReportIssuesToPullRequestSettings settings) return base.Initialize(settings) && this.azureDevOpsPullRequest.HasPullRequestLoaded; } - /// - public override IssueCommentFormat GetPreferredCommentFormat() - { - return IssueCommentFormat.Markdown; - } - /// bool IAzureDevOpsPullRequestSystem.ValidatePullRequest() { @@ -246,7 +240,7 @@ private bool AddThreadProperties( // Add a custom property to be able to return issue message from existing threads, // without any formatting done by this addin, back to Cake.Issues.PullRequests. - thread.SetIssueMessage(issue.Message); + thread.SetIssueMessage(issue.MessageText); return true; } diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj index d837bb4..01cf5e2 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj @@ -43,8 +43,8 @@ See the Project Site for an overview of the whole ecosystem of addins for workin - - + + diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs b/src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs index 35975dc..0ab8382 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs +++ b/src/Cake.Issues.PullRequests.AzureDevOps/ContentProvider.cs @@ -12,7 +12,7 @@ internal static class ContentProvider /// Comment content for the issue. public static string GetContent(IIssue issue) { - var result = issue.Message; + var result = issue.Message(IssueCommentFormat.Markdown); if (string.IsNullOrWhiteSpace(issue.Rule)) { return result; From a64f8c6a68e0be93fea279b9081f2e7fe37a3972 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 12 Oct 2019 08:20:17 +0200 Subject: [PATCH 39/44] Update documentation to addin rename (#144) --- ... cake.issues.pullrequests.azuredevops.png} | Bin docs/examples/azure-pipelines.md | 23 ++++---- docs/examples/index.cshtml | 2 +- docs/examples/pullrequest-id.md | 23 ++++---- docs/examples/repository-information.md | 23 ++++---- docs/features.md | 14 ++--- docs/index.cshtml | 8 +-- docs/requirements.md | 6 +- docs/setup.md | 54 +++++++++--------- 9 files changed, 75 insertions(+), 78 deletions(-) rename docs/{cake.issues.pullrequests.tfs.png => cake.issues.pullrequests.azuredevops.png} (100%) diff --git a/docs/cake.issues.pullrequests.tfs.png b/docs/cake.issues.pullrequests.azuredevops.png similarity index 100% rename from docs/cake.issues.pullrequests.tfs.png rename to docs/cake.issues.pullrequests.azuredevops.png diff --git a/docs/examples/azure-pipelines.md b/docs/examples/azure-pipelines.md index 662754b..6078ba5 100644 --- a/docs/examples/azure-pipelines.md +++ b/docs/examples/azure-pipelines.md @@ -1,21 +1,20 @@ --- Order: 30 Title: Using with Azure Pipelines -Description: Example how to use the Cake.Issues.PullRequests.Tfs addin from an Azure Pipelines build. +Description: Example how to use the Cake.Issues.PullRequests.AzureDevOps addin from an Azure Pipelines build. --- -This example shows how to write issues as comments to a Team Foundation Server (TFS) or -Azure DevOps pull request from an Azure Pipelines build. +This example shows how to write issues as comments to an Azure DevOps pull request from an Azure Pipelines build. -To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, -the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, +To write issues as comments to Azure DevOps pull requests you need to import the core addin, +the core pull request addin, the Azure DevOps support including the Cake.AzureDevOps addin, and one or more issue providers, in this example for JetBrains InspectCode: ```csharp #addin "Cake.Issues" #addin "Cake.Issues.InspectCode" #addin "Cake.Issues.PullRequests" -#addin "Cake.Issues.PullRequests.Tfs" -#addin "Cake.Tfs" +#addin "Cake.Issues.PullRequests.AzureDevOps" +#addin "Cake.AzureDevOps" ``` :::{.alert .alert-warning} @@ -27,7 +26,7 @@ See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-v In the following task we'll first determine if the build is running on Azure DevOps and for a pull request, then read the remote repository URL and pull request id from environment variables set by the Azure Pipelines build -and finally call the [TfsPullRequests] alias using the OAuth token provided by the Azure Pipeline build. +and finally call the [AzureDevOpsPullRequests] alias using the OAuth token provided by the Azure Pipeline build. :::{.alert .alert-info} Please note that you'll need to setup your Azure Pipelines build to allow scripts to @@ -68,10 +67,10 @@ Task("ReportIssuesToPullRequest").Does(() => ReportIssuesToPullRequest( InspectCodeIssuesFromFilePath( @"C:\build\inspectcode.log"), - TfsPullRequests( + AzureDevOpsPullRequests( repositoryUrl, pullRequestId, - TfsAuthenticationOAuth(EnvironmentVariable("SYSTEM_ACCESSTOKEN"))), + AzureDevOpsAuthenticationOAuth(EnvironmentVariable("SYSTEM_ACCESSTOKEN"))), repoRootFolder); } } @@ -79,6 +78,6 @@ Task("ReportIssuesToPullRequest").Does(() => }); ``` -[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C -[Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options?view=vsts&tabs=yaml#allow-scripts-to-access-the-oauth-token +[AzureDevOpsPullRequests]: ../../../../api/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases/64912B0A +[Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options#allow-scripts-to-access-the-oauth-token [OAuth authentication from Azure Pipelines]: ../setup#oauth-authentication-from-azure-pipelines diff --git a/docs/examples/index.cshtml b/docs/examples/index.cshtml index 31b5f6c..17e2702 100644 --- a/docs/examples/index.cshtml +++ b/docs/examples/index.cshtml @@ -1,6 +1,6 @@ --- Title: Examples -Description: Examples for using the Cake.Issues.PullRequests.Tfs addin. +Description: Examples for using the Cake.Issues.PullRequests.AzureDevOps addin. ---

@Html.Raw(Model.String(DocsKeys.Description))

diff --git a/docs/examples/pullrequest-id.md b/docs/examples/pullrequest-id.md index d37eaa3..843390d 100644 --- a/docs/examples/pullrequest-id.md +++ b/docs/examples/pullrequest-id.md @@ -1,10 +1,9 @@ --- Order: 10 Title: Using with pull request id -Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with pull request id. +Description: Example how to use the Cake.Issues.PullRequests.AzureDevOps addin with pull request id. --- -This example shows how to write issues as comments to a Team Foundation Server (TFS) or -Azure DevOps pull request while using pull request id. +This example shows how to write issues as comments to an Azure DevOps pull request while using pull request id. To determine the remote repository URL you need the [Cake.Git] addin: @@ -12,16 +11,16 @@ To determine the remote repository URL you need the [Cake.Git] addin: #addin "Cake.Git" ``` -To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, -the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, +To write issues as comments to Azure DevOps pull requests you need to import the core addin, +the core pull request addin, the Azure DevOps support including the Cake.AzureDevOps addin, and one or more issue providers, in this example for JetBrains InspectCode: ```csharp #addin "Cake.Issues" #addin "Cake.Issues.InspectCode" #addin "Cake.Issues.PullRequests" -#addin "Cake.Issues.PullRequests.Tfs" -#addin "Cake.Tfs" +#addin "Cake.Issues.PullRequests.AzureDevOps" +#addin "Cake.AzureDevOps" ``` :::{.alert .alert-warning} @@ -32,8 +31,8 @@ See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-v ::: In the following task we'll first determine the remote repository URL and -with this information call the [TfsPullRequests] alias, -which will authenticate through NTLM to a on-premise TFS instance: +with this information call the [AzureDevOpsPullRequests] alias, +which will authenticate through NTLM to an on-premise Azure DevOps Server instance: ```csharp Task("ReportIssuesToPullRequest").Does(() => @@ -45,13 +44,13 @@ Task("ReportIssuesToPullRequest").Does(() => ReportIssuesToPullRequest( InspectCodeIssuesFromFilePath( @"C:\build\inspectcode.log"), - TfsPullRequests( + AzureDevOpsPullRequests( repoRemoteUrl, pullRequestId, - TfsAuthenticationNtlm()), + AzureDevOpsAuthenticationNtlm()), repoRootFolder); }); ``` -[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/BC3F9B2C +[AzureDevOpsPullRequests]: ../../../../api/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases/64912B0A [Cake.Git]: https://www.nuget.org/packages/Cake.Git/ diff --git a/docs/examples/repository-information.md b/docs/examples/repository-information.md index a31c159..804ef7c 100644 --- a/docs/examples/repository-information.md +++ b/docs/examples/repository-information.md @@ -1,10 +1,9 @@ --- Order: 20 Title: Using with repository remote url and source branch name -Description: Example how to use the Cake.Issues.PullRequests.Tfs addin with repository remote url and source branch name. +Description: Example how to use the Cake.Issues.PullRequests.AzureDevOps addin with repository remote url and source branch name. --- -This example shows how to write issues as comments to a Team Foundation Server (TFS) or -Azure DevOps pull request while using repository information. +This example shows how to write issues as comments to an Azure DevOps pull request while using repository information. To determine the remote repository URL and source branch of the pull request you need the [Cake.Git] addin: @@ -12,16 +11,16 @@ To determine the remote repository URL and source branch of the pull request you #addin "Cake.Git" ``` -To write issues as comments to TFS or Azure DevOps pull requests you need to import the core addin, -the core pull request addin, the TFS/Azure DevOps support including the Cake TFS addin, and one or more issue providers, +To write issues as comments to Azure DevOps pull requests you need to import the core addin, +the core pull request addin, the Azure DevOps support including the Cake.AzureDevOps addin, and one or more issue providers, in this example for JetBrains InspectCode: ```csharp #addin "Cake.Issues" #addin "Cake.Issues.InspectCode" #addin "Cake.Issues.PullRequests" -#addin "Cake.Issues.PullRequests.Tfs" -#addin "Cake.Tfs" +#addin "Cake.Issues.PullRequests.AzureDevOps" +#addin "Cake.AzureDevOps" ``` :::{.alert .alert-warning} @@ -32,8 +31,8 @@ See [pinning addin versions](https://cakebuild.net/docs/tutorials/pinning-cake-v ::: In the following task we'll first determine the remote repository URL and -source branch of the pull request and with this information call the [TfsPullRequests] alias, -which will authenticate through NTLM to a on-premise TFS instance: +source branch of the pull request and with this information call the [AzureDevOpsPullRequests] alias, +which will authenticate through NTLM to an on-premise Azure DevOps Server instance: ```csharp Task("ReportIssuesToPullRequest").Does(() => @@ -46,13 +45,13 @@ Task("ReportIssuesToPullRequest").Does(() => ReportIssuesToPullRequest( InspectCodeIssuesFromFilePath( @"C:\build\inspectcode.log"), - TfsPullRequests( + AzureDevOpsPullRequests( repoRemoteUrl, sourceBranchName, - TfsAuthenticationNtlm()), + AzureDevOpsAuthenticationNtlm()), repoRootFolder); }); ``` -[TfsPullRequests]: ../../../../api/Cake.Issues.PullRequests.Tfs/TfsPullRequestSystemAliases/8B150084 +[AzureDevOpsPullRequests]: ../../../../api/Cake.Issues.PullRequests.AzureDevOps/AzureDevOpsPullRequestSystemAliases/8D75BECA [Cake.Git]: https://www.nuget.org/packages/Cake.Git/ diff --git a/docs/features.md b/docs/features.md index b2ff694..b3b4bc2 100644 --- a/docs/features.md +++ b/docs/features.md @@ -1,9 +1,9 @@ --- Order: 20 Title: Features -Description: Features of the Cake.Issues.PullRequests.Tfs addin. +Description: Features of the Cake.Issues.PullRequests.AzureDevOps addin. --- -The [Cake.Issues.PullRequests.Tfs addin] provides the following features. +The [Cake.Issues.PullRequests.AzureDevOps addin] provides the following features. :::{.alert .alert-info} There's a [demo repository] available which you can fork and to which you can create pull requests to test the integration functionality. @@ -11,7 +11,7 @@ There's a [demo repository] available which you can fork and to which you can cr # Basic features -* Writes issues as comments to Team Foundation Server (TFS) or [Azure DevOps] pull requests. +* Writes issues as comments to [Azure DevOps] pull requests. * Identification of pull requests through source branch or pull request ID. * Comments written by the addin will be rendered with a specific icon corresponding to the state of the issue. * Adds rule number and, if provided by the issue provider, link to the rule description to the comment. @@ -19,7 +19,7 @@ There's a [demo repository] available which you can fork and to which you can cr # Supported capabilities -The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. +The [Cake.Issues.PullRequests.AzureDevOps addin] supports all [Core features]. | | Capability | Remarks | |--------------------------------------------------------------------|--------------------------------|--------------------------------| @@ -29,7 +29,7 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. # Supported authentication methods -| On-Premise Team Foundation Server | Azure DevOps | Authentication method | +| Azure DevOps Server | Azure DevOps Service | Authentication method | |--------------------------------------------------------------------|--------------------------------------------------------------------|--------------------------------| | | | NTLM | | | | Basic authentication | @@ -39,10 +39,10 @@ The [Cake.Issues.PullRequests.Tfs addin] supports all [Core features]. For detailed instructions how to connect using the different methods see [Setup instructions]. -![Cake.Issues.PullRequests.Tfs](cake.issues.pullrequests.tfs.png "Cake.Issues.PullRequests.Tfs") +![Cake.Issues.PullRequests.AzureDevOps](cake.issues.pullrequests.azuredevops.png "Cake.Issues.PullRequests.AzureDevOps") [demo repository]: https://dev.azure.com/pberger/Cake.Issues-Demo -[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[Cake.Issues.PullRequests.AzureDevOps addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.AzureDevOps [Azure DevOps]: https://azure.microsoft.com/en-us/services/devops/ [Core features]: ../../overview/features#supported-core-functionality [Setup instructions]: setup diff --git a/docs/index.cshtml b/docs/index.cshtml index 4fa97ba..fbf68af 100644 --- a/docs/index.cshtml +++ b/docs/index.cshtml @@ -1,10 +1,10 @@ --- -Title: TFS & Azure DevOps -Description: Support for Team Foundation Server and Azure DevOps. +Title: Azure DevOps +Description: Support for Azure DevOps. ---

- Support for Team Foundation Server (TFS) and Azure DevOps is implemented in the - Cake.Issues.PullRequests.Tfs addin. + Support for Azure DevOps is implemented in the + Cake.Issues.PullRequests.AzureDevOps addin.

@Html.Partial("_ChildPages") \ No newline at end of file diff --git a/docs/requirements.md b/docs/requirements.md index bfe4a82..9c24511 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -1,9 +1,9 @@ --- Order: 10 Title: Requirements -Description: Requirements for the Cake.Issues.PullRequests.Tfs addin. +Description: Requirements for the Cake.Issues.PullRequests.AzureDevOps addin. --- -The requirements for using the [Cake.Issues.PullRequests.Tfs addin] are listed in the [release notes] for any specific version. +The requirements for using the [Cake.Issues.PullRequests.AzureDevOps addin] are listed in the [release notes] for any specific version. -[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs +[Cake.Issues.PullRequests.AzureDevOps addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.AzureDevOps [release notes]: release-notes diff --git a/docs/setup.md b/docs/setup.md index 17aced5..8d67acd 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -1,9 +1,9 @@ --- Order: 30 Title: Setup -Description: Instructions how to setup the Cake.Issues.PullRequests.Tfs addin. +Description: Instructions how to setup the Cake.Issues.PullRequests.AzureDevOps addin. --- -This page describes the different ways how the [Cake.Issues.PullRequests.Tfs addin] can be setup. +This page describes the different ways how the [Cake.Issues.PullRequests.AzureDevOps addin] can be setup. # NTLM authentication @@ -11,10 +11,10 @@ This page describes the different ways how the [Cake.Issues.PullRequests.Tfs add NTLM authentication is only available for on-premise Team Foundation Server. ::: -To authenticate with NTLM you can use the [TfsAuthenticationNtlm] alias from the [Cake.Tfs addin]. +To authenticate with NTLM you can use the [AzureDevOpsAuthenticationNtlm] alias from the [Cake.AzureDevOps addin]. The user needs to have `Contribute to pull requests` permission for the specific repository to -allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. +allow [Cake.Issues.PullRequests.AzureDevOps addin] to post issues as comments to pull requests. # Basic authentication @@ -22,22 +22,22 @@ allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull re Basic authentication is only available for on-premise Team Foundation Server. ::: -To authenticate with basic authentication you can use the [TfsAuthenticationBasic] alias from the [Cake.Tfs addin] and -need to [Configure TFS to use Basic Authentication]. +To authenticate with basic authentication you can use the [AzureDevOpsAuthenticationBasic] alias from the [Cake.AzureDevOps addin] and +need to [Configure AzureDevOps Server to use Basic Authentication]. The user needs to have `Contribute to pull requests` permission for the specific repository to -allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. +allow [Cake.Issues.PullRequests.AzureDevOps addin] to post issues as comments to pull requests. # Personal access token -To authenticate with an personal access token you can use the [TfsAuthenticationPersonalAccessToken] alias from the [Cake.Tfs addin]. +To authenticate with an personal access token you can use the [AzureDevOpsAuthenticationPersonalAccessToken] alias from the [Cake.AzureDevOps addin]. -If you want to use the [Cake.Issues.PullRequests.Tfs addin] with an personal access token see -[Authenticate access with personal access tokens for Azure DevOps Services and TFS] for instructions how to create +If you want to use the [Cake.Issues.PullRequests.AzureDevOps addin] with an personal access token see +[Authenticate access with personal access tokens for Azure DevOps] for instructions how to create a personal access token. The access token needs to have the scope `Code (read and write)` set and the user needs to have `Contribute to pull requests` -permission for the specific repository to allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. +permission for the specific repository to allow [Cake.Issues.PullRequests.AzureDevOps addin] to post issues as comments to pull requests. # OAuth authentication from Azure Pipelines @@ -45,14 +45,14 @@ permission for the specific repository to allow [Cake.Issues.PullRequests.Tfs ad OAuth authentication is only available for Azure DevOps. ::: -If you want to use the [Cake.Issues.PullRequests.Tfs addin] from an Azure Pipelines you can authenticate using the +If you want to use the [Cake.Issues.PullRequests.AzureDevOps addin] from an Azure Pipelines you can authenticate using the OAuth token provided to the build. For this you need to enable the [Allow scripts to access the OAuth token] option on the build definition. -To authenticate you can use the [TfsAuthenticationOAuth] alias from the [Cake.Tfs addin]. +To authenticate you can use the [AzureDevOpsAuthenticationOAuth] alias from the [Cake.AzureDevOps addin]. The user under which the build runs, named ` Build Service ()` (e.g. `Cake.Issues-Demo Build Service (cake-contrib)`), -needs to have `Contribute to pull requests` permission for the specific repository to allow [Cake.Issues.PullRequests.Tfs addin] +needs to have `Contribute to pull requests` permission for the specific repository to allow [Cake.Issues.PullRequests.AzureDevOps addin] to post issues as comments to pull requests. # Azure Active Directory @@ -61,18 +61,18 @@ to post issues as comments to pull requests. OAuth authentication is only available for Azure DevOps. ::: -To authenticate with Azure Active Directory you can use the [TfsAuthenticationAzureActiveDirectory] alias from the [Cake.Tfs addin]. +To authenticate with Azure Active Directory you can use the [AzureDevOpsAuthenticationAzureActiveDirectory] alias from the [Cake.AzureDevOps addin]. The user needs to have `Contribute to pull requests` permission for the specific repository to -allow [Cake.Issues.PullRequests.Tfs addin] to post issues as comments to pull requests. - -[Cake.Issues.PullRequests.Tfs addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.Tfs -[Cake.Tfs addin]: https://www.nuget.org/packages/Cake.Tfs -[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/auth/tfs-basic-auth?view=tfs-2018#configure-tfs-to-use-basic-authentication -[Authenticate access with personal access tokens for Azure DevOps Services and TFS]: https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=vsts -[Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options?view=vsts&tabs=yaml#allow-scripts-to-access-the-oauth-token -[TfsAuthenticationNtlm]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/6989592E -[TfsAuthenticationBasic]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/86407B1D -[TfsAuthenticationPersonalAccessToken]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E4AC3E3 -[TfsAuthenticationOAuth]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/B5D45B5D -[TfsAuthenticationAzureActiveDirectory]: https://cakebuild.net/api/Cake.Tfs/TfsAliases/0E787800 +allow [Cake.Issues.PullRequests.AzureDevOps addin] to post issues as comments to pull requests. + +[Cake.Issues.PullRequests.AzureDevOps addin]: https://www.nuget.org/packages/Cake.Issues.PullRequests.AzureDevOps +[Cake.AzureDevOps addin]: https://www.nuget.org/packages/Cake.AzureDevOps +[Configure TFS to use Basic Authentication]: https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/auth/tfs-basic-auth#configure-tfs-to-use-basic-authentication +[Authenticate access with personal access tokens for Azure DevOps]: https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate +[Allow scripts to access the OAuth token]: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/options#allow-scripts-to-access-the-oauth-token +[AzureDevOpsAuthenticationNtlm]: https://cakebuild.net/api/Cake.AzureDevOps/AzureDevOpsAliases/F2A040B7 +[AzureDevOpsAuthenticationBasic]: https://cakebuild.net/api/Cake.AzureDevOps/AzureDevOpsAliases/7CD679FF +[AzureDevOpsAuthenticationPersonalAccessToken]: https://cakebuild.net/api/Cake.AzureDevOps/AzureDevOpsAliases/F4DCC101 +[AzureDevOpsAuthenticationOAuth]: https://cakebuild.net/api/Cake.AzureDevOps/AzureDevOpsAliases/988E9C28 +[AzureDevOpsAuthenticationAzureActiveDirectory]: https://cakebuild.net/api/Cake.AzureDevOps/AzureDevOpsAliases/0B9F5DF6 From 266925373cfacfe22c8a45053af4b99fef332901 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 13 Oct 2019 15:19:19 +0200 Subject: [PATCH 40/44] Trigger pull request build for PRs targetting release or hotfix branches (#145) --- azure-pipelines.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 133a0f8..cfc3da0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,6 +6,8 @@ trigger: pr: - develop +- release/* +- hotfix/* jobs: - job: Windows From 957d5d0ddd3978a2ad2e9bc0145dadc044401e16 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 13 Oct 2019 17:14:36 +0200 Subject: [PATCH 41/44] Rename Team Foundation Server to Azure DevOps Server (#146) --- docs/setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/setup.md b/docs/setup.md index 8d67acd..ac9f128 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -8,7 +8,7 @@ This page describes the different ways how the [Cake.Issues.PullRequests.AzureDe # NTLM authentication :::{.alert .alert-info} -NTLM authentication is only available for on-premise Team Foundation Server. +NTLM authentication is only available for on-premise Azure DevOps Server. ::: To authenticate with NTLM you can use the [AzureDevOpsAuthenticationNtlm] alias from the [Cake.AzureDevOps addin]. @@ -19,7 +19,7 @@ allow [Cake.Issues.PullRequests.AzureDevOps addin] to post issues as comments to # Basic authentication :::{.alert .alert-info} -Basic authentication is only available for on-premise Team Foundation Server. +Basic authentication is only available for on-premise Azure DevOps Server. ::: To authenticate with basic authentication you can use the [AzureDevOpsAuthenticationBasic] alias from the [Cake.AzureDevOps addin] and @@ -42,7 +42,7 @@ permission for the specific repository to allow [Cake.Issues.PullRequests.AzureD # OAuth authentication from Azure Pipelines :::{.alert .alert-info} -OAuth authentication is only available for Azure DevOps. +OAuth authentication is only available for Azure DevOps Service. ::: If you want to use the [Cake.Issues.PullRequests.AzureDevOps addin] from an Azure Pipelines you can authenticate using the @@ -58,7 +58,7 @@ to post issues as comments to pull requests. # Azure Active Directory :::{.alert .alert-info} -OAuth authentication is only available for Azure DevOps. +OAuth authentication is only available for Azure DevOps Service. ::: To authenticate with Azure Active Directory you can use the [AzureDevOpsAuthenticationAzureActiveDirectory] alias from the [Cake.AzureDevOps addin]. From 2466f2b2cd76f915c6e77dfe4a0f5284ff6907de Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 13 Oct 2019 21:50:37 +0200 Subject: [PATCH 42/44] Update Cake.AzureDevOps to 0.4.0 (#147) --- .../Cake.Issues.PullRequests.AzureDevOps.Tests.csproj | 2 +- .../Cake.Issues.PullRequests.AzureDevOps.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj index 0b23fff..a795eed 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj index 01cf5e2..6379f0d 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj @@ -45,7 +45,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin - + From ad859cb571e8594d40c04a614235e1c94f204c75 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 18 Oct 2019 01:14:39 +0200 Subject: [PATCH 43/44] (GH-149) Embed icon in NuGet package (#150) --- .appveyor.yml | 2 +- .../Cake.Issues.PullRequests.AzureDevOps.csproj | 5 ++++- .../icon.png | Bin 0 -> 15580 bytes 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 src/Cake.Issues.PullRequests.AzureDevOps/icon.png diff --git a/.appveyor.yml b/.appveyor.yml index 0d21fc4..06c5830 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,7 +1,7 @@ #---------------------------------# # Build Image # #---------------------------------# -image: Visual Studio 2017 +image: Visual Studio 2019 #---------------------------------# # Build Script # diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj index 6379f0d..d96668b 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj @@ -25,7 +25,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin BBT Software AG and contributors Copyright © BBT Software AG and contributors Cake Script Cake-Issues Cake-PullRequestSystem Issues PullRequest TFS Azure-DevOps Azure-DevOps-Server - https://cdn.jsdelivr.net/gh/cake-contrib/graphics@a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png + icon.png https://cakeissues.net MIT git @@ -48,6 +48,9 @@ See the Project Site for an overview of the whole ecosystem of addins for workin +
+ + \ No newline at end of file diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/icon.png b/src/Cake.Issues.PullRequests.AzureDevOps/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9881edc4e937ff34999ecf375c550249d82acc32 GIT binary patch literal 15580 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 literal 0 HcmV?d00001 From a0d1fbde2a899eae6465ad928d578e766fa2c711 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 18 Oct 2019 01:17:59 +0200 Subject: [PATCH 44/44] Update Cake.Issues to 0.8.0 --- .../Cake.Issues.PullRequests.AzureDevOps.Tests.csproj | 6 +++--- .../Cake.Issues.PullRequests.AzureDevOps.csproj | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj index a795eed..7a610de 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps.Tests/Cake.Issues.PullRequests.AzureDevOps.Tests.csproj @@ -16,9 +16,9 @@ - - - + + + diff --git a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj index d96668b..d09e464 100644 --- a/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj +++ b/src/Cake.Issues.PullRequests.AzureDevOps/Cake.Issues.PullRequests.AzureDevOps.csproj @@ -43,8 +43,8 @@ See the Project Site for an overview of the whole ecosystem of addins for workin - - + +