[Coding] Linux Shell Scripting for Jenkins/TFS
Posted by Khatharsis on May 2, 2016
(Cross posted at Across Moon River)
I’ve been having a fun month or so bashing my head against the desk, flinging my mouse and keyboard at my cubicle wall, and shaking my fist at my computer. Okay, mainly just shaking my fist at my computer. The Jenkins build server (Windows) is something I’ve been hesitantly touching and handling because I inherited a Java project (my company was traditionally at Windows/.NET shop). Jenkins jobs work fine hooked up to Git (a vendor’s SCM), but as soon as we tried to hook it up to TFS, it’s been erroring out with the strangest GUID that doesn’t map to any user in the TFS system. So, my friend in IT suggested we set up a Linux build server, install Jenkins, and see what we can do from there.
In short, that didn’t work either. So, I found a workaround.
My experience with Linux has been embarrassingly only through Ubuntu and Mint GUIs and setting up a sandbox LAMP stack to work on my website. I haven’t touched it in a couple of years.
IT set me up with a headless CentOS VM and has been thankfully helpful and patient with my bumbling way around the command line. Luckily, my usage of the Vim plugin for Visual Studio has made me fairly comfortable with using it as a text editor and I felt quite at home writing a shell script in PuTTY.
Though, the shell script (bash?) syntax is still a bit foreign to me, like if statements and the bracket notations, but I was able to write something that does what I want it to do. Better yet, I was able to write one script to be shared across multiple jobs. How’s that for reuse? Unfortunately I don’t have the script with me, but I can lay out what it does.
Prereq: TFS command-line CLC from the Microsoft website. I dropped the contents of the zip file in /var/lib/jenkins/shared/tfs-clc. I don’t know what the best practice or the most appropriate place to put it would be and I wasn’t given any definite answers from my colleagues other than to just drop it somewhere in the Jenkins folder.
The script (tfs-get.sh) itself has a set of variables at the top:
- TFS credentials
- TFS collection URL, e.g., http://tfs.some-place-awesome.com:8080/tfs/
- Path to Jenkins job workspace folder*, e.g., /var/lib/jenkins/jobs/$1/workspace
- Path to TFS containing the code to be built**, e.g., $/TeamProject/SpecificFolder/$2
*Argument 1 ($1) – Jenkins job name
**Argument 2 ($2) – Our TFS server is shared among multiple teams and our code will never touch theirs, so this argument only contains the shortest relevant path (e.g., “ProjectA”, or “Project/Main”)
The script includes a check to ensure both arguments are provided and exits otherwise. Then, it will check to see if the workspace folder has a mapping by calling the command-line TFS “workfold” command. If it returns an error, it will create a workspace and map the current workspace folder to the appropriate location on the TFS server. Then, it fetches the code.
A lot of the command-line TFS commands require the same set of info as arguments, so setting up the parameters up top and passing them as parameters serve two purposes:
1. Easy to change values
2. Values are consistent
Though, I have the feeling I’m going to look at this script months from now and scratch my head for a good minute before I recall my intent.
On the Jenkins side, a pre-build execute shell step is all that is needed and would look something like:
sh /path/to/tfs-get.sh JobName TFSPath
Pretty simple and fun to explore. We’re still understanding the concept of automated builds, but given we’re generally hitting Build Now on the server when we want a build anyway, this gets us farther than the error (and therefore no build) we were getting before.