Qual è il modo migliore per far sì che TFS restituisca ciascun progetto nella propria directory?

Sto inserendo una grande base di codice in Team Foundation Server. Vorrei che il processo di compilazione creasse una build “pronta per l’implementazione” dei nostri progetti.

Il modo normale in cui lo abbiamo fatto è avere l’output di ogni progetto nella sua cartella. Quindi, per esempio, finiamo con qualcosa di simile

C:\project1\ assembly1.dll assembly2.dll project1.exe project1.exe.config C:\project2\ assembly2.dll assembly3.dll project2.exe project2.exe.config C:\project3\ assembly1.dll assembly3.dll project3.exe project3.exe.config 

Qual è il modo in cui ci piace

TFS, però, sembra voler attaccare tutto nella stessa directory.

 C:\output\ assembly1.dll assembly2.dll assembly3.dll project1.exe project1.exe.config project2.exe project2.exe.config project3.exe project3.exe.config 

che, sebbene salvi un po ‘di spazio su disco (gli assembly sono lì solo una volta ciascuno) non è come lo vogliamo.

Qual è il modo migliore per specificare dove TFS / MSBuild deve inserire i file di output? Devo modificare i file sln / csproj singolarmente per ottenerlo o posso farlo nel file TFSBuild.proj? (cioè, in un file specifico di MSBuild)

Ho appena scritto un altro metodo qui:

http://mikehadlow.blogspot.com/2009/06/tfs-build-publishedwebsites-for-exe-and.html ma se non puoi essere preso la briga di seguire il link, eccolo pieno:

In genere, è buona norma raccogliere tutto il codice sotto il controllo del proprio team in un’unica soluzione uber, come descritto in questo documento PDF di Patterns and Practices, Team Development with TFS Guide. Se si configura quindi il server di build TFS per creare questa soluzione, il suo comportamento predefinito è di collocare l’output di build in una singola cartella, ‘Release’.

Eventuali progetti di applicazioni Web nella soluzione verranno inviati anche a una cartella denominata _PublishedWebsites \. Questo è molto bello perché significa che puoi semplicemente automatizzare l’applicazione web con Robocopy.

Sfortunatamente non esiste un comportamento predefinito simile per altri tipi di progetto come WinForms, console o libreria. Sarebbe molto bello se potessimo avere una sottocartella _PublishedApplications \ con l’output di qualsiasi progetto selezionato. Fortunatamente non è così difficile da fare.

Il modo in cui _PublishedWebsites funziona è piuttosto semplice. Se guardi il file di progetto della tua applicazione web, noterai un’importazione nella parte inferiore:

  

Sulla mia macchina la proprietà MSBuildExtensionsPath valuta C: \ Program Files \ MSBuild, se apriamo il file Microsoft.WebApplication.targets possiamo vedere che si tratta di un semplice file MSBuild che riconosce quando la build non è una build desktop, vale a dire che è un TFS build e copia l’output in:

 $(OutDir)_PublishedWebsites\$(MSBuildProjectName) 

Ho semplicemente copiato il file Micrsoft.WebApplication.targets, l’ho messo sotto controllo sorgente con un percorso relativo dai miei file di progetto e ho cambiato _PublishedWebsites in _PublishedApplications e rinominato il file CI.exe.targets. Per ogni progetto che voglio inviare a _PublishedApplications, ho semplicemente aggiunto questa importazione nella parte inferiore del file di progetto:

  

Puoi modificare CI.exe.targets (o qualsiasi altra cosa tu voglia chiamarlo) per fare le tue offerte. Nel mio caso, l’unico cambiamento finora è aggiungere un paio di righe per copiare il file App.config:

  

C’è un sacco di roba in Microsoft.WebApplication.targets che è rilevante solo per le applicazioni web e può essere spogliato per altri tipi di progetti, ma lascerò che questo sia un esercizio per il lettore.

TFS 2012+

Mi piace questa soluzione …

Modifica la tua definizione di build. Nella sezione Processo, impostare gli MSBuild arguments su

/p:GenerateProjectSpecificOutputFolder=true

Come questo:

inserisci la descrizione dell'immagine qui

Per impostazione predefinita, ogni file di progetto (* .csproj, * .vbproj, ecc.) Specifica una directory di output predefinita (che di solito è bin \ Debug, bin \ Release, ecc.). Team Build sovrascrive questo in modo che tu non sia il capriccio di quali proprietà lo sviluppatore imposta nel file di progetto, ma anche in modo che Team Build possa fare supposizioni su dove si trovano gli output.

Il modo più semplice per ignorare questo comportamento è impostare CustomizableOutDir su true nel gruppo di oggetti SolutionToBuild come mostrato qui:

   CustomizableOutDir=true   

Ciò renderà la struttura della cartella di rilascio approssimativamente corrispondente a ciò che si otterrebbe localmente se si è creata la soluzione.

Questo metodo è decisamente preferibile per ignorare gli obiettivi Core * che possono causare problemi di aggiornamento.

Per ciascun nodo SolutionToBuild, impostare la proprietà OutDir su $ (OutDir) \ SubFolder
Per esempio:

    OutDir=$(OutDir)\Project1\   OutDir=$(OutDir)\Project2\   OutDir=$(OutDir)\Project3\   

(Funziona con TF2008, ma non con TF2005.)

Sono un po ‘in ritardo per la festa che risponde a questa domanda, ma c’è un modo molto semplice per implementare la risposta di Mike Hadlow. Qualcuno ha scritto un pacchetto di nuget che fa esattamente quello di cui parla Mike. Puoi trovarlo qui: http://www.nuget.org/packages/PublishedApplications

Aggiornamento per TFS 2010 (e TFS 2012 in arrivo). Jason Stangroome ha scritto un bel post sul blog che spiega come farlo.

http://blog.codeassassin.com/2012/02/03/override-the-tfs-team-build-outdir-property/

(link sopra è morto … link alla versione cache)

https://webcache.googleusercontent.com/search?q=cache:4rKu4oB3TwcJ:blog.stangroome.com/2012/02/03/override-the-tfs-team-build-outdir-property/+&cd=1&hl=en&ct = clnk & gl = ca

Sovrascrivere la proprietà Build OutDir del team TFS

Aggiornamento: con .NET 4.5 c’è un modo più semplice .

Un reclamo molto comune da parte degli utenti del sistema di generazione di Team Foundation Server è che modifica la struttura delle cartelle degli output del progetto. Per impostazione predefinita, Visual Studio inserisce tutti i file nella rispettiva cartella / bin / o / bin // ma Team Build utilizza solo una struttura a cartelle piatte inserendo tutti i file nella cartella principale o, ancora, una // sottocartella nella cartella. cartella, con tutte le uscite del progetto mescolate insieme.

Inoltre, poiché Team Build raggiunge questo risultato impostando la proprietà OutDir tramite la riga di comando MSBuild.exe combinata con la precedenza della proprietà di MSBuild, questo valore non può essere facilmente modificato da MSBuild stesso e la soluzione più diffusa è modificare il file Build Process Template * .xaml in usa un nome di proprietà diverso . Ma preferisco non toccare il stream di lavoro a meno che non sia assolutamente necessario.

Invece, utilizzo sia la soluzione prima che l’objective e le funzionalità di attività in linea di MSBuild v4 per sovrascrivere l’implementazione predefinita dell’attività MSBuild utilizzata per creare i singoli progetti nella soluzione. Nella mia implementazione alternativa, impedisco il passaggio della proprietà OutDir e passo attraverso una proprietà denominata PreferredOutDir invece che i singoli progetti possono utilizzare se lo si desidera.

La prima parte, che sostituisce la proprietà OutDir per la proprietà PreferredOutDir a livello di soluzione, viene raggiunta semplicemente aggiungendo un nuovo file alla directory in cui risiede il file della soluzione. Questo nuovo file dovrebbe essere denominato seguendo lo schema “before..sln.targets” Ad esempio, per un file di soluzione chiamato “Foo.sln”, il nuovo file sarà “before.Foo.sln.targets”. Il contenuto di questo nuovo file dovrebbe assomigliare a questo . Assicurati che questo nuovo file abbia il check-in sul controllo del codice sorgente.

La seconda parte, che consente a ciascun progetto di controllare la struttura della cartella di output, consiste semplicemente nell’aggiungere una riga al file * .csproj o * .vbproj del progetto (a seconda della lingua). Individua il primo elemento all’interno del file di progetto che non ha un attributo Condition specificato e individua il tag di chiusura corrispondente per questo elemento. Immediatamente sopra il tag di chiusura aggiungi una linea simile a questa:

$(PreferredOutDir)$(MSBuildProjectName)\

In questo esempio, il progetto verrà generato nella cartella di rilascio di Team Build sotto una sottocartella denominata come il file di progetto (senza l’estensione .csproj). Potresti scegliere un modello diverso. Inoltre, i progetti Web di solito creano la propria cartella di output sotto una sottocartella _PublishedWebSites della cartella di rilascio Team Build, per mantenere questo comportamento è sufficiente impostare la proprietà OutDir per uguagliare esattamente la proprietà PreferredOutDir.

Puoi verificare se le tue modifiche hanno funzionato sul tuo computer locale prima di effettuare il check-in semplicemente eseguendo MSBuild dalla riga di comando e specificando la proprietà OutDir proprio come fa Team Build, ad esempio:

msbuild Foo.sln /p:OutDir=c:\TestDropFolder\

Per chi è curioso di sapere come funziona con TFS 2010, questo post ha diverse risposte, di cui quella collegata ha funzionato molto bene per me.

Potresti avere un buildscript per progetto, che farebbe esattamente quello che vuoi. È sufficiente creare un nuovo file TFSBuild, aggiungere i progetti che si desidera creare al gruppo articoli (nell’ordine in cui si desidera vengano creati), impostare dove si desidera che l’output sia. Ciò avviene sovrascrivendo la proprietà – nel file TFSBuild.

Ma sono d’accordo anche con il poster precedente: perché non si esegue semplicemente un singolo script di build e si aggiunge un’attività zip alla fine? Il mantenimento di un buildscript per progetto aggiunge un sovraccarico di manutenzione …

Sling questo in un gruppo di proprietà:

 true 

Sostituirà la proprietà ‘CustomizableOutDir’ globale che, per impostazione predefinita, è impostata su False. L’impostazione di questo nelle proprietà di SolutionToBuild non funzionerà.

Raggiungi questo superando l’implementazione di destinazione CoreDropBuild predefinita.

Nel tuo file TFSBuild.proj (per impostazione predefinita memorizzato in TeamBuildTypes / ) aggiungi il seguente target:

    ...  

All’interno di questo objective è ansible manipolare l’output nel modo desiderato. L’impostazione predefinita è copiare semplicemente tutto da $ (BinariesRoot) \ $ (BuildType) a $ (DropLocation) \ $ (BuildNumber).

Di solito utilizzo il progetto Microsoft.Sdc.Tasks per le funzionalità di copia dei file.

Soluzione semplice:

Sostituisci tutti i nodes con . Questo ovviamente funzionerà solo per progetti pubblicabili (es. Progetti Web e applicazioni), non per progetti di biblioteca.

Così semplice 🙂