Hello Timblian

There is work and there's your life's work.

The kind of work that has your fingertips all over it, the kind of work you'd never compromise on. That you sacrifice a weekend for. You can do that kind of work at Timble. People don't join us to play it safe. They come here to swim with sharks.

We want your work to add up to something. Something big, something that couldn't happen anywhere else.

Before you continue, read our Company Manifesto.

Welcome to Timble.

You work at Timble, this is your playbook. It details how you and your teammates run our software development company and how we make open things for the web. It is a living document that you can edit in a GitHub repo.

It's filled with things we've learned based on our own experience and study of others' experiences and inspired from thoughbot's Playbook.



Our process is based on the Agile method, working in short development cycles. This keeps expectations clear and provides an acute focus on the task at hand.

= import('/partials/consulting/development-life-cycle') ?>

Each development cycle begins with planning, based on an evaluation of previous, defined objectives. When the development is completed, your team can test before starting a new cycle.

Gitlab Flow for Product Development

All product (DOCman, FILEman, etc) related development follows the Gitlab flow model

The article linked above explains the process in great detail but we will summarize the important points here.


  • Master branch is where the code resides waiting for the next release. Feature branches are created from and merged into this branch.

  • Version branches are created after a minor version is released and used for maintenance releases. It will be explained further below with an example.

  • Feature branches are where you make the magic happen. They are created for any ticket, no matter how small or big it is. Your code should go into a feature branch, be reviewed there, and then merged into the master branch. The naming convention is feature/TICKETID-branchname e.g. feature/42-dontpanic. Feature branches are branched from and merged into master branch.

At first, this might feel very abstract so let us explain the branches with an example:

Suppose that in our project 1.1.0 was released last week. We are going to do maintenance releases such as 1.1.1 and 1.1.2 in the future. And work for 2.0.0 is underway already.

Right now, master branch is used for 2.0.0 development. Work for 1.1.1 is going to be done in the version branch called 1.1.

The important parts:

  • If you are going to do a bug fix for the next maintenance release 1.1.1 you need to branch out from 1.1 branch and merge it back there.
  • If you are going to do a new feature for 2.0.0 you need to branch out from master and merge it back there.

Also make sure that all dependencies for your project are set to the same branch. For example if you are working on DOCman 2.1; Joomlatools Framework, and Joomlatools Framework Files will all need to be set to the 2.1 branch.

GitHub Flow for Continuous Integration

Continuous integrated projects (support.joomlatools.com) follow the GitHub Flow strategy.

GitHub Flow is a lightweight, branch-based workflow that supports teams and projects where deployments are made regularly.


  1. Create an issue
  2. Create a feature branch feature/123-foobar from master
  3. Commit against the issue for reference
  4. Merge to staging for testing
  5. Open a Pull Request to master when your work is ready
  6. Discuss and review your code with the team
  7. Close the Pull Request when work is reviewed
  8. Enjoy the smell of newly deployed code

In summary: whenever you move an issue's status to Review, you create a Pull Request. Merging the Pull Request closes the issue.

Be sure to read:

Tools & Services

Google Apps

Google Drive

Google Drive has a few pre-shared folders for easy organization and sharing of documents.

For example, when drafting a Joomlatools related blog post you simply need to add it to Team > Blogs > Joomlatools.

Google Groups

  • used for push communications
  • the tool to address 3 or more people
  • used for discussions that involve multiple people
  • used for company announcements

We have a few internal mailing lists:

  • group-team@timble.net (Team related communication)
  • group-joomlatools@timble.net (Joomlatools related communication)


If you have an @timble.net email address, you can create an account. Slack offers Desktop and Mobile Apps for every possible platform.

  • shows online presence which promotes collaboration and team spirit
  • while working on tasks, people should be online
  • used for one on one meetings and discussions
  • a tool for adhoc direct communication


Get notified only if someone wants your attention.

We use Slack to talk about everything, which means you can get a lot of notifications out of the box. Switch notifications to “only for Highlight Words and direct messages” to avoid distractions to your work flow.

Only notify people who are online

When you send a message with @channel, @group, or @everyone, notifications are dispatched far and wide. Desktops make that satisfying pop-pop sound, phones buzz in pockets, and another scrap is tossed onto everyone’s email mountain.

In 99% of the times you just want to get the attention of whoever is using Slack right now without plastering your message on every internet-capable device that we collectively own. And for that, you can use @here to message them and avoid nudging everyone else.

Keep in mind that whoever is online will still receive a notification, use sparingly!


All our code is located in GitHub across multiple organizations:

Two-factor authentication

You must have enabled two-factor authentication before you can accept our invitation to join any of our organizations.


Since GitHub doesn't have a Kanban board integrated we use ZenHub. ZenHub is simply installed as a Chrome-based plugin and available from within the GitHub interface.


Since GitHub doens't have the ability to track time we use Everhour. You can access Everhour using your company's Google Apps account. Two options to log time:

  1. Use the Everhour web interface, check the introduction video
  2. Install the Chrome Extension
    • Does not work when you are viewing the ticket using the ZenHub interface
    • Sometimes you'll need to reload the page before the Issue is properly linked to Everhour


1Password Teams gives you access to our internal resources. New team members need to be confirmed before they can access shared vaults. Ask for your invite in our Slack #onboarding channel if you haven't received one.

You get instant access with extensions for Chrome, Firefox and Internet Explorer, or with apps on iOS and Android.


Looking for a beautiful, efficient, and powerful Git app? Most Timblians use Tower.


It's no secret we are a Chrome fan but please use whatever makes you most productive.

Browser testing

In 1Password you have access to BrowserStack for browser testing your work.

Google Analytics Opt-Out

We have a few pages on our websites that generate low traffic so visiting it ourselves screw up our Google Analytics reports.

We suggest to install the Google Analytics Opt-Out plugin in your browser.

uBlock Origin

uBlock Origin: a fast, lightweight, and lean blocker for Chrome and Firefox. Completely free and open source.


Keybase makes it easier to create and manage a public key you can use to securely communicate with one another. We use it to pass sensitive information (passwords, API keys, ..) between both the team internally and external clients. All team members have a profile on Keybase. It is currently invite-only but most Timblians will have an invite for you. Don't worry if you're new to PGP encryption, the keybase tool and website will guide you through the process.

More info and examples at keybase.io.

Terminal (Oh-My-Zsh)

We are a big fan of Oh My Zsh, an open source, community-driven framework for managing ZSH configuration. It comes bundled with a ton of helpful functions, helpers, plugins, themes and a few things that make you shout.

We even have our own theme, ask Ercan or Tom for a copy.


Vagrant & VirtualBox

All our development is done in lightweight, reproducible, and portable development environments using Vagrant. Vagrant comes with support out of the box for VirtualBox, a free, cross-platform consumer virtualization product.

Make sure you have both installed on your system.

Using Git

We always use source code control. It's like a time machine. We can work in parallel universes of our source code, experimenting without fear of losing work. Roll back if something goes wrong.

Git is an open source source code control system written by Linus Torvalds. It's fast and great for working in branches.

We use GitHub for hosting our git repositories.

Your identity

Git depends on your name and email address to identify you. This information must be configured correctly once you start pushing commits to our repositories. Make sure your email address is the same as your GitHub account, so that commits can be linked to the correct user.

The Getting Started - First-Time Git Setup is a great guide to get started.

Global gitignore

Before you start, it's best to create a global .gitignore file that spans all your repositories system-wide. This global .gitignore file should ignore all IDE files (like .idea/ or .project/ directories) and system-specific files (like .DS_STORE). This way we can limit the size of the .gitignore file in the repository if everyone configures it locally, based on their system and tools.

Read more on GitHub about ignoring files. They also provides a collection of useful .gitignore templates.

Commit messages

To make it easy to navigate through a repository's history and automate changelog generation, we follow these conventions:

#ID: Commit message subject (max 70 chars)
- Change 1
- Change 2
BREAKING! Information about the breaking change and the fixes
that are required in the implementing code.

Commit messages should be written in the present tense, like:

  • Remove instead of Removed
  • Add instead of Added

The BREAKING line is optional. If the issue contains breaking changes this should be indicated in the issue description.

To see an example, take a look at this commit.

More background and tips on writing good commit messages:


Git knows two kinds of merging:

  • fast-forward merge
  • true merge

A fast-merge will just change the branch pointer instead of adding a merge commit. This means that this merge doesn't show up in the history. This is great for moving fast in your branches, but we clearly want to see when merges have happened on the master branch.

It makes debugging and collaborating in general a bit easier if we can figure out when a feature or hotfix branch was merged back. Any other merge isn't important (for example, pulling in the latest changes in a branch shouldn't add a commit).

This makes it your responsibility to keep track of adding a proper commit point. If you merge feature or hotfix back into master, you should create a commit by calling git merge with the --no-ff flag. If you are using the git flow tools (see below), this will be taken care of automatically for you.

Git Clients

Most of us use Tower. PHPStorm also has a very decent Git integration.


We prefix tags with 'v' and following semantic versioning. Example: v1.2.0.

For more info behind this reasoning, see the following discussions:

Semantic Versioning is about the numbering, not about how you tag your codebases. The v prefix is being used to keep your tools working nicely, eg git auto-completion will make searching for a tag much easier if you prefix it with a v. Overall, it would seem the consensus is to add the v prefix.


Almost all applications are built around our Joomlatools Framework and reusable components and extensions. It makes no sense to copy all that code into each application's repository: it would be a nightmare to maintain and synchronise changes.

We solve this using Git Submodules. They allow us to include other repositories into the main one. This ensures that the repository always works, points to the right version for each dependency and can be deployed easily. It also makes it possible to make changes to or pull in updates from the dependency repository.

It's also very easy to set up. We've published a post on our Developer blog to explain the why and how of this approach.

Useful resources


All our repositories need to have a CHANGELOG.md file which contains a curated, chronologically ordered list of notable changes for each version.

We follow the Keep a CHANGELOG convention.



  • Rule: "Everything is an issue!"
  • Task: All your work is being tracked through an issue, if it's not in a ticket you are not being paid.
  • Time: All your time is tracked against the tickets you work on.

For tasks without an issue like meetings, you can log time directly. In the related space or the overall Timble - Team space.


  • If an issue description is changed and this change is important for the developer working on it, he should be informed about the change using a comment.
  • An issue description should always reflect the latest state of the ticket, lets not leave ticket descriptions to an older state, if discussions have happened on them.
  • If a ticket description changes often during the lifetime of a ticket changes should be reflected using dates. Example: "30-12-2015: After discussion on Slack we decided that ...".
  • If the issue contains one or more breaking changes, they should be listed in the issue description and a breaking label should be added to the ticket.

Kanban workflow

  • Milestone iterations are done 3-4 weeks
  • Pair programming with distributed developers
  • There are at least 2 people working on a project
  • You create a ticket - work on the ticket - test ticket and manage it’s different phases
  • At least one other team member should have tested your branch before its being deployed

Kanban columns

New to Accepted
Create the branch feataure/#id-alias (alias should be lower case)
Accepted to Test
Deploy to staging environment for testing
Test to Review
Assign to another developer for reviewing and testing
Review to Ready
Merge to master branch
Ready to Closed
Deploy to live environment or create package. When deploying: make sure to be available during the next hours and the day after in case of unforeseen problems. We never deploy on a friday.


  • Highest: A high prio bug. Drop whatever you are working on and handle this first. Release needs to go out at lightning speed.
  • High: Tickets that need to be handled more urgently, typically within the next few days and released in this milestone. In most cases these are bugs.
  • Normal: This is the default priority for feature tickets being worked on for the current milestone. Ideally, all 'High' tickets should be finished before starting with these.
  • Low: This is for tickets that will be worked on some time in the future and with minimal priority, depending on the release cycle.
  • Lowest: We reserve this for really small stuff that we don't need to see on the board all the time and yet we have to keep an eye on. This includes things like a bug that has been reported once and never replicated in development or non blocking refactoring work that can be spread over multiple different releases.

Document your knowledge

All too often in 'real' offices, knowledge is shared by leaning over and telling someone.

Being part of a fully remote team means you have to document everything by writing it down. Knowledge needs to be accessible by everyone, at all times.

Each repository need have a README on how to get started. Detailed information should be added to the Wiki of the repository.

Joomlatools development


All the development is done using our Vagrant box.

The README will help explain what it is and how you install it. Once the installation is complete, you can SSH into the box as explained in the README by using the command:

vagrant ssh

With the Vagrant box, you have the full power of Linux regardless of your operating system and we all work on the same exact system minimizing the "it works on my machine" problems.

Note that, the box is a completely separate environment than your operating system. By default, you do not need to do any special setup, but keep in mind that the commands you run, the config files you change on your main operating system are NOT carried into the box.

Joomla Console

Our Vagrant box comes with our Joomla console installed by default. Please read the instructions on the above page as it explains how the tool works and what it helps you do.

You will use this tool daily, so we suggest you spend some time acquainting yourself with it.

A key concept to understand here is the symlinks. Once you have set up the Vagrant box, you will notice that two folders were created named Projects and www in the box folder.

  • Projects: will contain our projects like DOCman, FILEman, etc.
  • www: will contain Joomla websites that you do the development on. These sites are automatically created (and deleted) by the joomla command.

The projects are symlinked into the websites in the www folder automatically with the joomla command. Project files only exist in one location.

This way, you can open the Projects directory with PHPStorm and edit every project file from there without worrying about copying them into websites.

Setup script

To set up your Joomlatools development environment use the setup script.

The script will:

  • clone all Joomlatools projects from GitHub
  • create a Joomla site with all our extensions installed using symlinks

Log into the Vagrant box using SSH:

vagrant ssh

Run the setup script:

curl -s https://raw.githubusercontent.com/joomlatools/gists/master/setup.sh | bash

Open http://joomla.box/joomlatools and check that everything is up and running. You can open the Projects folder with PHPStorm.

Version Control

Before you start writing code, an important point is understanding the version control strategy for product development. See the Gitlab flow methodology information.

Task runner for assets, packaging etc.

We compile CSS from SASS, and also postprocess our JavaScript to compile and minify it. We use Mason, an in-house task runner, for this purpose (and some others like creating installable Joomla packages)

Installation instructions and a small tour of the product can be found in the repository README file.

Each repo has a mason.js and mason.yaml files for this. Your number one tool should be running mason inspect on a repository root as it lists all tasks for the repo and the config options it accepts.

A few common ones:

mason # run default tasks
mason inspect # show supported tasks and config options
mason --help # show help on mason usage
mason css # compile css (if repo supports it)
mason js # compile js (if repo supports it)
mason watch # watch for changes and re-compile on change
mason build # build installable package
mason bundle # build installable package with framework included, might need --config.githubToken="" passed

Extension releases

Follow the release checklist.

Support workflow

Follow the support guide.

Creating repositories

Naming conventions

Repository names format: organization-product-subproduct. For commercial extension repositories we skip the organization prefix.

A few examples:

  • joomlatools-framework: repository for the framework.
  • joomlatools-framework-files: repository for the files component of the framework.
  • docman: repository for DOCman.
  • docman-notify: repository for the notify plugin for DOCman.


You should add a description that explains why the repository exists and what it contains. If possible, a link that gives more information about the repository should be added.


Add the correct license file to the repo. In most cases, this will be either GPLv3 or MPLv2. If you are not sure which one you should use, just ask.


Each repository needs to have a README file. It should contain at least a short description and installation instructions. You can take a look at existing repositories for inspiration.

Start by copying the appropriate README template into the repository:


Github can fill the description field of new issues based on a template. We use this feature to make sure issues contain relevant information.

Start by creating .github/issue_template.md using the contents of the following Wiki page: * ISSUE_TEMPLATE template for repositories

You can remove the sections that are not applicable to the current repository.


After creating the repository please create these two milestones:

  • Backlog
  • 1.0

Issue labels

We have a script to set up and sync labels for our repositories. Detailed instructions on how you need to use it is included in the Label sync repository.

After you run the script labels will be created automatically.

Zenhub board

Go to the Boards section in the new repo, remove any existing columns, and add these:

  • New
  • Accepted
  • Review
  • Test
  • Ready

We use Zenhub for our Kanban workflow.

Writing blog posts

Blogs are created through collaborative work on a draft or idea. We use HackMD to collaborate on blog posts. You should create an account on HackMD to share drafts. Here is the workflow:

  • Create a ticket in the relevant repository. This could either be Joomlatools or Timble repositories.
  • Add blog label, set milestone to Current, and assign the ticket to yourself.
  • Create a draft in HackMD and add the link for the draft to the ticket description.
  • Set ticket to review and ask for feedback from fellow developers.
  • After the review is complete move the blog post into a feature branch. You can start from the Blog Template in the wiki.
  • Merge the feature branch into staging locally and push staging. This will trigger a rebuild of the site so in a few minutes you will have a live link to the post on the staging domain.
  • Create a pull request for the feature branch, add the staging link to the description, and assign it to an administrator for merging.

Cover image

The cover image of the blog post should have a ratio of 2:1. Minimum size is 1400x700 pixels so the image will look pixel-perfect on retina devices. Don't worry, the image is responsive to prevent wasting bandwidth.

The cover image is also being used for Twitter Cards (summary card with large image) when sharing.

Zoommy helps you find awesome free stock photos for your creative product or inspiration. More than 50 000 photos licensed under Creative Commons Zero & Public Domain from 50 sources. You can also use Unsplash if you are not able to install the app.




Getting paid is easy. Just send a monthly invoice to invoice@timble.net.

We hate administrative tasks as much as you. Therefor it is highly appreciated if you create your invoice before writing code in a new month.


If you are outside of Europe we use TransferWise to pay your invoice. We only ask you to mention it on your invoice together with the currency of your bank account.

Advantage of TransferWise is that you receive the payment in your currency, from a local bank account. Banks charge hidden fees when sending and receiving money abroad. With TransferWise you save up to 90%. Problem solved, money saved.

Interesting reads