4

継続的インテグレーション ビルドの一環として、SQL スクリプトを作成しています。この SQL スクリプトは、生成後に TFS にチェックインする必要があります。Powershell で TFS Powertools を使用しています。

私のマシンで使用したコードは次のとおりです。

Add-TfsPendingChange -Add -Item $filename | New-TfsChangeSet

私がいたフォルダーはTFSワークスペースにマップされているため、これは私の開発ボックスでうまく機能しました。ビルド サーバーに移動すると、TeamCity がチェックアウトをワークスペースにマップせず、ファイルをプルダウンするだけなので、機能しなくなります。

マップされたワークスペースにいなくても、ファイルを TFS の特定のフォルダーにチェックインするにはどうすればよいですか? それは可能ですか?

4

1 に答える 1

1

私は、GO を使用した継続的デリバリー プロジェクトでこれを行うために何かに取り組みました。PowerShell と .NET アセンブリ プロバイダーをチーム エクスプローラーと組み合わせて使用​​することで、動作するようになりました。PowerShell だけで動作させることはできませんでした (方法はあるかもしれませんが!)。

次のスクリプトは、パラメータとして指定されたマテリアル パスに含まれるすべてのものを、指定されたサーバー パス (これもパラメータ) にチェックインします。使用する資格情報と TFS サーバーの URL を指定することもできます。

このコードでは、Visual Studio または TFS チーム エクスプローラー クライアントをインストールする必要があります。AssemblyPath パラメーターでスクリプトにアセンブリのディレクトリの場所を指定する必要があります。これらのアセンブリが見つからない場合、スクリプトはエラーになり、不足しているアセンブリが表示されます。

注:コードはしばらくチェックされていないため、タイプミスなどがある可能性があります。問題があればお知らせください。お手伝いします。

[CmdletBinding(PositionalBinding=$false)]
Param(
    [Parameter(Mandatory)] [string] $ServerUrl,
    [Parameter(Mandatory)] [string] $ServerPath,
    [Parameter(Mandatory=$False)] [string] $Domain = "",
    [Parameter(Mandatory=$False)] [string] $Username = "",
    [Parameter(Mandatory=$False)] [System.Security.SecureString] $Password,
    [Parameter(Mandatory)] [string] [ValidateScript({($_ -eq $null) -or (Test-Path -Path $_ -PathType Container)})] $MaterialPath,
    [Parameter(Mandatory)] [string] [ValidateScript({ Test-Path -Path $_ -PathType Container})] $AssemblyPath
)

<#
    .SYNOPSIS
    Responsible for checking in files into Source Control
    .DESCRIPTION
#>

$clientDllName = "Microsoft.TeamFoundation.Client.dll"
$commonDllName = "Microsoft.TeamFoundation.Common.dll"
$versionControlClientDllName = "Microsoft.TeamFoundation.VersionControl.Client.dll"
$versionControlClientCommonDllName = "Microsoft.TeamFoundation.VersionControl.Common.dll"


#Create global variables to hold the value of Debug and Verbose action preferences which can then be used for all module function calls and passed into the remote session.
$verboseParameter = $PSCmdlet.MyInvocation.BoundParameters["Verbose"]
if ($verboseParameter -ne $null)
{
    $Global:Verbose = [bool]$verboseParameter.IsPresent
}
else
{
    $Global:Verbose = $false
}
$debugParameter = $PSCmdlet.MyInvocation.BoundParameters["Debug"]
if ($debugParameter -ne $null)
{
    $Global:Debug = [bool]$debugParameter.IsPresent
}
else
{
    $Global:Debug = $false
}

$scriptName = $(Split-Path -Leaf $PSCommandPath)

#Ensure any errors cause failure
$ErrorActionPreference = "Stop"

Write-Host "Running script ""$scriptName"" as user ""$env:USERDOMAIN\$env:USERNAME"""

#Check assembly path is a valid directory
If (Test-Path -Path $AssemblyPath -PathType Container)
{
    Write-Host "Loading required assemblies from assembly path ""$AssemblyPath"""

    $clientDllPath = Join-Path -Path $AssemblyPath -ChildPath $clientDllName
    $commonDllPath = Join-Path -Path $AssemblyPath -ChildPath $commonDllName
    $versionControlClientDllPath = Join-Path -Path $AssemblyPath -ChildPath $versionControlClientDllName
    $versionControlClientCommonDllPath = Join-Path -Path $AssemblyPath -ChildPath $versionControlClientCommonDllName

    If (!Test-Path -Path $clientDllPath -PathType Leaf)
    {
        Throw "Required assembly ""$clientDllName"" not found at path ""$clientDllPath"""
    }
    If (!Test-Path -Path $commonDllPath -PathType Leaf)
    {
        Throw "Required assembly ""$commonDllName"" not found at path ""$commonDllPath"""
    }
    If (!Test-Path -Path $versionControlClientDllPath -PathType Leaf)
    {
        Throw "Required assembly ""$versionControlClientDllName"" not found at path ""$versionControlClientDllPath"""
    }
    If (!Test-Path -Path $versionControlClientCommonDllPath -PathType Leaf)
    {
        Throw "Required assembly ""$versionControlClientCommonDllName"" not found at path ""$versionControlClientCommonDllPath"""
    }

    #Load the Assemblies
    [Reflection.Assembly]::LoadFrom($clientDllPath) | Out-Null
    [Reflection.Assembly]::LoadFrom($commonDllPath)| Out-Null
    [Reflection.Assembly]::LoadFrom($versionControlClientDllPath) | Out-Null
    [Reflection.Assembly]::LoadFrom($versionControlClientCommonDllPath) | Out-Null

    #If the credentials have been specified then create a credential object otherwise we will use the default ones
    If ($Username -and $Password)
    {

        $creds = New-Object System.Net.NetworkCredential($Username,$Password,$Domain)
        Write-Host "Created credential object for user ""$($creds.UserName)"" in domain ""$($creds.Domain)"""

        $tfsProjectCollection = New-Object Microsoft.TeamFoundation.Client.TFSTeamProjectCollection($ServerUrl, $creds)
    }
    else
    {
        Write-Host "Using default credentials for user ""$Env:Username"""
        $tfsProjectCollection = New-Object Microsoft.TeamFoundation.Client.TFSTeamProjectCollection($ServerUrl)
    }

    $versionControlType = [Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer]
    $versionControlServer = $tfsProjectCollection.GetService($versionControlType)

    Write-Host "Version control server authenticated user: $($versionControlServer.AuthenticatedUser)"

    #Create a local path in the temp directory to hold the workspace
    $LocalPath = Join-Path -Path $env:TEMP -ChildPath $([System.Guid]::NewGuid().ToString())
    $null = New-Item -Path $LocalPath -ItemType Directory

    #Create a "workspace" and map a local folder to a TFS location
    $workspaceName = "PowerShell Workspace_{0}" -f [System.Guid]::NewGuid().ToString()
    $workspace = $versionControlServer.CreateWorkspace($workspaceName, $versionControlServer.AuthenticatedUser)
    $workingfolder = New-Object Microsoft.TeamFoundation.VersionControl.Client.WorkingFolder($ServerPath,$LocalPath)
    $result = $workspace.CreateMapping($workingFolder)
    $result = $workspace.Get() #Get the latest version into the workspace

    Write-Host "Copying files from materials path ""$MaterialPath"" to temporary workspace path ""$LocalPath"""
    robocopy $MaterialPath $LocalPath /s | Out-Null

    $checkInComments = "Files automatically checked in by PowerShell script ""$scriptName"""

    #Submit file as a Pending Change and submit the change
    $result = $workspace.PendAdd($LocalPath,$true)
    $pendingChanges = $workspace.GetPendingChanges()

    Write-Host "Getting pending changes"

    #Only try to check in if there are changes
    If ($pendingChanges -ne $null)
    {
        If ($pendingChanges.Count -gt 0)
        {
            $changeSetId = $workspace.CheckIn($pendingChanges,$checkInComments)

            Write-Host "Successfully checked in ""$($pendingChanges.Count)"" changes using changeset id ""$changeSetId"""
        }
        else
        {
            Write-Host "No changes to check-in"
        }
    }
    else
    {
        Write-Host "No changes to check-in"
    }

    Write-Host "Deleting workspace and temporary folders"
    $result = $workspace.Delete()
    $null = Remove-Item -Path $LocalPath -Recurse -Force
}
else
{
    Write-Error "The path to required assemblies ""$AssemblyPath"" cannot be found"
}
于 2014-10-23T11:23:59.387 に答える