Building InnerSource practices through an internal developer portal

October 28, 2024

Building InnerSource practices through an internal developer portal

Ready to start?

This article first appeared in The New Stack, which you can read here.

Strengthening collaboration and breaking down silos are what InnerSource is all about; the methodology encourages an open-source way of thinking towards software development. It’s not a new practice; in fact, the term was first coined back in December 2000 by Tim O’Reilly, founder of O’Reilly Media. Despite it being a somewhat older term in an industry that loves to move on to the latest buzzwords and trends, it is still very much an approach that many engineering teams want to incorporate into their organizations. Gartner expects 40% of software engineering organizations to have InnerSource programs by 2026.

This is because they believe that the approach will improve code reusability, increase standardization and inspire a culture of autonomy and ownership among developers. Ultimately, the goal of InnerSource is to reduce duplication in development, lack of reuse and the resulting increased costs. But enterprises tend to struggle with the handoff between overarching strategy and tactical implementation. 

While no single tool can ensure that InnerSource will be adopted by developers, there are approaches that can help to implement InnerSource - including the use of an internal developer portal.

Here, we run down five key ways you can use an internal developer portal to help implement and encourage InnerSource within an organization:

The importance of a ‘trusted committer’

In her book “Understanding the InnerSource Checklist”, Silona Bonewald describes the role of a “trusted committer” as crucial to implementing InnerSource best practices. The trusted committer is a developer - often on a two week rotation - that mentors other developers and ensures standards are met when people create new PRs. Trusted committers lead the effort to reduce silos for their service by:

  • Maintaining contribution guidelines
  • Reviewing incoming pull requests to ensure they’re in accordance with these guidelines
  • Mentoring developers who fall outside of the contribution guidelines 
  • Requesting help from those who commit code to their service.

Portals create a place that makes the work of trusted committers easier, seen, acknowledged and easy to follow. 

In the most basic sense, an internal developer portal makes the presence of trusted committers known, just like software ownership can be driven through a portal. Having a portal can ensure ‘trusted committers’ for each service are known and rewarded by: 

  • Including an automatically updated ‘trusted committer’ schedule;
  • Assigning a “trusted committer” tag or property to the developer who is currently serving in this role; and
  • Gamifying the contribution of each trusted committer by maintaining a dashboard (depicting, for example, the number of PRs merged under their watch or the speed with which they respond to each PR).

Finally, Bonewald notes that serving as a trusted committer takes developers away from writing code, so passively recording their contributions using a portal is an excellent way to provide objective performance metrics in year-end performance conversations.

Bonewald suggests a promotion path to “Fellow” for developers who excel as trusted committers, which could be a tag or property depicted proudly on their user profile in a portal.

Developers may find it helpful to view the current trusted committer for a service they’ve discovered. trusted committers will also find it helpful to be identified using an automatically updated schedule.

Boosting discoverability

This method and the next are particularly important for organizations that have grown inorganically through acquisitions. Whether acquired companies have become a part of a single legal entity or become subsidiaries, the administrative burden of consolidating into a single source code management tool or adding all developers to all existing source code management tools is an insurmountable task and, without doing this, InnerSource efforts tend to languish in slide decks instead of thriving in the daily work of developers.

An alternative to consolidating tools or organizations is to integrate all existing repositories into a single catalog that acts as a foundation for a portal, where developers may discover metadata about all available services without exposing the source code by default. In doing so, developers can understand what a service does, how to contribute to it, and who the trusted committer is without ever seeing the source code. This immediately reduces duplication of both services and APIs.

Being able to send access requests to the right person

Once developers are prepared to contribute to or use the service they’ve discovered using a portal, they can use a self-service action to request access to only the repository in question. By implementing dynamic approvals, this request can be sent to the right person, whether that is the trusted committer, product manager or technical lead.

Access to a repository can be accomplished with a dropdown and a brief message, then can be routed to the trusted committer (or whoever is best to field these requests).

Creating new services that are InnerSource-ready from the outset

Engineering organizations that do not use a portal already struggle with streamlining new service creation: developers must submit individual, co-dependent tickets for a new repository, new pipelines, new project management tools, and others. Adding InnerSource requirements to scaffolding a new service is yet another trigger for developers to switch context when they should be – and want to be – writing code.

A welcome alternative to a ticket-driven process is a self-service action that allows developers to easily satisfy these requirements from the beginning. Instead of directing them to find, modify, and add the InnerSource documentation requirements (README.md, CONTRIBUTING.md, GETTINGSTARTED.md, and HELPWANTED.md), simply ask them to fill out the minimum requirements for these from the beginning in a self-service form. The automation that creates the new repository, pipeline, project management tool, and others can write these files to the new repository, allowing developers to shift their focus to writing the code for the new service nearly immediately.

Auto-populate the templates in this self-service action to ensure developers provide the right information from the beginning.

Scorecards for services

The approach above will satisfy InnerSource requirements for new services, but organizations tend to have a vast number of existing services that must be evaluated for compliance with InnerSource standards. Before instructing an InnerSource or DevOps team to create a repository scanner that evaluates all repositories, consider using a custom scorecard in a portal. A scorecard can be used to define, measure and track metrics related to each service or entity in an internal developer portal. In this case, a scorecard can help establish metrics to grade compliance with InnerSource standards, which will help managers or team leads to understand the gaps in existing services, then drive time-bound initiatives to fill those gaps.

Before building a repository scanner to check for InnerSource standards, consider using a scorecard instead.

Conclusion

By implementing a portal and deliberately configuring it to serve InnerSource purposes, engineering leaders can enjoy the benefits of InnerSource in their organizations. Developers will similarly enjoy the benefits of enhanced discoverability, ability to easily scaffold a new InnerSource-ready service, and quickly finding the right person to support their contributions.

{{cta_1}}

Check out Port's pre-populated demo and see what it's all about.

Check live demo

No email required

{{cta_2}}

Contact sales for a technical product walkthrough

Let’s start
{{cta_3}}

Open a free Port account. No credit card required

Let’s start
{{cta_4}}

Watch Port live coding videos - setting up an internal developer portal & platform

Let’s start
{{cta_5}}

Check out Port's pre-populated demo and see what it's all about.

(no email required)

Let’s start
{{cta_6}}

Contact sales for a technical product walkthrough

Let’s start
{{cta_7}}

Open a free Port account. No credit card required

Let’s start
{{cta_8}}

Watch Port live coding videos - setting up an internal developer portal & platform

Let’s start
{{cta-demo}}
{{reading-box-backstage-vs-port}}

Example JSON block

{
  "foo": "bar"
}

Order Domain

{
  "properties": {},
  "relations": {},
  "title": "Orders",
  "identifier": "Orders"
}

Cart System

{
  "properties": {},
  "relations": {
    "domain": "Orders"
  },
  "identifier": "Cart",
  "title": "Cart"
}

Products System

{
  "properties": {},
  "relations": {
    "domain": "Orders"
  },
  "identifier": "Products",
  "title": "Products"
}

Cart Resource

{
  "properties": {
    "type": "postgress"
  },
  "relations": {},
  "icon": "GPU",
  "title": "Cart SQL database",
  "identifier": "cart-sql-sb"
}

Cart API

{
 "identifier": "CartAPI",
 "title": "Cart API",
 "blueprint": "API",
 "properties": {
   "type": "Open API"
 },
 "relations": {
   "provider": "CartService"
 },
 "icon": "Link"
}

Core Kafka Library

{
  "properties": {
    "type": "library"
  },
  "relations": {
    "system": "Cart"
  },
  "title": "Core Kafka Library",
  "identifier": "CoreKafkaLibrary"
}

Core Payment Library

{
  "properties": {
    "type": "library"
  },
  "relations": {
    "system": "Cart"
  },
  "title": "Core Payment Library",
  "identifier": "CorePaymentLibrary"
}

Cart Service JSON

{
 "identifier": "CartService",
 "title": "Cart Service",
 "blueprint": "Component",
 "properties": {
   "type": "service"
 },
 "relations": {
   "system": "Cart",
   "resources": [
     "cart-sql-sb"
   ],
   "consumesApi": [],
   "components": [
     "CorePaymentLibrary",
     "CoreKafkaLibrary"
   ]
 },
 "icon": "Cloud"
}

Products Service JSON

{
  "identifier": "ProductsService",
  "title": "Products Service",
  "blueprint": "Component",
  "properties": {
    "type": "service"
  },
  "relations": {
    "system": "Products",
    "consumesApi": [
      "CartAPI"
    ],
    "components": []
  }
}

Component Blueprint

{
 "identifier": "Component",
 "title": "Component",
 "icon": "Cloud",
 "schema": {
   "properties": {
     "type": {
       "enum": [
         "service",
         "library"
       ],
       "icon": "Docs",
       "type": "string",
       "enumColors": {
         "service": "blue",
         "library": "green"
       }
     }
   },
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {
   "system": {
     "target": "System",
     "required": false,
     "many": false
   },
   "resources": {
     "target": "Resource",
     "required": false,
     "many": true
   },
   "consumesApi": {
     "target": "API",
     "required": false,
     "many": true
   },
   "components": {
     "target": "Component",
     "required": false,
     "many": true
   },
   "providesApi": {
     "target": "API",
     "required": false,
     "many": false
   }
 }
}

Resource Blueprint

{
 “identifier”: “Resource”,
 “title”: “Resource”,
 “icon”: “DevopsTool”,
 “schema”: {
   “properties”: {
     “type”: {
       “enum”: [
         “postgress”,
         “kafka-topic”,
         “rabbit-queue”,
         “s3-bucket”
       ],
       “icon”: “Docs”,
       “type”: “string”
     }
   },
   “required”: []
 },
 “mirrorProperties”: {},
 “formulaProperties”: {},
 “calculationProperties”: {},
 “relations”: {}
}

API Blueprint

{
 "identifier": "API",
 "title": "API",
 "icon": "Link",
 "schema": {
   "properties": {
     "type": {
       "type": "string",
       "enum": [
         "Open API",
         "grpc"
       ]
     }
   },
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {
   "provider": {
     "target": "Component",
     "required": true,
     "many": false
   }
 }
}

Domain Blueprint

{
 "identifier": "Domain",
 "title": "Domain",
 "icon": "Server",
 "schema": {
   "properties": {},
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {}
}

System Blueprint

{
 "identifier": "System",
 "title": "System",
 "icon": "DevopsTool",
 "schema": {
   "properties": {},
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {
   "domain": {
     "target": "Domain",
     "required": true,
     "many": false
   }
 }
}
{{tabel-1}}

Microservices SDLC

  • Scaffold a new microservice

  • Deploy (canary or blue-green)

  • Feature flagging

  • Revert

  • Lock deployments

  • Add Secret

  • Force merge pull request (skip tests on crises)

  • Add environment variable to service

  • Add IaC to the service

  • Upgrade package version

Development environments

  • Spin up a developer environment for 5 days

  • ETL mock data to environment

  • Invite developer to the environment

  • Extend TTL by 3 days

Cloud resources

  • Provision a cloud resource

  • Modify a cloud resource

  • Get permissions to access cloud resource

SRE actions

  • Update pod count

  • Update auto-scaling group

  • Execute incident response runbook automation

Data Engineering

  • Add / Remove / Update Column to table

  • Run Airflow DAG

  • Duplicate table

Backoffice

  • Change customer configuration

  • Update customer software version

  • Upgrade - Downgrade plan tier

  • Create - Delete customer

Machine learning actions

  • Train model

  • Pre-process dataset

  • Deploy

  • A/B testing traffic route

  • Revert

  • Spin up remote Jupyter notebook

{{tabel-2}}

Engineering tools

  • Observability

  • Tasks management

  • CI/CD

  • On-Call management

  • Troubleshooting tools

  • DevSecOps

  • Runbooks

Infrastructure

  • Cloud Resources

  • K8S

  • Containers & Serverless

  • IaC

  • Databases

  • Environments

  • Regions

Software and more

  • Microservices

  • Docker Images

  • Docs

  • APIs

  • 3rd parties

  • Runbooks

  • Cron jobs

Starting with Port is simple, fast and free.

Let’s start