tag:blogger.com,1999:blog-114857562024-03-07T23:52:16.277+01:00Thomas Ferris Nicolaisen's blogMy thoughts on software development.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.comBlogger260125tag:blogger.com,1999:blog-11485756.post-16454502055752348842021-02-16T18:44:00.001+01:002021-02-16T18:50:19.474+01:00Leaving eyeo<p>Thirteen blog posts later, this one notes my departure from eyeo after 4 years and 3 months.</p><p>I <a href="https://blog.tfnico.com/2017/01/joining-eyeo.html">joined eyeo</a> around the headcount of 80 employees, and now I think there's just over 250 people there.</p><p>My role coming in was as operations manager, doing a mix of infrastructure engineering and technical project management. I later on took on organizational development to help the company deal with its <a href="https://blog.tfnico.com/2017/12/joining-eyeo-year-in-review.html">growing pains</a>. We introduced cross-functional teams, departments (kind of like guilds), new leadership structures, goal-setting frameworks, onboarding processes and career frameworks. </p><p>And all of this in a rapidly growing <i>distributed</i> company. I'm proud and happy that for a long time I knew every employee by name and got to meet every single new-hire through training them on company structure and processes. </p><p>At some point, we had enough experienced leaders and organizational developers that I could zoom back in on working in one team, consulting them on <a href="https://blog.tfnico.com/2020/07/git-tools-for-keeping-patches-on-top-of.html">Git</a> and continuous integration, and coaching them on <a href="https://blog.tfnico.com/2018/07/mediation-in-teams.html">mediation</a>, <a href="https://blog.tfnico.com/2018/08/an-anecdote-about-trust.html">trust</a>, <a href="https://blog.tfnico.com/2018/11/working-in-teams-over-working-as.html">team work</a>, <a href="https://blog.tfnico.com/2019/01/hosting-gregorio-billikopfs-empathic.html">listening</a> and <a href="https://blog.tfnico.com/2020/06/recent-experiences-possible-posts.html">more</a>.</p><p>This kept me busy for the last two years. My team grew from a team of 8 into a business unit with over 40 people. Teams have grown and split and grown and split again. I've facilitated and led more retrospectives, virtual team days and workshops than I can count, some on-site in Cologne and during one team-week in Prague, but mostly distributed from as far west as California, across Europe and as far east as Vietnam.</p><p>Through this time, a feeling grew that I was approaching a crossroads for my own career. </p><p>The natural path was for me to continue developing as a coach to higher levels. I thought this was what I wanted for a long time, but the further I went down this path, the less time I had for software engineering and I missed it more and more. </p><p>At the same time, I felt my impact and contribution as a coach was falling below my personal potential. I realized I wanted be a software developer again, with coaching as a my secondary proficiency rather than the other way around.</p><p>One option would've been to find a more technical role within eyeo, but I wasn't able to find one matching the kind of backend/server-side development work I'm experienced with and interested in.</p><p>So I began to search outside of eyeo. I activated my network and ramped up a speedy but structured process of applying to a set of companies in parallel. Long story short, I'm going back to software development, and I will again be working out of an office in Bonn, as soon as the conditions allow for it at least. More about that in a future post.</p><p>It's definitely been a wild ride at <a href="https://eyeo.com/">eyeo</a>, and I'm grateful to all the people I worked with there and learned so much from. I hope they succeed on their mission for a safer and saner Internet, as that will benefit us all.</p><p></p>Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com4tag:blogger.com,1999:blog-11485756.post-85456275174678779262020-07-06T01:20:00.002+02:002020-07-06T01:20:39.325+02:00Git tools for keeping patches on top of moving upstreams<div>At work, we maintain patches for some pretty large open source repositories that regularly release new versions, forcing us to update our patches to match. <br /></div><div><br /></div><div>So far, we've been using basic Git operations to transplant our modifications from one major version of the upstream to the next.</div><p>Every time we make such a transplant, we simply squash together the modifications we made in the previous version, and land it as one big commit into the next version.</p><p>Those who are used to very stringent keeping of Git history may wrinkle their nose at this, but it is a pragmatic choice. Maintaining modifications on top of the rapidly changing upstream is a lot of work, and so far we haven't had the opportunity to figure out a more clever way to do it. Nor have we really suffered any consequences of not having an easy to read history of our modifications - it's a relatively small amount of patches, after all.</p><p>With a recent boost in team size, we may have that opportunity. Also the need for better history-keeping increases with our capability do to it well.<br /></p><p>From the days where I was <a href="https://blog.tfnico.com/search/label/git">more active in the Git community</a>, I've chatted with some people dealing with similar problems:<br /></p><p>First up was <a href="https://episodes.gitminutes.com/2014/04/gitminutes-28-johannes-schindelin-on.html">Johannes Schindelin</a>, now at Microsoft, the maintainer of Git for Windows. He has been keeping his own set of scripts for keeping the modifications needed in Git itself to make it work well on Windows. I'm not sure whether his scripts will be easy to re-use out of the box, but it is somehow reassuring that others have managed this kind of operation.</p><p>Another one was <a href="https://episodes.gitminutes.com/2018/02/gitminutes-44-josh-triplett-on-git.html">Josh Triplett</a> at Intel, who developed <a href="https://github.com/git-series/git-series">git-series</a> to help maintain patch-series as they were evolving and awaiting acceptance upstream (sometimes a patch series waiting for acceptance into the linux kernel can go for many months, and undergo dozens of iterations before finally being accepted, if ever). Now, based on what I remember, git-series could be just the thing for us. But perhaps there are other tools.</p><p>git-series takes inspiration from <a href="https://en.wikipedia.org/wiki/Quilt_(software)">Quilt</a>, which is the classic tool for maintaining patches. Quilt is not tied to a particular VCS.</p><p>Going from there, there is the similarly named <a href="https://github.com/jeffpc/guilt">Guilt</a>, which does tie into Git, persisting the managed patches as Git commits rather than patch files. And there's a similar tool called Stacked Git or <a href="https://stacked-git.github.io/">StGit</a> that does the same. Both of these are heavily inspired by Mercurial's MQ extension.</p><p>Another person into these challenges was <a href="https://episodes.gitminutes.com/2015/03/gitminutes-32-adam-spiers-on-git-deps.html">Adam Spiers</a> at SUSE, the author of <a href="https://github.com/aspiers/git-deps">git-deps</a>, a very nifty tool for analyzing dependencies between Git commits. He also authored <a href="https://github.com/aspiers/git-explode">git-explode</a>, which could be useful for us breaking our modification blob into smaller patches. Adam later pointed my attention to a tool called <a href="https://mackyle.github.io/topgit/">TopGit</a>, which seems to be developed for exactly our kind of use-case, although Adam did have <a href="https://github.com/greenrd/topgit/issues/created_by/aspiers">some qualms</a> about it. Similar to Johannes, he has developed some scripts of his own, which he was tempted to turn into a proper project.<br /></p><p>And a more random find: I found several of the above tools mentioned in <a href="https://git.github.io/rev_news/2019/08/21/edition-54/">Git Rev News #54</a>, where a new tool called <a href="https://mystor.github.io/git-revise.html">git-revise</a> was promoted.</p><p>Inspired by that, I took to searching the Git mailing list for some of the above keywords, and found that Stefan Xanos has <a href="https://public-inbox.org/git/86d0spzoi1.fsf@gmail.com/T/">discussed</a> and <a href="https://public-inbox.org/git/20190215043105.163688-1-sxenos@google.com/">proposed</a> designs of an evolve tool for Git. The topic was <a href="https://public-inbox.org/git/9CE46D29-4BCD-4E95-B2DA-939EA10D7934@jramsay.com.au/">brought up again</a> at the latest Git contributor summit. So maybe Git itself will offer more support for these kinds of use-cases some day.<br /></p><p>So, an overview of the tools I could find:<br /></p><p><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px; height: 284px; width: 682px;"><tbody><tr><td style="min-width: 60px;"><b> Tool</b></td><td style="min-width: 60px;"><b> Tech<span></span><br /></b></td><td style="min-width: 60px;"><b> Notes</b></td></tr><tr><td style="min-width: 60px;"> <a href="https://en.wikipedia.org/wiki/Quilt_(software)">Quilt</a><span><br /></span></td><td style="min-width: 60px;"> Bash<span></span> <br /></td><td style="min-width: 60px;"> Not based on Git</td></tr><tr><td> Git for Windows'<br /> <a href="https://github.com/git-for-windows/build-extra/blob/main/shears.sh">Garden shears</a></td><td> Sh</td><td> May be very specific to the Git <br />repository itself</td></tr><tr><td> <a href="https://github.com/git-series/git-series">git-series</a><span><br /></span></td><td> Rust</td><td> Irregular activity (only Josh <br />appears to be developing it)</td></tr><tr><td> <a href="https://github.com/jeffpc/guilt">Guilt</a></td><td> Sh</td><td> MQ like. Last commit was a<br />couple of years ago.</td></tr><tr><td> <a href="https://stacked-git.github.io/">StGit</a></td><td> Python<br /></td><td> MQ like. Actively developed.</td></tr><tr><td> <a href="https://mystor.github.io/git-revise.html">git-revise</a></td><td> Python<span></span></td><td> Circumvents the slowness of <br />rebase by working on the index <br />directly. Very new.</td></tr><tr><td> <a href="https://mackyle.github.io/topgit/">TopGit</a></td><td> Sh</td><td> 11 years of development and <br />still active! Mighty, almost <br />intimidating feature set.<br /></td></tr></tbody></table></p><p>To sum it up, it seems many people have related problems, but there are different pain points and workflows that seem to invite their own solutions. The tools may be either opinionated/tailored to specific use-cases. <br /></p><p>So we'll have to try them out, see what works, and perhaps even write our own scripts if that works best for us.<br /></p><p>I'd be happy to hear any feedback, additional tools or details I got wrong above.</p>Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com1tag:blogger.com,1999:blog-11485756.post-22137307620563450672020-06-14T19:07:00.001+02:002020-06-14T19:07:16.878+02:00Recent Experiences - Possible PostsOver the last year, I've been increasingly doing a lot of blogging the intranet at work. As a consequence of this, I think I've felt less urge for blogging out here.<br />
<br />
The same way an open source developer builds a public profile by having their product shared in the open, I think it makes sense for people who don't work on code to do the same in the form of blogging, vlogging, tweeting or writing posts on Twitter/Facebook.<br />
<br />
Unfortunately, the content I write on the intranet is very specific to that culture. So it wouldn't be right to copy it in here.<br />
<br />
What I can do is to iterate some of the topics just quickly in this post, and then think about what topics are worth writing more about here. Your feedback is appreciated! Write a comment below or <a href="https://twitter.com/tfnico/">tweet me</a> if you want to direct my writing in a particular direction. <br />
<h3>
What do I do anyway</h3>
For context, the last years my role has evolved quite a bit. I have a tricky profile to pin down into a role: I've drifted from software development through infrastructure/operations management, organizational development, and now currently I'm an agile coach for a business unit of development teams.<br />
<br />
I like this role because it gives me the freedom to operate where I can have the most impact, in a wide realm between technology and organization.<br />
<br />
While it seems everybody has become proficient in running distributed teams the last 3 months, I did get a head-start in this area by starting to work remotely almost 4 years ago.<br />
<h3>
What have I been writing about (internally)</h3>
In no particular order.. <br />
<ul>
<li>A whole bunch of pro-tips about GSuite, Google Calendar, Gmail, IRCcloud, BlueJeans, and so on.</li>
<li>Various exercises for distributed teams (various formats for retrospectives, team building, post-mortems, etc.)</li>
<li>Radiating availability and absence (particularly important in distributed teams)</li>
<li>Planning for operational capacity in globally distributed teams (hint: no single day is a holiday in all the world's countries)</li>
<li>Online meeting survival guide</li>
</ul>
Some of the more interesting things I've been doing (and could potentially write about) <br />
<ul>
<li>Coaching a team distributed over 11 countries (with time-zones from California to India)</li>
<li>Gathering said team for a week of co-located team building</li>
<li>Running one of those team weeks in a distributed form (due to COVID19)</li>
<li>Onboarding new-hires into distributed teams (building processes for this and practicing them)</li>
<li>Practicing leadership in distributed teams (do's and don'ts)</li>
<li>Setting up Jira projects for distributed Kanban teams</li>
</ul>
My inner imposter-syndrome-voice is saying that all these topics have been discussed at length already (I particularly enjoy the perspectives from the <a href="https://knowyourteam.com/">Know Your Team</a> blog).<br />
<br />
I still hope my writing on any of these topics will add something new to the public body of knowledge. Let me know which ones are more interesting to you!Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-17210532457503798402019-09-01T22:38:00.000+02:002019-09-01T22:38:22.860+02:00Using Voice-Chat for Gamers in Distributed TeamsThis is a post going into the usefulness of live voice-chat tools in distributed teams.<br />
<br />
If you've ever seen the <a href="https://www.youtube.com/watch?v=mLyOj_QD4a4">Leeeeeroooooyy Jeeeenkiiins</a>
video of World of Warcraft fame, you've heard this kind of tool in
action. It's how the participants in the video are speaking with each other - this is not a feature built into the World of Warcraft game - it's a separate team-oriented VoIP software, and it's all about
letting gamers communicate orally while gaming. <br />
<br />
Since these tools are for gamers, they have to be <br />
<ul>
<li>fast
(low latency)</li>
<li>light (as not to steal CPU-cycles from heavy games graphics) </li>
<li>moderate in bandwidth usage (as not to affect the game server connection)</li>
</ul>
There are several options around: <a href="https://teamspeak.com/en/">TeamSpeak</a>, <a href="http://www.ventrilo.com/">Ventrilo</a>, more recently the massively grown <a href="https://discordapp.com/">Discord</a>, and finally <a href="https://wiki.mumble.info/">Mumble</a>, which is the open-source alternative of the gang.<br />
A few years ago, when I <a href="https://blog.tfnico.com/2017/01/joining-eyeo.html">joined eyeo</a> (a distributed company), several of the operations team were avid gamers, and had a TeamSpeak server set up between them to allow voice chat during online gaming sessions (great team building option for distributed teams, by the way).<br />
<br />
As the team was growing, we began experimenting with using this service for team communication in between meetings (we switched to Mumble at some point, so I'll refer to it as Mumble from now on).<br />
<br />
<img alt="File:Metromumble dark preview.png" height="484" src="https://wiki.mumble.info/images/3/34/Metromumble_dark_preview.png" width="795" /> <br />
<br />
Mumble turned out to hit a pretty sweet spot compared to our conventional video conferencing software (we use BlueJeans):<br />
<br />
<b>A video conference needs many clicks to fire up and get everyone dialed in.</b><br />
<br />
Mumble, on the other hand, has the team constantly connected, so there's one click required to start speaking.<br />
<br />
The usual scenario would go like this:<br />
<br />
1) I ping someone on IRC, asking a question<br />
2) We go back and forth in writing for a few lines<br />
3) One of us would ask "mumble?"<br />
4) We both un-mute ourselves in Mumble and start speaking<br />
5) Others may listen in, and join the conversation if they feel like it, or move to a Busy channel if they want to focus on other work.<br />
<br />
<b>The video conferencing software will take up all bandwidth and resources</b><br />
<br />
Being optimized to imitate physical presence, the video conferencing software will exploit your laptop's resources to max quality, sometimes with devastating effects (especially on Linux).<br />
<br />
Mumble, on the other hand, sacrifices video completely and focuses on voice only. It is optimized to save resources, so you barely notice it is running.<br />
<br />
<b>Video conferences will not work for poor connections (or require you dial in via expensive phone numbers).</b> <br />
<br />
Mumble on the other hand, works excellently on poor connections. Latency is marvelously low, which can be tested with the "ping pong test":<br />
<br />
1) You say "ping"<br />
2) The other person says "pong" when they hear you<br />
3) You say "ping" when you hear their "pong"<br />
4) Repeat until you get a feel of how long a roundtrip takes<br />
<br />
In our video conferencing system, a roundtrip takes about 1-2 seconds (!).<br />
<br />
In Mumble, it's like being next to the other person You can barely notice the latency, even when speaking to colleagues halfway around the world (last Friday I did the ping test with one colleague in Yekaterinburg and the other in India).<br />
<br />
<i>I think this difference in latency may have a HUGE effect on natural discussions in larger distributed groups, but that's a theory for another day.</i><br />
<br />
So, as it turns out, the things that make gamers love Mumble may also let distributed teams love Mumble.<br />
<br />
<b><br /></b>
<b>If you want to try this out with your team right now</b>, you may be better off just starting with Discord, as it is a free and no-hassle setup. At eyeo we are pretty adamant on things like security and privacy, however, so we're glad we can use the awesome open-source Mumble on our own servers.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-48391624247867641362019-01-06T18:15:00.000+01:002019-01-06T18:15:34.074+01:00Hosting Gregorio Billikopf's Empathic Listening audio seminarLast year, I came across an awesome free resource for learning mediation and as part of that, empathic listening.<br />
<br />
As <a href="https://blog.tfnico.com/2018/07/mediation-in-teams.html">I blogged about at the time</a>, <a href="https://en.wikipedia.org/wiki/Gregorio_Billikopf">Gregorio Billikopf</a>'s audio seminar "Listening First Aid: An Empathic Approach" provided me some very useful knowledge, not only for conflict mediation, but for every day life: Listening is obviously a huge part of how we operate socially, and becoming better at it is something that not many think about, although it is sorely needed for many.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFkDJzFKivSTJH8Pey9I5_tLc7-3WUtugCYhDKoZbF6l7HXz-cReiQ-xgCr1NYcRhUxBGxdouJpYdoms36OPwDgz5c6XR2SI3c9ZPpAQ3nAKaiMV2ns6h5b9RFj-NNuzB1a0Oq/s1600/17976225973_f1c2052ac3_o%25281%2529.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="915" data-original-width="1600" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFkDJzFKivSTJH8Pey9I5_tLc7-3WUtugCYhDKoZbF6l7HXz-cReiQ-xgCr1NYcRhUxBGxdouJpYdoms36OPwDgz5c6XR2SI3c9ZPpAQ3nAKaiMV2ns6h5b9RFj-NNuzB1a0Oq/s320/17976225973_f1c2052ac3_o%25281%2529.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://www.flickr.com/photos/mikecogh/17976225973">"Engaging Conversation" by Michael Coghlan</a> licensed <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a> </td></tr>
</tbody></table>
<br />Naturally, I was keen on letting others in on Gregorio's resources, but <a href="https://nature.berkeley.edu/ucce50/ag-labor/7article/article40.htm">the website</a> where the audio seminar is hosted only offers a single zip file download containing the mp3 files, and a slow download at that. In this day and age where everything can be but a click away for attention, I figured it would be worthwhile making this content more accessible.<br />
<br />
I sent Gregorio an email to ask if he was interested in this, and he was quite enthusiastic about seeing this happen. With his permission, I spun up a website, uploaded the mp3s to YouTube and SoundCloud and after a little tweaking over the weekend, we've launched it here:<br />
<br />
<div style="text-align: center;">
<a href="https://listening.tfnico.com/"><span style="font-size: large;">https://listening.tfnico.com/</span></a></div>
<br />
I hope this will be useful for someone out there! Let me know if you have any feedback on the site.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-73401211058937939172019-01-04T16:58:00.000+01:002019-01-04T16:58:39.941+01:00Some Industry Practice and Thoughts on Roadmaps Recently, I signed up for doing an internal talk about roadmaps, and what they are generally all about. I figured this post would be a good start to get myself into crystallizing the message up front.<br />
<br />
Keeping in mind, roadmaps are but one component in an extremely complex domain involving many sciences, so this is one of those scratching-the-surface-posts.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn3TKX-FJTECK8n1IkeXd0QAVXH7iiXpJlVJOEdLw0ADrfxTYMUL7kYBTdlO-Li3IQ9_UhLqom5hekVTMDl9-siby48kVL6Z9iZKcO6AhQDuf_VEWkSj-V_rkCnfYi5KVU0BQ1/s1600/sketch1499772602801.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="398" data-original-width="294" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn3TKX-FJTECK8n1IkeXd0QAVXH7iiXpJlVJOEdLw0ADrfxTYMUL7kYBTdlO-Li3IQ9_UhLqom5hekVTMDl9-siby48kVL6Z9iZKcO6AhQDuf_VEWkSj-V_rkCnfYi5KVU0BQ1/s320/sketch1499772602801.png" width="236" /></a></div>
<h2>
Who's saying what out there</h2>
Before we start inventing our own wheels, it's nice to review what is the state of roadmaps out there. Perhaps there is some "industry best practice" ;)<br />
<br />
So I'll begin by collecting information from the first, best sources I know about.<br />
<br />
I happen to follow a couple of product management authorities on Twitter: <a href="https://twitter.com/lissijean">Melissa Perri</a> and <a href="https://twitter.com/johncutlefish">John Cutler</a>. Then recently, our internal head of product recently pointed out <a href="https://twitter.com/romanpichler">Roman Pichler</a>. Finally, there's the venerable <a href="https://twitter.com/cagan">Marty Cagan</a> who I reckoned has written a thing or two about roadmaps, and that was indeed the case.<br />
<br />
Note that each of these have published lots of more writing and even books on the surrounding subjects of product management, but here I've just gone through what I could quickly find online, going roughly from older to more recent:<br />
<h3>
Marty Cagan</h3>
... has written a lot of seminal work on the topic, and these are the ones I quickly found have to do with roadmaps in particular:<br />
<br />
In <a href="https://svpg.com/product-roadmaps/">Product Roadmaps</a> (Jan 2009), he lays down some foundations and terminology that just makes sense, like what a product roadmap is, the product strategy that needs to be behind it, and so on. He points out the danger of getting lost in feature requests, wishing we'll focus more on simpler, higher level plans of delivering user value. Sounds wise!<br />
<br />
In <a href="https://svpg.com/the-alternative-to-roadmaps/">The Alternative to Roadmaps</a> (Sep 2015) and the correlating <a href="https://svpg.com/roadmap-alternative-faq/">FAQ</a>, he repeats the issues of traditional feature focus, and goes deeper into the underlying causes that bring teams in that direction. He suggests The Product Vision combined with Business Objectives (recommending OKRs in particular), while concrete tasks go to the Product Backlog.<br />
<h3>
Roman Pichler</h3>
Being a trainer, he offers sound basics and easy-to-understand frameworks as preparation for his <a href="https://www.romanpichler.com/training-courses/agile-product-strategy-roadmaps-training-course/">strategy and roadmap course</a> (see the <i>Prerequisites and Prep Work</i> section), and he has a <a href="https://www.romanpichler.com/blog/category/product-roadmap/">collection of blog posts online</a> on the subject, and <a href="https://www.romanpichler.com/romans-books/">books</a>.<br />
<br />
He repeats Cagan's plea to focus on outcomes (using the words goals and benefits), and shares some very neat templates. Fit the roadmap in between the strategy and backlog, and <i>keep it simple</i>. I really do like Pichler's structured and simple way of explaining the material, plus the tips for getting buy-in.<br />
<h3>
Melissa Perri </h3>
... wrote <a href="https://melissaperri.com/blog/2014/05/19/rethinking-the-product-roadmap">Rethinking the Product Roadmap</a> (May, 2014), also suggesting we replace the traditional, over-filled, over-detailed roadmaps. She thoroughly illustrates the current issues, and suggests the Problem Roadmap to remedy. I understand <i>problem</i> here as being the inverse or negated form of outcome/objectives/goals/benefits mentioned earlier. She also suggests a quarterly cycle to explore/validate the problem at hand.<br />
<br />
In <a href="https://melissaperri.com/blog/2017/02/15/product-roadmaps">Effective Product Roadmaps</a> (Feb, 2017), Perri refines the approach and gives some very solid examples of what a better roadmap could be. Adding context (vision, challenge, target condition) on top, she picks up the term <i>theme</i> (which Cagan also mentioned has caused some confusion in product management history), and applies it to individual areas that have hypothesis/outcomes. Each theme can also be in a particular stage: Discovery or Delivery. Finally, she imagines this roadmap being part of a cross-team Portfolio Roadmap. <br />
<br />
She recently published a very interesting sounding book called <a href="https://melissaperri.com/book/">Escaping the Build Trap</a>. <br />
<h3>
John Cutler</h3>
... is a prolific writer on the subject, often tracing the discussion back to systems thinking and organizational, cultural aspects.<br />
<br />
<a href="http://eleganthack.com/a-map-from-goals-around-assumptions-through-tasks-towards-results/">A Map from Goals, Around Assumptions, Through Tasks, Towards Results</a> (Sep, 2016) introduces a structured expression of Because/By/While/Without, suggesting that solutions are recursively problems (with finer solutions). It reminds me a bit of User Stories, forcing us to think about The Why.<br />
<br />
He advises how to<a href="https://medium.com/@johnpcutler/stop-setting-up-product-roadmaps-to-fail-3189452360a3"> Stop Setting Up Product Roadmaps To Fail</a> (Apr, 2016).<br />
<br />
He repeats the sentiment that the others have made before him: <a href="https://hackernoon.com/keep-features-off-your-roadmap-b14543340881">Keep Features Off Your Roadmap</a> (Feb, 2017) <br />
<br />
And a big collection of thought-provoking <a href="https://medium.com/@johnpcutler/40-roadmap-item-questions-1a6895bf2e5a">40 Roadmap Item Questions</a> (Mar, 2018) <br />
<br />
<a href="https://mobile.twitter.com/johncutlefish/status/1069668045658894336">The need for a "solid roadmap that everyone understands" is a race to the bottom on some level</a> (twitter thread from Dec, 2018).<br />
<br />
<br />
So, that's about what I have time for reading up on in advance of my talk, so I'll end the post there. Let me know if I definitely missed some important sources on what roadmaps are all about!Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-59621815864775119162018-11-25T14:19:00.000+01:002018-11-25T14:19:54.258+01:00Developing The Organizational LanguageThis is another follow-up post on <a href="https://blog.tfnico.com/2017/12/joining-eyeo-year-in-review.html">my first year at eyeo</a>.<br />
<br />
In a company where the norm was to shun any hype, and avoiding cargo-culting by all means, it was not easy to use the language I had come to learn in the industry. Mentioning "Agile" would derail any discussion into shoot-downs, anecdotes and personal opinions and experiences. Few of the agile values, principles or practices were taken at face value. The more experienced colleagues had bad experiences with "agile transformations", and the large majority of younger colleagues had not recognized the pains of <a href="https://blog.tfnico.com/2018/01/how-silos-grow.html">silofication</a>, nor experienced the joy of successful organizational change.<br />
<br />
As is the norm these days, "DevOps" has already been reduced to infrastructure engineering. Scrum was a fad, XP forgotten, Kanban was a board on the wall. Sprints were pointless, we'd rather ship when there's a big enough reason to ship. Conway's and Little's laws were unknown, as were Lean, theory of constraints and other constructs I took as being common sense or industry "standard" (if there were such a thing).<br />
<br />
Rationality, skepticism and pragmatism ruled. Which can be good, but it can also grind conversations about organizational improvement to zero velocity (pun intended). How can we even discuss without having words for the things we see and the things we want?<br />
<h4>
The Survey</h4>
Around a month into joining eyeo, I started with a survey: "What should we call the things". The main goal was to manifest the separation between <a href="https://blog.tfnico.com/2008/12/projects-are-bad-for-software.html">temporary projects and more permanent value streams</a>, and separating the idea of cross-functional teams from profession groups.<br />
<br />
This lead to the introduction of some new entities that never really had organization-wide definition:<br />
<br />
<ul>
<li>Groups of people in the same profession were termed <i>departments</i></li>
<li><i>Project teams</i> would be our cross-functional groups (the ones working on a project or product together)</li>
<li><i>A</i> project team would own one or more <i>work streams </i>which were the categories of work they would do or take care of.</li>
</ul>
<br />
<h4>
The people and teams graph</h4>
Armed with these basic terms, we got management support and rolled on by beginning to map out the organization. I began building a graph database of persons, teams and departments to give a graphical overview of the relationships in the organization. This was useful for me to gain an understanding of the layout of the company, but it was more useful as a device for explaining others how we are a social network with many kinds of relations between many people and their areas of work.<br />
<br />
<span id="docs-internal-guid-c6df171d-7fff-ac7a-2470-ffda16a3ed2a"><img alt="Screenshot from 2016-11-22 00-57-32.png" height="302" src="https://lh3.googleusercontent.com/BZEvTCJ1bjLshJkaRYFOHeJOO44Iu7FP_cw_g8wQVTa-T4BDxdJUj2ldS27ppIMOZMIXsk9lwcJ05SjBP726XCCnOfgwLJkYj4YKeCwEUF7c08cM__1gYLt-dzDh-qHSXO7fT6q1cX0" width="640" /></span><br />
<br />
At some point, the database counted <i>almost a thousand relationships</i> in a company of less than a hundred! In retrospect, this is where we blundered by investing too long and too much time in analysis rather than learning through experimentation. We spent almost half a year before we went public with our findings and plan for the new organizational structure. A month would've been enough to get something <i>good enough to try</i>, and rather give people themselves the ability to chart out this graph in detail.<br />
<h4>
Launching the new organizational language</h4>
When we figured we had a very solid model of the organizational layout, basically a spreadsheet saying who belonged in a project team together, we published it along with a declaration of rules on how project teams could continue to change.<br />
<br />
While that launch and the following 6 months were bumpy and would be worthy of several blog posts in its own right, the short story is that while it alone failed at transforming the organization into where we wanted it to go, it successfully blasted the new terminology into the company.<br />
<br />
People began questioning and challenging both our new and the old organizational units placed around their own work - a crucial precursor to organizational development. Cross-functional teams and their work became a first-class citizen in our organizational language.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-28304613392797406782018-11-01T21:41:00.001+01:002018-11-01T21:41:10.632+01:00Working in Teams over Working as Individuals<div class="separator" style="clear: both; text-align: center;">
</div>
<blockquote class="twitter-tweet" data-lang="en" style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
</blockquote>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
I recently<span> </span><a href="https://twitter.com/tfnico/status/1041802243496988677">posted</a><span> </span>this sketch on Twitter:</div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHkX06O614hy0DRlJwawwhYhjkj7eMTZOCQTOvj0U9RM4I2v3ZWucsLBVdQwehLy6VzCyuau9Y0OqsUIEQXekXnr2nHkKAyH1PK1IqwMW3tm2gsUEfMQVIAw_APxi50cvhgOPJ/s1600/sketch1537219453997.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1600" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHkX06O614hy0DRlJwawwhYhjkj7eMTZOCQTOvj0U9RM4I2v3ZWucsLBVdQwehLy6VzCyuau9Y0OqsUIEQXekXnr2nHkKAyH1PK1IqwMW3tm2gsUEfMQVIAw_APxi50cvhgOPJ/s640/sketch1537219453997.png" width="640" /></a></div>
<br />
Thanks to a few mighty retweets, it gathered a lot of views (9000 impressions, whatever that means). While that's fun and all, I still felt a bit sad that such an awfully simple insight can garner much more popularity than a thorough blog post that I put some hours into.<br />
<br />
So, rather than let Twitter get away with this, I'll steal my own content back into the blog :)<br />
<br />
The thread went like this:<br />
<br />
<i>Pondering how to battle individualism in companies. For some, it is counter-intuitive that teams can be more responsive, faster and even more accountable than single individuals.</i><br />
<i><br /></i>
<i>Having "teams" in place is no guarantee that team work is happening. Be wary of too large teams, "I/me/mine", personal contact details instead of team point of contact. Good team is sailing crew, not galley slaves.</i><br />
<i><br /></i>
<i>Beware heroes, go-to persons, calling in favors and other shadow handling of work. Real teams make the work explicit, both requests/needs and responses.
</i><br />
<div>
<div>
<br />
<br /></div>
</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-66721689906727363582018-08-21T09:09:00.000+02:002018-08-21T09:09:16.745+02:00An Anecdote About TrustBack at uni, we had a <a href="https://blog.tfnico.com/2008/11/what-i-learned-about-project-management.html">semester about IT project management</a>, and one of the highlights was this two-day off-site where we went to a camp and did team-building kind of exercises to explore social dynamics and stuff.<br />
<br />
One exercise was called "Saboteur". In short, the mission was for the teams to recreate a complicated building block construction set in a different room. The constraint was that each team could only dispatch one person at a certain interval to study the original construction. The goal was to get to the identical structure first.<br />
<br />
Additionally, each team was "infiltrated" with an unknown amount of saboteurs, tasked with slowing down their teams without revealing their purpose.<br />
<br />
To counter for this, our team decided to use double-checking observation roundtrips to weed out the saboteur(s). The team members that were found to have provided wrong observations were excluded from making any more observation roundtrips. I remember this girl in particular that was caught making mistakes two times, and I suspected she was our saboteur. So I argued openly for excluding her, and I got the strong feeling she was lying when she claimed innocence, making me even more sure.<br />
<br />
In the end, we finished last of all the teams. Afterwards, we all seated around for reflection on the exercise, and the saboteurs were asked to stand up and reveal themselves. And, you guessed it, nobody stood up.<br />
<br />
What I took away was how dramatic the effect of just knowing that there could be a saboteur, and how convinced I had been in my suspicions. I might add that our team aced every other exercise in those two days, but this one left us in the dirt because without trust we were not able to work productively.<br />
<br />
----<br />
<br />
If you're looking to recreate this exercise, I found a similar one online: <a href="https://leadershipinspirations.com/2018/02/22/mole-game/">The Mole</a>. And yes, it's a bit like the <a href="https://en.wikipedia.org/wiki/Mafia_(party_game)">Werewolf party game</a>.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-75792787907640165642018-07-30T23:20:00.000+02:002018-07-30T23:20:35.320+02:00Mediation in TeamsI recently found myself mediating a personal conflict within a team. In this post, I'll share what I quickly had to pick up and learn in order to do so.<br />
<br />
<span style="background-color: orange;">Disclaimer: I am not a trained professional in conflict handling. If you find yourself in a similar situation, get professional help from a trained mediator and do not try to do anything without the backing of the supervisor(s) of everyone involved!</span><br />
<h3>
Spotting the conflict</h3>
I try to keep some tap on the conversations that are happening around the company, and in particular I try sensing conflicts. In this case, I spotted what at first looked like a regular somewhat heated exchange in a distributed team, and then as the discussion continued, the participants started to pull for executives to come in and break the argument in their favor. The topic under discussion was definitely a team-internal thing, so my alarm bell started chiming. This didn't feel like a regular technical discussion. It had an air of threat and desperation to it.<br />
<h3>
Getting hold of the situation</h3>
I first reached out to the team's project manager to point him at the situation. At first, he was hesitant to take any extra-ordinary action, instead preferring to deal with it at their next regular team meeting. I offered to facilitate a retrospective for them, which he accepted, and I figured this would be a good start, and I wasn't sure I should push for anything more urgent.<br />
<br />
Next, one of the executive managers who now had spotted the conflict (or had been pulled in by the participants) decided to speed things up, and I got invited to facilitate a meeting for the involved before the end of the week.<br />
<br />
Even though the invitation was formulated as a retrospective, I had a feeling it would be something else. So I quickly started reading up on <i>mediation</i>, in case that would be necessary.<br />
<h3>
Figuring out what to do</h3>
There's common sense, and then there's professional help. We do have several coaches around with more experience on this, but as vacations and timelines played out, I couldn't access them, and I figured expediency was the right thing for the situation. Starting at the obvious place, I skimmed through search results and Wikipedia until I came across <i>Party-directed mediation</i>.<br />
<br />
From <a href="https://en.m.wikipedia.org/wiki/Party-directed_mediation">Wikipedia</a>:<br />
<blockquote class="tr_bq">
Party-directed mediation (PDM) is an approach to mediation that seeks to empower each party in a dispute, enabling each party to have more direct influence upon the resolution of a conflict, by offering both means and processes for enhancing the negotiation skills of contenders. The intended prospect of party-directed mediation is to improve upon the ability and willingness of disputants to deal with subsequent differences.</blockquote>
It was developed by <a href="https://en.m.wikipedia.org/wiki/Gregorio_Billikopf">Gregorio Billikopf</a> who was very inspired by <a href="https://en.m.wikipedia.org/wiki/Carl_Rogers">Carl Rogers</a>, who again is the psychologist behind the "active listening" technique (and a whole lot of other stuff!). There's also some shared background here with <a href="https://en.wikipedia.org/wiki/Nonviolent_Communication">nonviolent communication</a>, and Billikopf references NVC quite a few times in his work.<br />
<br />
Now, I don't know my way around too much mediation material and theory, but I think I struck gold by quickly finding and making use of PDM, because:<br />
<br />
<ul>
<li>The material is very easy to understand, basic enough for layperson like myself and easily applicable.</li>
<li>Billikopf has published <a href="https://archive.org/details/PartyDirMediation_201404">a free book about it</a> (I sped through the first 4 chapters), so there's no hurdle for attaining it.</li>
<li>He has published <a href="https://nature.berkeley.edu/ucce50/ag-labor/7article/article40.htm">a free audio-book</a> about empathic listening (one hour, I listened to this twice).</li>
</ul>
<div>
There are areas where PDM does not apply well. My understanding is that it works well for parties that share a lot of the same goals, like colleagues in the same team, or divorced parents that want the best for their children. Less so when it's about reaching settlement between competitors or parties with little in common.</div>
<h3>
Inviting each party to a pre-caucus</h3>
<div>
This is the first part of PDM: The idea is to hear each party out separately in advance of the first meeting. This sounds like pretty much common sense to me (I invited them before I even found out this was a thing in PDM). Interestingly, this is quite frowned upon in other schools of mediation! You can read more about why in the book.</div>
<div>
<br /></div>
<div>
Each of these individual sessions were quite revealing. It turned out that the recently contested issue was the last in a series of events tied to a situation that had been souring for almost a year. The parties would work together "professionally", and have meetings where the underlying issues did not surface. I'm betting this is very common in workplace situations where mediation becomes necessary though.</div>
<div>
<br /></div>
<div>
The intention of the pre-caucus isn't so much to investigate what happened (although an understanding of this is certainly helpful - both parties should realize that you are genuinely trying to understand them and their (re)actions). Rather, this session gives each party an outlet to get out a lot of built-up pressurized frustration.</div>
<h3>
Initial session</h3>
<div>
The initial session was more of a inner-team meeting, where my aim was to get a shared understanding in the team of the issue(s) at hand. I started by explaining some rules of moderation and outlining the agenda. Then a more humorous check-in (what's your favorite breakfast?). </div>
<div>
<br /></div>
<div>
Then we did one larger round (10-20 mins for each of the 4 involved). I asked each of them "What is forming and storming in the team? How do you feel about how the team is working?"</div>
<div>
<br /></div>
<div>
Each of the involved answered in very different ways, but in the end most of the pent-up frustration became evident to everyone in the room. A memorable moment for me was when the third team member (not one of the conflicted parties) described the situation as being the child of a quarreling divorcing couple. This more than anything convinced me that this was a case for mediation rather than escalation.</div>
<div>
<br /></div>
<div>
We ended the session with each of the people present committing to a few action points, one of which being that the two conflicted parties continue with me into a mediation process.</div>
<h3>
Two rounds of mediation</h3>
<div>
I'm not sure what else I can say about these sessions than that they were really heavy mental work. I'm extremely glad that I had at least the PDM theory with me at this stage, as keeping the mediation centered was really difficult. These sessions were focused on getting each party to empathize with the other. It was quite the emotional roller-coaster, with making a lot of progress for then falling back again due to an old wound that got discovered again and again. In the end, we agreed that one of the party would put together a proposition on how they could agree to work together. </div>
<h3>
Concluding the mediation</h3>
<div>
At what felt like was the end of these conversations, I was quite certain that we would not be able to reach any compromise on how we could try to move on. The party with the proposition was about to abandon the idea, so we did another caucus to try one last time to build the empathy for the other party that would allow the proposition to come through. It worked, and at the time of writing, the parties are drafting this into agreement form.</div>
<div>
<br /></div>
<div>
At this point, I felt I had done what I could do for them at this stage. So I sent them off with a "good luck" email reminding them of the reasons I had found for believing they could and would work together excellently, if they would try trusting each other again. This part quoted below explained my perspective, and I think that frames well what this kind of mediation is about:<br />
<br /></div>
<div>
<i>I want to thank you both for being there this week. I commend you both for participating in the mediation willingly, and sharing so much of yourselves.</i><br />
<i>As you probably have figured out by now, it is not my place to pass any judgement on which of you did the most wrong or right.</i><br />
<i><br /></i>
<i>As a mediator, it's my place to assume that you both have made mistakes, and that your are both victims of the circumstances. Whether one of you is more right or wrong than the other, I don't know, and I'm not trying to find out. It has been our co-opt mission to get you into a conversation where you can arrive at a strong compromise together. Something good enough to try.</i><br />
<i>You were both quite caught up in seeing negative patterns in the other's acts over the preceding year. You both wanted solutions that you believed contradicted the wants of the other. You both felt the need to escalate the issue in order to get the other subdued in some way, to be guaranteed that you will not get hurt again.</i><br />
<i><br /></i>
<i>I understand you both. It is human to feel hurt, and fear future harm. There are enough outside factors here to have caused this situation without either one of you having to be more guilty than the other.
</i></div>
<h3>
Follow-up</h3>
<div>
The PDM technique is very time intensive. It could run over a dozen hour long sessions. In our case, we had limited time, especially on my end, and scheduling face time was difficult, being a distributed company. I had to conclude earlier than I felt comfortable with, but at the same time I felt we had given the situation a fair chance. </div>
<div>
<br /></div>
<div>
If they end up escalating the issues later anyway, the parties will at least now have a much clearer understanding of each other and their issues.</div>
<div>
<br /></div>
<div>
We'll also be looking into how we can instantiate a mediation/escalation processes across other teams in order to lead similar situations into the mediation funnel much earlier. Even if all teams are working well today, we want to have a system in place for handling conflicts before they snowball into dramatic proportions.</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-13543538977441497192018-02-04T22:09:00.000+01:002018-02-04T22:09:04.767+01:00The End of GitMinutes (my podcast)I'm just about ship <a href="http://www.gitminutes.com/">GitMinutes</a> episode 46, which is going to be the final episode. I'll just paste the outro script here, as it sums up the sentimental thoughts pretty well:<br />
<br />
I’m happy to have finally finished [publishing the last episodes from <a href="https://git-merge.com/">Git-Merge</a> 2017], just in time before Git-Merge 2018 takes place in March. I won’t be going there myself, so I’m counting on someone else to pick up the mic there.<br />
<br />
It’s sad to be shipping this one as it is probably the last GitMinutes episode ever. To go a bit down memory lane, 6 years ago, my daughter was born, and as I used a little of that paternity leave to set up my podcasting infrastructure and produce the first few episodes. Initially <a href="https://blog.tfnico.com/2013/03/announcing-gitminutes-podcast-for-git.html">it was just going to be 10 episodes</a> and call the experiment finished. Instead, I got to 46 episodes, the last dozen or so lazily tailing the last few Git-Merge conferences.<br />
<br />
To every one of my guests, thank you so much again for coming on to share your passion in this little niche of computer science and industry. I like to think that I gave voice to some people working on the plumbing of how software development works, and distributed it out to a little bit wider community.<br />
<br />
Big thanks to DigitialOcean for sponsoring GitMinutes. You can still use the promo code gitminutes10 when signing up if you want, and we’ll hope they’ll leave this server running with the podcast archive as long as possible.<br />
<br />
Finally thank you, dear listener, for listening. I used to keep this list of tweets, emails, endorsements and words of encouragement for the podcast, and I’d sometimes shift through it to give myself a motivation boost when editing long episodes. Looking at that spreadsheet now, I know I was definitely able to help a few of you with your transition to Git, understanding it, or just peaking your interest at getting deeper into it. As a long time blogger, I was mind-blown about how rewarding it is to podcast, the engagement from the audience was much stronger.<br />
<br />
So, I have a feeling this won’t be the last podcasting project I’m involved with. Personally I’ve started blogging about a bit more "higher" level, DevOps kind of transformation things.<br />
<br />
If you’re looking for another podcast about Git, there’s an excellent one by Edward Thomson and Martin Woodward you should check out: <a href="https://www.allthingsgit.com/">All Things Git</a>.<br />
<br />
There’s a monthly Git newsletter called <a href="https://git.github.io/rev_news/">Git Rev News</a> that you should check out and subscribe to. I was an initial contributor to this, but I've also retired from this effort recently.<br />
<div>
<br /></div>
<div>
I usually have had these 5-year runs for some particular field through my career. Early on it was about open source and CMSes, then later it became XP and agile engineering practices (CI and web-testing). Then came Git, and more configuration management and infrastructure. Now it's time to move on again, leaving my involvement with the Git community behind, unfortunately (it really is a fantastic community). So long, and thanks for the great time!</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-49299492419545092472018-02-02T23:27:00.000+01:002018-02-02T23:27:18.273+01:00Going for Lead-TimeNote: This topic of this post was heavily inspired by <a href="https://www.goodreads.com/book/show/17255186-the-phoenix-project">The Phoenix Project</a> and the succeeding tome of reference, <a href="https://www.goodreads.com/book/show/26083308-the-devops-handbook">The DevOps Handbook</a>.<br />
<br />
There are many metrics out there that can guide you to improve your business, but in the upside-down world of Internet business, many of these can be plain wrong, or at least they do not serve well as guides for what you should be doing. If you measure success by measuring profit, for instance, you'll run out of good will with your users or partners very quickly.<br />
<br />
Then there are a load of more noble but fuzzy numbers that you can measure by surveying employees or users. Think employee-happiness, etc. While these are definitely useful, they are easy to get wrong, and it's easy to over-do it, causing survey fatigue. They're also hard to trace from cause to effect. It's hard to say which particular company decision lead to some satisfaction rating going down.<br />
<br />
Take the <a href="https://en.wikipedia.org/wiki/SWOT_analysis">SWOT analysis</a> as a particular one of these surveys. It will give you a great map of what the employees of the company are feeling about a variety of things, and while this will certainly be helpful, it does not even attempt any root-cause connection, so it ends up being a collection of subjective opinions, which may or may not be pointing at the underlying issues.<br />
<br />
When it comes to getting real deep understanding of the issues of an organization, I'm personally a fan of the <i>good old retrospective</i>. Getting in a room or call with a smaller group of people who can genuinely build a common understanding of what is going wrong and right is golden, especially if done so on a repeated basis (as long as the resulting commitments and impediments are actually tended to). They don't scale so well, although I'm sure there are clever ways like open-space, or "scaling agile" techniques to help with that.<br />
<br />
But neither SWOTs nor retrospectives give you proper metrics. They're not fast. They're not objective. They're not automatic.<br />
<br />
So what number can we measure in an automatic way that actually gives us valuable input on how the organization is working? What number can we aim to change when changing the organization? What number can we ask about in every retrospective? The answer is <b>lead-time</b>.<br />
<br />
<br class="Apple-interchange-newline" /><br />
<span id="goog_157653054"></span><span id="goog_157653055"></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4S-tv6lNDAQAhFQly6vfCPlvBnqdL9Pfo0kcITBWDCX4G4SZg2uUzEmCbDHgl9A9X6ngpImilTW4yw7O0VjGYw63B9Osqc7pDqk3DE_2Nuta2G_Nnxv4zp8Dj7dsIR3MOXn3e/s1600/sketch1517609038884m.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4S-tv6lNDAQAhFQly6vfCPlvBnqdL9Pfo0kcITBWDCX4G4SZg2uUzEmCbDHgl9A9X6ngpImilTW4yw7O0VjGYw63B9Osqc7pDqk3DE_2Nuta2G_Nnxv4zp8Dj7dsIR3MOXn3e/s640/sketch1517609038884m.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">An example of "lead" from idea to change in the world. I left out waiting times, execution times, rework/failure rates, etc.<br /></td></tr>
</tbody></table>
Armed with <a href="https://en.wikipedia.org/wiki/Lead_time">lead-time</a>, the <a href="https://en.wikipedia.org/wiki/Theory_of_constraints">Theory of Constraints</a>, <a href="https://en.wikipedia.org/wiki/Little%27s_law">Little's Law</a> and <a href="https://en.wikipedia.org/wiki/Value_stream_mapping">value stream mapping</a>, you can go into any organization and start improving the system (yes, this is in a simplified sense what <a href="https://en.wikipedia.org/wiki/Lean_software_development">Lean is about</a>). You'll still need retrospectives and the like to explore how to improve the system, but lead-time trend over time will tell you how bad/good it is. Shorter lead-times is a near no-brainer for improving company performance. While shorter lead-time does directly equal higher velocity or more performance, it does mean you have much more opportunity to navigate tactically and strategically, and <i>improve</i> velocity and performance <i>more often</i>.<br />
<br />
After I joined eyeo and saw the dangers of increasing silofication, I started working for turning the ephemeral <i>cross-functional teams</i> into sustained, first-class organizational units. A lot of people who had been at the company for longer didn't see why this was necessary, so they asked me <i>why</i>.<br />
<br />
At first, I'd be stumped, thinking this was an obvious thing to do. Then I'd think more about the happy ways of working in a team like that, and how it's <i>just good</i>. Also, being able to point out all the explicit teams in some map would be really handy for new-hires to navigate with. However, arguing like that didn't get me very far. People had more important things to take care of, naturally.<br />
<br />
So I changed my line of argument: I looked at the current issues: projects seem to take a long time. Requests spend a lot of time hanging in free air before landing at the right desk. I then started building a case for <i>optimizing our structure for lead-time</i>:<br />
<br />
<ul>
<li>If any task that needs doing can bounce between the necessary experts within the border of a team that works tightly together, <i>lead-time will go down</i>.</li>
<li>If a domain of related tasks will always go to the same team, their ability to deal with these types of tasks will improve and <i>lead-time will go down</i>.</li>
<li>Related, if the inventory of related work-in-process is oriented around a fixed team, they can increase their focus and reduce the amount of concurrent tasks, making <i>lead-time go down</i>.</li>
<li>If an incoming project can be take on by an existing team of people who already are able to work and deliver together, yup, you got it, <i>lead-time will go down</i>.</li>
</ul>
Once people started seeing that my ideas were actually about fixing their biggest issues, seeing that their biggest issues could usually be expressed as length of lead-time, the tone changed quite a bit, and soon after that we got busy organizing the introduction of these new kinds of teams.<br />
<br />
How to turn lead-time into an actual metric then? That's for another blog-post.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-55786048669435214652018-01-01T23:51:00.001+01:002018-01-02T09:42:10.383+01:00How Silos GrowIn <a href="http://blog.tfnico.com/2017/12/joining-eyeo-year-in-review.html">my previous post</a>, I suggested several topics to blog about, based on my experiences of 2017. <i>How Silos Grow</i> was the topic most asked for:<br />
<blockquote class="tr_bq">
This was my initial shock after joining the company. Only a few years after taking off as a startup, the hedges began growing, seemingly almost by themselves, and against the will of the founders.<br />
I've worked in silos, and in companies without them, but I haven't been there to witness them coming into existence before. It is a fascinating phenomenon, yet oh, so common. And a killer of great companies.</blockquote>
This posts digs into why and how silos happen. It's a bit of a long one, so here's the TL;DR:<br />
<div>
<ul>
<li>It is about human nature.</li>
<li>Departments are a good thing (for some things).</li>
<li>People in different departments are inherently different.</li>
<li>The project method is still problematic (and reinforces the silos).</li>
<li>Cross-departmental teams should be the first-class organizational unit instead.</li>
</ul>
<div>
Although the idea to write this came from my first year at eyeo, this piece is about the sum of experiences I made in my entire career. My employer (still eyeo) went through some of the experiences that I write about below, but not all of them - and they are actively improving the weak spot.<br />
<div>
<h2>
Human nature</h2>
If I had some more time, I'd love to dig into the human social and biological reasons for this, but I'll just jump ahead and say there is something primal going on since prehistoric days, and in modern times it is still observable as loyalty to closer/similar people, and distrust for those distant/different. We group ourselves and bind with those of similar means and motives. It makes sense on a very basic level, but like many of our cognitive biases, it is counter-productive in a many modern scenarios, where nomad tribes and saber-tooth tigers are not involved.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivPAUssoTSs238w3WzySpMrd1kb9RP02ZQsddrrtudTv0nERU3MLGAjR6kmeXcQFM0FzSSyP9mBYqyrhtscs0Nwxfe10bMT_nr6o9jyl2jxgwbZpdbFycVab6rdIm1CNv9Q8qV/s1600/sketch1514841695924.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivPAUssoTSs238w3WzySpMrd1kb9RP02ZQsddrrtudTv0nERU3MLGAjR6kmeXcQFM0FzSSyP9mBYqyrhtscs0Nwxfe10bMT_nr6o9jyl2jxgwbZpdbFycVab6rdIm1CNv9Q8qV/s320/sketch1514841695924.png" /></a></div>
My colleague at eyeo, Aaron, <a href="https://autodidacticdesigner.com/2017/12/11/mo-people-mo-problems/">describes the mentality of it as "Us vs Them"</a>. It seems at times that humans just need that common foe to unite a given group, driving the plot for Wag the Dog, war on drugs, terror, and so on. But let us try to dig a bit deeper on why this happens in companies, especially small-medium sized ones that are growing past the 20 person mark.</div>
<div>
<h2>
Strength in departments</h2>
At a certain point in any fast-growing startup, the average count of person-to-stranger relationships will grow much faster than the rate at which people get to know each other.<br />
<br />
What people naturally do in such environments is to gravitate towards those they have the most in common with, or simply stick with the ones involved in their hiring and perhaps after hiring through some mentorship program. This tends to be with people of the same profession, or related ones, and the social bonds formed there will stay the strongest ones in the new-hire’s work life for some time. <br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOuJ1-bUoCbTuGJPbxPF5etdWZ8yiRGtteM6PAmQJOF9ljLOqIr7u26bYb-sKjfGQ_RcVW5zE_Wc0bWYjQIbjD1XT7Xss39TBgjoSpofUVhHr06KcKVi16RDkG697sTQRIcFyQ/s1600/sketch1514841666759.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOuJ1-bUoCbTuGJPbxPF5etdWZ8yiRGtteM6PAmQJOF9ljLOqIr7u26bYb-sKjfGQ_RcVW5zE_Wc0bWYjQIbjD1XT7Xss39TBgjoSpofUVhHr06KcKVi16RDkG697sTQRIcFyQ/s320/sketch1514841666759.png" /></a></div>
I think this is a good thing! Having this circle of closer peers provides a safe haven for new-hires while they learn to navigate the larger company. Furthermore, it provides a platform for learning, fostering knowledge and craftsmanship between those who share professions.<br />
<br />
Obviously, the kind of department I’m describing above is not a silo. It’s a catalyst for growth and development of people in a company.</div>
<div>
<h2>
Burgers, fries and coke</h2>
The typical line-up of departments are an odd bunch. Some of them are knowledge groups like I describe above, while others are defined by some function they provide to the rest of the company. Most of them are a mix of both.<br />
<br />
Some of the departments are half-function and half-product: Sales, marketing and support functions (IT, legal, accounting, etc) are often <b>not</b> considered within what I call the "hamburger" of product/service delivery:<br />
<br />
<ul>
<li>Product (research and design) </li>
<li>Development </li>
<li>QA </li>
<li>Operations</li>
</ul>
<div>
If you want anything from a particular product or service, these are the entities you have to bite through in order to get anything.</div>
<div>
<br /></div>
(If you know your Agile history, you'll remember that most of the industry managed to interweave the first three, and with the coming of DevOps, the fourth joined in as well.) <br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFbVM5yKwvtVORM9imNH8yZGnxIcui6uJkyxSHP6Hp5ddhfojfNRqM0AxtAZCj3QQFd4uRfkaiIILwDfn3qctnKggRwKG-udvOlPDkEI7MsnzSwQ4egezEi7NY3UHKKZ07w2Bv/s1600/sketch1514841913846.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFbVM5yKwvtVORM9imNH8yZGnxIcui6uJkyxSHP6Hp5ddhfojfNRqM0AxtAZCj3QQFd4uRfkaiIILwDfn3qctnKggRwKG-udvOlPDkEI7MsnzSwQ4egezEi7NY3UHKKZ07w2Bv/s320/sketch1514841913846.png" /></a></div>
The other less interdependent functions, like HR, sales or marketing (let's call them "fries" and "coke") are still left out of product/service in some of the most agile shops around to this very day. And because they are operationally separate, they get defined by separate purposes. Now, that's probably not a good way to split up your business/work, but hey, that’s just how it’s done in a lot of places. My point being: until all departments are part of the burger, you’re going to have some degree of silos.<br />
<h2>
Departments’ natural differences</h2>
As each employee can only be member of a single department, it draws in some odd borders throughout the company, like the <a href="http://blog.tfnico.com/2007/03/programming-designer.html">programming designer</a> - is she in Development or Product department? Infrastructure engineer is another one. Dev or Ops?<br />
<br />
Two colleagues independent of each other suggested us being divided by those <a href="https://en.wikipedia.org/wiki/Thinking,_Fast_and_Slow">who think fast and those who think slow</a>. This made me think of something I wrote in one of our internal methodology guides (the context was balance in the nature of work we do, but I'll come back to that another post, I hope):<br />
<blockquote class="tr_bq">
QA, operations and developers tend to focus on stability, while marketing and business people, designers and product managers focus on new features.</blockquote>
Of course, those things are results or symptoms of how we have (or have not) defined purpose within the company. Of course the latter groups will focus on novel things that drive interest from media and customers. The former groups know they'll get swamped with technical debt if they go chasing new features for too long.<br />
<br />
Another difference I think is gender-culture. The constellation of technical departments (the same one I mentioned tends to focus on stability) tends to consist of men, and they attract (or select) male new-hires, while the remaining ones have a more healthy mix. I don’t know enough about the psychology in play here, but in my experience, “male departments” tend to have rougher communication, somehow colder and very “evidence” oriented. The mixed departments have more empathy, more respectful tone and tolerance for intuition.<br />
<br />
Some departments may be elitist due to generally longer education paths or having more experienced members. Some departments may be made up of dominantly extrovert people while others consist of introverts. Some may be distributed while others are co-located.<br />
<br />
There are probably more reasons for departments being different from each other than I've listed above. Point is, these differences pose the departments in tension with each other, and may lead to avoidance, lack of trust or aggression, furthering silofication.<br />
<h2>
When do departments turn to silos</h2>
The very name-sake of the DevOps movement is the constellation of the Developers versus the Operations department. Already during the Agile revolution, we realized that velocity will hit a certain ceiling less we include the customer (often represented by product owners), QA and Operations in the development teams. Yet, we continue to see growing companies split the work by departments once they reach a certain size.</div>
<div>
<br /></div>
<div>
(Side-note: I believe the wiser companies break out sub- or separate companies before this happens, like <a href="https://www.joelonsoftware.com/2014/07/24/trello-inc/">Fog-Creek splitting out Trello</a>, or <a href="https://www.inc.com/magazine/201403/jason-fried/basecamp-focus-one-product-only.html">37signals splitting out everything but Basecamp</a>, or going further back: <a href="https://en.wikipedia.org/wiki/Ricardo_Semler">Semco’s satellite companies</a>.)<br />
<br />
When I joined eyeo a year ago, around the 80 person mark, I saw the manifestations of these departments, but the divisions had already begun years before. I'm re-telling a simplified version here, but some time during those early years:<br />
<ul>
<li>Business developers were hired to drive sales and partnerships. </li>
<li>IT administrators were hired to make sure everyone had the equipment they needed. </li>
<li>Infrastructure engineers were hired to take care of the infrastructure. </li>
<li>There was a steady hiring of software developers to develop and maintain the products. </li>
<li>A QA manager and testers were hired to take care of processes and well, QA obviously. </li>
<li>A product manager was hired to build an awesome "product team". </li>
</ul>
Maybe you already suspect the culprit here: Already at the hiring stage, new people are brought into the company with <i>role-specific purposes</i>, rather than <i>product-specific ones</i>. This does not alone explain why these new-hires organize themselves by their departments instead of the products/services they work on. Obviously, they’re still supposed to join up with people from different departments on demand, kick-off projects together, drive them to completion, then rinse and repeat. <br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisURg1BNJnAp7S3-bKbbkE5wxDrxIejIXOI_8fVFN9oLPoKO9JThfqzsH4oL-YNGrB39q1chciwdPTXT2FR67j7RQaQqqs59nFYyUBcXFwcZfE2Vxnur4LkvTo3qjp7q8v9oyi/s1600/sketch1514842871992.png"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisURg1BNJnAp7S3-bKbbkE5wxDrxIejIXOI_8fVFN9oLPoKO9JThfqzsH4oL-YNGrB39q1chciwdPTXT2FR67j7RQaQqqs59nFYyUBcXFwcZfE2Vxnur4LkvTo3qjp7q8v9oyi/s400/sketch1514842871992.png" width="400" /></a></div>
Now, what happens during the early years of a successful startup, is that it goes past that magic number of employees, somewhere between 20 and 40 perhaps, and things just get difficult:<br />
<ul>
<li>Number of products goes up (and platforms per product goes up) </li>
<li>Number of projects goes up (new product launches, new features in existing products, re-designs of existing services) </li>
<li>Number of services and users on these go up </li>
<li>More money, more media-attention, more responsibility to customers </li>
</ul>
As the stakes grow ever larger, people want to perform their best, and it seems intuitive for them to focus in on their own specialty and let others practice theirs. The work gravitates towards being department-oriented, because people have defined their purpose that way.<br />
<br />
Along with this, the lines of communication between individuals grow factorially. The essence being that any QA-person can do QA for any project, and the same for every other department for every project. Of course, everyone realizes person-project relationships are more sticky than this, but in a department-oriented company, the person-project relationship is a second-class citizen. <br />
<h2>
Projects and Departments</h2>
The cross-department project methodology works most of the time. Up to a certain size. Then you start getting the occasional misunderstanding: "I thought you were on that project. Who is? Oh, I don't know that person. Can I trust them with getting that right?"<br />
<br />
Then comes the differences in priorities: project A is more important than project B now, because project A is in the [department x] phase.<br />
<br />
Along with it come the hand-offs: [department x] cannot complete their work in project A before [department y] has finished their part. Lead-time goes down. Quality goes down. Rework goes up. Now you automatically get the blame-games. <br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifiCrB7EawNTYZmJWAe7MjtLwJaQjWQpTO81ugCE2bpPPwqln1ADCewEAhu7ftT539DsxjC-YCiiTBd4ZpmVD2GGlVmtK4TvynDFM7_Dcphm-tiaJibGj3XTzAk7_QLU64sftw/s1600/sketch1514843062156.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifiCrB7EawNTYZmJWAe7MjtLwJaQjWQpTO81ugCE2bpPPwqln1ADCewEAhu7ftT539DsxjC-YCiiTBd4ZpmVD2GGlVmtK4TvynDFM7_Dcphm-tiaJibGj3XTzAk7_QLU64sftw/s320/sketch1514843062156.png" /></a></div>
And at this point, we’ve pretty much re-invented waterfall. The silos are all around, and you’ll notice that project completion takes forever. The rare successes are overly celebrated by the managers that were in charge of them. Things just don’t get done any more. Toxic relationships develop across departments as tension grows. <br />
<h2>
How not to fix it</h2>
Companies that see projects slowing down into waterfall processes between blame-gaming departments may attempt to combat this in various ways.<br />
<br />
They may try putting systems in place to drive improvement. The danger here is that they will look for organizational units where they can latch on goal-processes, incentives, processes or responsibilities (think contractual obligations between departments) and hierarchies. But these measures will only strengthen the silofication and possibly lead to a culture of faking success (known from pretty much any large corporation out there), more blaming, less trust and even slower delivery.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUOqXuIDJc79KKDu5bsN3M-yv5266fH0j9yTFxQr76N_55nSWQijU8Z1f9Pkrh5ZVVIB5bn3Pi4gIlSHWs_WxBmvDkDjROx2opvA4dvIufFDA90I56H2JF0b1l6tSVxgbQGNtu/s1600/sketch1514843271649.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUOqXuIDJc79KKDu5bsN3M-yv5266fH0j9yTFxQr76N_55nSWQijU8Z1f9Pkrh5ZVVIB5bn3Pi4gIlSHWs_WxBmvDkDjROx2opvA4dvIufFDA90I56H2JF0b1l6tSVxgbQGNtu/s320/sketch1514843271649.png" /></a></div>
They may introduce an entity responsible for making the problem go away: Cross-departmental project managers, agile or DevOps coaches. This is probably a step in the right direction, but it will only do so much - at least the people in this unit should be calling for a new structure, where purpose can be placed where it should be. <br />
<h2>
How to start fixing it</h2>
This is probably where I should make a cut for a future blog post, but here’s the short version:<br />
<ul>
<li>Re-purpose the departments to be what they are best at: knowledge centrals/catalysts, and home-ground for new-hires. </li>
<li>Replace <a href="http://blog.tfnico.com/2008/12/projects-are-bad-for-software.html">temporary projects</a> with sustainable, product/service-oriented, fixed teams. Make these teams the first-class citizens of the organization. </li>
<li>Redefine people’s purpose in the organization: Ask them to commit to the success of their team, not the success of their department. </li>
<li>Long term (maybe): Spin off autonomous team-clusters into separate companies. </li>
</ul>
Department-oriented is a very old-fashioned way to work these days: We should have teams, each of them with a clear purpose focusing on the end-needs of the business or its customers. <br />
<br />
This means business-oriented, but also cross-functional and autonomous teams (because anything else will slow stuff down). The natural departmental differences will still occur, but already within the team on a daily basis, where they can be much better handled than between separate departments at irregular, painful intervals. In the sum of a cross-department team's actions we get a healthy balance of maintenance and innovation with shared purpose.</div>
</div>
</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-203244143007955662017-12-26T14:32:00.001+01:002017-12-26T14:32:52.350+01:00Joining eyeo: A Year in ReviewIt's been well over a year since I <a href="http://blog.tfnico.com/2017/01/joining-eyeo.html">joined eyeo</a>. And 'tis the season for yearly reviews, so...<br />
<br />
It's been pretty wild. So many times I thought "this stuff really deserves a bloggin", but then it was too inviting to grab onto the next thing and get that rolling.<br />
<br />
Instead of taking a deep dive into some topic already, I want to scan through that year in review and think for myself, what were the big things, the important things, the things I achieved, and the things I learned. And then later on, if I ever get around to it, grab one of these topics and elaborate in a dedicated blog-post. Like a bucket-list of the blog posts that I should have written. Here goes:<br />
<h3>
How given no other structures, silos will grow by themselves</h3>
This was my initial shock after joining the company. Only a few years after taking off as a startup, the hedges began growing, seemingly almost by themselves, and against the will of the founders. I've worked in silos, and in companies without them, but I haven't been there to witness them coming into existence before. It is a fascinating phenomenon, yet oh, so common. And a killer of great companies.<br />
<h3>
When you got no other reason for improving, go for lead time</h3>
There are so many reasons for why you would want to drive organizational change, stop the silofication, bring in some agile values, and so on. But the one reason that rings true and clear for any person in the company is <i>lead time</i>. Then you can slowly start to talk about the cost of WIP, hand-offs, and so on. When explaining the why, start with lead time.<br />
<h3>
The best patterns for introducing organizational change in are inscrutable</h3>
I tried out several patterns, from early adopters, to whispering in the general's ear. I tried driving changes by committee and without. We tried bootstrapping, and we tried organic change. It always felt like a mix of hurt and help, but it seems through any of the changes, they were for the better (unless they are driven by targets, of course). The only way to know for sure whether I had the right strategy is to go back in time and compare how the options would work out in alternative realities. So we're left with, once again, gut feelings.<br />
<h3>
Developing the ubiquitous language of organizational change</h3>
In a company where the norm is to shun any hype, and avoiding cargo-culting by all means, it was not easy to use the language I had come to learn in the industry. Mentioning Agile would derail any discussion into shoot-downs, anecdotes and personal opinions and experiences. Few of the agile values, principles or practices were taken at face value. The more experienced colleagues had bad experiences with "agile transformations", and the large majority of younger colleagues (funny, cause I feel like I've always been the youngest where ever I worked, and suddenly here I'm in the oldest 15 percentile) have not suffered the pains of silofication, nor experienced the joy of successful organizational change.<br />
<br />
As is the norm these days, "DevOps" has already been reduced to infrastructure engineering. Scrum is a fad, Kanban is a board on the wall, XP is some long gone neck-beard hippie thing. Sprints are pointless. Conway's law is unknown, as is Lean. Rationality, skepticism and pragmatism rules. Which can be good, but it can also grind conversations about organizational improvement to zero velocity (pun intended).<br />
<br />
So, I started with a survey, "What should we call the things". By now, we've basically come up with our own methodology. Hell, it's even one of them "scaling" ones. And we use a lot of seemingly boring words to describe very powerful things.<br />
<h3>
The emerging trend of self-management in organizations is going to be big</h3>
<div>
As eyeo is at the steps of exploiting more agile values and principles, we also look to the horizon to see what is coming. The ideas of <a href="http://www.reinventingorganizationswiki.com/Teal_Organizations">teal organizations</a> rhyme very well with agile and DevOps, but they go way beyond. Surprisingly (and yet, perhaps not), a lot of these self-organizing principles are easier to apply to eyeo than the agile predecessors. Albeit eyeo is an overgrown start-up of sorts, with the expected chaos, their universal inner values are <b>fairness</b> and <b>transparency</b>. Armed with this, a lot of the self-organizing patterns are a great fit.</div>
<h3>
Balancing the act of dropping into Operations, while driving organizational change</h3>
<div>
This is where I failed the hardest. And perhaps where I learned the most. How can I reconcile the act of supporting one particular department, while I at the same time am trying to break them up across cross-functional teams? I went on for too long ignoring this conflict, and it cost a lot of soul to make things right, and there's still a lot to do.</div>
<h3>
Building bridges in a company which is both remote and not</h3>
<div>
I am a hybrid remote worker, which means I am simply not a remote worker (or remotee, as they're called at eyeo). As most remote workers know, a mixed remote/local team is the trickiest constellation to have in any company. It does work at eyeo so far, mostly for historical reasons and remote culture being deep in the DNA of the founders, but it will only get us so far. We can't become co-located, nor does the majority really want to, so we have to improve. I've got some ideas, but haven't gotten so far with this yet.</div>
<h3>
Team autonomy vs company standardization</h3>
<div>
This one's a real classic. How can you pick a company-standard chat tool, while giving teams the autonomy to pick their own? This topic is fairly exhausted in the DevOps literature by now, I guess, so I'm not sure it's worth it. I got a lot of thoughts on it, but they may not be so original. A lot of it comes down to <b>decision making</b>, which in its own right is a big topic.</div>
<h3>
It's like blog post tapas</h3>
<div>
So, those are the ones I had in my head right now. If you got this far, and you'd care to give me a tweet, let me know which one I should write first.</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-4625370537343167992017-01-20T22:56:00.000+01:002017-01-20T22:56:38.368+01:00Joining EyeoA couple of months ago I left Viaboxx, more than five years after <a href="http://blog.tfnico.com/2011/07/new-job.html">I started there</a>.<br />
<br />
It was a great ride. It combined the excitement and intensity of working at a startup, with the safety of working with a profitable, self-organizing company of experienced full stack developers.<br />
<br />
During the time there I worked with everything from Raspberry Pis to huge parcel stations, from single-page-webapp AngularJS applications and Node, to state-of-the-art modern Java-cloud applications. I learned how to do infrastructure-as-code with Puppet, and immutable infrastructure with Docker. We developed our own products, did research projects and provided consulting for big enterprises - always learning, always trying out new things. Being small allowed us to optimize for learning while having an awesome culture where colleagues felt like family or great friends.<br />
<br />
Still, a part of me missed some of the challenges I worked more with when I was consulting, or working for larger companies. Helping people to work better. Working better together. All this thinking from <a href="http://blog.tfnico.com/search/label/agile">my agile days</a> went a little dormant while I was at Viaboxx because there we always did things right, methodology-wise. Most of the oncoming DevOps hype seemed unnecessary, because we were already optimizing for lead-time and were pretty streamlined.<br />
<br />
So, around last summer I decided to try something new. I've now finally joined a large but still growing company in Cologne called <a href="https://eyeo.com/">Eyeo</a>, although you may know them better as the creators of <a href="https://adblockplus.org/">Adblock Plus</a> and the concept of <a href="https://acceptableads.com/">Acceptable Ads</a>. I'll be focusing more in on the infrastructure/operational side of things, at the same time I'm taking on a more managerial position - which could mean pretty much anything, but some organizational coaching is included. Perhaps I'll get back to blogging more actively about the things I'm up to. No promises though.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-43934837716658028922016-03-28T02:15:00.000+02:002016-03-28T02:15:52.878+02:00Encrypting and Decrypting with SpringI was recently working with protecting some sensitive data in a typical Java application with a database underneath. We convert the data on its way out of the application using <a href="http://docs.spring.io/spring-security/site/docs/current/reference/html/crypto.html#spring-security-crypto-encryption">Spring Security Crypto Utilities</a>. It "was decided" that we'd be doing <a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES with a key-length of 256</a>, and this just happens to be the kind of encryption Spring crypto does out of the box. Sweet!<br />
<br />
The big aber is that whatever JRE is running the application has to be patched with <a href="http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html">Oracle's JCE</a> in order to do 256 bits. It's <a href="http://crypto.stackexchange.com/questions/20524/why-there-are-limitations-on-using-encryption-with-keys-beyond-certain-length/20525#20525">a fascinating story</a>, the short version being that U.S. companies are restricted from exporting various encryption algorithms to certain countries, and some countries are restricted from importing them.<br />
<br />
Once I had patched my JRE with the JCE, I found it fascinating how straight forward it was to encrypt and decrypt using the Spring Encryptors. So just for fun at the weekend, I threw together a little desktop app that will encrypt and decrypt stuff for the given password and salt. It's called <a href="https://github.com/tfnico/encryptomania">encryptomania</a>. Note that in order to run it you'll need the JCE (for now, see below).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><span style="margin-left: auto; margin-right: auto;"><a href="https://github.com/tfnico/encryptomania"><img border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qd8ajetTHdhi0lRFNqSR7KVA56axyZC0U1OGhUPcSEnVnw6fqrajNbeEoddppgeTlEmRKaS2vV4-rVWe6SFWJXMq-axKIDMsvhmH0_0_l9kbPHJI9g8kyIL0yREzVGdh43GC/s640/Screen+Shot+2016-03-27+at+00.57.25.png" width="640" /></a></span></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://github.com/tfnico/encryptomania">Screenshot from encryptomania, my little crypto GUI</a></td></tr>
</tbody></table>
<h4>
Some thoughts on the JCE</h4>
So at one level, Spring crypto has a problem in that they force all users of the library to patch their JRE. This makes it pretty much impossible to deploy in an environment where you don't have complete control of the environment (computers w/o root or admin-access, and PaaS). So it would be cool if they would support 128 bit key-length, and <a href="https://github.com/spring-projects/spring-security/issues/2917#issuecomment-201070281">I've started a patch to fix just that</a>.<br />
<br />
The other problem here is that Oracle doesn't just build the JCE into all the JREs. I mean, a malevolent programmer won't have any problems downloading the JCE into a country where it is not allowed, so it's more of a formal thing. And still if they would change the default here, it would take years for the change to propagate into all the data-centres around the world. I think we're better off betting on some other kind of encryption (maybe a 128 bit Twofish cipher out of <a href="http://www.bouncycastle.org/">Bouncy Castle</a>) to become more trusted than the one provided by Oracle.<br />
<br />
At the same time it is all a bit silly for your average non-critical webapp, as 128 bit AES is considered to be practically impossible to break in the foreseeable future.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-83160175180287076782016-03-15T22:51:00.004+01:002016-03-15T22:51:41.883+01:00Replacing Boxen with Vanilla Puppet (for setting up a new mac)I recently got a new MacBook at work and decided to overhaul my personal setup routine. <a href="http://blog.tfnico.com/2014/03/automating-computer-setup-with-boxen.html">Last time I tried an early version of Boxen</a>, and although I was pretty happy with it there were a few things that bothered me. It is very opinionated, and I had a hard time stopping it from overwriting my .gitconfig and things like that. It also dragged in a series of dependencies I didn't feel the need for, and made Homebrew a bit weird by installing it in the non-standard location <span style="font-family: Courier New, Courier, monospace;">/opt/boxen/homebrew</span>.<br />
<br />
Since Boxen is based on Puppet, and I've used plenty of Puppet on Linux, I wanted to simplify things a bit and see how far standard Puppet on OS X would get me.<br />
<br />
<div style="text-align: center;">
<i style="background-color: yellow;">Warning! Make sure you don't install puppet using brew! It'll install an old version which is not trivial to uninstall.</i></div>
<br />
It's fairly straight forward to <a href="http://docs.puppetlabs.com/puppet/latest/reference/install_osx.html">install Puppet on a Mac</a>, but since there is no standard package manager, like there's <i>yum</i> or <i>apt</i> on Linux, you have to set it up with a provider, in our case: <a href="http://brew.sh/">Homebrew</a>. I installed Homebrew manually at this point, but I think you could actually have Puppet do it for you.<br />
<br />
Next, we have to install a puppet module for Homebrew. I found found <a href="https://github.com/TheKevJames/puppet-homebrew">a good one here by Kevin James</a> (I tried the gildas and halyard ones first, but kept running into problems with them).<br />
<br />
As Puppet goes, it has to be executed as superuser:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> sudo puppet module install thekevjames-homebrew</span><br />
<div>
<br /></div>
<div>
and it depends on the Puppet standard library:</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> sudo puppet module install puppetlabs-stdlib</span></div>
<div>
<br />
Now we're ready to fire away and apply <a href="https://github.com/tfnico/prefs/blob/master/puppet-mac.pp">a puppet file defining our packages</a>:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> sudo puppet apply puppet-mac.pp</span></div>
<div>
<br />
As an example, consider <a href="https://github.com/tfnico/prefs/blob/master/puppet-mac.pp">my own puppet-mac.pp</a> - note how I've got various kinds of packages:<br />
<br />
<ul>
<li>normal packages, these are built from source by Homebrew</li>
<li>casks, which are Homebrew's notion of pre-built binaries</li>
<li>gems, for those weird pieces of software that are not available via Homebrew</li>
</ul>
<div>
People who enjoy Boxen will probably not see the big point of going this way, but I think it feels easier and more elegant. It also reduces the discrepancies between <a href="https://github.com/tfnico/prefs">my Linux and Mac setup</a>.</div>
</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-47294995939912362022015-11-12T00:50:00.000+01:002015-11-12T00:50:22.266+01:00Retiring from the Bonn Agile MeetupYesterday I organized my <a href="https://www.xing.com/communities/posts/bonn-agile-meetup-november-meta-meetup-1010439010">final meetup</a>.<br />
<br />
Back in February 2011, I invited to <a href="http://blog.bonnagile.de/2011/01/announcing-bonn-xp-meetup.html">the first meetup</a>, back then under the "XP" banner, <a href="http://blog.bonnagile.de/2011/06/announcing-bonn-agile-meetup.html">renaming to be Bonn Agile</a> a few months later.<br />
<br />
So, wow, that makes it nearly 5 years, or 50 meetups after a rough count.<br />
<br />
Most of these meetups were not organized by me though. I want to use this post for thanking the people who were around in the begining, co-organizing or just giving great feedback on how to get the meetup rolling.<br />
<br />
I'm sure I'm forgetting some names, but <a class="g-profile" href="https://plus.google.com/102434864554519245393" target="_blank">+Patrick Cornelißen</a>, <a class="g-profile" href="https://plus.google.com/103699919567837195295" target="_blank">+Kurt Häusler</a>, <a class="g-profile" href="https://plus.google.com/112664500238912557362" target="_blank">+Frederic Hemberger</a>, <a class="g-profile" href="https://plus.google.com/108237021430591826874" target="_blank">+Christoph Pater</a> and <a class="g-profile" href="https://plus.google.com/107809779697256129572" target="_blank">+Jan Ehrhardt</a> took their share of the load back then until they moved from Bonn to other places. <a class="g-profile" href="https://plus.google.com/118230224553209822753" target="_blank">+Simon Tiffert</a> and <a class="g-profile" href="https://plus.google.com/111951848426046290982" target="_blank">+Matthias Lübken</a> provided valuable advice when starting up. As companies go, <a class="g-profile" href="https://plus.google.com/110902767232024173779" target="_blank">+tarent solutions GmbH</a>, <a class="g-profile" href="https://plus.google.com/118051837465841569912" target="_blank">+doo</a> and, most of all <a class="g-profile" href="https://plus.google.com/115829799149144244825" target="_blank">+Data in Transit GmbH</a> (big thanks to <a class="g-profile" href="https://plus.google.com/106360473982261812887" target="_blank">+Jutta Horstmann</a>!) have been supporting the meetup since the very beginning, with <a class="g-profile" href="https://plus.google.com/107628989201200123764" target="_blank">+Viaboxx</a> (my employer) hosting the annual Sommerfest/BBQ.<br />
<br />
Also from the beginning and up unto the latest meetups were <a class="g-profile" href="https://plus.google.com/105706982508171910252" target="_blank">+Jan Nonnen</a>, <a class="g-profile" href="https://plus.google.com/100205954591737487855" target="_blank">+Christoph Baudson</a>, with later on help from <a class="g-profile" href="https://plus.google.com/116254233569668269224" target="_blank">+Andreas Kluth</a> and <a class="g-profile" href="https://plus.google.com/101095148819469405270" target="_blank">+Michael Kutz</a>. <a class="g-profile" href="https://plus.google.com/118312755693799104761" target="_blank">+Stefan Walter</a> and <a class="g-profile" href="https://plus.google.com/107075935238392349763" target="_blank">+Daniel Westheide</a> should also be mentioned.<br />
<br />
And finally all of you who just kept showing up and contributing to all the awesome discussions.<br />
<br />
Thank you all.<br />
<br />
I started the meetup at a point where I was feeling pretty lonely in a professional sense, and it has been such an uplifting ride, making many new good friends on the way. It has been a really important part of my life here in Germany, and it's going to be weird not to be organizing anymore.<br />
<br />
The meetup yesterday was an attempt of figuring out what to do with the meetup, as we all felt it has run out of steem recently. While I feel bad for jumping ship, I think it might be good to let someone else pick up the reins and transform the meetup into what it needs to be today in order to attract new people, topics and discussion. I think most agreed yesterday that changing from the "agile meetup" into something different was a good idea. Stay tuned to <a href="https://groups.google.com/forum/#!forum/bonnagile">the mailing list</a> to see what happens next. I know that there will be a last regular meetup on the 1st of December, and after that there will be some sort of relaunch at some point, with a new name and a new form of activities and organization.<br />
<br />
For my own sake, I'll be diverting my "community energy" into some personal projects, perhaps more on <a href="http://blog.tfnico.com/search/label/podcasting">the podcasting side</a>, but of course there's not so much time left after taking care of the kids, house and all that. One thing we concluded yesterday is that a meetup needs young blood to keep really active, or perhaps old blood with fewer commitments than I have.<br />
<br />
So here's to the Bonn Agile Meetup. May it rise again under a different banner and attract an ever larger and active community.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-39736135697014678322015-10-23T07:48:00.000+02:002015-10-23T07:48:16.621+02:00Android Voice Commands for Cyclists Listening to Podcasts or Music<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px;">
<i>Disclaimer: I do not recommend using earphones while on your bike, but there are times or roads where I think it's OK. Pull out your earphones when nearing potentially dangerous situations (like intersections). At least pause the audio.</i></div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px;">
<br /></div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px;">
These tips also apply to anyone unable to look at and touch their device, leaving voice commands their only option (useful for visually impaired people, people wearing thick gloves, etc).</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
First of all, you need an Android with a fairly new version of Google Now installed, like Lollipop.</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
<span style="font-weight: 700;">You'll need a headset with a microphone button.</span> I’ve got an iphone headset that works great with my old Moto G, excluding the volume control.</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
You need to make sure that <b>a connected headset can bypass the device’s lock mechanism</b>. It’s in:</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
Settings -> Language & input -> Google voice typing -> Hands-free</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
Your audio playback software has to work with the Google Now commands. I’ve tried Google Music and BeyondPod successfully.</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
So, off we go! You’ll want to practice a bit before doing this on your bike: </div>
<ol style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin: 1em 0px; padding: 0px 0px 0px 40px;">
<li>Lock your phone and put it in your pocket with the headset connected.</li>
<li>Hold down the mike button until you hear a bell like “ba-ding!”. </li>
<li>Let go of the button.</li>
<li>Enter the voice command clearly (you don’t have to say “OK Google” first)</li>
<li>Wait until you hear another cheery ding sound, followed by Google Now’s voice confirming your command.</li>
</ol>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px;">
If you hear “Bong bong bong bong…”, that means there’s no signal or something. Just try again later. If Google Now doesn't grok what you're trying to say, start over.</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
<i>Here are the commands I’ve found useful on the bike so far:</i></div>
<ul style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin: 1em 0px; padding: 0px 0px 0px 40px;">
<li>“<span style="font-weight: 700;">Resume</span>” - this will start audio playback in whatever state you did previously (I think). Also un-pause.</li>
<li>“<span style="font-weight: 700;">Pause</span>” - self-explanatory. Note that tapping the mike button will also pause/resume, but I have found it to be a bit unreliable when resuming especially.</li>
<li>“<span style="font-weight: 700;">Skip to the next track</span>” - self-explanatory, some variations in how you formulate it is OK I noticed.</li>
<li>“<span style="font-weight: 700;">Open beyondpod</span>” - opens the app BeyondPod. This could be useful if I want to get out of Google Music.</li>
<li>“<span style="font-weight: 700;">Tell my wife on hangouts, I’m on my way home</span>” - I always forget to tell my wife when I leave work on the bike, so this is handy. If you leave out the “on hangouts” bit, it will just send a text message. Not sure if other IMs are supported.</li>
<li>“<span style="font-weight: 700;">What time is it</span>” - handy to see if I’m running late.</li>
<li>“<span style="font-weight: 700;">What’s the weather like tonight/tomorrow</span>” - always good to know when cycling.</li>
<li>“<span style="font-weight: 700;">What’s my schedule today/tomorrow</span>” - I haven’t tried this but could be useful.</li>
<li>“<span style="font-weight: 700;">Help</span>” - this one will make Google Now explain some voice commands for you.</li>
</ul>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px;">
If you’re cycling with some speed, you’ll need to cup the mike with your hand to avoid overloading your command with noise from the wind. For the same reason, I try not doing phone-calls while on the bike.</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
Any useful commands that I’ve missed? </div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
There are various lists of possible voice commands online, but unfortunately most of them are just useful when you’re looking at the phone in your hand. More can be found here:</div>
<div style="background-color: white; color: #444444; font-family: 'Helvetica Neue', HelveticaNeue, Arial, sans-serif; font-size: 15px; line-height: 24px; margin-top: 1em;">
<a href="https://support.google.com/websearch/answer/2940021?hl=en">https://support.google.com/websearch/answer/2940021?hl=en</a></div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-61081840085396094742015-07-08T23:13:00.000+02:002016-03-15T22:51:58.697+01:00The Sweet Spot of DockerI just stumbled across this <a href="https://news.ycombinator.com/item?id=9844806">"Ask HN: What is the actual purpose of Docker?"</a>.<br />
<br />
After using Docker more and more over the last months, my answers have gradually changed. It used to be more hype-like, with "immutable infrastructure", "portable" and stuff like that. Now it's more practical, I feel I can say more concretely what our benefits are.<br />
<br />
My favorite answer comes down to Docker being a standardized way of deploying and running applications.<br />
<br />
The old way of deploying our software was complex with a taste of chaos, then became managed but complicated through the introduction of Puppet (or your configuration management tool of choice). I'm hoping Docker will nudge it more towards <a href="http://lizkeogh.com/2012/03/11/cynefin-for-devs/">the simple (quadrant)</a>.<br />
<br />
How we used to deploy (and still do) - most of these are done through home-made shell scripts we distribute using Puppet:<br />
<br />
<ul>
<li>Installing Debian packages (mostly standard packages, sometimes from 3rd party repositories)</li>
<li>Dropping WAR files into Tomcat (application server)</li>
<li>Expanding tar.gz files with Java applications embedding Jetty (application server) and home-made init/service-scripts</li>
</ul>
<br />
On top of that, some extra configuration is again provided by Puppet.<br />
<br />
Our scripts handle downloading artifacts from Maven repositories, restarting application servers, running the services, PID-files and log files. Always some variations from application to application.<br />
<br />
So in order to get an application running on a new server, we'd do this:<br />
<br />
<ol>
<li>Acquire the server</li>
<li>Install OS and provision environment using Puppet</li>
<li>Include deployment scripts for downloading and setting up the application</li>
<li>Include service scripts for the application (start, stop)</li>
<li>Run the deployment scripts and start the application</li>
</ol>
<br />
With Docker, we do this:<br />
<ol>
<li>Acquire the server</li>
<li>Install OS and set up Docker log into the Docker repository (using Puppet)</li>
<li>docker pull our application image</li>
<li>docker run our application image</li>
</ol>
<br />
It looks kind of similar, and it's not really a big drastic change. But we are saving a couple of steps:<br />
<br />
<ul>
<li>We don't have to write and distribute the deploy script for the application.</li>
<li>We don't have to nurse the service scripts for the the application.</li>
</ul>
<br />
Docker provides the above routines for us. And we can use the same routine whether it's a Java application built with appassembler, a Tomcat with a Grails application in it, a database, some simple executable or a cronjob. I always wanted something like <a href="https://github.com/appmgr/appmgr/blob/master/docs/app.txt">appmgr</a> for fixing this for my Java applications, but Docker solves it for everything.<br />
<br />
We do have to provision the container's parameters/configuration, but at least this is a uniform step no matter what application we're talking about.<br />
<br />
Of course, it's a lot of work to dockerize your infrastructure, and if it was only for the sake of the above benefits alone, it might not be worth it. As often mentioned in the HN discussion, I think Vagrant is a much more helpful tool to gain the benefits that you get from Docker from a developer's perspective, but Vagrant doesn't help you deploy software out on the real servers. So right now we've got Vagrant recipes that use Puppet to install Docker (see routine above, replace "acquire the server" with "vagrant up").Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-51742023887629345192015-05-02T00:05:00.000+02:002015-05-02T00:16:45.752+02:00A Better Way to Git Push to Deploy (updateInstead & push-to-checkout)Wow, nearly a year since my last post. I was sort of thinking it would be something more profound, but here goes: Git recently (with version 2.3) <a href="https://github.com/gitster/git/commit/72ecc6ef53cb2906f5efab11fa6ab26c1729f233">introduced</a> a way of easily pushing changes into a remote non-bare repository, a.k.a. <i>push-to-deploy</i>. The <a href="http://gitolite.com/deploy.html#checkout----the-fight-club-of-git-deployment">old way</a> would be to have a post-receive hook run some update logic which would do some procedure to update a non-bare repository. There now is a simple way of configuring the target repository to <a href="https://github.com/gitster/git/commit/1404bcbb6b3bdb248d32024430644e55faec91ce">update its work tree instead</a> upon being pushed to.<br />
<br />
Now, pushing to the target repo may fail in cases where it has been modified, so soon after, a new <i>push-to-checkout </i>hook <a href="https://github.com/git/git/commit/0855331941b723b227e93b33955bbe0b45025659">was introduced</a> to deal with this, but it will only take effect in Git 2.4. I'll show how to set up both below.<br />
<br />
Surprisingly, when searching for "push-to-checkout", I found very few articles about this, even though it was <a href="https://github.com/blog/1957-git-2-3-has-been-released">loudly mentioned on the GitHub blog</a> (<a href="https://github.com/blog/1994-git-2-4-atomic-pushes-push-to-deploy-and-more">twice</a>, and on <a href="http://stackoverflow.com/a/28257982/266875">StackOverflow</a>, <a href="http://stackoverflow.com/a/299886/266875">of course</a>). So here's another one for the googles. Besides, I just <a href="https://groups.google.com/d/msg/git-users/JCbtoxTgkuE/0BVvngKFgYcJ">wrote this whole example</a> on the Git Users Mailing list and figured I'd repeat it here.<br />
<br />
Note that as it happens, I've never found myself in the sorry position of having to deploy this way in real life (<span style="font-size: x-small;">real developers package their distributables</span>), so don't take my word this being the way to do it on production systems.<br />
<br />
Note that Git version must be >= 2.3 for this to work at all, and must be 2.4 in order for the push-to-checkout hook to take effect.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo-web]$ git --version</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">git version 2.3.6 </span></blockquote>
<br />
Take some random repo and clone it to a "remote" location:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[~/temp]$ git clone foo foo-web</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">Cloning into 'foo-web'...</span><span style="font-family: Courier New, Courier, monospace;">done.</span></blockquote>
<br />
So, let's pretend that this non-bare repository is on our web-host:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[~/temp]$ cd foo-web</span></blockquote>
<br />
Configure to update on incoming pushes:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo-web]$ git config receive.denyCurrentBranch updateInstead</span></blockquote>
<br />
Create the hook:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo-web]$ vim .git/hooks/push-to-checkout</span></blockquote>
<br />
Contents of the push-to-checkout hook, as exemplified in <a href="https://github.com/git/git/commit/0855331941b723b227e93b33955bbe0b45025659">the test here</a>:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">/bin/sh</span><br />
<span style="font-family: Courier New, Courier, monospace;">echo >&2 updating from $(git rev-parse HEAD)</span><br />
<span style="font-family: Courier New, Courier, monospace;">echo >&2 updating to "$1"</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">git update-index -q --refresh && git read-tree -u -m HEAD "$1" || {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> status=$?</span><br />
<span style="font-family: Courier New, Courier, monospace;"> echo >&2 read-tree failed</span><br />
<span style="font-family: Courier New, Courier, monospace;"> exit $status</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
Make the hook executable<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo-web]$ chmod +x .git/hooks/push-to-checkout</span></blockquote>
<br />
Now let's take it for a spin. Go back to the original repo:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo-web]$ cd ..</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">[~/temp]$ cd foo</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo]$ git remote add web ../foo-web</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo]$ git push web master</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">Everything up-to-date</span></blockquote>
<br />
OK, that wasn't very impressive. Make some changes first, a new file <b>heya.txt</b> for example:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo]$ echo `random_word` > heya.txt; git add .;git commit -m `random_word`</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">[master b6765e2] overpaint</span><span style="font-family: Courier New, Courier, monospace;"> 1 file changed, 1 insertion(+)</span><span style="font-family: Courier New, Courier, monospace;"> create mode 100644 heya.txt</span></blockquote>
<br />
Away we go:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo]$ git push web master</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">Counting objects: 3, done.</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">Delta compression using up to 4 threads.</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">Compressing objects: 100% (2/2), done.</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">Writing objects: 100% (3/3), 322 bytes | 0 bytes/s, done.</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">Total 3 (delta 0), reused 0 (delta 0)</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">To ../foo-web</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;"> eb2711a..b6765e2 master -> master</span> </blockquote>
Push succeeded! Now, let's see if our new file arrived OK:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo]$ cd ..</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">[~/temp]$ cd foo-web</span></blockquote>
<br />
Tada!<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[master][~/temp/foo-web]$ ls</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">README foo heya.txt</span></blockquote>
<div>
<br /></div>
<br />
<br />Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-52832945077437888732014-05-19T08:05:00.000+02:002014-05-19T08:05:02.744+02:00GitMinutes Taking on a SponsorI was a bit unsure whether I should put this post on the GitMinutes blog, but figured I'd rather not mess up the nice episode overview there. I'll share this link via the GitMinutes <a href="https://twitter.com/gitminutes">Twitter</a> and <a href="https://plus.google.com/+gitminutes/posts">Google+</a> feeds, and of course everyone listening will hear about it.<br />
<br />
I am a bit worried that some people will not like that I'm going in a commercial direction with the podcast. Git is an open source project, and all my guests have participated on a volunteer basis. I've received hundreds of micro-donations via <a href="https://www.gittip.com/tfnico/">Gittip</a> and <a href="https://flattr.com/thing/1226228/GitMinutes">Flattr</a>, and probably some of the donors expected the show to keep going as an independent thing. If anyone feels hurt by this move, let me know and I'll reimburse your donations at least.<br />
<br />
The main reason I'm doing this is that I want to create more GitMinutes content. Not only for the podcast, but maybe do screencasts and other stuff as well. I want to engage the community in a lot of new ways, and this will require resources that I don't want to pay out of my own pocket. Hopefully there will be some money left for me to keep as well, and this makes it easier for me to justify spending my free time on GitMinutes.<br />
<br />
Now, I carefully picked a sponsor exactly so that it will not influence the show in any way. They do not produce any Git tooling, but still they are relevant to most listeners. I purposefully did not want to bore you talking about some irrelevant product. Rather than that, I want to tell you how much I'm enjoying their product myself, cause I have been doing so for a long time.<br />
<br />
So head over to <a href="http://www.gitminutes.com/">GitMinutes</a> and listen to the freshly released episode 29, and you'll hear what the first sponsor is all about.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-35838310054660531402014-03-23T19:20:00.000+01:002014-03-23T19:20:06.365+01:00Managing dot-files with vcsh and myreposSay I want to get my dot-files out on a new computer. Here's what I do:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"># install vcsh & myrepos via apt/brew/etc</span><br />
<span style="font-family: Courier New, Courier, monospace;">vcsh clone https://github.com/tfnico/config-mr.git mr</span><br />
<span style="font-family: Courier New, Courier, monospace;">mr update</span><br />
<br />
Done! All dot-files are ready to use and in place. <a href="http://dotfiles.github.io/">No deploy command, no linking up symlinks to the files</a>. No checking/out in my entire home directory as a Git repository. Yet, all my dot-files are neatly kept in fine-grained repositories, and any changes I make are immediately ready to be committed:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">config-atom.git</span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.atom/*</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-mr.git</span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.mrconfig</span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.config/mr/*</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-tmuxinator.git </span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.tmuxinator/*</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-vim.git</span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.vimrc</span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.vim/*</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-bin.git </span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/bin/*</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-git.git </span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.gitconfig</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-tmux.git </span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.tmux.conf </span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">config-zsh.git</span><br />
<span style="font-family: Courier New, Courier, monospace;"> -> ~/.zshrc</span><br />
<div>
<br /></div>
<div>
How can this be? The key here is to use <a href="https://github.com/RichiH/vcsh">vcsh</a> to keep track of your dot-files, and its partner <a href="http://myrepos.branchable.com/">myrepos/mr</a> for operating on many repositories at the same time.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM8KijalmXQoLI5hzwiIfQF0UhKH0erPTct9zIGqHTjgU5o-WXoTcYkCYFpmi2uWiYrpIrbMXjjoK6XtuBdS9D1xKcFwrATPtlCfePbecTY44Vf_tpzfZIMJYImqHzpsoCfDNc/s1600/Sketch226221227.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM8KijalmXQoLI5hzwiIfQF0UhKH0erPTct9zIGqHTjgU5o-WXoTcYkCYFpmi2uWiYrpIrbMXjjoK6XtuBdS9D1xKcFwrATPtlCfePbecTY44Vf_tpzfZIMJYImqHzpsoCfDNc/s1600/Sketch226221227.png" height="306" width="320" /></a></div>
<div>
<br /></div>
<div>
I discovered vcsh when I had its creator, <a href="http://episodes.gitminutes.com/2013/06/gitminutes-13-richard-hartmann-on.html" target="_blank">Richard Hartmann guesting on GitMinutes</a>, and I'm still surprised how little known this great tool is. Partly responsible for this I guess is that it's a bit hard to understand how vcsh works, and the README only does a half-good job at explaining it.</div>
<div>
<br /></div>
<div>
So let me try with my own words:</div>
<div>
<br /></div>
<div>
vcsh is a sort of a Git wrapper that let's you track files in Git repositories, while the actual files (work-tree) are in your home directory. </div>
<div>
<br /></div>
<div>
For example, my .gitconfig is tracked in this repository: </div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">~./config/mr/repo.d/config-git.git</span> (<a href="https://github.com/tfnico/config-git">see it on GitHub</a>)</div>
<div>
<br /></div>
<div>
But vcsh sets the working directory to be <span style="font-family: Courier New, Courier, monospace;">~</span>, so when I check out the contents of the repository, it lands directly in my home directory.</div>
<div>
<br /></div>
<div>
vcsh works pretty much like Git, except for most commands you tell it which repository to work on:</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">vcsh init git # creates a bare repository by with the name 'git' under ~./config/mr/repo.d/</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">vcsh git add .gitconfig # adds the file to the 'git' repository</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">vcsh git commit -m "My initial .gitconfig"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">vcsh git diff # shows any changes you have made to your .gitconfig since</span></div>
<div>
<br /></div>
<div>
If you know about Git's ability to keep the <span style="font-family: Courier New, Courier, monospace;">GIT_DIR</span> separate from the work-tree, this should be pretty easy to grasp.</div>
<h2>
Enter myrepos</h2>
<div>
If you're happy to keep all your dot-files in one repository, you'd be well off using vcsh by itself. But if you prefer having several repositories (perhaps you don't want all dot-files on a particular computer), or if you have any other Git repositories you always need checked out on your computer, <i>myrepos </i>is the tool for syncing a bunch of repositories in one go.</div>
<div>
<br /></div>
<div>
Imagine myrepos like this: It's a file with a list of repositories to should be managed on your computer:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">[$HOME/projects/foo]</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">checkout = git clone git@github.com:tfnico/foo.git</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">[$HOME/projects/bar]</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">checkout = git clone git@github.com:tfnico/bar.git</span></div>
</div>
<div>
<br /></div>
<div>
Lucky for us, it also does the right thing with vcsh repositories:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">[$HOME/.config/vcsh/repo.d/various.git]</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">checkout = vcsh clone git@github.com:tfnico/config-various.git various</span></div>
</div>
<div>
<br /></div>
<div>
That's pretty straight forward. Now you'll soon realize that myrepos and vcsh overlap in the sense that they both can do Git operations, and this can be a bit confusing. I'll try postulating a bit on which is for what:</div>
<div>
<ul>
<li>myrepos is for checking out or operating a bunch of repositories at the same time. This includes your vcsh repositories.</li>
<li>vcsh is for managing files and directories in your home directory. The contents of a vcsh repository is all relative to home.</li>
<li>The myrepos configuration is kept in a vcsh repository. So in order to bootstrap, doing a vcsh clone of our mr repository is the first thing we do (as we did near the top of this blog post).</li>
<li>As myrepos also operates your vcsh repositories, it also manages its own configuration. As an effect, if you make any changes to your myrepos config on one computer, you'll have to run `mr update` twice in order to see the changes on another computer.</li>
<li>If you're making changes on one repository, like your vim-config, use vcsh to diff and commit the changes.</li>
<li>If you want to push or pull all the latest changes in all your repositories, use myrepos.</li>
</ul>
<div>
Some food for thought: Consider <a href="https://github.com/tfnico/config-mr">my vcsh repo for myrepos</a> - I could have kept the .mrconfig file by itself in a vcsh repository, and then have mr check out the <span style="font-family: Courier New, Courier, monospace;">~/.conf/mr/</span> stuff as a normal mr.git repo inside of <span style="font-family: Courier New, Courier, monospace;">~/.conf/</span>. This hypothetical aside, it makes more sense to keep files for one purpose in one repo.</div>
</div>
<div>
<br /></div>
<div>
I can understand after writing this that it's really hard to come up with a good README for vcsh. But I like to consider how much <a href="https://github.com/tfnico/prefs/commits/master">time I've spent on dealing with my dot-files</a>, and how much more time I spent <i>not managing them</i>. In light of that, spending half a day on getting vcsh and mr set up right doesn't seem too bad. They are simply the best tools for the job (and other jobs), and the only draw-back is a little learning curve.</div>
Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-36066375578216416262014-03-21T22:10:00.000+01:002016-03-15T22:52:58.607+01:00Automating Computer Setup with BoxenI just finished setting up a new laptop at work, and in doing so I revamped my personal computer automation quite a bit. I set up <a href="http://boxen.github.com/" target="_blank">Boxen</a> for installing software, and I improved my handling of dot-files using <a href="https://github.com/RichiH/vcsh" target="_blank">vcsh</a>, which I'll cover in the next blog-post after this one.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJKWsH6JnnU1zTr1KocHHidnE2xor9nZSnanzbJ-rq5gUaVhVrxf1oqPuEF9eeHYbBwxohj25n4bAERqTMmMcVSCaQZ1cvlNkpLU832Z6CqepQrr3tOqAGLHb6Yj02U0ewvEw1/s1600/Sketch215214310.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJKWsH6JnnU1zTr1KocHHidnE2xor9nZSnanzbJ-rq5gUaVhVrxf1oqPuEF9eeHYbBwxohj25n4bAERqTMmMcVSCaQZ1cvlNkpLU832Z6CqepQrr3tOqAGLHb6Yj02U0ewvEw1/s1600/Sketch215214310.png" height="317" width="400" /></a></div>
<div>
<br /></div>
Since it's a Mac, it doesn't come with any reasonable package manager built in. A lot of people get along with a combination of <a href="http://brew.sh/" target="_blank">homebrew</a> or <a href="http://www.macports.org/" target="_blank">MacPorts</a> plus manual installs, but this time I took it a step further and decided to install all the "desktop" tools like VLC and Spotify using <a href="http://boxen.github.com/" target="_blank">GitHub's Boxen</a>:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> include vlc</span><br />
<span style="font-family: Courier New, Courier, monospace;"> include cyberduck</span><br />
<span style="font-family: Courier New, Courier, monospace;"> include pgadmin3</span><br />
<span style="font-family: Courier New, Courier, monospace;"> include spotify</span><br />
<span style="font-family: Courier New, Courier, monospace;"> include jumpcut</span><br />
<span style="font-family: Courier New, Courier, monospace;"> include googledrive</span><br />
<span style="font-family: Courier New, Courier, monospace;"> include virtualbox</span><br />
<br />
If the above excerpt looks like Puppet to you, it's because it is. The nice thing about this is that I can apply the same puppet scripts on my Ubuntu machines as well. Boxen is Mac-specific, Puppet is not.<br />
<br />
It was a little weird to get started with Boxen, as you're offered a download, but you are supposed to fork their <a href="https://github.com/boxen/our-boxen/" target="_blank">our-boxen</a> repo and take it from there. Here's a short recap:<br />
<br />
<ol>
<li>Create <span style="font-family: Courier New, Courier, monospace;">/opt/boxen/</span> and give yourself permissions to write in it</li>
<li>Clone your our-boxen fork into <span style="font-family: Courier New, Courier, monospace;">/opt/boxen/repo</span></li>
<li>cd into repo and run <span style="font-family: Courier New, Courier, monospace;">./script/boxen</span></li>
<li>Add further modules (recipes) in <span style="font-family: Courier New, Courier, monospace;">repo/Puppetfile</span> and include them in <span style="font-family: Courier New, Courier, monospace;">repo/manifests/site.pp</span></li>
<li>Run boxen again (should be automatically added to your global PATH by now).</li>
<li>Commit and push your changes so you can apply the same to other machines, or share with colleagues.</li>
</ol>
<br />
I found lots of good modules by just scrolling through all the repos in <a href="https://github.com/boxen" target="_blank">the Boxen organization</a>. You can lock versions for the modules, and do some special configuration in some cases, just look in each module repo's README if you need something special.<br />
<br />
Note that you're bound to run into a bunch of <a href="https://github.com/boxen/our-boxen/issues" target="_blank">hiccups</a> along the way. Most of these have known solutions, so just search through the module's issues. In a few cases I ended up doing <span style="font-family: Courier New, Courier, monospace;">brew install <module></span> directly to get one working, which is OK since Boxen uses Homebrew as <a href="http://docs.puppetlabs.com/references/latest/type.html#package" target="_blank">package provider</a>.<br />
<br />
Expect to fiddle with this a couple of hours the first time you add all your favorite modules. When downloading a lot of large packages, Boxen will break down with long stack traces because of network timeouts. Just keep restarting it and keep it up until it's done.<br />
<br />
Here's <a href="https://github.com/tfnico/my-boxen" target="_blank">my boxen repo.</a> The interesting files there are <a href="https://github.com/tfnico/my-boxen/blob/master/Puppetfile" target="_blank">Puppetfile</a> and <a href="https://github.com/tfnico/my-boxen/blob/master/manifests/site.pp" target="_blank">manifests/site.pp</a>. You can also put some personal stuff (a Boxen repo is supposed to be used across a whole team) in a <a href="https://github.com/tfnico/my-boxen/blob/master/modules/people/manifests/tfnico.pp" target="_blank">personal config</a>, but I didn't really get into this yet.Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0tag:blogger.com,1999:blog-11485756.post-64455838341575487102014-03-09T02:25:00.002+01:002014-03-09T02:25:41.508+01:00Calling All Programmer PodcastsOne of the reasons why <a href="http://blog.tfnico.com/2013/03/announcing-gitminutes-podcast-for-git.html">I started podcasting</a>, is that I <a href="http://blog.tfnico.com/2013/03/the-stuff-you-didnt-get-around-to-read.html">listen to a lot of podcasts</a>.<br />
<br />
It took me a long while to build up my podcatching portfolio. For half a year, I listened to mostly gaming podcasts because the only programmer podcasts I knew about was <a href="http://hanselminutes.com/">Hanselminutes</a> and <a href="http://javaposse.com/">Java Posse</a>. I simply didn't know <a href="http://www.tfnico.com/podcasts-for-programmers">what programmer podcasts were out there</a>.<br />
<br />
Podcast discovery is about as well established as it was 10 years ago, meaning <b>iTunes</b>. Of course you can blindly google for "<topic> podcast", or you might start off with some recommendations from friends, but there still is no established way of discovering more podcasts of the kind you'd like (1).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHyjmSfMzwHBX4fpykdn1fsHZMQwd6AvPn1fzZoI2FKvZOtSN53L5NeTJELUCzitSW4xRkjfBVhtF6NRdD_pmYvRPxgpJETA53RL8WpfRwT3rCtrO7ou3ECMXiMIBADPG79EM7/s1600/Sketch902114.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHyjmSfMzwHBX4fpykdn1fsHZMQwd6AvPn1fzZoI2FKvZOtSN53L5NeTJELUCzitSW4xRkjfBVhtF6NRdD_pmYvRPxgpJETA53RL8WpfRwT3rCtrO7ou3ECMXiMIBADPG79EM7/s1600/Sketch902114.png" height="180" width="320" /></a></div>
<br />
Another problem is that I see very little cross-pollination between the programmer podcasts. Even though they intersect just the right amount, I never heard <a href="http://javascriptjabber.com/">JavaScript Jabber</a> mentioned on <a href="http://thechangelog.com/">TheChangelog</a>, for example (2).<br />
<br />
To help remedy this <a href="http://www.tfnico.com/podcasts-for-programmers">I've thrown together all the currently active, English-speaking programmer-oriented podcasts</a> that I'm aware of. This is just a quick stab at helping you discover what's out there in our genre. Kind of like a good old webring, or a Yahoo directory.<br />
<br />
I'd love to make the collection a bit more interactive, perhaps pulling in some RSS data to present the latest release date, amount of episodes and stuff like that.<br />
<br />
But for starters, it'll just be a place you can point programmers who have just figured out podcasts. Let me know if there are any you think should be added via <a href="https://twitter.com/tfnico" target="_blank">Twitter</a> or <a href="https://plus.google.com/+ThomasFerrisNicolaisen/posts" target="_blank">Google+</a>, or just comment on this post. In the long term, perhaps I can move the list to more of a community wiki thing.<br />
<br />
<span style="font-size: x-small;">(1) <a href="http://stitcher.com/">Stitcher</a> shows some promise here, seeking to be the Pandora of podcasts, but I don't use it as I prefer my selected listening software (<a href="http://beyondpod.com/">BeyondPod</a>), and neither do most podcast-listening programmers out there, I suspect. </span><br />
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;">I don't use iTunes either, and I don't like their obscure algorithms of deciding what is "new or noteworthy". </span><br />
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;">(2) Exception-wise, I did get an initial boost in listenership from <a class="g-profile" href="https://plus.google.com/105487854388646525021" target="_blank">+Randal L. Schwartz</a> mentioning <a class="g-profile" href="http://www.gitminutes.com/" target="_blank">GitMinutes</a> on FLOSS Weekly (twice I think).</span>Thomas Ferris Nicolaisen http://www.blogger.com/profile/17464665832399025601noreply@blogger.com0