6

Using continuous integration represents an (almost) mandatory requirement for a software project to be agile. And without CI there can be no continuous delivery/deployment.

But CI can face scalability challenges, see How can continuous integration scale for very large projects/teams?.

Splitting work on multiple smaller pre-integration branches would allow work on those branches to be agile, but then merging of those pre-integration branches needs to be handled. And those would be massive, unpredictable merges, rather difficult to plan and incorporate into an Agile framework. Until the merge is actually performed one can't really tell if it'll take 2 hours, 2 days or 2 entire sprints to complete.

So how can Agile methodologies still be applied to massive, monolithic software projects with 100s/1000s of developers?

  • 1
    This question is mixing two big topics, one is Agile for big teams, another is Ci/CD for many/big projects. It would really benefit if you could split this into two questions at least and not muddle one with the other. "Branches" are not Agile, people and teams and work items is where Agile is scoped. – Evgeny Mar 3 '17 at 16:56
  • But these topics are, IMHO, very much related. Looking them together, as a system (which is the reality, if you think about it) can offer opportunities for optimisations which can't be seen if looking at each of them in isolation. – Dan Cornilescu Mar 3 '17 at 17:15
  • What takes 2 hours/days, deployment, automated testing or manual merging? – kenorb Mar 4 '17 at 11:24
  • @kenorb: the whole thing - I mean you can't really declare the branch merge successful until the SCM merge is done and committed, artifacts are successfully built and tested and deployment actually proves that the whole thing is acceptable (or Done?) – Dan Cornilescu Mar 6 '17 at 17:50
4

Well, you won't be able to apply an Agile methodology to a large team. One of usual principle is to work on Pizza Team (Less than 10 persons which can share a large pizza for diner together) because the lack of formalism advocated by Agile process makes it hardly applicable to a large team, the information would be scattered and some would be lost in the crowd.

So before thinking about the CI system, you'll have to review the organization around the software you build.
This mainly need to refactor a large project in smaller independent pieces, this could be separate softwares (and you'll take the path of microservices) or it could just be an architecture design within the software, where a class/object/library is given to a small team. This team has to document its service input and output (service contract/service orientation).

Once this is done you can split the responsibility of each independent piece to a smaller team which will be able to apply an Agile process.
This may solve the CI/CD problem, splitting the code base would allow each team to follow it's own pace, as long as it's interface is properly versioned and that the input/output are fixed for a type of call you can make parts of the product evolve while some other part keep a previous behavior.

The main drawback is that the service contracts from each part must be compatible between versions in use, which need a dependency system to know which part use which version of what before dropping an unused version of an API. This brings problems to make breaking changes and usually need a careful transverse planning between producer and consumers.

  • For embedded systems with legacy monolithic code microservices are rarely a practical solution. And, in general, microservices add a whole new dimension into the systems' complexity, they're really not as easy as they're often advertised as. But I digress - the question is specifically about monolithic sw ;) – Dan Cornilescu Mar 3 '17 at 14:09
  • Then the second alternative, splitting by "library" (hard to tell without a real insight on what code base we are talking about) could be a way, for large libraries, splitting the responsibility on parts with the fewer possible overlaps (and once done, splitting the library itself whenever possible) could be a way to tackle the problem. – Tensibai Mar 3 '17 at 14:13
  • There are definitely examples of how large teams apply Agile methods. SAFe is an example, so is LeSS. – Evgeny Mar 3 '17 at 17:54
  • Any real world examples of those methods successfully implemented ? I only remember failures getting back to a V cycle or long iteration, kind of hybrid organization at end and not really Agile – Tensibai Mar 3 '17 at 18:02
3

We went from a large, monolithic backend application worked on by 100s of devs into docker based microservices, deployments using ansible and similar DevOps fluff. Here are some notes on the process:

  1. Determine the domain boundaries inside your monolithic app. Make sure calls between boundaries happen as less as possible (by call I mean either in-process calls, or database access).
  2. Split the devs into teams, and assign each of them one slice of the domain. (It is possible that one domain will be worked on multiple teams as well)
  3. Specify cross boundary calls still happen, and define an API around it. Make sure only this intermediate library is used when doing cross domain calls.
  4. Have proper tests around these intermediate libraries, that check that they are working properly.
  5. Split up the code based on these domain.

Now, each of your teams should be both smaller, and work on their piece of code without worrying too much about the others. The tests you put into these intermediate libraries should cover regressions from outside callers, and the internal code is your responsibilty. Obviously if the intermediate libraries needs changes, or if your tests tell you that you are not adhering to the API specifications anymore (which can, and will happen occasionally), then you need to start talking to the other team(s) using these APIs.

Once you are happy you can try to replace these intermediate libraries to be HTTP API calls instead of in-process calls. Once this is done, you can actually split up your large app into real, smaller pieces (they will probably still not be "micro" services, but much-much smaller and more manageable). Also they will at least belong to one specific domain, and also have a clear, well defined API that others (including new microservices mostly free of your legacy big app) can use to obtain their data.

2

Yes, splitting the bigger team into smaller, agile-size sub-teams is obviously necessary. But it's far from sufficient to also be performant overall, at the bigger team level.

With a highly scalable CI system in place it is possible even for very large teams to use trunk-based integration, in a single master branch, thus completely avoiding the intermediate integration branches and the unknowns/risks/delays/costs associated with their merges which would otherwise represent serious obstacles impacting the sub-teams. See How can continuous integration scale for very large projects/teams?

With these obstacles out of the way the sub-teams can really make the best out of the agile techniques as they're automatically all on the same page and benefit from all advantages of the CI methodology.

Such approach works equally well:

  • for monolithic codebases/producs which can't/won't be split into micro-services for whatever reason
  • for codebases/producs split into micro-services, even if for reasons other than independent deployment capabilities - which don't want to deal with inter-service dependency management and prefer to stick to monolithic deployments (they still share the same development branch)

Note: the actual SCM repository is irrelevant, it can be any combination of repos managed together as a single one, the term branch denotes just the common logical representation of whatever physical/actual repo branches exist in that combination.

1

I've been working on couple of Agile projects with over 100 developers without any problems, so from my personal experience, to deal with such big workflow, here are some suggestions:

  • Team definitely should to be split (max. ~12 people each).

    Make sure you've the right people with the right skills in each team, so they're independent (cross-functional teams). DevOps doesn't have to be part of development teams.

  • Each team should work on their own components/modules, so their work won't conflict with other teams.

  • Once feature/component or bug is completed and tested in separate branch, developer should be responsible for sending and maintaining a valid mergeable Pull Request to be approved by other team members.
  • Often commits and pulling from master branch will avoid any surprises about code conflicts.
  • Each Pull Request should be automatically tested in CI and once approved, should be merged (either development or master branch).
  • Deployment to development branch should be done on each Pull Request being merged and tested on development environment by automated tests and manually, so only stable code can progress upstream.

To summarize, the main point in order to avoid spending too much time on merging complex branches, introduce Pull Request, so each requester is responsible for mergeability of his own code and other developers are responsible for reviewing the change, so no any unpredictable branches or conflicts are possible in this case.

So yes, Agile methodologies can scale for massive scale projects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.