{"id":3245,"date":"2018-02-21T12:53:38","date_gmt":"2018-02-21T20:53:38","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vsappcenter\/?p=3245"},"modified":"2019-02-16T15:30:27","modified_gmt":"2019-02-16T22:30:27","slug":"how-mono-repo-and-one-infra-help-us-deliver-a-better-developer-experience","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/appcenter\/how-mono-repo-and-one-infra-help-us-deliver-a-better-developer-experience\/","title":{"rendered":"How \u201cMono-repo&#8221; and &#8220;One Infra\u201d Help Us Deliver a Better Developer Experience"},"content":{"rendered":"<p>As a team, from Visual Studio App Center engineers to product managers, designers, and QA, our goal is simple: build an amazing product for developers. We decided early on that to help our team deliver on our goal, we\u2019d create a set of values that would guide our decisions and keep us on the right path as we add new features, prioritize enhancements to services, or build integrations. We wanted these values to drive not just the product, but our team culture, and after many discussions, we established four core values: customer obsession, simplicity, no silos, and growth mindset. <\/p>\n<p>As an Engineering Manager, I\u2019m responsible for my teams\u2019 execution, and I contribute technically to the product. Yet as a team, we are all empowered to improve our product and design the world we want to work with. This laser-focus on a central goal and ground rules sounds great on paper, but what does it actually mean? It means <strong>we constantly assess our tools, infrastructure, team structure, and development processes<\/strong> to make sure they\u2019re simple, open, and freeing us to focus on delivering the best possible developer experience. <\/p>\n<p>Goals and principles are different for every organization, but they make it easier to make hard decisions, prioritize one developer\u2019s project over another\u2019s, and stop doing things that just aren\u2019t working. You may already have goals and values in place; if not, it\u2019s never too late to get started, because it never ends.  <\/p>\n<p>In this post, I\u2019ll share how and why we implemented one of our most recent changes: moving to <em>Mono-repo<\/em> and <em>One Infra<\/em>, including why we unified our development and infrastructure and what\u2019s next.  <\/p>\n<p>To learn more about how our team works, check out Lukas Spie\u00df&#8217; <a href=\"https:\/\/blogs.msdn.microsoft.com\/vsappcenter\/how-the-visual-studio-mobile-center-team-does-code-review\/\" rel=\"noopener\" target=\"_blank\">How We Do Code Review<\/a> and Benny Scholtysik&#8217;s <a href=\"https:\/\/blogs.msdn.microsoft.com\/vsappcenter\/how-we-build-sdks-developers-love\/\" rel=\"noopener\" target=\"_blank\">How We Build SDKs Developers Love<\/a>. <\/p>\n<h2>Why Mono-repo?<\/h2>\n<p>App Center uses a micro-services architecture to give us the flexibility to break things down into small units that perform a single business function and can be developed and deployed independently. When we started, we chose to use multiple repositories.<\/p>\n<p>When we were shipping a first version of the product, this made sense for two reasons: <\/p>\n<ul>\n<li><strong>Clear Ownership<\/strong>: A small team owns the codebase end-to-end. Each App Center service team&mdash;Build, Test, Distribute, Crashes, and Analytics&mdash;was free to independently develop and deploy updates.<\/li>\n<li><strong>Scale<\/strong>: Smaller code bases are easier to manage and cause fewer merge conflicts. Large codebases can be inefficient, taking a long time to clone, pull, and push.<\/li>\n<\/ul>\n<p>We have several teams spread across multiple time zones, and, with the above approach, it was challenging to share and standardize code across the multiple repositories. A team member working on one service couldn\u2019t easily clone a repository and know how to get started. Since developers didn\u2019t always have a full understanding of the \u201cbig picture\u201d across App Center, our code reviews weren\u2019t as effective as they could be, and shared code didn\u2019t feel \u201cshared, so we were doubling effort in some scenarios.  <\/p>\n<p>Multiple repositories across multiple teams meant each team created their own infrastructure. We\u2019d started with a common direction, using DC\/OS and multiple data sources like SQL Server, Casandra, Table, and Blob storage. But, as teams pushed the product forward, how we set up infrastructure drifted in multiple directions. We were duplicating how we managed and accessed our infrastructure, and each team had to do secret management and rotation.  <\/p>\n<p>As we compared this to our \u201cno silos\u201d value, it went against building one team with knowledge across the product. We decided to move to Mono-repo and <a href=\"https:\/\/trunkbaseddevelopment.com\/monorepos\/\" rel=\"noopener\" target=\"_blank\">trunk based development<\/a> and use a common infrastructure for our build and deployment pipeline. Value and goal check: this eliminates silos, helps us work better as <strong>one<\/strong> team, and frees us to constantly deliver customer value. <\/p>\n<h2>Going from Multi to Mono(-repo)<\/h2>\n<p>To move our code from multiple repositories in different source providers into one, each team migrated their development or master branch (including its history) into a new Visual Studio Team Services project repo: <\/p>\n<ol>\n<li>We wrote a script to move the current repo into a \u201cMono-repo\u201d branch.<\/li>\n<li>To simplify the transition and to plan for a folder structure in the future, repositories went into a sub-directory under the root path.<\/li>\n<li>Once code was working and the build definitions were migrated, we created a Pull Request and merged to our new Mono-repo master.<\/li>\n<\/ol>\n<p>We used kebob format (tools-swagger-codegen) for our folders, making descriptions as robust as possible (within a reasonable length) and removing team-specific names for code. For example, we called our user service <em>Vanaheim<\/em> which was confusing to new team members and teams working on other services. When we moved to Mono-repo, <em>Vanaheim<\/em> became <em>accounts-management-service<\/em> a clear, descriptive, and easily understandable identifier. <\/p>\n<p>After a few weeks, we\u2019d fully transitioned, but it\u2019s a constant work in progress; we want it to be a never-ending, iterative process. As we continue development over time, we\u2019ll continuously make our code better, simplifying processes and working together to build better product.  <\/p>\n<h2>Creating One Infra<\/h2>\n<p>Shifting to Mono-repo gave us an opportunity to rework and consolidate our infrastructure too. Each team used Docker to deploy code into different orchestrators, read secrets their own way, and had their own approach to logging and telemetry. In addition to consolidating repositories, we\u2019d unify and share code in way that didn\u2019t require cloning and duplication.  <\/p>\n<p>We use Visual Studio Team Services to consolidate builds, packages, and deployments. Promoting a single artifact reduces our total number of build definitions to one per service or component we create. To get our build definitions working inside of our new Mono-repo, we followed the below steps: <\/p>\n<ul>\n<li>Rename build definition to match the repository folder name. <\/li>\n<li>Set a path filter to the Trigger, so Continuous Integration is only triggered when changes are made under the components folder.\n&nbsp;\n<img decoding=\"async\" src=\"\" alt=\"\" width=\"750\" class=\"aligncenter size-large wp-image-3255\" \/><\/li>\n<p>&nbsp;<\/p>\n<li>Add a ROOT_FOLDER variable that specifies your directory name.<\/li>\n<li>Add a <em>Shell Exec<\/em> step to the Build Tasks to move your service into the root, so all existing tasks execute as normal (refer to CI above for <em>Shell Exec<\/em> code).\n&nbsp;\n<img decoding=\"async\" src=\"\" alt=\"\" width=\"750\" class=\"aligncenter size-large wp-image-3265\" \/><\/li>\n<p>&nbsp;<\/p>\n<li>Add any other required steps to build the code.<\/li>\n<\/ul>\n<p>We use three environments: integration, staging and production, and two Visual Studio Team Services control our releases. Our integration definition automatically deploys changes merged into\u202fmaster\u202fto the corresponding integration environment.  <\/p>\n<p>The majority of our existing integration definition didn\u2019t require any alterations, other than adding a new step to create the git tags. The production definition deploys the integration artifacts to staging and creates an automatic pending approval for a production deployment. After qualifying our staging environment is ready, we generate an approval for production. In the future, as we grow and add more features, we\u2019ll fully automate this, too, allowing releases to go straight to production.  <\/p>\n<h2>What\u2019s Next<\/h2>\n<p>Given our growth mindset approach to development, we\u2019re continuing to iterate and refine our processes. Our next step is to consolidate subscriptions and services, including moving our Docker deployments to Azure Service Fabric as our orchestrator to consolidate our logging and telemetry infrastructure, as well as standardizing how we access and rotate secrets.  <\/p>\n<p>This automation and consolidation brings us back to our core values and goal, since every simplified process means each team member spends more time delivering value to developers and less time managing infrastructure. <\/p>\n<h2>Final Thoughts<\/h2>\n<p>The move to Mono-repo and a common infrastructure is ongoing, but we\u2019re already seeing some positive results. Team members are more productive, code is less complex, and there\u2019s more knowledge sharing across teams. Teams don\u2019t just work and own one feature area, they work on the most important set of features across the product, so we have all hands on deck for high-priority items.  <\/p>\n<p>We\u2019re committed to delivering customer value and making App Center the best CI\/CD experience for all developers, so you can ship better apps faster and focus on delivering value to your users. <\/p>\n<p><a href=\"http:\/\/appcenter.ms\/login\" rel=\"noopener\" target=\"_blank\">Log in<\/a> to see what we\u2019ve been up to, or <a href=\"http:\/\/appcenter.com\/signup\" rel=\"noopener\" target=\"_blank\">create your free account<\/a> to get started.  <\/p>\n<p>We\u2019d love to hear from you. Sign in and click the \u201cchat\u201d icon from your App Center dashboard to tell us what you\u2019d like to see next, your team values, or how you\u2019ve streamlined your development pipeline. We\u2019re all ears!\n&nbsp;\n&nbsp;\n<a href=\"https:\/\/appcenter.ms\/signup\"><img decoding=\"async\" src=\"\" alt=\"Get started now button\" width=\"200\" class=\"aligncenter size-full wp-image-2585\" \/><\/a>\n&nbsp;\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As a team, from Visual Studio App Center engineers to product managers, designers, and QA, our goal is simple: build an amazing product for developers. We decided early on that to help our team deliver on our goal, we\u2019d create a set of values that would guide our decisions and keep us on the right [&hellip;]<\/p>\n","protected":false},"author":42,"featured_media":38034,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[16],"tags":[],"class_list":["post-3245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mobiledev"],"acf":[],"blog_post_summary":"<p>As a team, from Visual Studio App Center engineers to product managers, designers, and QA, our goal is simple: build an amazing product for developers. We decided early on that to help our team deliver on our goal, we\u2019d create a set of values that would guide our decisions and keep us on the right [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/posts\/3245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/comments?post=3245"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/posts\/3245\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/media\/38034"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/media?parent=3245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/categories?post=3245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/appcenter\/wp-json\/wp\/v2\/tags?post=3245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}