|
1 | | -# bigrails-teams |
| 1 | +# Teams |
| 2 | + |
| 3 | +This gem is a simple, low-dependency, plugin-based manager for engineering teams within a codebase. |
| 4 | + |
| 5 | +## Usage |
| 6 | + |
| 7 | +To use teams, add YML files in `config/teams` that start with structure: |
| 8 | +`config/teams/my_team.yml` |
| 9 | +```yml |
| 10 | +name: My Team |
| 11 | +``` |
| 12 | +
|
| 13 | +`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: |
| 14 | + |
| 15 | +```ruby |
| 16 | +class MyGithubPlugin < Teams::Plugin |
| 17 | + extend T::Sig |
| 18 | + extend T::Helpers |
| 19 | +
|
| 20 | + GithubStruct = Struct.new(:team, :members) |
| 21 | +
|
| 22 | + sig { returns(GithubStruct) } |
| 23 | + def github |
| 24 | + raw_github = @team.raw_hash['github'] || {} |
| 25 | +
|
| 26 | + GithubStruct.new( |
| 27 | + raw_github['team'], |
| 28 | + raw_github['members'] || [] |
| 29 | + ) |
| 30 | + end |
| 31 | +
|
| 32 | + def member?(user) |
| 33 | + members = github.members |
| 34 | + return false unless members |
| 35 | +
|
| 36 | + members.include?(user) |
| 37 | + end |
| 38 | +
|
| 39 | + sig { override.params(teams: T::Array[Teams::Team]).returns(T::Array[String]) } |
| 40 | + def self.validation_errors(teams) |
| 41 | + errors = T.let([], T::Array[String]) |
| 42 | +
|
| 43 | + teams.each do |team| |
| 44 | + errors << missing_key_error_message(team, 'github.team') if self.for(team).github.team.nil? |
| 45 | + end |
| 46 | +
|
| 47 | + errors |
| 48 | + end |
| 49 | +end |
| 50 | +``` |
| 51 | + |
| 52 | +After adding the proper GitHub information to the team YML: |
| 53 | +```yml |
| 54 | +name: My Team |
| 55 | +github: |
| 56 | + team: '@org/my-team |
| 57 | + members: |
| 58 | + - member1 |
| 59 | + - member2 |
| 60 | +``` |
| 61 | + |
| 62 | +1) You can now use the following API to get GitHub information about that team: |
| 63 | +```ruby |
| 64 | +team = Teams.find('My Team') |
| 65 | +MyGithubPlugin.for(team).github |
| 66 | +``` |
| 67 | +2) Running team validations (see below) will ensure all teams have a GitHub team specified |
| 68 | + |
| 69 | +Your plugins can be as simple or as complex as you want. Here are some other things we use plugins for: |
| 70 | +- Identifying which teams own which feature flags |
| 71 | +- Mapping teams to specific portions of the code through `code_ownership` |
| 72 | +- Allowing teams to protect certain files and require approval on modification of certain files |
| 73 | +- Specifying owned dependencies (ruby gems, javascript packages, and more) |
| 74 | +- Specifying how to get in touch with the team via slack (their channel and handle) |
| 75 | + |
| 76 | +## Configuration |
| 77 | +You'll want to ensure that all teams are valid in your CI environment. We recommend running code like this in CI: |
| 78 | +```ruby |
| 79 | +require 'teams' |
| 80 | +errors = ::Teams.validation_errors(::Teams.all) |
| 81 | +if errors.any? |
| 82 | + abort <<~ERROR |
| 83 | + Team validation failed with the following errors: |
| 84 | + #{errors.join("\n")} |
| 85 | + ERROR |
| 86 | +end |
| 87 | +``` |
| 88 | + |
| 89 | +## Contributing |
| 90 | + |
| 91 | +Bug reports and pull requests are welcome! |
| 92 | + |
0 commit comments