houston-core 0.7.0 → 0.8.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +45 -45
  3. data/app/assets/javascripts/houston/app/models/ticket.coffee +7 -5
  4. data/app/assets/javascripts/houston/app/views/new_ticket_view.coffee +1 -21
  5. data/app/assets/javascripts/houston/core/handlebars_helpers.coffee +0 -6
  6. data/app/assets/stylesheets/houston/application/commit.scss +16 -0
  7. data/app/assets/stylesheets/houston/application/navigation.scss +1 -0
  8. data/app/assets/stylesheets/houston/application/new_ticket_view.scss +0 -4
  9. data/app/assets/stylesheets/houston/application/projects.css.scss +0 -14
  10. data/app/assets/stylesheets/houston/application/release_form.scss +1 -1
  11. data/app/assets/stylesheets/houston/application/teams.scss +68 -0
  12. data/app/assets/templates/tickets/index.hbs +0 -1
  13. data/app/controllers/github/pulls_controller.rb +1 -0
  14. data/app/controllers/project_tickets_controller.rb +1 -5
  15. data/app/controllers/projects_controller.rb +10 -12
  16. data/app/controllers/teams_controller.rb +60 -0
  17. data/app/controllers/users_controller.rb +12 -12
  18. data/app/helpers/commit_helper.rb +3 -5
  19. data/app/helpers/exposure_helper.rb +1 -1
  20. data/app/helpers/ticket_helper.rb +0 -13
  21. data/app/interactors/ticket_report.rb +0 -7
  22. data/app/mailers/project_notification.rb +2 -23
  23. data/app/mailers/view_mailer.rb +0 -1
  24. data/app/models/ability.rb +28 -19
  25. data/app/models/commit.rb +0 -4
  26. data/app/models/project.rb +14 -29
  27. data/app/models/release.rb +0 -18
  28. data/app/models/role.rb +0 -22
  29. data/app/models/team.rb +43 -0
  30. data/app/models/team_user.rb +68 -0
  31. data/app/models/ticket.rb +2 -22
  32. data/app/models/user.rb +21 -30
  33. data/app/views/devise/sessions/new.html.erb +9 -7
  34. data/app/views/layouts/_mobile_navigation.html.erb +5 -3
  35. data/app/views/layouts/_navigation.html.erb +11 -10
  36. data/app/views/layouts/_tester_bar.html.erb +1 -1
  37. data/app/views/layouts/application.html.erb +1 -2
  38. data/app/views/project_tickets/_tickets.html.erb +0 -1
  39. data/app/views/project_tickets/index.xls.erb +0 -35
  40. data/app/views/project_tickets/new.html.erb +1 -2
  41. data/app/views/projects/_form.html.erb +7 -12
  42. data/app/views/projects/index.html.erb +10 -17
  43. data/app/views/releases/_changelog.html.erb +11 -14
  44. data/app/views/teams/_form.html.erb +45 -0
  45. data/app/views/teams/edit.html.erb +8 -0
  46. data/app/views/teams/index.html.erb +62 -0
  47. data/app/views/teams/new.html.erb +7 -0
  48. data/app/views/users/_form.html.erb +2 -11
  49. data/app/views/users/index.html.erb +8 -20
  50. data/app/views/users/new.html.erb +1 -1
  51. data/config/initializers/inflections.rb +7 -6
  52. data/config/routes.rb +19 -17
  53. data/db/migrate/20160812233255_repurpose_users_role.rb +16 -0
  54. data/db/migrate/20160813001242_create_teams.rb +42 -0
  55. data/db/structure.sql +110 -116
  56. data/lib/houston/boot.rb +0 -1
  57. data/lib/houston/boot/configuration.rb +26 -11
  58. data/lib/houston/boot/events.rb +0 -4
  59. data/lib/houston/version.rb +1 -1
  60. data/templates/new-instance/config/abilities.rb +68 -51
  61. data/templates/new-instance/config/conversations/mentions/unfurl_tasks.rb +1 -1
  62. data/templates/new-instance/config/events/deploy/notify_deployer_when_finished.rb +24 -16
  63. data/templates/new-instance/config/events/tests/email_when_completed.rb +11 -0
  64. data/templates/new-instance/config/integrations/ldap.rb +4 -0
  65. data/templates/new-instance/config/main.rb +10 -17
  66. data/templates/new-module/test/fixtures/users.yml +1 -2
  67. data/test/acceptance/creating_a_release_test.rb +1 -1
  68. data/test/factories/project_factory.rb +1 -0
  69. data/test/factories/user_factory.rb +3 -1
  70. data/test/fixtures/teams.yml +2 -0
  71. data/test/fixtures/teams_users.yml +5 -0
  72. data/test/fixtures/users.yml +1 -2
  73. data/test/integration/ci_integration_test.rb +2 -2
  74. data/test/support/config.rb +3 -5
  75. data/test/unit/controllers/deploys_controller_test.rb +11 -5
  76. data/test/unit/controllers/users_controller_test.rb +46 -0
  77. data/test/unit/models/release_test.rb +0 -9
  78. data/test/unit/models/serializer_test.rb +0 -8
  79. data/test/unit/models/ticket_test.rb +0 -32
  80. metadata +21 -24
  81. data/app/assets/javascripts/houston/app/table_row_expander.coffee +0 -52
  82. data/app/assets/javascripts/houston/app/views/problems_view.coffee +0 -114
  83. data/app/assets/stylesheets/houston/application/follow_up.scss +0 -44
  84. data/app/controllers/project_exceptions_controller.rb +0 -36
  85. data/app/controllers/project_pretickets_controller.rb +0 -27
  86. data/app/mailers/deploy_notification.rb +0 -33
  87. data/app/models/antecedent.rb +0 -15
  88. data/app/models/ticket_antecedent.rb +0 -39
  89. data/app/models/value_statement.rb +0 -9
  90. data/app/presenters/problem_presenter.rb +0 -49
  91. data/app/presenters/tester_presenter.rb +0 -15
  92. data/app/views/project_notification/follow_up.html.erb +0 -26
  93. data/app/views/project_pretickets/show.html.erb +0 -49
  94. data/app/views/releases/_antecedents.html.erb +0 -12
  95. data/config/initializers/hard_coded_knowledge.rb +0 -141
  96. data/db/migrate/20130427223925_create_project_quotas.rb +0 -14
  97. data/db/migrate/20140506035755_create_value_statements.rb +0 -9
  98. data/lib/houston/boot/ticket_antecedent_serializer.rb +0 -21
  99. data/test/unit/models/ticket_antecedents_test.rb +0 -38
@@ -6,4 +6,3 @@ require "houston/boot/events"
6
6
 
7
7
  require "houston/boot/active_record_serializer"
8
8
  require "houston/boot/readonly_hash_serializer"
9
- require "houston/boot/ticket_antecedent_serializer"
@@ -24,6 +24,11 @@ module_function
24
24
 
25
25
  def initialize
26
26
  @root = Rails.root
27
+ @roles = {}
28
+ @roles["Team Owner"] = Proc.new do |team|
29
+ can :manage, team
30
+ can :manage, Project, team_id: team.id
31
+ end
27
32
  @modules = []
28
33
  @gems = []
29
34
  @ticket_types = {}
@@ -170,18 +175,12 @@ module_function
170
175
  @environments ||= []
171
176
  end
172
177
 
173
- def roles(*args)
174
- @roles = args if args.any?
175
- ["Guest"] + (@roles ||= [])
176
- end
177
-
178
- def default_role
179
- "Guest"
178
+ def roles
179
+ @roles.keys
180
180
  end
181
181
 
182
- def project_roles(*args)
183
- @project_roles = args if args.any?
184
- ["Follower"] + (@project_roles ||= [])
182
+ def role(role_name, &abilities_block)
183
+ @roles[role_name] = abilities_block
185
184
  end
186
185
 
187
186
  def ticket_types(*args)
@@ -224,7 +223,16 @@ module_function
224
223
 
225
224
  def authentication_strategy(strategy=nil, &block)
226
225
  @authentication_strategy = strategy if strategy
227
- @authentication_strategy_configuration = HashDsl.hash_from_block(block) if block_given?
226
+ if block_given?
227
+ @authentication_strategy_configuration = HashDsl.hash_from_block(block)
228
+
229
+ if authentication_strategy == :ldap
230
+ %i{host port base field username_builder}.each do |required_field|
231
+ next if @authentication_strategy_configuration.key?(required_field)
232
+ raise "#{required_field} is a required field for :ldap authentication"
233
+ end
234
+ end
235
+ end
228
236
 
229
237
  @authentication_strategy
230
238
  end
@@ -269,6 +277,13 @@ module_function
269
277
  context.instance_exec(user, &@abilities_block)
270
278
  end
271
279
 
280
+ def configure_team_abilities(context, teammate)
281
+ teammate.roles.each do |role|
282
+ abilities_block = @roles.fetch(role)
283
+ context.instance_exec(teammate.team, &abilities_block)
284
+ end
285
+ end
286
+
272
287
 
273
288
 
274
289
 
@@ -1,9 +1,5 @@
1
1
  Houston.register_events {{
2
2
 
3
- "antecedent:{type}:released" => params("antecedent").desc("A ticket or commit with an antecedent of {type} was released"),
4
- "antecedent:{type}:resolved" => params("antecedent").desc("A ticket with an antecedent of {type} was resolved"),
5
- "antecedent:{type}:closed" => params("antecedent").desc("A ticket with an antecedent of {type} was closed"),
6
-
7
3
  "commit:create" => params("commit").desc("A new commit was created"),
8
4
 
9
5
  "daemon:{type}:start" => desc("Daemon {type} has started"),
@@ -1,3 +1,3 @@
1
1
  module Houston
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0.pre"
3
3
  end
@@ -1,73 +1,90 @@
1
1
  # This block uses the DSL defined by CanCan.
2
2
  # https://github.com/ryanb/cancan/wiki/Defining-Abilities
3
3
 
4
- Houston.config.abilities do |user|
5
- if user.nil?
4
+ Houston.config do
6
5
 
7
- # Customers are allowed to see Release Notes of products, for production
8
- can :read, Release do |release|
9
- release.project.category == "Products" && (release.environment_name.blank? || release.environment_name == "production")
10
- end
11
6
 
12
- # Customers are allowed to see Features, Improvements, and Bugfixes
13
- can :read, ReleaseChange, tag_slug: %w{feature improvement fix}
7
+ role "Maintainer" do |team|
14
8
 
15
- else
9
+ # Maintainers can create releases
10
+ can :manage, Release, project_id: team.project_ids
16
11
 
17
- # Everyone can see Releases to staging
18
- can :read, Release
12
+ # Maintainers can change projects' settings
13
+ can :update, Project, id: team.project_ids
19
14
 
20
- # Everyone is allowed to see Features, Improvements, and Bugfixes
21
- can :read, ReleaseChange, tag_slug: %w{feature improvement fix}
15
+ end
22
16
 
23
- # Everyone can see Projects
24
- can :read, Project
25
17
 
26
- # Everyone can see Tickets
27
- can :read, Ticket
18
+ role "Developer" do |team|
28
19
 
29
- # Everyone can see Milestones
30
- can :read, Milestone
20
+ # Developers can see commits and can manage
21
+ # tickets, pull requests, and alerts
22
+ can :read, Commit, project_id: team.project_ids
23
+ can :update_tickets, Milestone, project_id: team.project_ids
24
+ can :manage, Task, project_id: team.project_ids
25
+ can :create, Ticket, project_id: team.project_ids
26
+ can :close, Ticket, project_id: team.project_ids
27
+ can :manage, Github::PullRequest, project_id: team.project_ids
28
+ can :manage, Houston::Alerts::Alert, project_id: team.project_ids
29
+ can :manage, Sprint
31
30
 
32
- # Everyone can see Users and update themselves
33
- can :read, User
34
- can :update, user
31
+ end
35
32
 
36
- # Everyone can make themselves a "Follower"
37
- can :create, Role, name: "Follower"
38
33
 
39
- # Everyone can remove themselves from a role
40
- can :destroy, Role, user_id: user.id
34
+ role "Tester" do |team|
41
35
 
42
- # Developers can
43
- # - create tickets
44
- # - see other kinds of Release Changes (like Refactors)
45
- # - update Sprints
46
- # - break tickets into tasks
47
- if user.developer?
48
- can :read, [Commit, ReleaseChange]
49
- can :manage, Sprint
50
- can :manage, Task
51
- end
36
+ # Testers can create tickets and be assigned Alerts
37
+ can :create, Ticket, project_id: team.project_ids
38
+ can :manage, Houston::Alerts::Alert, project_id: team.project_ids
52
39
 
53
- # Testers and Developers can
54
- # - create tickets
55
- # - see and manage alerts
56
- if user.tester? or user.developer?
57
- can :create, Ticket
58
- can :manage, Houston::Alerts::Alert
59
- end
40
+ end
60
41
 
61
- # The following abilities are project-specific and depend on one's role
62
- roles = user.roles.participants
63
- if roles.any?
64
42
 
65
- # Maintainers can manage Releases, close Tickets, and update Projects
66
- roles.maintainers.pluck(:project_id).tap do |project_ids|
67
- can :manage, Release, project_id: project_ids
68
- can :close, Ticket, project_id: project_ids
69
- can :update, Project, id: project_ids
43
+ abilities do |user|
44
+ if user.nil?
45
+
46
+ # Customers are allowed to see Release Notes of products, for production
47
+ can :read, Release do |release|
48
+ release.environment_name == "production"
70
49
  end
50
+
51
+ else
52
+
53
+ if user.admin?
54
+
55
+ # Admins can see Actions
56
+ can :read, Action
57
+
58
+ end
59
+
60
+ # Employees can see Teams
61
+ can :read, Team
62
+
63
+ # Employees can see Releases to staging
64
+ can :read, Release
65
+
66
+ # Employees can see Projects
67
+ can :read, Project
68
+
69
+ # Employees can see Tickets
70
+ can :read, Ticket
71
+
72
+ # Employees can see Roadmaps
73
+ can :read, Roadmap
74
+ can :read, Milestone
75
+
76
+ # Employees can see Users and update themselves
77
+ can :read, User
78
+ can :update, user
79
+
80
+ # Employees can read and tag and create feedback
81
+ can :read, Houston::Feedback::Comment
82
+ can :tag, Houston::Feedback::Comment
83
+ can :create, Houston::Feedback::Comment
84
+
85
+ # Employees can update their own feedback
86
+ can [:update, :destroy], Houston::Feedback::Comment, user_id: user.id
87
+
71
88
  end
72
89
  end
73
90
  end
@@ -1,6 +1,6 @@
1
1
  Houston::Slack.config do
2
2
  overhear(/\b(?<task>\d+[a-z]+)\b/) do |e|
3
- next unless e.user && e.user.developer?
3
+ next unless e.user
4
4
  tasks = Task.joins(:ticket)
5
5
 
6
6
  if project = e.channel.name != "test" && Project.find_by_slug(e.channel.name)
@@ -1,23 +1,31 @@
1
1
  Houston.config do
2
- on "deploy:completed" => "deploy:slack-deployer-of-finished-deploy" do
3
- next if deploy.build_releasignore?
2
+ on "deploy:succeeded" => "deploy:slack-deployer-of-finished-deploy" do
3
+ next if deploy.build_release.ignore?
4
+ next unless deployer = deploy.user
4
5
 
5
- deployer = deploy.user
6
- if deployer
7
- message = "#{deployer.first_name}, your deploy of #{deploy.project.slug} " <<
8
- "to #{deploy.environment_name} just finished. " <<
9
- slack_link_to("Click here to write release notes",
10
- Rails.application.routes.url_helpers.new_release_url(
11
- deploy.project.to_param,
12
- deploy.environment_name,
13
- host: Houston.config.host,
14
- deploy_id: deploy.id,
15
- auth_token: deployer.authentication_token))
16
- slack_send_message_to message, deployer
6
+ message = "#{deployer.first_name}, your deploy of #{deploy.project.slug} " <<
7
+ "to #{deploy.environment_name} just finished. " <<
8
+ slack_link_to("Click here to write release notes",
9
+ Rails.application.routes.url_helpers.new_release_url(
10
+ deploy.project.to_param,
11
+ deploy.environment_name,
12
+ host: Houston.config.host,
13
+ deploy_id: deploy.id,
14
+ auth_token: deployer.authentication_token))
15
+ slack_send_message_to message, deployer
16
+ end
17
+
18
+ on "deploy:succeeded" => "deploy:email-deployer-of-finished-deploy" do
19
+ next if deploy.build_release.ignore?
20
+
21
+ maintainers = deploy.project.maintainers
22
+ maintainers.each do |maintainer|
23
+ Houston.deliver! ProjectNotification.maintainer_of_deploy(maintainer, deploy)
17
24
  end
18
25
 
19
- Houston.try({max_tries: 3}, Net::OpenTimeout) do
20
- DeployNotification.new(deploy).deliver! # <-- after extracting releases, move this to Releases
26
+ deployer = deploy.deployer
27
+ if !deployer.blank? && !maintainers.with_email_address(deployer).exists?
28
+ Houston.deliver! ProjectNotification.maintainer_of_deploy(deployer, deploy)
21
29
  end
22
30
  end
23
31
  end
@@ -0,0 +1,11 @@
1
+ Houston.config do
2
+ on "test_run:complete" => "test_run:email-results" do
3
+ project = test_run.project
4
+ committers = test_run.commits_since_last_test_run.map { |commit| commit.author_email.downcase }
5
+ recipients = (committers + Array(test_run.agent_email)).uniq \
6
+ - project.maintainers.map(&:email) \
7
+ + project.maintainers
8
+
9
+ Houston.deliver! ProjectNotification.test_results(test_run, recipients)
10
+ end
11
+ end
@@ -1,5 +1,9 @@
1
1
  # Houston.config.authentication_strategy :ldap do
2
+ # instructions "You can log in with your corporate username and password"
2
3
  # host "10.5.3.100"
3
4
  # port 636
4
5
  # ssl :simple_tls
6
+ # base "dc=cph, dc=pri"
7
+ # field "samaccountname"
8
+ # username_builder Proc.new { |attribute, login, ldap| "#{login}@cph.pri" }
5
9
  # end
@@ -177,10 +177,13 @@ Houston.config do
177
177
  # bundle config local.houston-<MODULE> ~/Projects/houston-<MODULE>
178
178
  #
179
179
 
180
+ use :feedback
181
+ use :roadmaps
182
+
180
183
  use :alerts do
181
184
 
182
- # Who can be assign an Alert?
183
- workers { User.developers }
185
+ # Who can be assigned an Alert?
186
+ workers { User.unretired }
184
187
 
185
188
  # Set a target-time for the Alert to be closed.
186
189
  # This block sets a goal of closing alerts within
@@ -211,23 +214,13 @@ Houston.config do
211
214
  # Roles and Abilities
212
215
  # ---------------------------------------------------------------------------
213
216
  #
214
- # Every user will have one Role. You can refer to a user's roles when you
215
- # define her abilities. Houston will add the role "Guest" to this list.
216
- # "Guest" is the default role.
217
+ # A user may belong to one or more teams. Within each team, a user can be
218
+ # given one or more team-specific roles. Define those roles and the abilities
219
+ # they grant below.
217
220
  #
218
- # NOTE: Presently, Houston requires that "Tester" be one of these roles.
219
-
220
- roles "Developer",
221
- "Tester"
222
-
223
- # Users additionally have any number of project-specific roles. You can
224
- # refer to these as well when configuring abilities.
221
+ # Houston adds the "Team Owner" role which will be given the ability to manage
222
+ # teams and their projects.
225
223
  #
226
- # NOTE: Presently, Houston requires that "Maintainer" be one of these.
227
-
228
- project_roles "Maintainer",
229
- "Owner"
230
-
231
224
  # Houston uses CanCan to check authorize users to do particular actions.
232
225
  # Houston will pass a user to the block defined below which should declare
233
226
  # what abilities that user has.
@@ -4,7 +4,6 @@ admin:
4
4
  email: admin@example.com
5
5
  email_addresses:
6
6
  - admin@example.com
7
- administrator: true
8
- role: Developer
7
+ role: Owner
9
8
  encrypted_password: $2a$10$Pf9Q94yN7t/YGqGS6pBl5uOL8lUvqgWpGeXRMHGbgPU0ixbWzthOG
10
9
  # password: password
@@ -12,12 +12,12 @@ class CreatingAReleaseTest < ActionDispatch::IntegrationTest
12
12
 
13
13
  @user = User.first
14
14
  @project = Project.create!(
15
+ team: Team.first,
15
16
  name: "Test",
16
17
  slug: "test",
17
18
  ticket_tracker_name: "Houston",
18
19
  version_control_name: "Git",
19
20
  props: {"git.location" => Rails.root.join("test", "data", "bare_repo.git").to_s})
20
- @project.roles.create!(name: "Maintainer", user: user)
21
21
  @ticket = @project.tickets.create!(
22
22
  number: 116,
23
23
  type: "Bug",
@@ -1,5 +1,6 @@
1
1
  FactoryGirl.define do
2
2
  factory :project do
3
+ team { Team.first }
3
4
  name "Test"
4
5
  slug "test"
5
6
  end
@@ -8,6 +8,8 @@ FactoryGirl.define do
8
8
  end
9
9
 
10
10
  factory :developer, :parent => :user do
11
- role "Developer"
11
+ after(:create) do |user|
12
+ Team.first.add_teammate user, "Developer"
13
+ end
12
14
  end
13
15
  end
@@ -0,0 +1,2 @@
1
+ default:
2
+ name: "Default Team"
@@ -0,0 +1,5 @@
1
+ teams_users_1:
2
+ team: default
3
+ user: boblail
4
+ roles:
5
+ - Team Owner
@@ -4,7 +4,6 @@ boblail:
4
4
  email: bob@example.com
5
5
  email_addresses:
6
6
  - bob@example.com
7
- administrator: true
8
- role: Developer
7
+ role: Owner
9
8
  encrypted_password: $2a$10$Pf9Q94yN7t/YGqGS6pBl5uOL8lUvqgWpGeXRMHGbgPU0ixbWzthOG
10
9
  # password: password
@@ -32,7 +32,7 @@ class CIIntegrationTest < ActionDispatch::IntegrationTest
32
32
  should "alert maintainers when a build cannot be triggered" do
33
33
  skip "TMI: This is dependent on configured roles!"
34
34
  @project = create(:project, ci_server_name: "Mock")
35
- project.add_teammate users(:boblail)
35
+ project.team.add_teammate users(:boblail)
36
36
 
37
37
  any_instance_of(Houston::Adapters::CIServer::MockAdapter::Job) do |job|
38
38
  stub(job).build! { |commit| raise Houston::Adapters::CIServer::Error }
@@ -71,7 +71,7 @@ class CIIntegrationTest < ActionDispatch::IntegrationTest
71
71
  commit = "whatever"
72
72
  results_url = "http://example.com/results"
73
73
  @project = create(:project, ci_server_name: "Mock")
74
- project.add_teammate users(:boblail)
74
+ project.team.add_teammate users(:boblail)
75
75
  @test_run = TestRun.create!(project: project, sha: commit)
76
76
 
77
77
  any_instance_of(Houston::Adapters::CIServer::MockAdapter::Job) do |job|
@@ -2,11 +2,9 @@ Houston.config do
2
2
  host "houston.test.com"
3
3
  mailer_sender "houston@test.com"
4
4
 
5
- # TODO: The Sprints feature requires there to be a "Developer" role
6
- roles "Developer", "Tester"
7
-
8
- # TODO: Some tests require the role "Maintainer" to be defined
9
- project_roles "Maintainer"
5
+ role "Developer" do |team|
6
+ can :manage, Sprint
7
+ end
10
8
 
11
9
  # TODO: without ticket_types configured, tests that cover them should be skipped
12
10
  ticket_types({