Using Powershell to checkin zip file to TFS

1.3k views Asked by At

My build server is doing all the steps necessary to build a zip of the new website. I would like to add a step to checkin zipfile to TFS. I have created a ps1 file to perform the checkin. I am running it in ISE so there is no dependency on having TeamCity. Here are the errors that I am seeing.

  1. No matter how I do workspace.GET, it does not get the latest code from the server.

  2. Even when I change a file on the hard drive it does not see changes.

  3. Because no changes are detected the zip is not checked in to TFS.

Here is the code....

#============================================================================
# Method to check in all zip files
#
# Example of WorkingDir passed in
# "D:\TeamCity\buildAgent\work\281509782e84e723\Powershell"
#
# Example of where freshly created zips live
# "D:\TeamCity\buildAgent\work\281509782e84e723\Zips"
#
# this script is based on
# From https://github.com/mmessano/PowerShell/blob/master/TFSCheckIn.ps1
# From http://stackoverflow.com/questions/25917753/check-a-file-into-tfs-using-powershell
# from http://lennartjansson2.wordpress.com/2011/10/13/setting-tfs-vcs-security-with-ps-2/
#
#============================================================================

function StackOverflow {
    Param( [Parameter(Mandatory=$true)][string]$WorkingDir )   

    Write-BuildLog "Inside StackOverflow"

    # Get the direcory where new zips where built
    $NewZipFiles =  $WorkingDir + "\..\Zips\*"

    # This is the url to the TFS server + Project collection 
    $tfsServer =  "YourServerAndCollection";

    # this is the full path on server where zips live
    # You need to start description with $
    $tfsServerPath = "$/MyProject/FullPathToDirwithZips"

    # Where on local hard drive should files from TFS be placed
    $LocalCkoutDir =  "D:\MyLocalHDPath"

    # Debug print var to verify correct
    Write-BuildLog "NewZipFiles => $NewZipFiles"
    Write-BuildLog "tfsServer => $tfsServer"
    Write-BuildLog "tfsServerPath => $tfsServerPath"
    Write-BuildLog "LocalCkoutDir => $LocalCkoutDir"

    # Get the TeamCity build number
    #$VarName = "BUILD_NUMBER"
    #$TeamCityVersionNbr = (get-item env:$VarName).Value
    $TeamCityVersionNbr = "MyProject_03_02_81"
    Write-BuildLog "Version Nbr $TeamCityVersionNbr"
    $CheckInComment =  "Check in zips for $BuildNumber"

    # Load the assemblies needed for TFS:
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client") | out-null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Common") | out-null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client") | out-null

    #Set up connection to TFS Server and get version control
    $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($tfsServer)
    $versionControlType = [Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer]
    $versionControlServer = $tfs.GetService($versionControlType)

    #check to see if workspace already exists.  If it does delete it.
    $WorkSpaceNameForCheckIn = "TeamCityWorkspace"
    $ThisBoxName = [System.Environment]::MachineName
    $test = $versionControlServer.QueryWorkspaces( $WorkSpaceNameForCheckIn, $versionControlServer.AuthenticatedUser, $ThisBoxName )
    if ( $test.length -eq 1 )
    {
        $test[0].Delete()
    }   

    # Generate a workspace
    $workspace = $versionControlServer.CreateWorkspace($WorkSpaceNameForCheckIn);

    # Map Server path to local path
    $workspace.Map($tfsServerPath, $LocalCkoutDir)

    # DEBUG: build filename of a zip.   
    # We will overwrite this file to test the get
    $file = "AZipFileThatExists.zip"
    $filePath = $LocalCkoutDir + "\" + $file
    "hello world" | Out-File $filePath

    # I tried the simple get but it does not get
    # Get the zip files from the server to local directory
    $getstatus = $workspace.Get()   

    # Csharp way of doing it
    #workspace.Map(projectPath, workingDirectory);
    # var myItemSpec = new ItemSpec(projectPath, RecursionType.Full);
    #GetRequest request = new GetRequest(myItemSpec, VersionSpec.Latest);
    #GetStatus status = workspace.Get(request, GetOptions.GetAll | GetOptions.Overwrite); // this line doesn't do anything - no failures or er

    # This does not work either
    # Powershell checkout the file.  Overwrite if file exists.  Get even if TFS thinks it is up to date.    
    $NewItemSpec = New-Object Microsoft.TeamFoundation.VersionControl.Client.ItemSpec ( $tfsServerPath, [Microsoft.TeamFoundation.VersionControl.Client.RecursionType]::Full)
    $NewRequest =  New-Object Microsoft.TeamFoundation.VersionControl.Client.GetRequest( $NewItemSpec,  [Microsoft.TeamFoundation.VersionControl.Client.VersionSpec]::Latest)
    $getstatus = $workspace.Get( $NewRequest,  [Microsoft.TeamFoundation.VersionControl.Client.GetOptions]::GetAll -bOr [Microsoft.TeamFoundation.VersionControl.Client.GetOptions]::Overwrite )

    # I have not tested the rest of this since the "get" does not work.
    # Mark the files before we refresh them with new zips
    $result = $workspace.PendEdit($LocalCkoutDir)

    # Copy zips that where built by TeamCity to checkin direcory
    Copy-Item $NewZipFiles $LocalCkoutDir -force -recurse

    # check if we have some pending changes.  If we do checkin changes
    $pendings = $workspace.GetPendingChanges();
    if($pendings.Count -gt 0){
        $result = $workspace.CheckIn($pendings, $CheckInComment);
        Write-BuildLog "Changes where checked in";
    }
    else
    {
       Write-BuildLog "No changes found";
    }

    # delete the workspace
    $result = $workspace.Delete()
}

#============================================================================
# Write to the build log
#============================================================================
function Write-BuildLog {
    param( [Parameter( Mandatory=$true)]  $Message
           )

    write-host $Message
    #write-host "##teamcity[message text='" + $Message + "']"
}

$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
StackOverflow $myDir
1

There are 1 answers

0
PreguntonCojoneroCabrón On

use the tf command line

Example for checkin:
cd C:\TFS\Arquitectura
%ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\TF.exe checkin $/Arquitectura/Main /recursive

On Windows x64
"%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe" checkin $/Arquitectura/Main /recursive

See for more information on the tf commandline: http://msdn.microsoft.com/en-us/library/z51z7zy0(v=VS.90).aspx

Only learning curve about use tf.exe with Powershell. Maybe source code sample is required.

Source: Scripting TFS Command Line for Get Latest Version, Check Out and Check in, programmatically