Jenkins (or Hudson if you work for Oracle) is a great, simple and steady continuous integration and build server. One of its greatest features is that despite being packaged as a standard .war ready to be dropped into your JEE web container of choice … it also contains an embedded web container that makes the .war everything you need in most situations. Simply run
java -jar jenkins.war
and up starts Jenkins on port 8080 in all of its glory. All of Jenkins’ configuration files, plugins, and working directories go under <USER_HOME>/.jenkins by default. Perfect.
Except if you want to run multiple instances on the same machine. We are going to get a config folder collision. It turns out this is a piece of cake, but the docs are hard to find. Jenkins will use a JENKINS_HOME path environement variable for its configuration files if one is set so a simple change means we can run Jenkins out of any directory we desire:
java -DJENKINS_HOME=/path/to/configs -jar jenkins.war
What about the port you say? Winston, the embedded web container used, has a simple property for this too:
java -DJENKINS_HOME=/path/to/configs -jar jenkins.war --httpPort=9090
As agile software developers we work hard to make the development process as flexible and lean as possible for our customers. We work hard to estimate accurately, deliver working code quickly, and only do the work needed to finish the story right in front of us. This discipline is hard but keeps our customers in the loop and getting the most for their money/time. In order to keep up with the customer’s every changing requirements we often push-off decisions to the last responsible moment. By delaying making expensive decisions until our hand is forced, we reduce waste and can stay focused on delivering value with each finished story.
But, when is the last responsible moment? Who decides? Has it changed?
With our heads down in the trenches, knocking out stories left and right, and moving fast toward our client’s vision … we have to keep these questions in mind. A recent project reminded me of this. Our team did a great job at empowering our client to shift our priorities as their business understanding changed. We offered options, gave accurate estimates for stories, and allowed them to shift the work at hand each iteration. We did exactly what we were setting out to do.
Unfortunately, we were so focused on short-term flexibility and options that the higher level vision began to slip, and some decisions were made AFTER the last responsible moment.
The key here is the responsible. While we work to increase our productivity, reduce waste, and keep our customer’s immediate desires met … we need to keep in mind that the short-term decisions add up. Long off decisions and high level visions don’t need to be fully spec’ed and decided day 1, but the same way we maintain our suite of tests as requirements change, short-term decisions needed to be reconciled with the high level vision. A great team keeps in mind when this last responsible moment is for different kinds of decisions and revisits these frequently.
While working on getting QUnit-CLI cleaned up and refactored a bit, I realized I needed to tie the example code in the Git repository to a particular version of QUnit.js (those guys are making changes too fast for me to keep up). I have used SVN:externals prevsiously so Git submodules seemed like an obvious solution. A single submodule should allow me to keep QUnit-CLI inherently pointing to a particular revision of QUnit.js without requiring me to seperately document which version I was testing against.
The man page for git-submodule as well as the Git Book chapter on Submodules do a good job of documenting the command with some simple examples, but none that were 100% clear for my needs. In addition, I need my Git submodule to point to a specific commit (or branch) so that everyone cloning my code consistently can run my examples w/o fear that a new commit on HEAD will break something.
Step 1 : Add the submodule
Once the module is checked out, I need to add the QUnit submodule. First grab the GitHub url for my QUnit fork (eventually this will be replaced with the main QUnit repo) and execute the “add” command from within your local repository root.
git submodule add git://github.com/asynchrony/qunit.git qunit
Afterward there will be two modified and staged objects in your repo: .gitmodules will contain the submodule’s local path and source URL and a new folder named qunit which contains a full clone of your source repository.
** Fraser Speirs has a good writeup on what is going on behind the scenes with the Git internals and how the key to all of this is in the index files of each repo and the modes the changes are committed with. **
Step 2 : Fix the submodule to a particular commit
By default the new submodule will be tracking HEAD of the master branch but will NOT be updated as you update your primary repo. In order to change the submodule to track a particular commit or different branch change directory to the submodule folder and switch branches just like you would in a normal repo.
git checkout -b dev_branch origin/dev_branch
Now the submodule is fixed on the development branch instead of HEAD of master. Just easily I could set it to specific commit or tag.
Step 3 : Commit everything
Now from your primary repository you still have two modified objects: .gitmodules file and qunit folder. Commiting these changes will persist the new submodule tracking your desired branch.
Step 4 : Clone Recursive
The next time you (or someone else) clones this repo, they will need to do one of two things.
A) Add the –recursive flag to their git clone command
git clone REPO_URL --recursive
B) manually initialize and the submodules after the clone
git clone REPO_URL git submodule update --init --recursive
My current client was my first experience with remote pairing (local team of developers remote pairing with equal number of client developers). Overall things went much better than I expected however the communication bandwidth difference between remote and local is VERY apparent and a huge loss. Most of the time we try to set up cross-company pairs which benefits reducing knowledge silos, but increases communication costs.
Per the client’s request we have been using Microsoft Communicator with decent success. Lag is an issue but luckily both companies have adequate network speeds to make up for it. Working on a thick-client Windows application means no to terminal work but I will definitely look into tmux and NX next time.
The biggest disadvantage of remote pairing is the loss non-verbal communication and flow. I am a firm believer in the value of pairing in all but the most trivial of tasks, but haven’t been able to muster the same level of interaction over a headset. All of my best development/pairing experiences have been working with a pair which I was “in tune with”. The non-verbal communication (e.g. grunts and quick points) and fluidity (taking quick breaks for a drink, answering a question for another dev in the war room, etc) were the key to our productivity and happiness.
One of the biggest technical issue I have found is war-room spacial awareness while STILL hearing your pair clearly. A high quality headset (mic and earphones) is invaluable when working remotely, but this limits your “presence” in the war room. Side conversations get missed or get replaced by more “formal/slow/inefficient” means of communication. Find a solution to that, and things would be much better.
Pairing is not easy in the best of conditions. It is so easy for one or both developers to wander off (mentally or otherwise). On top of convincing developers to open themselves up for constructive criticism and constant communication there is always the adventure that is convincing the business side of things that the “extra” expense now is worth it tomorrow.
Despite all that, it is worth it. Pairing keeps me pushing myself to work harder/faster/better and leaves no room for bad habits and poor choices. My first day at Asynchrony I paired for ~8 hours with a great developer and promptly came home to my wife and collapsed. She, being the loving wife she is, was concerned my first day had gone poorly. I said no. Great in fact. I wrote more high quality code that day than I had in the past month working in a cube by myself. My brain was just dead tired.
Prompted by a question from my good friend Kevin Berridge about agile team stand-up meetings, I quickly came up with a long list of do’s and don’ts but nothing substantial. Nothing immediately profound. Any quick google search can give you tips, tricks and pitfalls. I wanted something more. To try and ignite my thoughts I began writing down words that came to mind when I thought about a good daily standup meeting …
When daily standups go well, the team has a clear understanding of how they go to where they are today, where they are trying to go, and the route they are going to follow.
When daily standups go bad, individuals get frustrated, time is wasted, problems reoccur, and the meeting ends up being a means to justify paychecks and appease management.
Whether you focus your meeting on what each individual did yesterday/is doing today/is blocked by or on how the story board changed from yesterday, the real goal should be focusing the team toward a common short term goal, and making any impediments very visible. The meeting should be for the team, by the team and to the team.
Often I see standups where everyone ends up telling the PM/Scrum Master/Team Lead what they worked on yesterday and an excuse about not yet knowing what they were going to do today. Have the team talk to the team. If what you are sharing doesn’t have value to the rest of the team, don’t share it right now. If a detailed discussion starts between on some members of the team, wait until the standup is over. If the meeting stops providing value at 5 minutes, stop the meeting. If the meeting is going past 10-15 minutes, stop and have the team decide if it should continue or be broken up in favor of smaller discussions.
Daily standups are great way to get everyone on the same page, re-focus the team on the highest priority items, and lay out a quick plan of attack. Like time-outs in the middle of a big game, they need to help bring everyone together and formulate a short term plan to victory. Especially when King James shows up.
Agile is all about the profit
While considering my teammate Amos’ recent blog post where he debates what Agile really is my mind was drawn to a statement our current client made during one of our early project kickoff meeting. While discussion why his clients have been successful following his plans he made the statement:
You will never go broke, making a profit
At the time this seemed like a good joke and litte more. However, the more I thought about it, the more it rang true. What does this have to do with Agile software development? While questioning what is or is-not Agile and what his definition of Agile might be missing, he says:
… The one thing that I didn’t mention above. … Delivering a useable project at any point in development. That is it. That is what I’m missing. This has got to be the hardest part of agile. …
I think the key here is the value of a shipped product is ALWAYS greater than that of one sitting on the shelf. Value is the key. To me, the agile mindshift is one of always producing value for the customer, for the team, or for yourself.
Produce value for the client:
- by adapting to their ever changing business needs with understanding, speed, and energy
- by aligning all user stories with tangible user value and goals
- by planning and documenting in inverse proportion to the item’s priority and deadline
- worry about what is in front of you first and put off decisions to the last responsible moment (stolen and probably butchered from a WWBBD: What Would Brian Button Do)
- by working on the highest bang-for-the-buck stories first, top down, and delivering working code as often as possible
Produce value for the team:
- by conducting frequent retrospectives where the team can think about how they are doing and how they can be better
- by realizing that many/most of a team’s problems are really “people” issues masquerading as technical ones
- by actively paying down technical debt
- by reducing knowledge silos and keeping the team only full of valuable members and all members valuable
Produce value for your self:
- by staying motivated and positive
- by keeping the thirst for knowledge alive and always learning from any experience
- by taking greater pride in the success of the team over the success of an individual ego
- by working to be a great communicator: to team members, to the client, to your code (Tests)
I didn’t mean for this post to turn into a list of things to do … but often our practices are the best way we can take abstract principles and make them tangible. So long as the practices don’t become to focal point, they are a useful way to monitor, enforce and discuss the important concepts.
Profit really is the key. Our client helped his clients by making sure they were profitable. Sure, maybe they could have been more profitable, if they had taken bigger risks and bet the farm for instance, but year after year a steady profit is inspiring.
Which brings me to the Underwear Gnomes of South Park. Their business plan was a simple one.
- Collect Underpants
By focussing on providing value (profit) at each point along the way, maybe step 2 wouldn’t be such a mystery. Granted, gnomes are pretty agile to begin with. Fast too.