2014-01-10 6 views
7

In der neuen Version von TeamFoundation 2013 Standard-Build-Vorlagen fehlt die Workspace-Variable. Es wird als Eingabeparameter für einige Schlüsselaktivitäten wie ConvertWorkspaceItem benötigt. Wie bekomme ich den aktuellen Arbeitsbereich für TfvcTemplate.12.xaml Templates? Ich habe versucht, this msdn thread zu verwenden, aber es funktioniert nicht für mich (gibt null Arbeitsbereichnamen zurück). Irgendwelche Vorschläge?So erhalten Sie das Arbeitsbereichsobjekt in neuen TeamFoundation 2013-Vorlagen

+0

Beachten Sie, dass TFS 2013 eine ResetEnvironemnt-Aufgabe im abschließenden Teil der Try-Kompilier-, Test- und Veröffentlichungssequenz hinzugefügt hat. Jede Variable, die vor dieser Rücksetzaufgabe initialisiert wurde, wird nach der Kompilierung gelöscht. Das hat mich drei Arbeitstage gekostet, um herauszufinden, warum ich Nullreferenz-Ausnahmen erhielt. – JDennis

Antwort

2

Ich ging mit einem Hack mit internen Klassen von Microsoft.TeamFoundation.Build.Activities.dll (von Microsoft verwendet, um den Namen des Arbeitsbereichs zu erstellen). Sie müssen benutzerdefinierte Aktivität mit folgendem Code erstellen:

public sealed class GetDefaultWorkspace : BaseActivity<Workspace> 
{  
    public override Activity CreateBody() 
    { 
     var type = typeof(TfGetSources).Assembly.GetType("Microsoft.TeamFoundation.Build.Activities.TeamFoundation.TfGetSources+GetDefaultWorkspaceName"); 

     var activity = (CodeActivity<string>)Activator.CreateInstance(type); 
     var sequence = new Sequence(); 
     var workspaceName = new Variable<string>(); 

     sequence.Variables.Add(workspaceName); 
     sequence.Activities.Add(activity); 
     activity.Result = (OutArgument<string>) workspaceName; 

     sequence.Activities.Add(new GetWorkspace 
      { 
       Name = workspaceName, 
       Result = new LambdaReference<Workspace>(ctx => Result.Get(ctx)) 
      }); 

     return sequence; 
    } 
} 
6

Es gibt eine neue Aktivität im Jahr 2013 GetLocalPath genannt, die ConvertWorkspaceItem ersetzt. Die Aktivität befindet sich unter dem Namespace Microsoft.TeamFoundation.Build.Activities.Core in der Microsoft.TeamFoundation.Build.Activities Assembly.

Es verwendet die LocalPathProvider-Klasse, die alle im Build verwendeten Arbeitsbereiche aggregiert und die Pfadübersetzung für alle von ihnen an einer Stelle verfügbar macht. Das entfernt im Grunde genommen die Abhängigkeit, den Arbeitsbereich zu kennen, um Serverpfade in lokale Pfade zu übersetzen, und ermöglicht es Ihnen, so viele Arbeitsbereiche zu verwenden, wie Sie möchten, ohne sich Gedanken darüber machen zu müssen, etwas in der Leitung zu unterbrechen.

Wenn MS etwas wegnimmt, ist es meistens aus einem guten Grund. "hacken" ist wirklich nicht notwendig.

+0

Recht, um den lokalen Pfad zu erhalten. Was ist, wenn ich während des Builds einige Dateien auschecken möchte? –

+0

Wenn ich mich richtig erinnere (eine Weile, seit ich in der IL herumgestöbert habe), solange Sie die Aktivitäten für ein 'Manual' verwenden, dann fügen Sie auch ihre Zuordnung für GetLocalPath hinzu. –

+0

Stellen Sie sicher, dass Sie wissen, dass dies eine neue Aktivität in der TOOLBOX ist - Sie können die Methode nicht einfach direkt aufrufen –

0

Ich glaube, dass die hier verwendete Methode den bereits heruntergeladenen Arbeitsbereich verwenden wird. Beachten Sie, dass dieser Ansatz nur innerhalb des Bereichs "Run on agent" nach "Initialize Environment" und vor ResetEnvironment innerhalb der finally-Anweisung von Try Compile, Test, Publish funktioniert. Sonst hat der Workflow kein Quellverzeichnis.

http://social.msdn.microsoft.com/Forums/vstudio/en-US/420ba073-bdf5-4ab4-88da-c84561d1a1ba/creating-dynamic-working-folder-in-tfs2013-defaulttemplate?forum=tfsbuild

2

Diese Antwort könnte besser funktionieren für manche Leute. Die Antwort von Ghord funktioniert gut und übergibt den Arbeitsbereich zurück, wo er im XAML verwendet werden kann. Doch für meine Zwecke nur ich den Arbeitsbereich in meiner benutzerdefinierten TFS Aktivitäten wollen, so landete ich mit dieser Alternative up ...

public sealed class CustomActivity : CodeActivity 
{ 
    protected override void Execute(CodeActivityContext context) 
    { 
     // get workspace 
     var buildDetail = context.GetExtension<IBuildDetail>(); 
     var buildAgent = context.GetExtension<IBuildAgent>(); 
     var buildDirectory = buildAgent.GetExpandedBuildDirectory(buildDetail.BuildDefinition); 
     var workspacePath = Path.Combine(buildDirectory, "src"); 
     var wsInfo = Workstation.Current.GetLocalWorkspaceInfo(workspacePath); 
     var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(wsInfo.ServerUri); 
     tfs.Connect(ConnectOptions.None); 
     var vcs = tfs.GetService<VersionControlServer>(); 

     // finally can get to the workspace here 
     var workspace = vcs.GetWorkspace(workspacePath); 
    } 
} 

Mit dieser Methode muss ich wieder keine Aktivität haben, die nur die Arbeitsbereich, und müssen den Arbeitsbereich dann in andere TFS-Aktivitäten übergeben. Ich bekomme den Arbeitsbereich nur aus meiner eigenen Aktivität heraus, während er läuft.