Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
2e2e6f95
Commit
2e2e6f95
authored
Dec 08, 2020
by
Sean Arnold
Committed by
Mayra Cabrera
Dec 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add oncall rotation and participant table
- Add migrations - Add models - Add specs
parent
e01351e1
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
364 additions
and
0 deletions
+364
-0
app/models/concerns/enums/data_visualization_palette.rb
app/models/concerns/enums/data_visualization_palette.rb
+33
-0
changelogs/unreleased/262857-creation-rotation-table-models.yml
...logs/unreleased/262857-creation-rotation-table-models.yml
+5
-0
db/migrate/20201124030537_create_incident_management_on_call_rotations.rb
...124030537_create_incident_management_on_call_rotations.rb
+35
-0
db/migrate/20201125233219_add_incident_management_on_call_participants.rb
...125233219_add_incident_management_on_call_participants.rb
+33
-0
db/schema_migrations/20201124030537
db/schema_migrations/20201124030537
+1
-0
db/schema_migrations/20201125233219
db/schema_migrations/20201125233219
+1
-0
db/structure.sql
db/structure.sql
+67
-0
ee/app/models/incident_management/oncall_participant.rb
ee/app/models/incident_management/oncall_participant.rb
+31
-0
ee/app/models/incident_management/oncall_rotation.rb
ee/app/models/incident_management/oncall_rotation.rb
+26
-0
ee/app/models/incident_management/oncall_schedule.rb
ee/app/models/incident_management/oncall_schedule.rb
+2
-0
ee/spec/factories/incident_management/oncall_participant.rb
ee/spec/factories/incident_management/oncall_participant.rb
+10
-0
ee/spec/factories/incident_management/oncall_rotations.rb
ee/spec/factories/incident_management/oncall_rotations.rb
+11
-0
ee/spec/models/incident_management/oncall_participant_spec.rb
...pec/models/incident_management/oncall_participant_spec.rb
+72
-0
ee/spec/models/incident_management/oncall_rotation_spec.rb
ee/spec/models/incident_management/oncall_rotation_spec.rb
+35
-0
ee/spec/models/incident_management/oncall_schedule_spec.rb
ee/spec/models/incident_management/oncall_schedule_spec.rb
+2
-0
No files found.
app/models/concerns/enums/data_visualization_palette.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
module
Enums
# These color palettes are part of the Pajamas Design System.
# See https://design.gitlab.com/data-visualization/color/#categorical-data
module
DataVisualizationPalette
def
self
.
colors
{
blue:
0
,
orange:
1
,
aqua:
2
,
green:
3
,
magenta:
4
}
end
def
self
.
weights
{
'50'
=>
0
,
'100'
=>
1
,
'200'
=>
2
,
'300'
=>
3
,
'400'
=>
4
,
'500'
=>
5
,
'600'
=>
6
,
'700'
=>
7
,
'800'
=>
8
,
'900'
=>
9
,
'950'
=>
10
}
end
end
end
changelogs/unreleased/262857-creation-rotation-table-models.yml
0 → 100644
View file @
2e2e6f95
---
title
:
Add oncall rotations and participants tables
merge_request
:
49058
author
:
type
:
added
db/migrate/20201124030537_create_incident_management_on_call_rotations.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
class
CreateIncidentManagementOnCallRotations
<
ActiveRecord
::
Migration
[
6.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
unless
table_exists?
(
:incident_management_oncall_rotations
)
with_lock_retries
do
create_table
:incident_management_oncall_rotations
do
|
t
|
t
.
timestamps_with_timezone
t
.
references
:oncall_schedule
,
index:
false
,
null:
false
,
foreign_key:
{
to_table: :incident_management_oncall_schedules
,
on_delete: :cascade
}
t
.
integer
:length
,
null:
false
t
.
integer
:length_unit
,
limit:
2
,
null:
false
t
.
datetime_with_timezone
:starts_at
,
null:
false
t
.
text
:name
,
null:
false
t
.
index
%w(oncall_schedule_id id)
,
name:
'index_inc_mgmnt_oncall_rotations_on_oncall_schedule_id_and_id'
,
unique:
true
,
using: :btree
t
.
index
%w(oncall_schedule_id name)
,
name:
'index_inc_mgmnt_oncall_rotations_on_oncall_schedule_id_and_name'
,
unique:
true
,
using: :btree
end
end
end
add_text_limit
:incident_management_oncall_rotations
,
:name
,
200
end
def
down
with_lock_retries
do
drop_table
:incident_management_oncall_rotations
end
end
end
db/migrate/20201125233219_add_incident_management_on_call_participants.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
class
AddIncidentManagementOnCallParticipants
<
ActiveRecord
::
Migration
[
6.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
PARTICIPANT_ROTATION_INDEX_NAME
=
'index_inc_mgmnt_oncall_participants_on_oncall_rotation_id'
PARTICIPANT_USER_INDEX_NAME
=
'index_inc_mgmnt_oncall_participants_on_oncall_user_id'
UNIQUE_INDEX_NAME
=
'index_inc_mgmnt_oncall_participants_on_user_id_and_rotation_id'
disable_ddl_transaction!
def
up
unless
table_exists?
(
:incident_management_oncall_participants
)
with_lock_retries
do
create_table
:incident_management_oncall_participants
do
|
t
|
t
.
references
:oncall_rotation
,
index:
false
,
null:
false
,
foreign_key:
{
to_table: :incident_management_oncall_rotations
,
on_delete: :cascade
}
t
.
references
:user
,
index:
false
,
null:
false
,
foreign_key:
{
on_delete: :cascade
}
t
.
integer
:color_palette
,
limit:
2
,
null:
false
t
.
integer
:color_weight
,
limit:
2
,
null:
false
t
.
index
:user_id
,
name:
PARTICIPANT_USER_INDEX_NAME
t
.
index
:oncall_rotation_id
,
name:
PARTICIPANT_ROTATION_INDEX_NAME
t
.
index
[
:user_id
,
:oncall_rotation_id
],
unique:
true
,
name:
UNIQUE_INDEX_NAME
end
end
end
end
def
down
drop_table
:incident_management_oncall_participants
end
end
db/schema_migrations/20201124030537
0 → 100644
View file @
2e2e6f95
2929b74d9b9d6e205c0e1fb2aaaffe323394058f6e583c56035a2c83b4d4ff03
\ No newline at end of file
db/schema_migrations/20201125233219
0 → 100644
View file @
2e2e6f95
451d7f29392f965467f364c7b119d269551e2dc1485e8cb15ebd14753fdb6e6a
\ No newline at end of file
db/structure.sql
View file @
2e2e6f95
...
...
@@ -12989,6 +12989,44 @@ CREATE SEQUENCE import_failures_id_seq
ALTER
SEQUENCE
import_failures_id_seq
OWNED
BY
import_failures
.
id
;
CREATE
TABLE
incident_management_oncall_participants
(
id
bigint
NOT
NULL
,
oncall_rotation_id
bigint
NOT
NULL
,
user_id
bigint
NOT
NULL
,
color_palette
smallint
NOT
NULL
,
color_weight
smallint
NOT
NULL
);
CREATE
SEQUENCE
incident_management_oncall_participants_id_seq
START
WITH
1
INCREMENT
BY
1
NO
MINVALUE
NO
MAXVALUE
CACHE
1
;
ALTER
SEQUENCE
incident_management_oncall_participants_id_seq
OWNED
BY
incident_management_oncall_participants
.
id
;
CREATE
TABLE
incident_management_oncall_rotations
(
id
bigint
NOT
NULL
,
created_at
timestamp
with
time
zone
NOT
NULL
,
updated_at
timestamp
with
time
zone
NOT
NULL
,
oncall_schedule_id
bigint
NOT
NULL
,
length
integer
NOT
NULL
,
length_unit
smallint
NOT
NULL
,
starts_at
timestamp
with
time
zone
NOT
NULL
,
name
text
NOT
NULL
,
CONSTRAINT
check_5209fb5d02
CHECK
((
char_length
(
name
)
<=
200
))
);
CREATE
SEQUENCE
incident_management_oncall_rotations_id_seq
START
WITH
1
INCREMENT
BY
1
NO
MINVALUE
NO
MAXVALUE
CACHE
1
;
ALTER
SEQUENCE
incident_management_oncall_rotations_id_seq
OWNED
BY
incident_management_oncall_rotations
.
id
;
CREATE
TABLE
incident_management_oncall_schedules
(
id
bigint
NOT
NULL
,
created_at
timestamp
with
time
zone
NOT
NULL
,
...
...
@@ -18231,6 +18269,10 @@ ALTER TABLE ONLY import_export_uploads ALTER COLUMN id SET DEFAULT nextval('impo
ALTER
TABLE
ONLY
import_failures
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'import_failures_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
incident_management_oncall_participants
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'incident_management_oncall_participants_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
incident_management_oncall_rotations
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'incident_management_oncall_rotations_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
incident_management_oncall_schedules
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'incident_management_oncall_schedules_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
index_statuses
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'index_statuses_id_seq'
::
regclass
);
...
...
@@ -19440,6 +19482,12 @@ ALTER TABLE ONLY import_export_uploads
ALTER
TABLE
ONLY
import_failures
ADD
CONSTRAINT
import_failures_pkey
PRIMARY
KEY
(
id
);
ALTER
TABLE
ONLY
incident_management_oncall_participants
ADD
CONSTRAINT
incident_management_oncall_participants_pkey
PRIMARY
KEY
(
id
);
ALTER
TABLE
ONLY
incident_management_oncall_rotations
ADD
CONSTRAINT
incident_management_oncall_rotations_pkey
PRIMARY
KEY
(
id
);
ALTER
TABLE
ONLY
incident_management_oncall_schedules
ADD
CONSTRAINT
incident_management_oncall_schedules_pkey
PRIMARY
KEY
(
id
);
...
...
@@ -21373,6 +21421,16 @@ CREATE INDEX index_import_failures_on_project_id_not_null ON import_failures USI
CREATE
INDEX
index_imported_projects_on_import_type_creator_id_created_at
ON
projects
USING
btree
(
import_type
,
creator_id
,
created_at
)
WHERE
(
import_type
IS
NOT
NULL
);
CREATE
INDEX
index_inc_mgmnt_oncall_participants_on_oncall_rotation_id
ON
incident_management_oncall_participants
USING
btree
(
oncall_rotation_id
);
CREATE
INDEX
index_inc_mgmnt_oncall_participants_on_oncall_user_id
ON
incident_management_oncall_participants
USING
btree
(
user_id
);
CREATE
UNIQUE
INDEX
index_inc_mgmnt_oncall_participants_on_user_id_and_rotation_id
ON
incident_management_oncall_participants
USING
btree
(
user_id
,
oncall_rotation_id
);
CREATE
UNIQUE
INDEX
index_inc_mgmnt_oncall_rotations_on_oncall_schedule_id_and_id
ON
incident_management_oncall_rotations
USING
btree
(
oncall_schedule_id
,
id
);
CREATE
UNIQUE
INDEX
index_inc_mgmnt_oncall_rotations_on_oncall_schedule_id_and_name
ON
incident_management_oncall_rotations
USING
btree
(
oncall_schedule_id
,
name
);
CREATE
INDEX
index_incident_management_oncall_schedules_on_project_id
ON
incident_management_oncall_schedules
USING
btree
(
project_id
);
CREATE
UNIQUE
INDEX
index_index_statuses_on_project_id
ON
index_statuses
USING
btree
(
project_id
);
...
...
@@ -23745,6 +23803,9 @@ ALTER TABLE ONLY namespace_statistics
ALTER
TABLE
ONLY
clusters_applications_elastic_stacks
ADD
CONSTRAINT
fk_rails_026f219f46
FOREIGN
KEY
(
cluster_id
)
REFERENCES
clusters
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
incident_management_oncall_participants
ADD
CONSTRAINT
fk_rails_032b12996a
FOREIGN
KEY
(
oncall_rotation_id
)
REFERENCES
incident_management_oncall_rotations
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
events
ADD
CONSTRAINT
fk_rails_0434b48643
FOREIGN
KEY
(
project_id
)
REFERENCES
projects
(
id
)
ON
DELETE
CASCADE
;
...
...
@@ -23922,6 +23983,9 @@ ALTER TABLE ONLY saml_group_links
ALTER
TABLE
ONLY
group_custom_attributes
ADD
CONSTRAINT
fk_rails_246e0db83a
FOREIGN
KEY
(
group_id
)
REFERENCES
namespaces
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
incident_management_oncall_rotations
ADD
CONSTRAINT
fk_rails_256e0bc604
FOREIGN
KEY
(
oncall_schedule_id
)
REFERENCES
incident_management_oncall_schedules
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
analytics_devops_adoption_snapshots
ADD
CONSTRAINT
fk_rails_25da9a92c0
FOREIGN
KEY
(
segment_id
)
REFERENCES
analytics_devops_adoption_segments
(
id
)
ON
DELETE
CASCADE
;
...
...
@@ -24252,6 +24316,9 @@ ALTER TABLE ONLY resource_weight_events
ALTER
TABLE
ONLY
approval_project_rules
ADD
CONSTRAINT
fk_rails_5fb4dd100b
FOREIGN
KEY
(
project_id
)
REFERENCES
projects
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
incident_management_oncall_participants
ADD
CONSTRAINT
fk_rails_5fe86ea341
FOREIGN
KEY
(
user_id
)
REFERENCES
users
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
user_highest_roles
ADD
CONSTRAINT
fk_rails_60f6c325a6
FOREIGN
KEY
(
user_id
)
REFERENCES
users
(
id
)
ON
DELETE
CASCADE
;
...
...
ee/app/models/incident_management/oncall_participant.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
module
IncidentManagement
class
OncallParticipant
<
ApplicationRecord
include
BulkInsertSafe
self
.
table_name
=
'incident_management_oncall_participants'
enum
color_palette:
Enums
::
DataVisualizationPalette
.
colors
enum
color_weight:
Enums
::
DataVisualizationPalette
.
weights
belongs_to
:rotation
,
class_name:
'OncallRotation'
,
foreign_key: :oncall_rotation_id
belongs_to
:user
,
class_name:
'User'
,
foreign_key: :user_id
validates
:rotation
,
presence:
true
validates
:color_palette
,
presence:
true
validates
:color_weight
,
presence:
true
validates
:user
,
presence:
true
,
uniqueness:
{
scope: :oncall_rotation_id
}
validate
:user_can_read_project
,
if: :user
,
on: :create
delegate
:project
,
to: :rotation
,
allow_nil:
true
private
def
user_can_read_project
unless
user
.
can?
(
:read_project
,
project
)
errors
.
add
(
:user
,
'does not have access to the project'
)
end
end
end
end
ee/app/models/incident_management/oncall_rotation.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
module
IncidentManagement
class
OncallRotation
<
ApplicationRecord
self
.
table_name
=
'incident_management_oncall_rotations'
enum
length_unit:
{
hours:
0
,
days:
1
,
weeks:
2
}
NAME_LENGTH
=
200
belongs_to
:schedule
,
class_name:
'OncallSchedule'
,
inverse_of:
'rotations'
,
foreign_key:
'oncall_schedule_id'
has_many
:participants
,
class_name:
'OncallParticipant'
,
inverse_of: :rotation
has_many
:users
,
through: :participants
validates
:name
,
presence:
true
,
uniqueness:
{
scope: :oncall_schedule_id
},
length:
{
maximum:
NAME_LENGTH
}
validates
:starts_at
,
presence:
true
validates
:length
,
presence:
true
validates
:length_unit
,
presence:
true
delegate
:project
,
to: :schedule
end
end
ee/app/models/incident_management/oncall_schedule.rb
View file @
2e2e6f95
...
...
@@ -11,6 +11,8 @@ module IncidentManagement
DESCRIPTION_LENGTH
=
1000
belongs_to
:project
,
inverse_of: :incident_management_oncall_schedules
has_many
:rotations
,
class_name:
'OncallRotation'
has_many
:participants
,
class_name:
'OncallParticipant'
,
through: :rotations
has_internal_id
:iid
,
scope: :project
...
...
ee/spec/factories/incident_management/oncall_participant.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:incident_management_oncall_participant
,
class:
'IncidentManagement::OncallParticipant'
do
association
:rotation
,
factory: :incident_management_oncall_rotation
association
:user
,
factory: :user
color_palette
{
IncidentManagement
::
OncallParticipant
.
color_palettes
.
first
.
first
}
color_weight
{
IncidentManagement
::
OncallParticipant
.
color_weights
.
first
.
first
}
end
end
ee/spec/factories/incident_management/oncall_rotations.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:incident_management_oncall_rotation
,
class:
'IncidentManagement::OncallRotation'
do
association
:schedule
,
factory: :incident_management_oncall_schedule
sequence
(
:name
)
{
|
n
|
"On-call Rotation #
#{
n
}
"
}
starts_at
{
Time
.
current
}
length
{
5
}
length_unit
{
:days
}
end
end
ee/spec/models/incident_management/oncall_participant_spec.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
IncidentManagement
::
OncallParticipant
do
let_it_be
(
:rotation
)
{
create
(
:incident_management_oncall_rotation
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
subject
{
build
(
:incident_management_oncall_participant
,
rotation:
rotation
,
user:
user
)
}
it
{
is_expected
.
to
be_valid
}
before_all
do
rotation
.
project
.
add_developer
(
user
)
end
describe
'.associations'
do
it
{
is_expected
.
to
belong_to
(
:rotation
)
}
it
{
is_expected
.
to
belong_to
(
:user
)
}
end
describe
'.validations'
do
it
{
is_expected
.
to
validate_presence_of
(
:rotation
)
}
it
{
is_expected
.
to
validate_presence_of
(
:user
)
}
it
{
is_expected
.
to
validate_presence_of
(
:color_weight
)
}
it
{
is_expected
.
to
validate_presence_of
(
:color_palette
)
}
context
'when the participant already exists in the rotation'
do
before
do
create
(
:incident_management_oncall_participant
,
rotation:
rotation
,
user:
user
)
end
it
'has validation errors'
do
expect
(
subject
).
to
be_invalid
expect
(
subject
.
errors
.
full_messages
.
to_sentence
).
to
eq
(
'User has already been taken'
)
end
end
context
'when participant cannot read project'
do
let_it_be
(
:other_user
)
{
create
(
:user
)
}
subject
{
build
(
:incident_management_oncall_participant
,
rotation:
rotation
,
user:
other_user
)
}
context
'on creation'
do
it
'has validation errors'
do
expect
(
subject
).
to
be_invalid
expect
(
subject
.
errors
.
full_messages
.
to_sentence
).
to
eq
(
'User does not have access to the project'
)
end
end
context
'after creation'
do
let
(
:project
)
{
rotation
.
project
}
before
do
project
.
add_developer
(
other_user
)
end
it
'is valid'
do
subject
.
save!
remove_user_from_project
(
other_user
,
project
)
expect
(
subject
).
to
be_valid
end
end
end
end
private
def
remove_user_from_project
(
user
,
project
)
Members
::
DestroyService
.
new
(
user
).
execute
(
project
.
project_member
(
user
))
end
end
ee/spec/models/incident_management/oncall_rotation_spec.rb
0 → 100644
View file @
2e2e6f95
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
IncidentManagement
::
OncallRotation
do
let_it_be
(
:schedule
)
{
create
(
:incident_management_oncall_schedule
)
}
describe
'.associations'
do
it
{
is_expected
.
to
belong_to
(
:schedule
)
}
it
{
is_expected
.
to
have_many
(
:participants
)
}
it
{
is_expected
.
to
have_many
(
:users
).
through
(
:participants
)
}
end
describe
'.validations'
do
subject
{
build
(
:incident_management_oncall_rotation
,
schedule:
schedule
,
name:
'Test rotation'
)
}
it
{
is_expected
.
to
validate_presence_of
(
:name
)
}
it
{
is_expected
.
to
validate_length_of
(
:name
).
is_at_most
(
200
)
}
it
{
is_expected
.
to
validate_uniqueness_of
(
:name
).
scoped_to
(
:oncall_schedule_id
)
}
it
{
is_expected
.
to
validate_presence_of
(
:starts_at
)
}
it
{
is_expected
.
to
validate_presence_of
(
:length
)
}
it
{
is_expected
.
to
validate_presence_of
(
:length_unit
)
}
context
'when the oncall rotation with the same name exists'
do
before
do
create
(
:incident_management_oncall_rotation
,
schedule:
schedule
,
name:
'Test rotation'
)
end
it
'has validation errors'
do
expect
(
subject
).
to
be_invalid
expect
(
subject
.
errors
.
full_messages
.
to_sentence
).
to
eq
(
'Name has already been taken'
)
end
end
end
end
ee/spec/models/incident_management/oncall_schedule_spec.rb
View file @
2e2e6f95
...
...
@@ -7,6 +7,8 @@ RSpec.describe IncidentManagement::OncallSchedule do
describe
'.associations'
do
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
have_many
(
:rotations
)
}
it
{
is_expected
.
to
have_many
(
:participants
).
through
(
:rotations
)
}
end
describe
'.validations'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment