Our software development process – step by step
This is a description of our approach to software development. If you don’t feel like getting into too much details, see the TL; DR (Too Long; Didn’t Read) version just below.
1. You provide us with the requirements.
2. We clear out all the doubts (cooperating with you via Redmine / phone / Skype / Hangout / chat software). If you need an estimate, you get it.
3. We do the coding (plus, optionally, automated test code coverage + code reviews). Additionally, the code is always statically analysed to ensure code quality and to detect specific types of bugs.
4. We let you verify/test/sign off the new functionality on a freshly-built virtual server (e.g. http://feature-2854.testing.clientname.com).
5. After the sign off, we release the tested code to production.
6. We monitor the infrastructure and application (and give you access to all the logs, so you have all the data to see how your application is performing, how stable it is etc.)
The following documentation is targeted mainly for technical project managers or technology officers.
Our development processes are focused around our Bugtracking / Planning software, we use Redmine for that purpose. It’s a great, fully configurable and customizable tool with a lot of great add-ons that enabled us to fine tune our process along the years we’ve been using it. Inside we usually work with a scrum-ban hybrid approach to project management.
The ticket flow usually starts with a ticket (feature request, bug, etc) reported by the Client. When a ticket is created the Client has to decide if they need an estimate for the job, if they feel they need test coverage, select a deadline and priority. The reported ticket is normally placed on a separate Triage list, where it is reviewed by our Project Manager, who may need to discuss some details with the Client before moving the ticket to the development team’s kanban board (coding phase – described below).
Redmine is also a place to browse through code commits, store project regardless of the billing method (fixed price / time and material), we need this information internally, for process optimization and we give our Clients access to that data on-line. We want our clients to trust us and we believe in being transparent. The timelogs are later used for invoicing in Time & Material projects and simply for our business-analysis in fixed-price ones.
We try to make the feedback loop with our clients as short as possible. We will keep you involved and we will invite you to our chat (Slack equivalent) to work as closely as possible. We integrate our chat rooms with all other tools – bug tracker, deployment, error log, etc to stay informed about events in our projects.
OK, so that’s where things get serious and where we feel the strongest. We want our code to be state-of-the-art, readable and performing well – as close to perfection as possible.
We obviously use Git as a version control system. Depending on the project’s specifics and/or client’s expectations, we use either git-flow or Github flow approaches.
Depending on the project’s needs, in this phase we can cover the developed code with unit / functional / acceptance tests. We will help you decide which parts of the code will really benefit from it.
As a rule in each of our projects we do automated, static code analysis that as a pre-commit hook, so that a developer can’t even add his code to repository if automatic checks reveal that it’s in some way suboptimal (e.g. it contains code smells, doesn’t adhere to coding standards or simply breaks during interpretation/compilation).
We love new technology. It’s fun to explore, it’s sexy, and often easy to learn. But we also have to advocate boring old stuff – it’s production ready, it’s field-tested, it has support and extensive documentation. We usually try to keep a sane mixture of these, to keep everyone happy. Our development stack currently consists of (selected technologies from most current projects):
- Symfony2 PHP framework
- HTML5 + CSS3 + Grunt
- MySQL or PostgreSQL
- Ionic Framework / ReactJS / Meteor
- Android SDK
- Spring Framework
- Asterisk VoIP
Depending on the deal with you, we can allocate our testers to do manual user acceptance tests (UAT) based on predefined test suites. We use both real device sets (iPads, iPhones, Samsung Galaxies, Samsung Galaxy Tabs) and http://browserstack.com when needed.
If you feel like it, we can use TDD approach while developing software for you, or at least cover the most critical functionalities with functional/acceptance tests. Depending on technology and test types, we’re using various solutions to cover your application with automated tests (PHPUnit, JUnit, Behat, Mink, Jasmine, Selenium etc.).
We use Jenkins as our CI (and CD) server, no surprises here. We deploy using a fully automated build to all stages with a single click. It’s faster, less error-prone and we can easily monitor the build times.
The most interesting aspect, and we owe it to other parts of our infrastructure, are our feature- -deployments. We can deploy individual branches, tags or commits (anything passing as a GIT refspec, really) in separate environments all accessible from the Internet, so you can test it. No more tideous merging and operations effort just to push a set of tickets to sign-off. The times, when a simple feature had to wait ages to land on productions, because it got mixed-up in a sprint with some more complex ones are bygone. Continuous-delivery at its finest.
Realtime web application issues monitoring
We develop and run our apps in production in our own Data Center. We strongly believe in fully owning all the technology that is core to our bussiness. We couldn’t survive a day without our own devel opment servers, git repos, etc. While it might not always be as cost-effective as buying, we also develop tremendous sysadmin skills that give us an advantage over code-only shops – we don’t just build apps, we build them to last and withstand. We know load-balancers, high-availability, SQL replication and sharding and all the cool enterprise stuff other companies never heard of. TCP three-way handshake and TCP slow start have their effect too and you really should know that.
We have a fully reduntant (currently Tier-3 equivalent, Tier-4 investment in progress). We also operate a fail-over scenario with a partner Data Center in a remote location to provide High Availability for mission-critical applications. We encrypt our BGP sessions too.
We operate a small private OpenStack cloud and we think it’s cool.
We currently use The Foreman for bare-metal provisioning (we migrated from Cobbler), we leave everything after OS deployment to Ansible.
We use Ansible to keep the configuration of our servers, both bare-metal and virtual (application configuration). Starting at network device configuration ending with PHP package installation – its simplicity, ease of use and versioning allow us to quickly provision servers for scalability and exercise Disaster Recovery scenarios.
We run daily incremental, weekly and monthly full backups and store them on tape in a safe location, 10km away from our DC.
We’ve been an early adopter of Docker, which has meanwhile crossed the chasm and we’re happy to have it in our toolbox. It makes our operations a whole lot easier, finally development, staging and production enviroments can all be identical! Docker also helps us quickly deploy ephemeral application instances for QA, UAT, etc.
At the application level we mainly use nginx for load balancing, as well as our main HTTP (and HTTP/2, as of recently) server. We’ve also had experience with other tools (HAProxy).
Aside from traditional Nagios-based monitoring we use Ganglia and InfluxDB + Grafana to visualize the current state of our cluster.