Skip to content

Commit 51564ad

Browse files
author
Alex Evanczuk
authored
Merge pull request #1 from bigrails/ae-initial-commit
Initial extraction from Gusto's codebase
2 parents da3e630 + ac5537b commit 51564ad

File tree

18 files changed

+635
-1
lines changed

18 files changed

+635
-1
lines changed

.github/workflows/ci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
ruby:
11+
- 2.7
12+
# See comment comes from https://github.com/ruby/setup-ruby#matrix-of-ruby-versions
13+
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
14+
- '3.0'
15+
- 3.1
16+
- head
17+
env:
18+
BUNDLE_GEMFILE: Gemfile
19+
name: "Tests: Ruby ${{ matrix.ruby }}"
20+
steps:
21+
- uses: actions/checkout@5126516654c75f76bca1de45dd82a3006d8890f9
22+
- name: Set up Ruby ${{ matrix.ruby }}
23+
uses: ruby/setup-ruby@bd94d6a504586da892a5753afdd1480096ed30df
24+
with:
25+
ruby-version: ${{ matrix.ruby }}
26+
- name: Run tests
27+
run: |
28+
gem install bundler
29+
bundle install --jobs 4 --retry 3
30+
bundle exec rspec
31+
static-type-checking:
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@5126516654c75f76bca1de45dd82a3006d8890f9
35+
- name: Set up Ruby
36+
uses: ruby/setup-ruby@bd94d6a504586da892a5753afdd1480096ed30df
37+
with:
38+
ruby-version: head
39+
- name: Run static type checks
40+
run: |
41+
gem install bundler
42+
bundle install --jobs 4 --retry 3
43+
bundle exec srb tc

.github/workflows/publish.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Publish Gem
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
tags:
8+
- v*
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@5126516654c75f76bca1de45dd82a3006d8890f9
15+
16+
- name: Release Gem
17+
if: contains(github.ref, 'refs/tags/v')
18+
uses: cadwallion/publish-rubygems-action@8f9e0538302643309e4e43bf48cd34173ca48cfc
19+
env:
20+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
21+
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/.bundle/
2+
/.yardoc
3+
/_yardoc/
4+
/coverage/
5+
/doc/
6+
/pkg/
7+
/spec/reports/
8+
/tmp/
9+
10+
# rspec failure tracking
11+
.rspec_status

.rspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--format documentation
2+
--color
3+
--require spec_helper

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See https://github.com/bigrails/bigrails-teams/releases

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source 'https://rubygems.org'
2+
3+
# Specify your gem's dependencies in teams.gemspec
4+
gemspec

Gemfile.lock

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
PATH
2+
remote: .
3+
specs:
4+
teams (1.11.0)
5+
sorbet-runtime
6+
7+
GEM
8+
remote: https://rubygems.org/
9+
specs:
10+
coderay (1.1.3)
11+
diff-lcs (1.4.4)
12+
method_source (1.0.0)
13+
pry (0.14.1)
14+
coderay (~> 1.1)
15+
method_source (~> 1.0)
16+
rake (13.0.6)
17+
rspec (3.10.0)
18+
rspec-core (~> 3.10.0)
19+
rspec-expectations (~> 3.10.0)
20+
rspec-mocks (~> 3.10.0)
21+
rspec-core (3.10.1)
22+
rspec-support (~> 3.10.0)
23+
rspec-expectations (3.10.1)
24+
diff-lcs (>= 1.2.0, < 2.0)
25+
rspec-support (~> 3.10.0)
26+
rspec-mocks (3.10.2)
27+
diff-lcs (>= 1.2.0, < 2.0)
28+
rspec-support (~> 3.10.0)
29+
rspec-support (3.10.2)
30+
sorbet (0.5.9889)
31+
sorbet-static (= 0.5.9889)
32+
sorbet-runtime (0.5.9889)
33+
sorbet-static (0.5.9889-universal-darwin-14)
34+
sorbet-static (0.5.9889-universal-darwin-15)
35+
sorbet-static (0.5.9889-universal-darwin-16)
36+
sorbet-static (0.5.9889-universal-darwin-17)
37+
sorbet-static (0.5.9889-universal-darwin-18)
38+
sorbet-static (0.5.9889-universal-darwin-19)
39+
sorbet-static (0.5.9889-universal-darwin-20)
40+
sorbet-static (0.5.9889-universal-darwin-21)
41+
sorbet-static (0.5.9889-x86_64-linux)
42+
43+
PLATFORMS
44+
arm64-darwin-21
45+
ruby
46+
x86_64-darwin-20
47+
x86_64-linux
48+
49+
DEPENDENCIES
50+
pry
51+
rake
52+
rspec (~> 3.0)
53+
sorbet
54+
teams!
55+
56+
BUNDLED WITH
57+
2.3.9

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Gusto
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,92 @@
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+

Rakefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# typed: ignore
2+
3+
require 'bundler/gem_tasks'
4+
require 'rspec/core/rake_task'
5+
6+
RSpec::Core::RakeTask.new(:spec)
7+
8+
task default: :spec

0 commit comments

Comments
 (0)