Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sharing code among multiple projects: the case ...

Sharing code among multiple projects: the case of private libraries

As tech companies grow, they often find the need to develop multiple projects or applications in order to better address their challenges. Along with its main app, Deezer has also released Deezer for Creators, Audiobooks by Deezer, Android-TV apps, and (soon) a public SDK. Many other businesses have expanded as well - you can think of Uber with Uber Eats or BlaBlaCar with BlaBlaCar Daily for instance.

These applications share a lot of common code, from authentication to playback engine, to Design System. Is there a way to factorise it?

At Deezer, we chose to publish our code in libraries, which led us to reflect on:
- the content of these libraries,
- the extraction of features and components into a library,
- the organisation of the libraries (e.g. single or multiple libraries, library modules),
- the versioning and the handling of repositories (monorepo vs multiple repos),
- the release of libraries and their integration into projects.

Our return on experience will help you discover possible solutions, better understand the pitfalls to avoid (as we fell into some of them), and see how private libraries could benefit your own organisation.

Jean-Baptiste VINCEY

April 25, 2022
Tweet

More Decks by Jean-Baptiste VINCEY

Other Decks in Technology

Transcript

  1. • Be easy to integrate • Induce no integration delay

    • Allow frequent change / API change • Be appropriate for apps with various pace Shared code should:
  2. 2017 Android TV developed with common modules 2018 Android TV

    paused 2019 Mobile app goes on with API changes on common modules 2020 Android TV update required 2 months just to compile again
  3. Source code Compiled artifact Easy to integrate ++ - No

    integration delay ++ - Frequent change / API change ++ + Appropriate for apps with di ff . timelines --- +++
  4. • Only share what is common • Keep client speci

    fi cities on client side • No over con fi guration • Extend features with speci fi c behaviours on client side • Be generic enough (but not too much) Any type, but should comply with criteria: What sort of content?
  5. ?

  6. • [major] major change (min Android SDK etc.) • [minor]

    default new version • [patch] urgent bug fi x • Unique version for all libs → all libs are released together → one lib can only depend on the same version of an other lib [major].[minor].[patch] Versioning
  7. Publishing Script steps: Script 1: resolve version 2: publishes Core

    3: publishes Design System 4: publish Features
  8. • Be easy to integrate • Induce no integration delay

    • Allow frequent change / API change • Be appropriate for apps with various pace Shared code should:
  9. Git flow Deezer app Deezer libs develop libs-snapshot master stable-2.2

    stable-2.3 2 weeks master = future 2.3 master = future 2.4 Use libs snapshot (master = future 2.3) Use libs snapshot (master = future 2.4) Use libs stable-2.2 Use libs stable-2.3
  10. Publishing to maven local To work with local lib changes

    on client projects Script 1: resolve version 2: publish Core 3: publish Design System 4: publish Features
  11. Publishing to maven local To work with local lib changes

    on client projects Suffix on every libs package name: _local Example: com.deezer.designsystem_local → prevents clash with Nexus → enforces usage of local version
  12. androidLibsVersion = "2.3.+" androidLibsGroupSuffix = project.hasProperty("useAndroidLibsLocal") && useAndroidLibsLocal == ''true''

    ? ''_local'' : '''' designsystemGroup = ''com.deezer.designsystem'' + androidLibsGroupSuffix libraries = [ design_buttons: "${designsystemGroup}:buttons:${androidLibsVersion}" ] build.gradle
  13. Script 1. Add new icon on Design System locally (based

    on branch master) 2. Publish libs locally
  14. 1. Add new icon on Design System locally (based on

    branch master) 2. Publish libs locally 3. Switch to use local libs project.ext.set("useAndroidLibsLocal", "true") local_overrides.gradle
  15. 1. Add new icon on Design System locally (based on

    branch master) 2. Publish libs locally 3. Switch to use local libs 4. Develop feature on app locally (based on branch libs-snapshot)
  16. 1. Add new icon on Design System locally (based on

    branch master) 2. Publish libs locally 3. Switch to use local libs 4. Develop feature on app locally (based on branch libs-snapshot) 5. Create Pull Request on Design System
  17. 1. Add new icon on Design System locally (based on

    branch master) 2. Publish libs locally 3. Switch to use local libs 4. Develop feature on app locally (based on branch libs-snapshot) 5. Create Pull Request on Design System 6. Create Pull Request on app for feature, including the link to the PR on Design System

  18. Script 1. Add new icon on Design System locally (based

    on branch master) 2. Publish libs locally 3. Switch to use local libs 4. Develop feature on app locally (based on branch libs-snapshot) 5. Create Pull Request on Design System 6. Create Pull Request on app for feature, including the link to the PR on Design System
 7. Once validated, merge Pull Request on Design System and publish snapshot of the libs
  19. 1. Add new icon on Design System locally (based on

    branch master) 2. Publish libs locally 3. Switch to use local libs 4. Develop feature on app locally (based on branch libs-snapshot) 5. Create Pull Request on Design System 6. Create Pull Request on app for feature, including the link to the PR on Design System
 7. Once validated, merge Pull Request on Design System and publish snapshot of the libs 8. Once validate, merge Pull Request on app side
 

  20. • Min Android SDK
 • Metadata (e.g. *.kotlin_module fi les)


    • R8 consumer rules
 • Resource visibility
 • Kotlin explicit API mode Library development considerations
  21. • Libraries as modules • Source code: easier to integrate

    • Compiled: supports versioning, better for projects with various timelines • The organisation of libraries is key to foster reusability • Distribution enables easy integration on client projects • Git fl ow and local publication can help reduce the integration delay • Sample apps and documentation are essential to ease libraries usage Takeaways