本文介绍了TFS 2017 vNext Build使用Powershell获得工作空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我有一个项目,需要在构建过程中更改一些文件.我必须使用Powershell来执行此操作.我已经配置了所有必需的步骤来执行此操作.所有步骤都可以在我的客户端PC上进行.构建服务器具有相同的配置.已安装Vs 2015(用于TF Powertools 2015)和VS 2017.当我对构建进行排队时,构建在他尝试获取工作区时失败.也许是因为生成代理仅创建本地工作区?至此,所需的更改已经签出.我无法使用TF.exe签入,因为有些签入策略会阻止没有相关工作项的签入.这是我在此步骤中尝试做的事情:

I have a project where it is needed to change some files during build process.I have to use Powershell to do this. I have already configured all required steps to do this. All steps work on my client pc. The Build server has the same configuration. Vs 2015 (for TF Powertools 2015) and VS 2017 installed. When I queued a Build, the build fails at the point where he tries to get the Workspace. Maybe this is because, the build agent creates only local workspaces? At this point the required changes are already checked out. I Cannot use TF.exe checkin, because there are checkin policies which prevents the checkin without associated workitem. This is what I try to do at this step:

  • 通过源路径($ Env:BUILD_SOURCESDIRECTORY)获取工作区
  • 获取此工作空间的待定更改$pendingChanges = $tfsws.GetPendingChanges()
  • 创建带有关联工作项的workitemcheckininfo
  • 使用创建的workitemcheckininfo $changesetNumber = $tfsws.CheckIn($pendingChanges,"$CommentString checked in by BuildServer",$null, $workItemChanges,$null)
  • 进行签入
  • Get Workspace via path of the sources ($Env:BUILD_SOURCESDIRECTORY)
  • Get the pending changes of this workspace $pendingChanges = $tfsws.GetPendingChanges()
  • Create workitemcheckininfo with an associated workitem
  • Checkin with created workitemcheckininfo $changesetNumber = $tfsws.CheckIn($pendingChanges,"$CommentString checked in by BuildServer",$null, $workItemChanges,$null)

由于我没有进入工作区(步骤1),因此以下步骤将不会开始.

As I dont get the Workspace (step 1), the following steps will not start.

这是我到目前为止尝试过的:

This is what I tried so far:

$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer"
#$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0"
Add-Type -path "$binpath\Microsoft.TeamFoundation.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.WorkItemTracking.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.VersionControl.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.Common.dll"

$teamProjectCollection = "http://mytfs/tfs/defaultcollection"
$tfs = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($teamProjectCollection)

#The next line fails, as the commandlet is from TF Powertools 2015 and the TFS server is 2017.
#I get the error message "Microsoft.TeamFoundation.Client.TfsTeamProjectCollection cannot be converted to Microsoft.TeamFoundation.Client.TfsTeamProjectCollection"
$tfsws = Get-TfsWorkspace -Server $tfs -Computer $hostname -Owner $Username

2

$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer"
#$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0"
Add-Type -path "$binpath\Microsoft.TeamFoundation.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.WorkItemTracking.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.VersionControl.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.Common.dll"

$localReference = join-path $Env:BUILD_SOURCESDIRECTORY $TargetBranch
$teamProjectCollection = "http://mytfs/tfs/defaultcollection"
$tfsTeamProjectCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($teamProjectCollection)
$versioncontrolServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])

#The next lines fail, as $versioncontrolServer is nothing
[Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.EnsureUpdateWorkspaceInfoCache($versionControlServer, $username);
$tfsws = $versioncontrolServer.GetWorkspace($localReference)

可能导致问题的两件事:1st => build agent仅使用本地工作区? 2nd => TFS 2017和VS 2015是否兼容不够?

Two things, that maybe causing the problems: 1st => build agent only uses local workspaces? 2nd => TFS 2017 and VS 2015 are not compatible enough?

有人有好的工作示例或解决方案吗?

Has someone a good working example or solution?

我考虑了其他选择.也许我可以编写一个可执行文件来完成我的工作.

I thought about other options. Maybe I could program an executable, which does my stuff.

我可以在没有工作空间的情况下签入,以后再关联工作项吗?如何以编程方式将工作项与现有变更集相关联?

Can I checkin without workspace and later associate the workitem? How to programmatically associate a workitem with an existing Changeset?

推荐答案

如果没有工作空间,则无法签入.

You cannot checkin without workspace.

但是,该过程将在获取源代码"步骤中创建本地工作区.因此,您可以绕过签入策略直接签入更改,然后稍后将工作项与特定的更改集关联.

However the process will create a local workspace in get source step. So you can directly check in the changes bypass the check in policies, then associate a workitem with the specific Changeset later.

要绕过/覆盖签入策略,您可以在签入命令下方运行(您可以在命令下方复制并另存为PowerShell/cmd脚本,然后添加PowerShell/Command运行脚本的任务).请参见检入命令:

To bypass/override the check in policies, you can run below check in command (You can copy below command and save as a PowerShell/cmd script, then add a PowerShell/Command task to run the script). See Checkin command:

tf Checkin $source_dir /comment:"Change files" /noprompt /force /bypass /override:"Without associating workitem"

注意::请确保您使用的代理为2.122.1或更高版本,否则您可能会遇到错误,请参见以获取详细信息.

Note: Make sure that the agent you are using is 2.122.1 or later version, otherwise you may meet errors, see this related thread for details.

要将工作项与现有变更集相关联:

带有客户端API的C#:

C# with Client API:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace APPI
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://xxx.xxx.xxx.xxx:8080/tfs/DefaultCollection";
            TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(new Uri(url));
            WorkItemStore wis = ttpc.GetService<WorkItemStore>();
            VersionControlServer vcs = ttpc.GetService<VersionControlServer>();
            int wid = 194;
            int cid = 440;
            WorkItem wi = wis.GetWorkItem(wid);
            Changeset cs = vcs.GetChangeset(cid);
            ExternalLink el = new ExternalLink(wis.RegisteredLinkTypes["Fixed in Changeset"], cs.ArtifactUri.AbsoluteUri);
            wi.Links.Add(el);
            wi.Save();
        }
    }
}

具有REST API的PowerShell:

PowerShell with REST API:

Param(
   [string]$collectionurl = "http://server:8080/tfs/DefaultCollection",
   [string]$keepForever = "true",
   [string]$WorkitemID = "194",
   [string]$ChangesetID = "439",
   [string]$user = "UserName",
   [string]$token = "password/token"
)

# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

function CreateJsonBody
{

    $value = @"
[
 {
    "op": "add",
    "path": "/relations/-",
    "value": {
      "rel": "ArtifactLink",
      "url": "vstfs:///VersionControl/Changeset/$ChangesetID",
      "attributes": {
        "name": "Fixed in Changeset"
      }
    }
  }
]

"@

 return $value
}

$json = CreateJsonBody

$uri = "$($collectionurl)/_apis/wit/workitems/$($WorkitemID)?api-version=1.0"
$result = Invoke-RestMethod -Uri $uri -Method Patch -Body $json -ContentType "application/json-patch+json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

这篇关于TFS 2017 vNext Build使用Powershell获得工作空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-07 20:33