Skip to content

Repository files navigation

CodeTeams

This gem is a simple, low-dependency, plugin-based manager for teams within a codebase.

Usage

To use code_teams, add YML files in config/teams that start with structure: config/teams/my_team.yml

name: My Team

code_teams leverages a plugin system because every organization's team practices are different. Say your organization uses GitHub and wants to ensure every team YML files has a GitHub owner. To do this, you create a plugin:

classMyGithubPlugin < CodeTeams::PluginextendT::SigextendT::HelpersGithubStruct=Struct.new(:team,:members)sig{returns(GithubStruct)}defgithubraw_github=@team.raw_hash['github'] || {}GithubStruct.new(raw_github['team'],raw_github['members'] || [])enddefmember?(user)github.members.include?(user)endsig{override.params(teams: T::Array[CodeTeams::Team]).returns(T::Array[String])}defself.validation_errors(teams)errors=T.let([],T::Array[String])teams.eachdo |team|
ifself.for(team).github.team.nil?errors << missing_key_error_message(team,'github.team')endenderrorsendend

After adding the proper GitHub information to the team YML:

name: My Teamgithub:
team: '@org/my-team'members:
- member1
- member2
  1. You can now use the following API to get GitHub information about that team:

    team=CodeTeams.find('My Team')members=team.github.membersgithub_name=team.github.team

    Alternatively, you can assign an accessor method name that differs from the plugin's class name:

    classMyPlugin < CodeTeams::Plugindata_accessor_name:other_namedefother_name# ...endend# You can then use:team.other_name# similarly to the Github example above# You can then access data in the following manner:team.other_name.attribute_name

    However, to avoid confusion, it's recommended to use the naming convention whenever possible so that your accessor name matches your plugin's name

  2. Running team validations (see below) will ensure all teams have a GitHub team specified

    Your plugins can be as simple or as complex as you want. Here are some other things we use plugins for:

    • Identifying which teams own which feature flags
    • Mapping teams to specific portions of the code through code_ownership
    • Allowing teams to protect certain files and require approval on modification of certain files
    • Specifying owned dependencies (Ruby gems, JavaScript packages, and more)
    • Specifying how to get in touch with the team via Slack (their channel and handle)

Configuration

You'll want to ensure that all teams are valid in your CI environment. We recommend running code like this in CI:

require'code_teams'errors=CodeTeams.validation_errors(CodeTeams.all)iferrors.any?abort<<~ERROR Team validation failed with the following errors:#{errors.join("\n")} ERRORend

Testing

code_teams provides test helpers for creating temporary teams in your specs without writing YML files to disk. Add the following to your spec_helper.rb (or rails_helper.rb):

require'code_teams/testing'CodeTeams::Testing.enable!

This gives you:

  • A code_team_with_config helper method available in all specs
  • Automatic cleanup of testing teams between examples

Example usage in a spec:

RSpec.describe'my feature'doit'works with a team'doteam=code_team_with_config(name: 'Test Team')expect(CodeTeams.find('Test Team')).toeq(team)endend

Contributing

Bug reports and pull requests are welcome!

About

A low-dependency gem for declaring and querying engineering teams

Resources

Code of conduct

Stars

19 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages