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

Monorepo w Allegro

Monorepo w Allegro

Prezentacja opowie o ewolucji projektu Allegro na platformę iOS. Historia zaczyna się ponad 6 lat temu od małego projektu w jednym repozytorium. Z czasem aplikacja rozrosła się i projekt rozbito na wiele repozytoriów. Dzisiaj, przy jeszcze większej skali, ponownie używamy jednego repozytorium. Podczas prezentacji poznacie strukturę projektu aplikacji Allegro, proces jej budowania i testowania. Dowiecie się o plusach i minusach stosowanych rozwiązań oraz naszych planach na przyszłość.

Aleksander Grzyb

September 24, 2018
Tweet

More Decks by Aleksander Grzyb

Other Decks in Programming

Transcript

  1. Monorepo w Allegro
    Allegro Tech Talks #12, Poznań
    Aleksander Grzyb, iOS Developer

    View Slide

  2. 2

    View Slide

  3. 3

    View Slide

  4. 4
    Poznań
    8 osób

    View Slide

  5. 5
    Poznań
    8 osób
    Wrocław
    5 osób

    View Slide

  6. 6
    Poznań
    8 osób
    Wrocław
    5 osób
    Warszawa
    9 osób

    View Slide

  7. 7
    github.com/AlDanial/cloc
    --------------------------------------------------------------------------------
    Language             Files        Lines        Blank      Comment         Code
    --------------------------------------------------------------------------------
    Objective-C           3939       397898        81232        31898       284768
    C/C++ Header          3813       232674        39049        43800       149825
    JSON                   838       137764          770            0       136994
    Swift                 2538       178624        33677        15496       129451
    Markdown               104        13464         3899            0         9565
    Bourne Shell            48         3633          453          302         2878
    Plain Text              14         1123          192            0          931
    PHP                      1          849          182            6          661
    Ruby                     5          608           74           15          519
    Python                   6          440          101           27          312
    CSS                      1          425           85          161          179
    Awk                      1           60            4           13           43
    YAML                     1           29            5            0           24
    HTML                     2           23            3            0           20
    --------------------------------------------------------------------------------
    Total                11311       967614       159726        91718       716170
    --------------------------------------------------------------------------------
    --------------------------------------------------------------------------------
    Language             Files        Lines        Blank      Comment         Code
    --------------------------------------------------------------------------------
    Objective-C           3939       397898        81232        31898       284768
    C/C++ Header          3813       232674        39049        43800       149825
    Swift                 2538       178624        33677        15496       129451

    View Slide

  8. 8
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  9. 9
    Separacja i reużywalność

    Produktywność
    Odpowiedzialność


    View Slide

  10. 10
    Produktywność

    Separacja i reużywalność

    Odpowiedzialność

    View Slide

  11. 11
    Odpowiedzialność

    Separacja i reużywalność
    Produktywność


    View Slide

  12. 12
    Stopień realizacji
    Czas

    View Slide

  13. 13
    //
    // main.m
    // Allegro
    //
    // Created by Jakub Kuzimski on 22.08.2012.
    // Copyright (c) 2012 Jakub Kuzimski. All rights reserved.
    //
    #import
    #import "APAppDelegate.h"
    int main(int argc, char *argv[]) {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([APAppDelegate class]));
    }
    }
    22.08.2012

    View Slide

  14. 14

    View Slide

  15. 15
    Separacja i reużywalność

    Produktywność
    Odpowiedzialność


    View Slide

  16. 16
    Separacja i reużywalność
    Produktywność


    Odpowiedzialność

    View Slide

  17. 17
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  18. 18
    Allegro
    Strona oferty
    Strona główna
    Proces zakupowy
    Networking
    UI

    View Slide

  19. 19
    Strona oferty

    View Slide

  20. 20
    Strona oferty

    View Slide

  21. 21
    Strona oferty

    View Slide

  22. 22
    Strona oferty

    View Slide

  23. 23
    Strona oferty

    View Slide

  24. 24
    Strona oferty

    View Slide

  25. 25
    OfferDetails.podspec
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end

    View Slide

  26. 26
    OfferDetails.podspec
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }

    View Slide

  27. 27
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    OfferDetails.podspec

    View Slide

  28. 28
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end
    spec.version = "2.0.0"
    OfferDetails.podspec

    View Slide

  29. 29
    Allegro/Podfile
    source "https://allegro_git/pods.specs.git"
    source "https://github.com/CocoaPods/Specs"
    target "Allegro" do
    pod "Registration", "1.5.0"
    pod "Cart", "3.1.2"
    pod "OfferDetails", "2.0.0"
    (...)
    end

    pod update OfferDetails
    pod "OfferDetails", "2.0.0"

    View Slide

  30. 30
    Allegro/Podfile
    source "https://allegro_git/pods.specs.git"
    source "https://github.com/CocoaPods/Specs"
    target "Allegro" do
    pod "Registration", "1.5.0"
    pod "Cart", "3.1.2"
    pod "OfferDetails", "2.0.0"
    (...)
    end

    pod update OfferDetails
    source "https://allegro_git/pods.specs.git"

    View Slide

  31. 31
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  32. 32
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  33. 33
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  34. 34
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  35. 35
    Allegro
    Strona oferty
    Proces zakupowy
    Networking
    1.0.0

    View Slide

  36. 36
    Allegro
    Strona oferty
    Proces zakupowy
    Networking
    1.0.1
    Networking
    1.0.0

    View Slide

  37. 37
    Allegro
    Strona oferty
    Proces zakupowy
    Networking
    1.0.1

    View Slide

  38. 38
    Allegro
    Strona oferty
    Proces zakupowy
    Wyszukiwanie
    Rejestracja
    Networking
    1.0.0
    Networking
    1.0.5
    UI
    2.0.0
    UI
    2.2.0
    UI
    2.1.0
    Networking
    1.1.0

    View Slide

  39. 39

    View Slide

  40. 40
    1. Przenieść kod z modułu strony oferty do AllegroCommons.

    View Slide

  41. 41
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.

    View Slide

  42. 42
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.
    3. Wydać nowe AllegroCommons.

    View Slide

  43. 43
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.
    3. Wydać nowe AllegroCommons.
    4. Uaktualnić AllegroCommons w module oferty.

    View Slide

  44. 44
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.
    3. Wydać nowe AllegroCommons.
    4. Uaktualnić AllegroCommons w module oferty.
    5. Uaktualnić AllegroCommons w module procesu zakupowego.

    View Slide

  45. 45
    (...)
    <<<<<<< HEAD
    PODFILE CHECKSUM: 15f6bd662808121403ea733c7263b90e7b912840
    =======
    PODFILE CHECKSUM: 4c795d243895a6e7905e0606b06679090f723b4a
    >>>>>>> develop
    └── Allegro
    ├── Allegro
    ├── Allegro.xcodeproj
    ├── Allegro.xcworkspace
    ├── AllegroStubbedUITests
    ├── AllegroTests
    ├── Podfile
    ├── Podfile.lock
    ├── Pods.xcodeproj
    ├── Pods
    │ ├── ...
    │ ├── Manifest.lock
    │ └── ...
    └── fastlane
    Allegro/Podfile.lock
    ├── Podfile.lock
    ├── Pods.xcodeproj
    │ ├── Manifest.lock

    View Slide

  46. 46

    View Slide

  47. 47
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View Slide

  48. 48
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View Slide

  49. 49
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View Slide

  50. 50
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View Slide

  51. 51

    View Slide

  52. 52

    View Slide

  53. 53

    View Slide

  54. 54
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search
    └── fastlane
    └── Fastfile

    View Slide

  55. 55
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search
    └── fastlane
    └── Fastfile
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane

    View Slide

  56. 56
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search
    └── fastlane
    └── Fastfile
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search

    View Slide

  57. 57
    git remote add MODULE-origin https://allegro_git/iosmodules/MODULE.git
    git fetch MODULE-origin
    git merge --allow-unrelated-histories MODULE-origin/develop
    git remote remove MODULE-origin
    git push origin

    View Slide

  58. 58
    git remote add MODULE-origin https://allegro_git/iosmodules/MODULE.git
    git fetch MODULE-origin
    git merge --allow-unrelated-histories MODULE-origin/develop
    git remote remove MODULE-origin
    git push origin
    --allow-unrelated-histories

    View Slide

  59. 59
    (...)
    target :OfferDetails do
    project '../AllegroModules/OfferDetails/OfferDetails.xcodeproj'
    workspace 'Allegro'
    pod_OfferDetailsDependencies
    target :OfferDetailsTests do
    inherit! :search_paths
    pod_FBSnapshotTest
    pod_CommonPodsForTargetsWithTests
    end
    end
    (...)
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── ...
    │ ├── OfferDetails
    │ │ ├── OfferDetails
    │ │ ├── OfferDetails.xcodeproj
    │ │ ├── OfferDetailsTests
    │ │ └── fastlane
    │ ├── ...
    └── fastlane
    └── Fastfile
    Allegro/Podfile
    │ ├── Podfile

    View Slide

  60. 60

    View Slide

  61. 61

    View Slide

  62. 62
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile

    View Slide

  63. 63
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")

    View Slide

  64. 64
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")

    View Slide

  65. 65
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end

    View Slide

  66. 66
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end

    View Slide

  67. 67
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    fastlane/Fastfile
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    ["AllegroModules/OfferDetails",
    "AllegroModules/Origami",
    "AllegroModules/CrossSell",
    "Allegro/Pods/Metrum",
    "AllegroModules/Networking",
    "Allegro/Pods/AllegroCommons"]

    View Slide

  68. 68
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end

    View Slide

  69. 69

    View Slide

  70. 70

    View Slide

  71. 71

    View Slide

  72. 72
    ├── Allegro
    ├── AllegroModules
    ├── Toolset
    │ ├── SwiftFormat
    │ │ ├── run_swiftformat.sh
    │ │ ├── run_swiftformat_in_modules.sh
    │ │ └── swiftformat-0.30.2
    │ ├── SwiftLint
    │ │ ├── run_swiftlint.sh
    │ │ └── swiftlint-0.25.0
    │ └── clang-format
    │ ├── clang-format
    │ ├── reformat_all.sh
    │ └── run_clang_format.sh
    └── ...
    github.com/nicklockwood/SwiftFormat github.com/realm/SwiftLint clang.llvm.org/docs/ClangFormat.html

    View Slide

  73. 73
    ├── Allegro
    ├── AllegroModules
    ├── Configuration
    │ ├── Project-Debug.xcconfig
    │ ├── Project-Lab.xcconfig
    │ ├── Project-Release.xcconfig
    │ └── Project-Shared.xcconfig
    └── ...

    View Slide

  74. 74

    View Slide

  75. 75
    Allegro/Podfile
    post_install do | installer |
    Dir["../AllegroModules/*/"].map { |a| File.basename(a) }.each do |filePath|
    Dir.glob(File.join("Pods", "**", "Pods-#{filePath}.debug.xcconfig")).each do |file|
    File.open(file, 'a') { |f| f.puts "\n#include \"../../Configuration/Project-Debug.xcconfig\" " }
    end
    (...)
    end
    (...)
    end

    View Slide

  76. 76
    (...)
    PODS_PODFILE_DIR_PATH = ${SRCROOT}/../../Allegro
    PODS_ROOT = ${SRCROOT}/../../Allegro/Pods
    #include "../../Configuration/Project-Debug.xcconfig"
    Allegro/Pods/Target Support Files/Pods-OfferDetails/Pods-OfferDetails.debug.xcconfig
    #include "../../Configuration/Project-Debug.xcconfig"
    #include \"../../Configuration/Project-Debug.xcconfig\"
    Allegro/Podfile
    post_install do | installer |
    Dir["../AllegroModules/*/"].map { |a| File.basename(a) }.each do |filePath|
    Dir.glob(File.join("Pods", "**", "Pods-#{filePath}.debug.xcconfig")).each do |file|
    File.open(file, 'a') { |f| f.puts "\n#include \"../../Configuration/Project-Debug.xcconfig\" " }
    end
    (...)
    end
    (...)
    end

    View Slide

  77. 77
    + ,

    View Slide

  78. 78

    View Slide

  79. 79

    View Slide

  80. 80
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  81. 81
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  82. 82
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View Slide

  83. 83

    View Slide

  84. 84
    https://engineering.shopify.com/blogs/engineering/mobile-tophatting-at-shopify-1

    View Slide

  85. 85

    View Slide

  86. 86
    Ciekawe źródła
    • Faster Together: Uber Engineering’s iOS Monorepo
    • Why Google Stores Billions of Lines of Code in a
    Single Repository
    • µFeatures Guidelines

    View Slide

  87. View Slide