Set a TeamCity parameter to a date variable - teamcity

I have a TeamCity build that passes some arguments to an .exe and runs it daily. One argument is for a date parameter, currently set to a static date. It now needs to be dynamic, passing in the current date.
I tried setting the value to %env.BUILD_START_DATE% but this makes all my agents incompatible because of an implicit requirement for that env variable. I also tried setting the date in the DOS command line script, skipping TC params altogether, but it still ends up with that implicit requirement.

The top answer here: TeamCity Current Date variable in MMdd format
indicated need for a TC plugin, the second answer, however, did not require a plugin and is mostly complete. How I made it work on a variation of that second answer:
1.) Add a powershell build step to run the following:
echo "##teamcity[setParameter name='env.BUILD_START_DATE' value='$([DateTime]::Now)']"
2.) Give env.BUILD_START_DATE a default value in the Environment Variables section. Without the default value TC thinks having this value is an implicit requirement of a build agent, rendering all of them incompatible.

If you are unfamiliar with PowerShell, here is a Bash approach.
You can set a parameter with script and retrieve the value from the next build step.
echo "##teamcity[setParameter name='env.BUILD_START_DATE' value='$(date +%%Y-%%m-%%dT%%H:%%M:%%S%%z)']"
The doubled %% is because TeamCity considers % as its own parameter in build script.
The parameter will have ISO8601 format timestamp. For other formats, please see various Bash date format at here; https://www.tutorialkart.com/bash-shell-scripting/bash-date-format-options-examples/

You can set the variable in the config, which should be overridden during runtime. I don't see env.BUILD_START_DATE in my TC parameters, but I do see system.buildStartTime. I set it to a dummy value (I use "[Filled Automatically]"), and everything works fine. Build gets run and system.buildStartTime gets overridden at build time.

Related

How to make Gitlab CI not apply variable when the variable is in file

I have created a GitLab pipeline and predefined variable (type file). That file contains a variable ${myVar} that should not has to be applied before some steps of the job.
I found that when I open that file using cat, the ${myVar} disappeared. Looks like it was applied but with an empty string since its content has not yet been generated.
Question: how to tell GitLab CI to ignore variables in the variable file
The issue is fixed. All you need to do is to add one more $ sign before the variable. Hence instead of ${myVar} you need to specify $${myVar} in this case GitLab CI will not apply the variable
As of Gitlab 13.7 you can disable variable expansion for the variable (enabled by default). See:
https://gitlab.nposervices.com/help/ci/variables/index#expand-cicd-variables

CMake: How to add a custom variable for user macro with a value that depends on build configuration?

I use CMake version 3.16.
I tried the following:
set_property(TARGET ${PLUGIN_NAME} PROPERTY VS_GLOBAL_FR_VERSION
$<$<CONFIG:Debug2017>:"2017">
$<$<CONFIG:Release2017>:"2017">
$<$<CONFIG:Debug2018>:"2018">
$<$<CONFIG:Release2018>:"2018">
$<$<CONFIG:Debug2019>:"2019">
$<$<CONFIG:Release2019>:"2019">
)
And it kind of worked...
This variable (FR_VERSION) is supposed to be used in a script that is launched after build. This is how it looks:
add_custom_command(TARGET ${PLUGIN_NAME} POST_BUILD
COMMAND echo $(FR_VERSION)
COMMENT "This command will copy files to dist"
VERBATIM
)
In Visual Studio, however, we got the following:
echo $<$<CONFIG:Debug2017>:"2017">;$<$<CONFIG:Release2017>:"2017">;$<$<CONFIG:Debug2018>:"2018">;$<$<CONFIG:Release2018>:"2018">;$<$<CONFIG:Debug2019>:"2019">;$<$<CONFIG:Release2019>:"2019">
which fails to execute with the error message:
"The syntax of the command is incorrect."
If I don't try to set a different value for different build configs like this:
set_target_properties(${MAYA_PLUGIN_NAME} PROPERTIES VS_GLOBAL_FR_MAYA_VERSION "2018")
then the post-build script is generated as expected. (But this is not acceptable to me, because I need different parameter values for different build configurations).
I would appreciate any advice at this point.
Some target properties support generator expressions, while others do not. The documentation for a property will explicitly say that generator expressions are supported. Take the COMPILE_FEATURES property, for example:
Contents of COMPILE_FEATURES may use “generator expressions” with the syntax $<...>.
The documentation for VS_GLOBAL_<variable> does not have such language. Thus, as suggested, you can put the generator expression directly in the add_custom_command() call, which is supported:
add_custom_command(TARGET ${PLUGIN_NAME} POST_BUILD
COMMAND echo $<$<CONFIG:Debug2017>:"2017">
$<$<CONFIG:Release2017>:"2017">
$<$<CONFIG:Debug2018>:"2018">
$<$<CONFIG:Release2018>:"2018">
$<$<CONFIG:Debug2019>:"2019">
$<$<CONFIG:Release2019>:"2019">
COMMENT "This command will copy files to dist"
)

system variable configuration in teamcity for adding timestamp to it

I have created a parameter in Team city that is system parameter as shown below
system.version and its value is gla so it is like
system.version=gla
now can you please advise in Team City how can I configure this variable such as i want date time stamp to be appended since this variable is need to be changed every time when my build runs so I want to add the dates time stamp to this system variable please advise how to achieve this in team city.
You can add an initial build step that writes out a service message to update the parameter value (example below in PowerShell):
Step 1
$date = Get-Date
Write-Host "##teamcity[setParameter name='system.version' value='gla$date']"
Step x
Write-Host '%system.version%' # will output the new value
You can write a custom build step that calls a shell command and appends date/time to your variable
#!/bin/bash
date_var=`date +%Y%M` --> Define your format here
echo "##teamcity[setParameter name='system.version' value='$date_var']"
PS: you can use the new value of your variable only from the next build step

CMake override cached variable using command line

As I understand it, when you provide a variable via the command line with cmake (e.g. -DMy_Var=ON), that variable is stored inside the cache. When that variable is then accessed on future runs of the CMake script, it will always get the value stored inside the cache, ignoring any subsequent -DMy_Var=OFF parameters on the command line.
I understand that you can force the cache variable to be overwritten inside the CMakeLists.txt file using FORCE or by deleting the cache file, however I would like to know if there is a nice way for the -DMy_Var=XXX to be effective every time it is specified?
I have a suspicion that the answer is not to change these variables within a single build but rather have separate build sub-dirs for the different configs. Could someone clarify?
I found two methods for changing CMake variables.
The first one is suggested in the previous answer:
cmake -U My_Var -D Mu_Var=new_value
The second approach (I like it some more) is using CMake internal variables. In that case your variables will be still in the CMake cache, but they will be changed with each cmake invocation if they are specified with -D My_Var=.... The drawback is that these variables would not be seen from GUI or from the list of user's cache variables. I use the following approach for internal variables:
if (NOT DEFINED BUILD_NUMBER)
set(BUILD_NUMBER "unknown")
endif()
It allows me to set the BUILD_NUMBER from the command line (which is especially useful on the CI server):
cmake -D BUILD_NUMBER=4242 <source_dir>
With that approach if you don't specify your BUILD_NUMBER (but it was specified in previous invocations), it will use the cached value.
You could use
CMake -UMy_Var -DMy_Var=new_value
see documentation https://cmake.org/cmake/help/v3.9/manual/cmake.1.html
I hope this helps.
Find this post by coincidence.
It seems the behavior described by OP isn't the case for CMake 3.12 onwards. For previous releases, I didn't make some tests so cannot confirm.
Variables provided by -D on command line are stored in CMakeCache.txt. They can be overridden, even the same variable is repeatedly provided and the last one is set to the value for that variable.
For example, a very easy CMake script
message(STATUS "FOO = " ${FOO})
$ cmake -DFOO=123 -DFOO=321 .. # the last one takes effect
-- FOO = 321
-- Configuring done
-- Generating done
-- Build files have been written to: xxx
$ cmake .. # cache is remembered
-- FOO = 321
-- Configuring done
-- Generating done
-- Build files have been written to: xxx
$ cmake -DFOO=changed .. # override it
-- FOO = changed
-- Configuring done
-- Generating done
-- Build files have been written to: xxx

How to set Sphinx's `exclude_patterns` from the command line?

I'm using Sphinx on Windows.
Most of my documentation is for regular users, but there are some sub-pages with content for administrators only.
So I want to build two versions of my documentation: a complete version, and a second version with the "admin" pages excluded.
I used the exclude_patterns in the build configuration for that.
So far, it works. Every file in every subfolder whose name contains "admin" is ignored when I put this into the conf.py file:
exclude_patterns = ['**/*admin*']
The problem is that I'd like to run the build once to get both versions.
What I'm trying to do right now is running make.bat twice and supply different parameters on each run.
According to the documentation, I can achieve this by setting the BUILDDIR and SPHINXOPTS variables.
So now I have a build.bat that looks like this:
path=%path%;c:\python27\scripts
rem BUILD ADMIN DOCS
set SPHINXOPTS=
set BUILDDIR=c:\build\admin
call make clean
call make html
rem BUILD USER DOCS
set SPHINXOPTS=-D exclude_patterns=['**/*admin*']
set BUILDDIR=c:\build\user
call make clean
call make html
pause
The build in the two different directories works when I delete the line set BUILDDIR=build from the sphinx-generated make.bat file.
However, the exclude pattern does not work.
The batch file listed above outputs this for the second build (the one with the exclude pattern):
Making output directory...
Running Sphinx v1.1.3
loading translations [de]... done
loading pickled environment... not yet created
Exception occurred:
File "C:\Python27\lib\site-packages\sphinx-1.1.3-py2.7.egg\sphinx\environment.
py", line 495, in find_files
['**/' + d for d in config.exclude_dirnames] +
TypeError: coercing to Unicode: need string or buffer, list found
The full traceback has been saved in c:\users\myusername\appdata\local\temp\sphinx-err-kmihxk.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
Either send bugs to the mailing list at <http://groups.google.com/group/sphinx-dev/>,
or report them in the tracker at <http://bitbucket.org/birkenfeld/sphinx/issues/>.
What am I doing wrong?
Is the syntax for exclude_patterns in the sphinx-build command line different than in the conf.py file?
Or is there a better way to build two different versions in one step?
My first thought was that this was a quoting issue, quoting being notoriously difficult to get right on the Windows command line. However, I wasn't able to come up with any combination of quoting that changed the behavior at all. (The problem is easy to replicate)
Of course it could still just be some quoting issue I'm not smart enough to figure out, but I suspect this is a Sphinx bug of some kind, and hope you will report it to the Sphinx developers.
In the meantime, here's an alternate solution:
quoting from here:
There is a special object named tags available in the config file. It can be used to query and change the tags (see Including content based on tags). Use tags.has('tag') to query, tags.add('tag') and tags.remove('tag') to change
This allows you to essentially pass flags into the conf.py file from the command line, and since the conf.py file is just Python, you can use if statements to set the value of exclude_patterns conditionally based on the tags you pass in.
For example, you could pass Sphinx options like:
set SPHINXOPTS=-t foradmins
to pass the "foradmins" tag, and then check for it in your conf.py like so:
exclude_patterns = blah
if tags.has('foradmins'):
exclude_patterns = []
That should allow you to do what you want. Good Luck!

Resources