Sunday, 2 December 2018

Ice Breaker: The story of my sprint

Retrospective icebreakers can serve more than one purpose. On one hand you are looking to break down barriers and encourage the team to communicate (which will pay dividends in the retrospective that follows the icebreaker), but you can also use the icebreaker to help people focus on what happened over the last sprint.

With this as my aim, I created an icebreaker that worked out so well, that I thought I had to share it.

The Story of My Sprint

Around a table, get people working in pairs to add a story to a comic strip in order to represent the sprint (or an aspect of the sprint) that they have just completed. 

After this is done, the pairs read out their comic to the group. It is important that all of the pairs are given the same comic strip so that you can appreciate the different stories that the pairings are applying to the same illustrations.

Duration: 5-10mins

Example: Below are the results of this ice-breaker from my scrum team

Instructions : Prep Work

  1. Find a comic strip which has enough panels to fill a single sheet of A4 with enough room in the gutters for dialogue or descriptions to be written. Feel free to choose something obscure so the team writes their own story as opposed to regurgitating a known dialog. (the example I used was from 'One Punch Man').
  2. Edit out any existing text and dialogue. (This allows people to add their own dialogue and framing without being constrained by the 'original' story that the comic strip conveyed)
  3. Print your comic strip onto A4 so that you have enough for every 2 people in the scrum team (print some spare just in case, but keep them out of sight unless they are needed).
  4. Make sure you have plenty of pens!!

Instructions : The Session

  1. Place several copies of the comic strip onto the table, and let the team know what they are looking at. If the comic strip you chose is one that you are familiar with, you get a relatively easy way of introducing it. As usual you want this exercise to appear like a natural thing to do. Don't tell the group what the 'actual story' is; if the original story was about Batman stealing a car, you may get theft as a theme to everyone's stories which would corrupt the sprint stories.
  2. Ask everyone to get into pairs. You know your team best but be aware that the story should be the product of co-operation for each pair.
  3. Ask the pairs to take a comic strip and a couple of pens, and try and write a story based on the sprint that has just been completed. Let them know that they have 5 mins to get their story written down. Feel free to continue your coaching and coaxing through this period; you can tell them it doesn't matter whether the story describes a single event, overall feeling or anything else, as long as it is based on the sprint. Also feel free to be quiet and allow the room to be filled with the noise of the pairs coming up with their stories. Feel free to write one yourself, this might be helpful in the next phase of this icebreaker.
  4. Now that all of the stories have been written, it is time to share them. If your team are a bit reluctant, this is where having your own story comes into play. Set an example and read/narrate your story to the group, if you want your team to express them selves, this is how you set the example. Trace the story panels with your finger as you read it, this will enable the team to follow the story more easily. With the example set, ask the pairings to, in turn, read their stories out loud, with as much gusto as possible.
  5. Congratulate everyone on their stories. 
  6. Declare that there were some interesting things that were covered in the stories and that they might help us focus on what we feel worked well and what we may want to change as we move into the main part of the retrospective.

The End

Hopefully this pre-retrospective icebreaker works as well for you as it did for us. We found it a great way to get everyone communicating and was a fun way to remind ourselves of some of the things that happened in the sprint that may otherwise been forgotten about.

Wednesday, 28 November 2018

Adventures resigning an ipa with xCode 10.1 - aka arm64e causes 'Invalid Swift Support'

Re signing our ipa

I was recently in a position where we needed to re-sign an iOS app. One of my colleagues had already integrated a script into our TFS build process for handling this: However we also wanted to ensure that we will be using the same version of support libraries in our package as we have available when we do the signing, so in the loop we also copy the support files from xCode into our app too.

cp -f "${DEVELOPER_DIR}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/${SWIFT_LIB}" "${APP}/Frameworks/${SWIFT_LIB}"

Impact of xCode 10.1

This had been fine until our most recent submission, where we got the following error uploading through App Store Connect:
We identified one or more issues with a recent delivery for your app, "XXX". Please correct the following issues, then upload again.
Invalid Swift Support - The files libswiftCore.dylib, ..., ..., etc. don’t match /Payload/, ..., ..., etc. Make sure the files are correct, rebuild your app, and resubmit it. Don’t apply post-processing to /Payload/, ..., ..., etc
One of the things that had changed since our last submission was the version of xCode that we were using. A review of the release notes revealed the following; XCode 10.1 now contains support for a preview of the arm64e architecture but carries the following warning:
The App Store and TestFlight don't accept submissions containing arm64e. xCode will remove arm64e content from your app when you distribute from the Organizer window. (42296212)
Because our continuous integration pipeline pulls the support files directly from xCode, we were now unwittingly packaging arm64e as part of the support files which is not supported on submissions to the store. This consequently reports the 'Invalid Swift Support' message.

We can verify the inclusion of arm64e by interrogating the libraries using the lipo command

lipo -info "${DEVELOPER_DIR}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/${SWIFT_LIB}"

more information on lipo can be found here

Removing the unsupported arm64e architecture

Now we know that we are not allowed to upload arm64e support, and that xCode would normally omit this from the release on our behalf, we can simply do the same and strip the unwanted architecture from the libraries that we are using.

To do this, instead of copying the support files out of xCode we could output the support files with the unsupported architecture removed. ie:
lipo "${DEVELOPER_DIR}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/${SWIFT_LIB}" -remove arm64e -output "${TEMP_IPA_BUILT}/SwiftSupport/${SWIFT_LIB}"
lipo "${DEVELOPER_DIR}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/${SWIFT_LIB}" -remove arm64e -output "${APP}/Frameworks/${SWIFT_LIB}"

We are now able to submit our app successfully as before.


When arm64e is supported we can revert back to copying the full support library or we could spin this around and explicitly declare the support we want contained within our swift support libraries.

Most importantly, we can continue signing and submitting our app. Which is nice.

Monday, 26 March 2018

The Continuous Delivery Maturity Matrix

The Continuous Delivery Maturity Matrix is a yardstick which against which you can measure your current processes. Ultimately this equates to how well you are able to deliver your projects.

Why is this a good thing? Well, once something is measurable, it is actionable.

The Matrix is split into rows (Quality Levels) and Columns (Aspects of Delivery). You should be able to give a Quality level for each Aspect based on your current development life-cycle. This can help us to understand where our weak points are, or why we may be unable to deliver consistently.

Image result for continuous delivery maturity
Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation
by Jez Humble and David Farley

The following is an extract from a piece that I wrote in 2012.

Delivery had been a big problem for us, but the matrix helped us to understand how we could make the delivery process more reliable and robust. I took a copy of the matrix and marked where we were against it (see above). Something had to change, and the matrix helped us to identify the adjustments that we we could make and also helped us to use an appropriate language with our line managers. Where we were regressive, we would take action to become repeatable. Where we were repeatable, we would take action to become consistent, etc.

Our improvement would not have happened without measuring against this matrix. It is my belief that after every project delivery we should grade ourselves against this matrix as part of the project review, learn the cause of failure and create actions to address this in subsequent project deliveries.

Please take a moment, have a think about your latest project delivery, grade against the matrix, and have a think of how it could have been less painful.

Remember, when it comes to software delivery: "If it hurts. Do it more frequently".
Understand the pain and address it.

Two books that should be on your book shelf.
Continuous Delivery
Continuous Integration

Sunday, 21 January 2018

Moving Xamarin's Android dependencies off your Primary drive

The other day I wanted to get the latest android SDK, but due to insufficient space on my primary drive this failed.

What follows is the process by which you can get from this situation into one where you can have as many SDKs and Android Virtual Devices as you want (as long as you have somewhere other than your primary drive to park it).

First, make sure you are fixing the right problem.

Just because our drive is too full to accommodate any more SDK artifacts or create a new AVD, that doesn't mean they themselves are to blame. So let's find out before we go any further.

Running a utilities like WinDirStat, TreeSize (etc) will quickly show you what your disk fillers are.
For me the biggest culprits were the android SDK and my AVD's (hence the blog post).

Moving the SDKs

Moving the SDKs is pretty straight forwards, in your IDE you will find the settings for Xamarin, including the location of the Android SDK's.

Visual Studio - Options menu.
  • Go to this location and copy the Android folder (containing the SDKs) to your secondary drive.
  • Update the reference in your IDE.

Once done, you should see that when you open your 'SDK manager'. The being used should now be the new one that you defined in the previous step.

  • Delete the original Android SDK folder from your primary drive, to free up some space.

Moving the AVDs

Let's see if we can make more room by moving those AVD files...

  • Add the following key to your environment variables
  • Assign it a value of where you would like your .android folder to live, eg.

If you want to use your existing devices, copy your existing .android folder from your primary drive to this location.

This variable will kick in after a restart.
You can verify that this change has been applied by Opening your AVD manager from Visual Studio and looking at the address at the top line.

Monday, 28 March 2016

The NDC Experience

Back in January, I was lucky enough to go to NDC in London.

This was a great experience, and one that I would recommend to any of my colleagues. So, to give them an idea of what it was all about, I gave a presentation on it. This presentation, including a Q&A session, lasted for 45mins, and was designed to pass on what I learned from going to NDC. It wasn't recorded, but I'm happy to share the slideshow (link below).

It was also a nice opportunity to use Prezi

Tuesday, 6 October 2015

Send me a picture, so I can remember


Sprint retrospectives are important. This may sound like I'm stating the obvious but please make sure that you have concise retrospectives.

The big benefits of a good retrospective include
  • Getting honest feedback on the progress of your project. 
  • Gauging the teams mental state. 
  • Strengthening relationships between the team members (after all, we are in this together).
If you are organising the retrospective, your biggest job is to help people to give open feedback. You can do this by creating an environment in which they are comfortable and giving them tasks that help elicit the information as opposed to directly asking for feedback on the sprint.

The following exercise describes one of the methods for garnering feedback.

Postcards from the Sprint

  • Before the retrospective
    1. Get (or make*) some postcards. Try to use a wide selection of destinations, 10 postcards of the east coast is not a good selection. 
    2. Get (or make**) some tokens. Make sure that these are easily identifiable (eg. Monopoly pieces).
  • In the Retrospective
    1. Ask all member of the retrospective to choose a token.
    2. Spread out the post cards on a flat surface.
    3. Ask the members of the retrospective to place their token onto the postcard that they 'feel' represents the sprint that we have just completed.
          - Wait for everyone to place their token - 
    4. Choose a token (not a person***) and ask who that token belongs to. Ask that person to describe in what way they feel that that postcard represented the sprint.
    5. Remember to say thank you. 

Why is this a good exercise

  • The postcards act as a starting point, whether that it is an association to the place, geography or a metaphor, the person is grounded by the selected image and merely needs describe a context.
  • Everyone gets to express an uninterrupted opinion and comment on the sprint.
  • The tokens are ambiguous, and therefore the running order is random.
  • Members choices are 'locked in' so there is no playing follow the leader when they are expressing their feeling.

Retrospectives should not feel like a chore and it is not a cull-able step in the process. So keeping people engaged at this stage is important. we've managed it all sprint and by Jove we'll keep them engaged in the retrospectives too!!

* How to make a postcard: Find a royalty free picture, resize it, print it, cut it out, laminate it.
** How to make a token: (see 'How to make a postcard' above).
*** Not a person: We want to disassociate any feeling of singling out, identifying or alienating individuals when eliciting unbiased feedback, hence the tokens.

Saturday, 27 June 2015

When is a valid win32 application, not a valid win32 application

What happened

Recently I've needed to upgrade an application to use 4.0.3 of the .Net Framework. The upshot of this was that the application was no longer XP compatible.

Not a valid win32 application

This was un-expected, there isn't a compatibility issue with XP and this version of the framework. However, upon inspection, the compiler had marked the application as being for Vista OS onwards. Explicitly set this to XP and the application is once more a valid win32 application.


This is how it was done.

  1. We inspected the application.exe header using dumpbin. This is a Visual Studio command line utility.
  2. Here we could see that it was targeting /subsystemversion 6.00 which is Vista, considering the change we made, this is neither desired or required. Ideally we would ask the compiler to mark this correctly for us, but msBuild doesn't expose this switch. So instead we would need to change this post compilation.
  3. So we added a build step to adjust this flag after compilation. For this we used editbin. Another Visual Studio command line utility. To set the

    editbin.exe "$(TargetPath)" /SUBSYSTEM:WINDOWS,5.01 /OSVERSION:5.1

You can use DUMPBIN to examine COFF object files, standard libraries of COFF objects, executable files, and dynamic-link libraries (DLLs). You can start this tool only from the Visual Studio command prompt. You cannot start it from a system command prompt or from File Explorer.

You can use EDITBIN to modify object files, executable files, and dynamic-link libraries (DLL). You can start this tool only from the Visual Studio command prompt. You cannot start it from a system command prompt or from File Explorer.

Specifies the minimum version of the subsystem on which the generated executable file can run, thereby determining the versions of Windows on which the executable file can run.
Specifies the execution environment that's required by the executable image.