We are an extremely productive company which spends most of the time coding. For this reason, in the past few years, we have refined our development methodology, to be able to be efficient and to have fun while doing our job.
We follow an agile approach to organize our work, in order to retain some flexibility and plan according to every week's needs. Conventional planning doesn't match very well with web development, because it's too strict and it assumes that everything is known from the get-go.
Unless our clients tell us otherwise, we use Github to store our code. We recommend working with Git because of its distributed nature, high performance and its massive community.
We usually use Github to log our tasks and keep them organized as well, but we're happy to adapt to each client's preferred communication tools. We have worked with Basecamp, Trello, JIRA, Asana and more.
First, we start with an early high-level definition of the tasks of the project, and we distribute these tasks in different milestones. Our milestones are never longer than 3 or 4 weeks of work. Each of them is a Github Project (a board with different columns) and every task is a Github Issue, with its corresponding labels, a title and a description.
The first milestone starts right after the project kick-off. Every week, we check the first column of the board and we pick the tasks which we believe we can complete before the end of the week. These tasks are moved to the second column of the board, named “Current Week”.
When choosing what to do next, our developers check the “Current Week” column and take the first available tasks at the top of the column. Afterwards, they assign themselves to the tasks and move them to the “In Progress” column. This column allows us to see who is working in each task and what is being developed.
It is worth mentioning, too, that we create a new branch in the Git repository for each one of the tasks that are being developed, in order to keep the code properly organized and avoid conflicts between people working on the same files.
When a task is finished, the developer creates a Pull Request detailing what has been changed and what needs to be known, moves the task to the “Review Pending” column and assigns a code reviewer.
The code reviewer is another developer or a high-level profile in charge of reviewing the code and the functional aspects of the task assigned to him. This methodology allows us to craft better-written code, reduce the number of errors and improve our coding skills. A number of automatic tests and continuous integration systems are run to ensure that nothing breaks the functionality of the application and that the written code follows our style guidelines.
Once the Pull Request is approved by the code reviewer, the developer of the task merges the branch into the source code and deploys the new feature. To complete the development cycle, the task is moved to a column named “Done”.
Of course, the development cycle can get a bit more complex, especially when we deal with production applications that need to track versions, test environments and more complex branching methodologies. However, in general terms, this methodology can be applied to all our projects.
Stages and Environments
From the very early stages of the project, we set up different test servers and even the production environment. This strategy allows us to test the features we are developing very quickly and do small but frequent releases.
Most of the projects start with a Sketch or Illustrator design. Right after that, the design is implemented in static HTML and CSS. We use frameworks like SASS and tools like Middleman to facilitate this process. At this point, we set up what we call a "design server": an environment where we deploy the static but browsable version of the application.
In the design server, the client can see how the application will look like and behave in a real browser. Thanks to this extra stage, we can gather feedback from our clients very early and iterate before implementing the application logic, thus avoiding countless hours undoing work.
After finishing this static implementation, we start with the backend development. This is when we set up another test environment, to showcase the features once they've been implemented. Also, this is when we usually set up the production environment as well.
As you can see, we never wait until the entire platform is finished to start doing manual tests and gathering feedback from our clients. When we finish a new feature, we immediately deploy it to a test server and release it to the production environment, later on.