TeamCity Conditional SMB Upload path - teamcity

Using TeamCity version 2017.2.3 (build 51047).
I have a SMB Upload build step and would like to upload the builds from the default branch to a different location than all other builds.
I seen the following variable that will tell me if its a deafult build %teamcity.build.branch.is_default% however im not too sure how or even if its possible to specify conditional Target URL for the SMB Upload step.
Either with some form on IF block, or ternary statement inline.
Non of this is done using PowerShell. All through the UI, i would prefer to keep it that way if possible. Our old TeamCity install saws essentially just a glorified PowerShell script runner and grew into this un maintainable monolith, besides PowerShell is a rather terrible language.
Essentially what i would like would be builds on any branch going to
//DataStore/builds/my-api-%build.number%.zip
Whilst builds on the default branch go to
//DataStore/builds/default/my-api-%build.number%.zip
Any help would be appreciated thanks.

In general, this is not possible. The SMB Upload runner doesn't let you specify a condition anywhere in it.
If conditional steps were possible, you could create two steps: Upload from default and Upload from non-default, each with a different Target URL. It turns out that conditional build steps are the most voted-for feature in TeamCity, see this ticket, yet JetBrains are quite opposed to the idea. You may want to vote for the ticket, or at least monitor it.
There is one thing that you can do, other than Powershell. The Target URL field expands variables. (You can tell this by typing a percent sign in the text field: TeamCity immediately starts suggesting variable names. Compare this with the Step name text field above: that has no variable expansion.) Thus, you could enter a Target URL in this form:
//DataStore/builds/%teamcity.build.branch.is_default%/my-api-%build.number%.zip
That way, you'll end up with files being uploaded as
//DataStore/builds/true/my-api-1234.zip
//DataStore/builds/false/my-api-1235.zip
Now that's kind-of ugly. You can improve it in two ways:
1) create symlinks or junctions on your file server (on the directory/filesystem level), so that the above are accessible to the clients as
//DataStore/builds/default/my-api-1234.zip
//DataStore/builds/my-api-1235.zip
2) even better, you can set up a variable that will either contain the value "/default" or "". Then you can change your Target URL to //DataStore/builds%myCleverVariable%/my-api-%build.number%.zip. To do that, you'll need an extra step before this one, a Powershell runner, that will test the value of %teamcity.build.branch.is_default% and set %myCleverVariable% accordingly, using TeamCity service messages.

The conditional build step feature has been implemented in TeamCity 2020.1

Related

Get Octopus Deployment Folder at beginning of release process

I'm using an Octopus custom template with a powershell script to delete old deployments by age or by count. However, it relies on running after an actual deployment step, so that it can access the output variables of that step. For example,
DeploymentFolder:
#{Octopus.Action[Deployment Step Name].Output.Package.InstallationDirectoryPath}
This works great when, for example, you haven't run out of disk space. However, it doesn't work so well when disk space is low (since you didn't have this step running before) and Octopus can't deploy a new version due to the low disk space condition, thus you can't run the delete old files step. (I know one can change the Octopus parameter for what's considered too little disk space, but I'd rather not do that.) This additionally has a problem where if you want to enter a hardcoded path (say you're experiencing a temporary problem with your script and just need to delete a bunch of old deployments, but don't currently have the permissions needed to delete them manually from the server), it's too easy to accidentally leave off the final version-number-bearing folder and have the underlying script get confused.
Is there some way that I can get the deployment folder for the current environment, and combine it with my NuGet package name (and whatever other parts are in the deployment folder name), so I can work out the expected deployment folder in advance?
The actual deployment folder being used is E:\Octopus\Applications\LifeCycle\NugetPackageName.
I think I can get the NugetPackageName with $OctopusParameters['Octopus.Action[Deployment Step Name].Package.NuGetPackageId'] (though I am not sure, as Octopus.Action.Package.NuGetPackageId is listed as an "Action-Level Variable", and thus may not be available in advance of the step running. I'd be willing to hard-code the NuGet package name if I had to.
About the LifeCycle part, I don't know if that is actually a LifeCycle name. It may be a coincidence that it matches. I'm not sure. For the life of me I can't figure out where this comes from.
I also can't figure out where E:\Octopus\Applications\ comes from, so that I can get this value automatically instead of hard-coding it.
This variable will be available at the start of the deployment:
$OctopusParameters['Octopus.Action[Deployment Step Name].Package.NuGetPackageId']
You can get E:\Octopus\Applications\ from an environment variable called TentacleApplications:
$myRootDir = $env:TentacleApplications

Post build event depending on configuration name in new ASP.NET 5 project

I'm writing a unified project for 3 smart TVs. I have also 3 configurations created in Visual Studio. Now I want to execute some CLI scripts depending on selected configuration.
The problem is in new ASP.NET 5 project I don't have an editor for post build events.
I know I have to do this in project.json. What I found is:
"scripts": {
"postbuild": ""
}
But using this one I can't create different CLI scripts for different configurations.
I found also:
"configurations": {
},
And I guess this is probably what I want, but... How to use it? Intellisense has no power here and also I wasn't lucky searching the Web...
[edit]
Maybe I should try with .xproj?
You'll need to build a master script which uses the available context and environment variables to switch and run the other scripts of your choice.
In addition to the list of variables Here for compile, you also get these for publish related scripts and then these are available everywhere, as are environment variables returned by Environment.GetEnvironmentVariable, which can be seen here.
The image below shows the intellisense from the VS2015 Update 3 RTM, but it's misleading, since you get others depending on the script block you're using:
So, your full list of context variables that you can use to control flow in your scripts is:
Every script block:
%project:Directory%
%project:Name%
%project:Version%
Compile specific:
%compile:TargetFramework%
%compile:FullTargetFramework%
%compile:Configuration%
%compile:OutputFile%
%compile:OutputDir%
%compile:ResponseFile%
%compile:RuntimeOutputDir% (only available if there is runtime output)
%compile:RuntimeIdentifier% (only availabe if there is runtime output)
%comiple:CompilerExitCode% (only available in the postcompile script block)
Publish specific:
%publish:ProjectPath%
%publish:Configuration%
%publish:OutputPath%
%publish:TargetFramework%
%publish:FullTargetFramework%
%publish:Runtime%
I investigated on this a bit but did not really get to any good result.
There are some project variables that are exposed in scripts. Unfortunately, those are very limited:
%project:Name% gives you the project name
%project:Directory% gives you the project directory
%project:Version% gives you the project version
So there is no way to access the build configuration or the environment here.
The configurations option in the project.json is also limited to build configurations and only allows declaring compilation options there, so that also doesn’t work.
Unfortunately, there also doesn’t seem to be another way to solve this. At least not right now. I would consider myself sending a pull request to DNX to add some additional project variables which one could use but at the moment, it doesn’t really make any sense to invest time into DNX: After all it’s being replaced by the dotnet CLI. We’ll see if that one will come with functionality to access the environment—and if not, I might end up submitting a pull request to add this functionality. But until we get there, I’m afraid there is no solution for this.

How do I include a file dynamically into a TeamCity build

I am fairly new to TeamCity and have recently been tasked with creating various builds, which I have done with no real issues.
What I am trying to do now though is include an external text file into the build output.
The external text file will be received from a service call made during the build.
These are my intended build steps:
Check out solution.
Restore packages.
Run tests.
Call web service with a configurable parameter and receive text file back.
Include text file in build.
Deploy.
Steps 1,2,3 and 6 are covered.
What are my options here? I must confess I do not really know where to begin.
I've spent some time today googling but it has been tricky getting the correct search term to return information on what I am trying to achieve.
I've seen some confusing articles on a 'meta runner'.
Any pointers to get me started in the right direction would be much appreciated.
Thanks.
Use a TeamCity command line build step - https://confluence.jetbrains.com/display/TCD9/Command+Line
I assume you are using build steps for all the other steps you listed so this is simply another of those.
The command line process would run somewhere under your checkout folder and thus anything it downloads would be made available as an artifact for your build

Default value for checkbox parameter in TeamCity

I'm building nuget in TeamCity and would like to append suffix "-pre" to version number when build is triggered by a checkin. And when build is triggered manually, I'd like to be able to provide a checkbox if this build should be a preview release or production-worthy.
I've got a Configuration Parameter created like that:
In this case I always have -pre added to the version number, even if I trigger the build manually and don't check the checkbox.
If I remove the value -pre from the default value of the parameter, then checkbox prompt works as expected. But when my build is triggered via a check-in, the system does not give me -pre suffix and I end up with a production release which should only be created manually.
Any way to implement what I need?
Alternatively I only want to publish nugets only on a manual trigger of the build and don't really care about pre-releases, but I can't seem to find any way to check if the build was triggered manually or via a check-in.
The first part is relatively easy, using a step to check the value of the checkbox and set a parameter based on it - Here I've used powershell but this could be done in bash (I've assumed powershell as you're producing nuget packages)
Note that I have reversed your logic a bit, but it produces the outcome you desire.
Define two varibles
Setup the checkbox
Setup two build steps
In the first step, test the parameter and use it to set another parameter
In the second step I'm proving the value has been set correctly
You should be able to use %ReleaseSuffix% when you need it.
Regarding your second requirement, I'm again going to make an assumption that you only want to publish a nuget package based on it being a Release build rather than a Pre-Release (if I've assumed this incorrectly let me know)
Conditional build steps based on a parameter value are something I've been tracking for a while now on YouTrack. This has been requested since 2011, but has still not made it in as a feature. I made this comment back in 2014 as a work around, but don't have the Java skills (you might) - My comment on YouTrack Issue
There is an alternative way to get this working, that might require some reworking of your build configurations.
If your "Publish NuGet" step is not triggered by anything (assumming it's triggered by the previous build finishing) then you could have a build step that
Checks the %ReleaseSuffix% parameter
Calls the REST API to trigger the build to publish the NuGet
It would potentially look something like this - just ensure you replace the highlighted bits
TeamCity Documentation
Hope this helps
Although the accepted answer here is very good, it does have a flaw; you will not be able to use the Assembly Info Patcher build feature, as this executes before the first step. Unless you wish to chain your builds together, setting the version in the first and using that in the second (yuck).
I have managed to find a solution which should give you the same results by tinkering with the parameters, setting them as follows:
The reason for using the "EmptyString" parameter is because without it, checked value defaults to "true".
I have tested this with manual triggers (release & prerelease) and VCS triggers (prerelease only), all functioning as expected on TeamCity v9.0.3 (build 32334).

Best strategy for automating multiple builds from a single white-label xcode project?

I'm researching the best approach to automating our build process. I've got my own ideas (through experience on a previous non-iOS project) but need good arguments for and against various possibilities.
Objective: A single xcode project with a single target (think white-label) needs to be built in 1..N different flavours (concrete brandings) with minimum user interaction and minimum technical knowledge. For AdHoc and/or AppStore.
Essentially, that will mean specifying per build; a folder containing Icons + Splashscreen, a bundle containing brand specific resources and (presumably?) the Info.plist, specifying appname, bundle-id, etc.
Issues that need to be respected or clarified;
Manual build of a single brand via Idiot-Proof GUI (choose a git
branch/tag, specify a certain brand, configure the app e.g.
IAP-enabled, server-domainname, etc - will be written to the
info.plist)
In previous manual tests, setting the executable name in
the plist didn't work? Sorry, have forgotten the exact problem..
perhaps was only an Xcode Debug buildconfig problem, not relevant to
a distribution build?
Code-Signing?!? Can the profile be specified
on-the-fly? Some brands need to be built with the customer's own
profile.
My personal feeling: Hudson or CruiseControl + Xcode plugin.
There seems to be plenty of documentation around for an Xcode solution and I've seen this in action on a Flex project I worked on, with almost exactly the same white-label/branding requirements. Of course that was using Ant script though and there was NO behavioral config to respect. That's my only uncertainty here... I suspect it would have to be hardcoded somewhere, but that's not the answer that's going to please some people. There is a wish to be able to specify the various app-config settings (server url, is function Foo supported, is the view X displayed, etc, etc) via a GUI form, when building manually. I'm not sure how easy it would be to shoehorn that into a typical Hudson or CC config?
And hence one suggestion that has been made is to write an OSX app for building our clients. The theory being, nice clean non-tech UI for entering all the necessary meta data & app setting and a big shiny green button labelled "Build". But personally I'm skeptical that this approach is any more flexible or easier to implement than a classic CI solution.
So the question is basically, what's preferable; a classic server based, version control integrated, CI approach or a custom OSX utility?
Whichever we go for it'll almost certainly be a requirement to get it up and running in 2 or 3 days (definately less than one week).
IMHO you can resolve all issues using different targets of XCode.
Every target will share the code but it could:
be signing with diferent profiles
use diferent plist: this implies having different names..
use diferent brand images. You only have to name the image with the same name and select the correct target in file inspector.
Build with one click in XCode.
I hope this helps
An extremely later reply, but the approach I would take would be to create the white label IPA, and then create a script to:
1. Unzip it (change the .ipa file extension to .zip).
2. Change assets.
Update the info.plist (using Plistbuddy command)
Zip it again.
Resign the code.
See this script as a starting point: https://gist.github.com/catmac/1682965
Very late answer. But I would go with different .xcconfig files and multiple schemes. The scheme names could be a combination of target/brand.

Resources