houston-core 0.7.0 → 0.8.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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({