Keeping C.A.L.M.S. at HolidayCheck

In the last article called “Adapting DevOps culture with C.A.L.M.S. I’ve described the C.A.L.M.S. model and showed its importance and usefulness for proper adaptation of DevOps culture.

At HolidayCheck we believe in DevOps culture and try to follow it on daily basis. As a DevOps Engineer, I’m a member of developer teams and provide them with support regarding infrastructure and system engineering. Having the ability to work with several different scrum teams in this company I have noticed that there are better and worse adaptations of DevOps culture. However, the most recent one I had a chance to work with did it surprisingly well and I would like to share my thoughts about last six months working with them.

Six months ago I was assigned to a newly formed squad with one focus: to integrate external user handling solution with our platform. At first, it sounds simple. However, if you have three different platforms, written in different tech stacks, some of them during migration, some considered legacy with lack of documentation or people knowing how it works –it can be more difficult than one could think. Apart from writing our own services, we were also meant to work with code owned by other teams. That meant sending pull requests and asking people to review and accept. It’s also worth mentioning that there was already one approach to rewrite user handling modules. It was very painful and did not finish, which made user handling the least pleasant part to be developed in the IT department.
On top of that, the new team was assembled from people who hadn’t worked with each other before. They were taken from other teams and an external outsourcing company. It all made me a bit skeptical about this project.

Surprisingly, I have noticed that every team member independently brought elements of DevOps culture to the team. People had a strong sense of ownership, willingness to make a change despite the known UH reputation. Every sprint they focused on minimizing work-in-progress to deliver as much as possible, even if that caused their own tasks not to be delivered. But what I liked most was no fear of stepping out of one’s comfort zone and do stuff they were not specialized in.

The code we started to develop was kept as simple as possible, allowing people to take over development in case of someone else’s unexpected absence. Also, automation was kept lean. We chose Jenkins 2.X as our build/deployment server, set up a hook on whole GitHub repository and agreed that every repo, every branch will have a Jenkinsfile describing a pipeline. Although I was the one to set up the initial tool, the whole process of building and improving pipeline was quickly taken over by all team members adjusting it to their needs while I was providing support if needed. Demands, expectations, and being pushy were replaced here by pairing, contributing, and supporting to have it ready sooner.

We remembered to stay lean. Having a continuous delivery pipeline, every change merged to the release branch was immediately deployed to production. Also, we focused on the absolute MVP to be able to go live and handle at least some test traffic. This gave us very important feedback regarding possible improvements. Pull requests to other repositories were prepared and posted in advance. Therefore we had our changes in foreign code already deployed to production, not interfering with current functionalities and waiting for a moment to take over user handling flow.
As we were a pretty small team with three developers, a product owner and a devop, we were trying to keep meetings brief. People didn’t need reminding to prepare for refinements or plannings, so the time needed to work out an agreement was also short.

Before going live we started defining metrics and aggregating logs in one place. We had to put some extra effort to automatically pull logs from the provider but that paid off with detailed user monitoring and ability to cross check error logs with events delivered by a third party site. As the output, we got multiple dashboards and log filters analyzing almost every aspect of the running application: from pure system metrics like resource consumption, latency, and uptime, to detailed information about user behavior with an ability to trace errors back to few requests before to better understand the context. After exposing a new login to live traffic every 5xx error was immediately alerted on team’s Slack channel and, thanks to gathered links and dashboards, we could identify a root cause within a few minutes.

I also saved one more surprise for the end. Although the company policy was to have co-located teams, due to a shortage of personnel our team was partly distributed. Apart from me, all team members were sitting in the same room in Munich, DE and I was working from the office in Poznań, PL. Also due to other responsibilities I could not allocate more than 60% of my time for this team.
Our internal communication, sharing opinions and ideas, was so good that most of the time I didn’t feel excluded at all. To be honest, working with them, even as a remote devop, was more enjoyable to me than working with some other teams co-located in one room.

Now that our goal is achieved and I am switching teams once again, I have decided to take a look back at the last 12 sprints and try to learn from it. And of course to share with you.

Was it really that candy-sweet all the time? Of course not, we had our problems. Starting with me not being 100% in the team. I regret that I could not get more involved in coding. Sometimes, especially in the very middle of the project, our meetings were too long and seemed pointless to me. Out CI pipeline crashed several times, blocking the whole development process and causing lot of tension. We were dependent on other teams which sometimes weren’t willing to help us because it was not compliant with their OKRs. It all happened more than I’d like, but I’m happy that we did work it out together and fixed it instead of pointing fingers.

What I personally learned from it was that:

  • the proper mindset is an absolute foundation for good DevOps culture
  • having a smaller team of engineers inclined to be full-stack means it’s better at self-managing and does not suffer in case of someone being suddenly absent
  • automation should be lean and constantly improved. Don’t put too much overhead on it at the beginning.
  • we should treat our applications as our own piece of production cake, equip it with a number of useful metrics and get knowledge out of them
  • ideas for the technological process should not be turned down by product people, as they influence greater delivery speed in the end of the day

I hope that I can take this knowledge and use it in the new project I’m about to join.

Adapting DevOps culture with C.A.L.M.S.

DevOps is still quite a buzzword. There are already plenty of articles describing what it is and what it isn’t. I think we can agree that it’s a culture, a way of work. I’m also sure that most of us have a general impression about what it should look like: development and operations working together, breaking down silos, deliver faster, automate, etc. All of these are important and true, but still only seem to be a partial description. I started looking for a more complex description. And I found a very interesting model describing the culture. It’s C.A.L.M.S.

C.A.L.M.S. is an acronym for five major points describing a DevOps culture. Let’s have a quick look at them:

C – Culture
This is something you cannot implement. First, you should start with people having a proper mindset and it should concern ALL team members. Everyone should be focused on a common goal and help others achieve it whether it’s within your specialization area or not. Stepping out of your comfort zone and leaning towards becoming a full-stack engineer is encouraged.

A – Automation
We want to do as little boring stuff as possible. Therefore everything that can be automated should be done this way. And that’s not only writing scripts for testing and deployment but also adapting the idea of programmable infrastructure and having everything written down, versioned, and automatically managed.

L – Lean
Automating everything can be a pitfall that overcomplicates the infrastructure. Therefore engineers should focus on keeping everything minimal, yet useful. That doesn’t concern only automation – code deployments to production environment should be small and frequent and whole applications being developed – simple and easy to understand. It also applies to team size: larger teams find it more difficult to agree on something.

M – Measurement
Frequent releases give great flexibility but also can put the production environment in danger. That’s why a developed application should be equipped with useful metrics and monitored in real time. In case of problems the team can be notified quickly and is able to develop a fix. Teams can also monitor how new features influence user behavior.

S – Sharing
Sharing is essential for improving the communication flow and making people work together. Therefore it’s important to share ideas, experiences, thoughts: inside the team, among teams, and even outside the company.

What I like most about this model is how these points interact with each other. Automation should always be lean and robust. Providing an automated CI/CD pipeline helps teams to stay lean. While setting up monitoring it’s better to choose only valuable metrics and set up handy dashboards and alerts. The metrics can be shared among teams to set up a more complex application analysis tool that would automatically provide some wider context into the data we collect, which can be automatically analyzed and trigger lean changes in features …
The foundation for all these things is Culture. In my opinion that’s the most difficult point of all five. Without it, the other four points are just minor improvements to everyday work.

If you liked this article and would like to read about how this model applies to the team I used to work with, please let me know by leaving a comment.


Time as Scrum Master’s poison

I believe that, as Scrum Master, you can’t create a high-performing team in one or two weeks. Let’s imagine that after laborious months of your work a team is stable, aware of its dysfunctions and moving towards self-organization. People know one another, they collaborate well and delivery product frequently. What about you Scrum Master? How would you feel after being part of a team for 12, 18 months?

In this post, I would like to raise an issue which is being part of a team for too long is a poisoning situation for Scrum Master.

Someone could start asking what is the reason for saying this if you still have lots to do as Scrum Master…

Looking at your team…
… there is a still room for a team improvement,
… there is a still way to speed up a product delivery,
… there is a still possibility to raise a technical quality.

This person could be probably right while mentioning those arguments. So why „time factor” sound as a poison for Scrum Master in my opinion? I would like to refer to the theory of System Thinking to help to understand this point of view. Peter M. Senge said:

System Thinking is a discipline of seeing whole

In discussed topic, when you join a team as Scrum Master everything is new for you. You are asking lots of questions, you are trying to understand dependencies (both technical and product-wise) and a relationship between people. Your goal is to gather as much information as you could to have a high-level understanding of a current situation. So what you are aiming to is to create a picture of a whole. You are fresh-minded, not influenced by your work environment, not blinded by anything. All of these help you to propose relevant actions and introduce your agility plan. You strongly believe that it is the proper way. It sounds so exciting, you are stimulated by new surroundings, you have lots of positive attitude in your activities. Wouldn’t it be perfect if such case stayed for a long time?

The reality is that after a few months working with a team, you are becoming part of the system, you would be only „system component”. You are losing an external point of view. You start ignoring obvious things that influence and slow down a team. They could prevent people from a continuous learning. What worse is that you stop developing your skills. It could be very difficult to step out from this situation as you could not be even aware of it. You live in a comfort zone, you are safe inside a team, which is working well but not as much effective as it could be. That’s why I’m saying the longer you stay in the same team the less you support them. In such case “time” is a poison for being Scrum Master.

So how to avoid it? What antidotes Scrum Master should take to recover? I’ll tell you my secret medicines in the next post.

*Image source: Gwendolyn Knapp book’s cover

How we stopped worrying and learned to use Kotlin in our Androd App

Kotlin is a relatively new programming language, becoming more and more popular among Android developers. It is officially defined as Statically typed programming language for the JVM, Android and the browser by its creators, JetBrains – who are also responsible for the Android Studio (and other great IDEs).

Kotlin at HolidayCheck

After the release of Kotlin in stable version, Android team at HolidayCheck decided to finaly give it a go. We’ve implemented a significant feature of Android app (Booking Module) over the course of three months, learned from our mistakes and enjoyed every single moment of the Kotlin experiment. We can safely say it went well and we’re not looking back.

Here are the top 5 reasons why we recommend everyone to try it in their Android apps.

NullPointerException hell is gone

This might not be the most important reason, but it resonates with every Java developer so strongly, that it needed to be put in the first place. Kotlin is type and null safe. If you use it correctly, NPEs will not happen, it is guaranteed by the language. References that might contain null value, must be explicitly marked as nullable – everything else must have value and the compiler makes sure of it. This is built into type system, no Optional<T> needed.

Lambda expressions & collections

Lambda expressions were one of the most imporant additions to Java 8 – it’s finally available for Android so it’s not such a game changer now, but still – Kotlin adds its own lambda support without the need for Java 8 or external libraries for Android.

Lambdas alone can greatly reduce boilerplate code, but their use with collections shows real power in expressiveness and conciseness. Simple mapping and filtering collections is a touch of functional programming that every modern application needs.

Simplified and more powerful syntax

Operator overloading and extension functions greatly improve expressiveness of the code – no static helper classes needed for simple calculations performed on your custom objects. Setting text on your TextView or hiding it when the text is empty – simple as writing one function shared among all TextViews, instead of polluting view code with logic and if statements.

As a matter of fact, if in Kotlin is an expression, so it can return a value. The same applies to when expression, an improved switch operator.

Default function parameters? Check. No semicolons required? Check. String interpolation? Check, check, check.

You don’t need to go all in

Greenfield projects are rare, most of our day-to-day work is all about maintaining software and building features on top of existing codebase. Some projects (even in the worst tech-debt imaginable), cannot be migrated (even into the most promising programming language ever) for the cost of stopping development. We wouldn’t do that either, but fortunately this is not the case. You can migrate old code or write only new one in Kotlin and everything works fine with Java, because the bytecode is JVM-compatible.

Great way to dive into Kotlin development in your Android app is to separate one single Activity in your project and (re)write it in Kotlin. If anything goes wrong, you can always go to Java, even for single, specific classes.

Java Interoperability

Of course the code of your beloved Android app doesn’t exist in vacuum. What about all those Java libraries, that are not (and probably never will be) ported to Kotlin? Fear not, they don’t need to. You can simply cal Java code from Kotlin and vice versa. Thanks to that, Kotlin can be easily adopted in current code, hopefully phasing out Java in the future.

This list is of course not exhaustive, Kotlin has many other features available. In case this doesn’t convince you, here’s a sneak peek of upcoming changes in version 1.1.

Get started right away

This tutorial shows how you can start with Kotlin, migrating single classes one by one. If anything goes wrong, make sure you have the latest Android Studio and Kotlin plugin installed.

Bonus: Anko library

Anko is a DSL for Android, written in Kotlin. It greatly simplifies development, both in terms of code we must write, as well as its complexity, getting rid of many points of interaction with Android SDK and Java quirks. Be aware though – it’s specific to Android and can potentially introduce yet-another level of complexity if you’re just starting out with migration to Kotlin.


Agility insights

I’ve been talking recently lots with people from different companies to understand how they are moving towards agility. Many of them are saying – yes we are fully doing Agile right now. When I’m hearing this “magic” sentence I always ask – please tell me more… tell me what do you mean by “doing Agile”, how it works for you…

So here is a summary of Agile perspective that is evolving inside those companies:

  • Agile equals iterative delivery,
  • Scrum Master is a report manager,
  • Scrum Master is responsible for assigning tasks to developer,
  • Scrum Master acts as project manager,
  • Product Owner assigns stories to sprints,
  • Two roles exists inside a team: Project Manager & Product Owner,
  • Agile ceremonies make company agile,
  • Developer is mostly interested in his tasks,
  • Agile means writing requirement as User Story.

Does it sound familiar to you? Is it one of the companies that you know? Those are typical Agile Anti-patterns in my opinions and in fact most of them are against an agile mindset. Understanding how companies imagine agility helps me realise how much work still need to be done to create the right meaning of it. After fixing it inside your working environment you could start to create a people-oriented organisation based on learnings and transparency.


London Lean Kanban Days – key takeways

There was London Lean Kanban Days conference last week. Thanks to HolidayCheck I had a pleasure to participate in this event. As well as being excited by announced speakers (Pawel Brodzinski, Tobbe Gyllebring, Gitte Klitgaard) I was really looking to meet British Lean community to get a different perspective. In this post, I would like to share with you key takeaways from this conference.

  • Visualize a problem rather solve it – creating an awareness is often enough, then let people fix it – as a coach you don’t have to do everything by your own.
  • Lean = LeaRn – we sometimes forget about the main concept of lean which is continuous learning while focusing on other Lean principles like establishing flow, implementing pull approach or defining value from a customer perspective. Take your time for reflection, analyze what you achieved and learned.
  • Acknowledge yourself – you need to take advantage of the imposter syndrome by things like realizing that your experience is unique, fear indicates growth and keeping pushing your boundaries, improving where you have a passion.
  • Traditional project management is much closer to Agile mindset nowadays. The most needed skill for a project manager is leadership and an organization should aim to be adaptable.
  • Extreme self-organization at the company level is doable – it takes a time, it is not one-day shift and probably part of people will decide to leave your company.
  • While doing a change you need to have someone responsible for delivering value, and facilitating the risk assessment, you need to focus on organizational goals instead of local targets.

Android Runtime Permissions

Android Runtime Permissions

Permissions are used to restrict access to sensitive resources, data and hardware features. Android 6.0 Marshmallow (SDK level 23) introduced the concept of Runtime Permissions, changing many aspects of managing them in Android. The change is aimed to greatly improve user experience and it seems the Android Team did just that. On the other hand, developers need to incorporate those changes into their apps, which might not look that easy at first glance.

Traditional permission model

  • application install requires all of the permissions to be accepted by the user
  • the only way to revoke them is to uninstall application (all or nothing approach)
  • new permissions prevent apps from auto-updating, they need additional review by the user1
  • required permissions are declared in Android Manifest and application can assume, that if it is installed, it has all of them granted

New runtime permission model

Now, every permission falls into one of three protection levels:

  • normal applications get them by default at the time of installation (for instance Internet connectivity)
  • dangerous must be granted explicitly by the user
  • signature custom permissions based on signing certificates that should match in order to request them, typically used by applications by the same developer in order to exchange some private, proprietary data

In addition to protection levels, new concept of permission groups has been introduced:

  • few separate permissions (like we are used to) might be grouped together into one group
  • user implicitly grants us all permissions from the group, that requested permission belongs to
  • if we ask for more than one permission in a group, they are granted/denied automatically based on users decision regarding the group

Dont assume that if you possess a permission from particular group, you also have all the other permissions from that group always ask for specific ones, because current behavior might change in the future.

What all of that means for your users, is they can just install any given app from the Play Store and start using it right away (no questions during installation asked). Permissions falling into normal protection level are granted by default, and those should be enough for typical app to function, at least at the beginning. The process of asking for permissions is pushed back to the last possible moment the moment that user wants to perform an action requiring dangerous permission, for example action of taking a photo would be briefly interrupted by a system dialog with permission request. Finally, user can grant or revoke2 any permission at any time from system settings, without uninstalling app.

App permissions can be fine-tuned separately app by app

When user revokes permissions, our applications process gets killed.

All is fine for the user, but life of an ordinary Android developer has just got slightly more complicated. Were now required to take extra care and prepare for few scenarios, making sure that we:

  • declare required permissions in Android Manifest as usual
  • check on-the-fly, that we are actually granted permissions required to perform given actions
  • disable certain UI controls or indicate in other ways that application could perform those actions, if it had those permissions
  • are prepared for permission revocation at any given time
  • make a clear distinction between permissions vital to your application and optional ones
  • show disclaimers and reasoning behind requests up-front or in context as they are needed

Asking for Runtime Permissions

All features are backported to both Support Library v4 and v13.

1. Opt-in for Runtime Permissions

In order to opt-in for Runtime Permissions, you need to build your application with Target SDK 23 or higher. If youre using Gradle (which you should be doing), make sure its set in build.gradle:

compileSdkVersion 23
targetSdkVersion 23

2. Declare permissions in AndroidManifest

No changes here, declare needed permissions in AndroidManifest.xml as usual:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>



3. Make sure to check if permissions have been granted and ask for them if necessary

System window pops up to get user's approval

public class MainActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, 123);
        } else {
            Log.d("PLAYGROUND", "Permission was already granted");

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 123) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d("PLAYGROUND", "Permission has been just granted");
            } else {
                Log.d("PLAYGROUND", "Permission has been denied or request cancelled");

As you can see, we use few new methods from Runtime Permissions API. Those are fairly straightforward, but there are few things to note:

  • you can request many permissions, passing an array to ActivityCompat#requestPermissions() method
  • you need to make sure the code is prepared for brief interruption introduced by the request, as well as correctly receive result in onRequestPermissionsResult(), the mechanism is the same as onActivityResult() that you should be already familiar with
  • you can check approval/denial on single permission level notice that response contains requested permissions and separate results for them

You are required to check permissions status every time you might need them, dont assume that you got permission once and its available forever.

Additional considerations

I suppose youve noticed that after first denial user is given the option not to bug them anymore with our request. This is virtually our last chance to explain them reasoning behind the request. In order to do that gracefully, API contains method that returns true, if we previously requested particular permission, but user denied the request:

if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
	// the request has been denied previously, show explanation why you need this, then request permission again!
} else {
	// ask without explanations

Please note, this method returns false if user already checked Never ask again checkbox.

Asking second time, user can permanently dismiss this dialog for our app

Theres another feature introduced in SDK 23. You can ask for permissions only if the platform supports runtime permissions, so you can optionally provide new features, but dont request new permissions from users on older platforms upon auto-update of existing installed app. All we need is declaration in Android Manifest:

<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>

This permission would behave as runtime permission and request for it would appear only on Android 6.0 and newer. For users on older platforms, nothing changes.

Few points to keep in mind

  • apps compiled with Target SDK < 23 are treated as usual
  • many basic permissions are granted by default
  • you still need to declare them in the Manifest
  • you must check every time you need them (Activity#onCreate() is sufficient)

Protip: Android Studio parses annotations and warns you if you try to make an API call but dont request needed permissions.

  1. That leads to developers requesting more permissions that they really need, in order to prevent already installed applications from bugging user again when new app features arrive. This is bad practice. ©
  2. This doesnt mean legacy apps are going to crash like crazy after you revoke permissions, throwing Exceptions all over the place. What really happens is, on Android 23+, API calls that had been restricted would return empty data sets or default values, as if there were no data available. ©

Content Freaks & Mob programming adventure

cf-logo-v3In Holidaycheck’s Poznań IT department we work in teams that consist of frontend & backend developers. We pay a lot of attention to knowledge sharing within a team in order to have a common understanding of our architecture and why we’ve chosen one solution over another . For a long time we’ve had well balanced sprints, meaning that we had a few frontend and backend tasks in each sprint. Recently however, due to our business strategy and migration process of our platform, more and more tasks have became frontend focused.

We didn’t want our backend devs to get bored! We wanted to use the potential of the whole team, which meant involving backend devs in frontend tasks. We started looking for solutions that can be helpful in learning new technology stack. One of the things that came to mind was pair programing, which is a great idea for sharing knowledge, but… our scrum master proposed to try MOB programming… We thought: “Why not!? We are an agile team, so why not to try something different and learn !?” 😉

MOB programming in a nutshell, is a scaled up version of Pair programming, with more than two developers. In our case it was four: two frontend and two backend guys. We’ve prepared one of our conference rooms  to be the headquarters of our MOB programming session. We used a big TV as an external monitor – just to feel more comfortable and not to squeeze four people in front of a tiny laptop screen for hours 🙂  Second laptop was used for research, to not disturb the main flow of coding.


We’ve picked one frontend story, which was not very complex, but great for learning the basics. At the beginning of our MOB  session, backend part of our team had a feeling that the story is just a piece of cake … but it wasn’t. Backend guys haven’t had any experience with our current frontend stack and didn’t have a clue about how complex and tricky the story  might be. After we’ve discussed how we would implement the story, we were ready to code! Development process looked a little bit different from pair programming. One of the developers was a “driver”, sat in front of the laptop and owned the keyboard. He was coding what was discussed and agreed on by everyone.   The session revolved around frontend guys suggesting how the story should be done, which was then being discussed by everyone. From time to time, we also had a discussion regarding more general programming ideas like testing approach etc. The MOB session was divided into short iterations  (15-20 min) in which each of us became the driver, which allowed previous driver to focus on research and discussion.

Good parts:

  • sharing knowledge
  • new angle of looking at solutions that we are using on daily basis
  • rise  of team spirit and collaboration
  • backend guys started to like coding on frontend stack

Other observations:

  • the session slowed down the progress of product features in the current sprint, but that was expected and accounted for, as we believe it will enable us to be faster in future
  • frontend guys would love to do a similar session with a backend story 🙂
  • a whole day is too long to develop in that style
  • MOB approach shouldn’t be abused!  🙂

In summary, although we had certain reservations before we started, MOB programming turned out to be a really great experience for us! We think we will be using it   in future, as a mean  of fast learning and knowledge sharing… Maybe frontend guys will learn & love Scala? 🙂   Time will tell… 🙂

Journey to T-Shape team

t-shapeThere is a trend on the IT market to be software developer who has expertise in one specific technology (vertical line in “T”) and knows others at levels that don’t stop him from understanding a full code (horizontal line in “T”). This whole idea seems to help building cross-functional team, one of core thing in Agile world.

Currently the team that I’m working with has decided to try to become T-Shape one. There have been a few discussions how to tackle it, what should be assumptions and how we can manage dependencies. We have used brainstorming session to create a plan that all of us would support. Here is our approach:

  1. Create skill matrix to get knowledge what kind of expertise team has.
  2. Identify skills that should be strengthened.
  3. Verify in which directions team member would like to develop.
  4. Each team member proposes plan of skill’s development with clearly stated goals.
  5. Scrum Master facilitates and challenges progress on skills’ learning plan on monthly basis.

On top of this, the whole team has agreed that during transformation into T-Shape developer we still need to follow principles mentioned as below:

  • Each team member has main focus on core skill/-s.
  • We will plan how to grow individual horizontal skills during sprint planning so we could forecast more accurate sprint deliverable.
  • Each team member is responsible for his/her skill’s development.
  • Each team member seeks actively new ways of skills’ learning.

As you can see the team has decided to move closer to be cross-functional team in structured way, doing it step by step. Such approach gives them a chance to adjust it if needed and to validate their progress (see points 4. & 5.). Additionally it should help minimizing an influence on sprint deliverables. Keep finger crossed!

If you have any experience in creating T-Shape team let me know. I’m curious to find out how you have transitioned to it and I’m open for your advice!


Marathon Maven plugin from HolidayCheck

At HolidayCheck we are using both Docker and Apache Mesos with Mesosphere’s Marathon. Therefore for our development teams creating services using Maven we wanted to set up easy to use configurations bound to standard Maven lifecycle phases.

Starting with Docker Maven plugin

As wiring a Java/Scala project for Docker is possible by multiple existing plugins, we have chosen Spotify’s Docker Maven plugin, as it best suited our needs, was easy to integrate and allowed to use Git commit hashes (aside from standard artifact versions) in Docker image names for uniqueness.

Marathon Maven plugin usage example

You can have a look at the plugin on the GitHub:
or even start using it already in your project:


To interact with Marathon the plugin uses Marathon Java API client. In the processConfig goal the plugin takes marathon.json file currently located by default in root project directory, which might
look like the one here:

  "id": "/my-service-1",
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "",
      "network": "BRIDGE",
      "portMappings": [
        {"containerPort": 7070},
        {"containerPort": 7071}
  "env": {
    "PATH_PREFIX": "/my-service",
    "_JAVA_OPTIONS": "-Xms64m -Xmx128m -XX:MaxPermSize=64m"
  "instances": 1,
  "cpus": 0.5,
  "mem": 256,
  "healthChecks": [
      "protocol": "HTTP",
      "portIndex": 0,
      "path": "/my-service/v1.0/healthcheck",
      "gracePeriodSeconds": 3,
      "intervalSeconds": 10,
      "timeoutSeconds": 10,
      "maxConsecutiveFailures": 5

replaces container/docker/image with the value provided to the plugin and evaluated taking into account all used variables e.g.:
The result is put into project’s target directory by default. Then it’s being picked up by the deploy goal and submitted to Marathon’s API endpoint with some minor handling of a situation whether the app already exists or not in the cluster.

Docker and Marathon plugins join forces

As mentioned earlier the Marathon plugin goes well with the Docker plugin, mostly due to the fact that we might bind those two plugins together and hook them nicely to proper Maven lifecycle phases and (what is very important in our scenario) to use Git commit hash as the Docker image name detected previously by the Docker plugin to be used in Marathon plugin’ configuration:

                <cmd>java -jar /${}.jar</cmd>

Now simply type:

mvn clean deploy

and you should have it deployed and running on your target environment.

Have a good time using Marathon Maven plugin! If you are willing to contribute your pull requests are welcome.