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
d06de98f
Commit
d06de98f
authored
Aug 24, 2021
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab master
parents
7dea1523
d48341c4
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
224 additions
and
172 deletions
+224
-172
app/assets/javascripts/graphql_shared/constants.js
app/assets/javascripts/graphql_shared/constants.js
+1
-0
app/assets/javascripts/lib/utils/text_markdown.js
app/assets/javascripts/lib/utils/text_markdown.js
+3
-1
app/assets/javascripts/vue_shared/components/markdown/field.vue
...sets/javascripts/vue_shared/components/markdown/field.vue
+11
-2
app/models/concerns/featurable.rb
app/models/concerns/featurable.rb
+21
-0
app/models/project_feature.rb
app/models/project_feature.rb
+4
-12
app/services/ci/after_requeue_job_service.rb
app/services/ci/after_requeue_job_service.rb
+3
-10
config/feature_flags/development/ci_same_stage_job_needs.yml
config/feature_flags/development/ci_same_stage_job_needs.yml
+0
-8
db/post_migrate/20210823193234_remove_allow_editing_commit_messages_from_project_settings.rb
...ve_allow_editing_commit_messages_from_project_settings.rb
+17
-0
db/schema_migrations/20210823193234
db/schema_migrations/20210823193234
+1
-0
db/structure.sql
db/structure.sql
+0
-1
doc/ci/yaml/index.md
doc/ci/yaml/index.md
+1
-2
ee/app/assets/javascripts/security_dashboard/graphql/mutations/note_delete.mutation.graphql
..._dashboard/graphql/mutations/note_delete.mutation.graphql
+8
-0
ee/app/assets/javascripts/vulnerabilities/components/history_comment.vue
...avascripts/vulnerabilities/components/history_comment.vue
+20
-16
ee/spec/frontend/vulnerabilities/history_comment_spec.js
ee/spec/frontend/vulnerabilities/history_comment_spec.js
+71
-41
ee/spec/models/project_feature_spec.rb
ee/spec/models/project_feature_spec.rb
+4
-0
lib/gitlab/ci/pipeline/seed/build.rb
lib/gitlab/ci/pipeline/seed/build.rb
+1
-6
lib/gitlab/ci/yaml_processor.rb
lib/gitlab/ci/yaml_processor.rb
+3
-13
spec/frontend/lib/utils/text_markdown_spec.js
spec/frontend/lib/utils/text_markdown_spec.js
+19
-0
spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
...nents/__snapshots__/snippet_description_edit_spec.js.snap
+1
-0
spec/frontend/vue_shared/components/markdown/field_spec.js
spec/frontend/vue_shared/components/markdown/field_spec.js
+12
-1
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+0
-10
spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
+0
-4
spec/lib/gitlab/ci/yaml_processor_spec.rb
spec/lib/gitlab/ci/yaml_processor_spec.rb
+0
-24
spec/models/concerns/featurable_spec.rb
spec/models/concerns/featurable_spec.rb
+4
-1
spec/models/project_feature_spec.rb
spec/models/project_feature_spec.rb
+7
-10
spec/services/ci/after_requeue_job_service_spec.rb
spec/services/ci/after_requeue_job_service_spec.rb
+0
-10
spec/support/shared_examples/models/concerns/featurable_shared_examples.rb
...ed_examples/models/concerns/featurable_shared_examples.rb
+12
-0
No files found.
app/assets/javascripts/graphql_shared/constants.js
View file @
d06de98f
...
...
@@ -11,3 +11,4 @@ export const TYPE_SCANNER_PROFILE = 'DastScannerProfile';
export
const
TYPE_SITE_PROFILE
=
'
DastSiteProfile
'
;
export
const
TYPE_USER
=
'
User
'
;
export
const
TYPE_VULNERABILITY
=
'
Vulnerability
'
;
export
const
TYPE_NOTE
=
'
Note
'
;
app/assets/javascripts/lib/utils/text_markdown.js
View file @
d06de98f
...
...
@@ -232,7 +232,9 @@ export function insertMarkdownText({
.
join
(
'
\n
'
);
}
}
else
if
(
tag
.
indexOf
(
textPlaceholder
)
>
-
1
)
{
textToInsert
=
tag
.
replace
(
textPlaceholder
,
()
=>
selected
.
replace
(
/
\\
n/g
,
'
\n
'
));
textToInsert
=
tag
.
replace
(
textPlaceholder
,
()
=>
selected
.
replace
(
/
\\
n/g
,
'
\n
'
).
replace
(
/
\/(
n|t|r
)
/g
,
'
\\
$1
'
),
);
}
else
{
textToInsert
=
String
(
startChar
)
+
tag
+
selected
+
(
wrap
?
tag
:
''
);
}
...
...
app/assets/javascripts/vue_shared/components/markdown/field.vue
View file @
d06de98f
...
...
@@ -15,6 +15,14 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import
MarkdownHeader
from
'
./header.vue
'
;
import
MarkdownToolbar
from
'
./toolbar.vue
'
;
function
cleanUpLine
(
content
)
{
return
unescape
(
stripHtml
(
content
)
.
replace
(
/
\\(
n|t|r
)
/g
,
'
/$1
'
)
.
replace
(
/
\n
/g
,
''
),
);
}
export
default
{
components
:
{
GfmAutocomplete
,
...
...
@@ -129,7 +137,7 @@ export default {
return
text
;
}
return
unescape
(
stripHtml
(
richText
).
replace
(
/
\n
/g
,
''
)
);
return
cleanUpLine
(
richText
);
})
.
join
(
'
\\
n
'
);
}
...
...
@@ -141,7 +149,7 @@ export default {
return
text
;
}
return
unescape
(
stripHtml
(
richText
).
replace
(
/
\n
/g
,
''
)
);
return
cleanUpLine
(
richText
);
}
return
''
;
...
...
@@ -272,6 +280,7 @@ export default {
:can-suggest=
"canSuggest"
:show-suggest-popover=
"showSuggestPopover"
:suggestion-start-index=
"suggestionsStartIndex"
data-testid=
"markdownHeader"
@
preview-markdown=
"showPreviewTab"
@
write-markdown=
"showWriteTab"
@
handleSuggestDismissed=
"() => $emit('handleSuggestDismissed')"
...
...
app/models/concerns/featurable.rb
View file @
d06de98f
...
...
@@ -83,6 +83,10 @@ module Featurable
end
end
included
do
validate
:allowed_access_levels
end
def
access_level
(
feature
)
public_send
(
self
.
class
.
access_level_attribute
(
feature
))
# rubocop:disable GitlabSecurity/PublicSend
end
...
...
@@ -94,4 +98,21 @@ module Featurable
def
string_access_level
(
feature
)
self
.
class
.
str_from_access_level
(
access_level
(
feature
))
end
private
def
allowed_access_levels
validator
=
lambda
do
|
field
|
level
=
public_send
(
field
)
||
ENABLED
# rubocop:disable GitlabSecurity/PublicSend
not_allowed
=
level
>
ENABLED
self
.
errors
.
add
(
field
,
"cannot have public visibility level"
)
if
not_allowed
end
(
self
.
class
.
available_features
-
feature_validation_exclusion
).
each
{
|
f
|
validator
.
call
(
"
#{
f
}
_access_level"
)}
end
# Features that we should exclude from the validation
def
feature_validation_exclusion
[]
end
end
app/models/project_feature.rb
View file @
d06de98f
...
...
@@ -54,7 +54,6 @@ class ProjectFeature < ApplicationRecord
validates
:project
,
presence:
true
validate
:repository_children_level
validate
:allowed_access_levels
default_value_for
:builds_access_level
,
value:
ENABLED
,
allows_nil:
false
default_value_for
:issues_access_level
,
value:
ENABLED
,
allows_nil:
false
...
...
@@ -110,17 +109,6 @@ class ProjectFeature < ApplicationRecord
%i(merge_requests_access_level builds_access_level)
.
each
(
&
validator
)
end
# Validates access level for other than pages cannot be PUBLIC
def
allowed_access_levels
validator
=
lambda
do
|
field
|
level
=
public_send
(
field
)
||
ENABLED
# rubocop:disable GitlabSecurity/PublicSend
not_allowed
=
level
>
ENABLED
self
.
errors
.
add
(
field
,
"cannot have public visibility level"
)
if
not_allowed
end
(
FEATURES
-
%i(pages)
).
each
{
|
f
|
validator
.
call
(
"
#{
f
}
_access_level"
)}
end
def
get_permission
(
user
,
feature
)
case
access_level
(
feature
)
when
DISABLED
...
...
@@ -142,6 +130,10 @@ class ProjectFeature < ApplicationRecord
project
.
team
.
member?
(
user
,
ProjectFeature
.
required_minimum_access_level
(
feature
))
end
def
feature_validation_exclusion
%i(pages)
end
end
ProjectFeature
.
prepend_mod_with
(
'ProjectFeature'
)
app/services/ci/after_requeue_job_service.rb
View file @
d06de98f
...
...
@@ -10,16 +10,9 @@ module Ci
private
def
process_subsequent_jobs
(
processable
)
if
Feature
.
enabled?
(
:ci_same_stage_job_needs
,
processable
.
project
,
default_enabled: :yaml
)
(
stage_dependent_jobs
(
processable
)
|
needs_dependent_jobs
(
processable
))
.
each
do
|
processable
|
process
(
processable
)
end
else
skipped_jobs
(
processable
).
after_stage
(
processable
.
stage_idx
)
.
find_each
do
|
job
|
process
(
job
)
end
(
stage_dependent_jobs
(
processable
)
|
needs_dependent_jobs
(
processable
))
.
each
do
|
processable
|
process
(
processable
)
end
end
...
...
config/feature_flags/development/ci_same_stage_job_needs.yml
deleted
100644 → 0
View file @
7dea1523
---
name
:
ci_same_stage_job_needs
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59668
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/328253
milestone
:
'
14.1'
type
:
development
group
:
group::pipeline authoring
default_enabled
:
true
db/post_migrate/20210823193234_remove_allow_editing_commit_messages_from_project_settings.rb
0 → 100644
View file @
d06de98f
# frozen_string_literal: true
class
RemoveAllowEditingCommitMessagesFromProjectSettings
<
ActiveRecord
::
Migration
[
6.1
]
include
Gitlab
::
Database
::
MigrationHelpers
def
up
with_lock_retries
do
remove_column
:project_settings
,
:allow_editing_commit_messages
end
end
def
down
with_lock_retries
do
add_column
:project_settings
,
:allow_editing_commit_messages
,
:boolean
,
default:
false
,
null:
false
end
end
end
db/schema_migrations/20210823193234
0 → 100644
View file @
d06de98f
b85ef326056bb152d527e34b49caa3c40ee8685c3b14654992246c6adf082f8c
\ No newline at end of file
db/structure.sql
View file @
d06de98f
...
...
@@ -17343,7 +17343,6 @@ CREATE TABLE project_settings (
squash_option smallint DEFAULT 3,
has_confluence boolean DEFAULT false NOT NULL,
has_vulnerabilities boolean DEFAULT false NOT NULL,
allow_editing_commit_messages boolean DEFAULT false NOT NULL,
prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL,
cve_id_request_enabled boolean DEFAULT true NOT NULL,
mr_default_target_self boolean DEFAULT false NOT NULL,
doc/ci/yaml/index.md
View file @
d06de98f
...
...
@@ -1594,8 +1594,7 @@ production:
-
In
[
GitLab 14.1 and later
](
https://gitlab.com/gitlab-org/gitlab/-/issues/30632
)
you
can refer to jobs in the same stage as the job you are configuring. This feature is
enabled on GitLab.com and ready for production use. On self-managed
[
GitLab 14.2 and later
](
https://gitlab.com/gitlab-org/gitlab/-/issues/30632
)
this feature is available by default. To hide the feature, ask an administrator to
[
disable the `ci_same_stage_job_needs` flag
](
../../administration/feature_flags.md
)
.
this feature is available by default.
-
In GitLab 14.0 and older, you can only refer to jobs in earlier stages.
-
In GitLab 13.9 and older, if
`needs:`
refers to a job that might not be added to
a pipeline because of
`only`
,
`except`
, or
`rules`
, the pipeline might fail to create.
...
...
ee/app/assets/javascripts/security_dashboard/graphql/mutations/note_delete.mutation.graphql
0 → 100644
View file @
d06de98f
mutation
(
$id
:
ID
!)
{
destroyNote
(
input
:
{
id
:
$id
})
{
errors
note
{
id
}
}
}
ee/app/assets/javascripts/vulnerabilities/components/history_comment.vue
View file @
d06de98f
<
script
>
import
{
GlButton
,
GlSafeHtmlDirective
as
SafeHtml
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
deleteNoteMutation
from
'
ee/security_dashboard/graphql/mutations/note_delete.mutation.graphql
'
;
import
EventItem
from
'
ee/vue_shared/security_reports/components/event_item.vue
'
;
import
createFlash
from
'
~/flash
'
;
import
{
TYPE_NOTE
}
from
'
~/graphql_shared/constants
'
;
import
{
convertToGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
__
,
s__
}
from
'
~/locale
'
;
import
HistoryCommentEditor
from
'
./history_comment_editor.vue
'
;
...
...
@@ -115,25 +118,26 @@ export default {
});
});
},
deleteComment
()
{
async
deleteComment
()
{
this
.
isDeletingComment
=
true
;
const
deleteUrl
=
this
.
comment
.
path
;
axios
.
delete
(
deleteUrl
)
.
then
(()
=>
{
this
.
$emit
(
'
onCommentDeleted
'
,
this
.
comment
);
})
.
catch
(()
=>
createFlash
({
message
:
s__
(
'
VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later.
'
,
),
}),
)
.
finally
(()
=>
{
this
.
isDeletingComment
=
false
;
try
{
await
this
.
$apollo
.
mutate
({
mutation
:
deleteNoteMutation
,
variables
:
{
id
:
convertToGraphQLId
(
TYPE_NOTE
,
this
.
comment
.
id
),
},
});
this
.
$emit
(
'
onCommentDeleted
'
,
this
.
comment
);
}
catch
(
e
)
{
createFlash
({
message
:
s__
(
'
VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later.
'
,
),
});
}
this
.
isDeletingComment
=
false
;
},
cancelEditingComment
()
{
this
.
isEditingComment
=
false
;
...
...
ee/spec/frontend/vulnerabilities/history_comment_spec.js
View file @
d06de98f
import
{
mount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Vue
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
deleteNoteMutation
from
'
ee/security_dashboard/graphql/mutations/note_delete.mutation.graphql
'
;
import
EventItem
from
'
ee/vue_shared/security_reports/components/event_item.vue
'
;
import
HistoryComment
from
'
ee/vulnerabilities/components/history_comment.vue
'
;
import
HistoryCommentEditor
from
'
ee/vulnerabilities/components/history_comment_editor.vue
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
createFlash
from
'
~/flash
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
const
mockAxios
=
new
MockAdapter
(
axios
);
jest
.
mock
(
'
~/flash
'
);
Vue
.
use
(
VueApollo
);
describe
(
'
History Comment
'
,
()
=>
{
let
wrapper
;
const
createWrapper
=
(
comment
)
=>
{
const
createApolloProvider
=
(...
queries
)
=>
{
return
createMockApollo
([...
queries
]);
};
const
createWrapper
=
({
comment
,
apolloProvider
}
=
{})
=>
{
wrapper
=
mount
(
HistoryComment
,
{
apolloProvider
,
propsData
:
{
comment
,
notesUrl
:
'
/notes
'
,
...
...
@@ -138,7 +149,7 @@ describe('History Comment', () => {
});
describe
(
`when there's an existing comment`
,
()
=>
{
beforeEach
(()
=>
createWrapper
(
comment
));
beforeEach
(()
=>
createWrapper
(
{
comment
}
));
it
(
'
shows the comment with the correct user author and timestamp and the edit/delete buttons
'
,
()
=>
{
expectExistingCommentView
();
...
...
@@ -187,44 +198,6 @@ describe('History Comment', () => {
});
});
it
(
'
deletes the comment when the confirm delete button is clicked
'
,
()
=>
{
mockAxios
.
onDelete
().
replyOnce
(
200
);
deleteButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
confirmDeleteButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
expect
(
confirmDeleteButton
().
props
(
'
loading
'
)).
toBe
(
true
);
expect
(
cancelDeleteButton
().
props
(
'
disabled
'
)).
toBe
(
true
);
return
axios
.
waitForAll
();
})
.
then
(()
=>
{
expect
(
mockAxios
.
history
.
delete
).
toHaveLength
(
1
);
expect
(
wrapper
.
emitted
().
onCommentDeleted
).
toBeTruthy
();
expect
(
wrapper
.
emitted
().
onCommentDeleted
[
0
][
0
]).
toEqual
(
comment
);
});
});
it
(
'
shows an error message when the comment cannot be deleted
'
,
()
=>
{
mockAxios
.
onDelete
().
replyOnce
(
500
);
deleteButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
confirmDeleteButton
().
trigger
(
'
click
'
);
return
axios
.
waitForAll
();
})
.
then
(()
=>
{
expect
(
mockAxios
.
history
.
delete
).
toHaveLength
(
1
);
expect
(
createFlash
).
toHaveBeenCalledTimes
(
1
);
});
});
it
(
'
saves the comment when the save button is clicked on the comment editor
'
,
()
=>
{
const
responseData
=
{
...
comment
,
note
:
'
new comment
'
};
mockAxios
.
onPut
().
replyOnce
(
200
,
responseData
);
...
...
@@ -261,9 +234,66 @@ describe('History Comment', () => {
});
});
describe
(
'
deleting a note
'
,
()
=>
{
it
(
'
deletes the comment when the confirm delete button is clicked
'
,
async
()
=>
{
createWrapper
({
comment
,
apolloProvider
:
createApolloProvider
([
deleteNoteMutation
,
jest
.
fn
().
mockResolvedValue
({
data
:
{
destroyNote
:
{
errors
:
[],
note
:
null
,
},
},
}),
]),
});
deleteButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
confirmDeleteButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
confirmDeleteButton
().
props
(
'
loading
'
)).
toBe
(
true
);
expect
(
cancelDeleteButton
().
props
(
'
disabled
'
)).
toBe
(
true
);
await
axios
.
waitForAll
();
expect
(
wrapper
.
emitted
().
onCommentDeleted
).
toBeTruthy
();
expect
(
wrapper
.
emitted
().
onCommentDeleted
[
0
][
0
]).
toEqual
(
comment
);
});
it
(
'
shows an error message when the comment cannot be deleted
'
,
async
()
=>
{
createWrapper
({
comment
,
apolloProvider
:
createApolloProvider
([
deleteNoteMutation
,
jest
.
fn
().
mockRejectedValue
({
data
:
{
destroyNote
:
{
errors
:
[{
message
:
'
Something went wrong
'
}],
note
:
null
,
},
},
}),
]),
});
deleteButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
confirmDeleteButton
().
trigger
(
'
click
'
);
await
axios
.
waitForAll
();
expect
(
createFlash
).
toHaveBeenCalledTimes
(
1
);
});
});
describe
(
'
no permission to edit existing comment
'
,
()
=>
{
it
(
'
does not show the edit/delete buttons if the current user has no edit permissions
'
,
()
=>
{
createWrapper
({
...
comment
,
currentUser
:
{
canEdit
:
false
}
});
createWrapper
({
comment
:
{
...
comment
,
currentUser
:
{
canEdit
:
false
}
}
});
expect
(
editButton
().
exists
()).
toBe
(
false
);
expect
(
deleteButton
().
exists
()).
toBe
(
false
);
...
...
ee/spec/models/project_feature_spec.rb
View file @
d06de98f
...
...
@@ -54,4 +54,8 @@ RSpec.describe ProjectFeature do
end
end
end
it_behaves_like
'access level validation'
,
ProjectFeature
::
EE_FEATURES
do
let
(
:container_features
)
{
project
.
project_feature
}
end
end
lib/gitlab/ci/pipeline/seed/build.rb
View file @
d06de98f
...
...
@@ -15,12 +15,7 @@ module Gitlab
@context
=
context
@pipeline
=
context
.
pipeline
@seed_attributes
=
attributes
@stages_for_needs_lookup
=
if
Feature
.
enabled?
(
:ci_same_stage_job_needs
,
@pipeline
.
project
,
default_enabled: :yaml
)
(
previous_stages
+
[
current_stage
]).
compact
else
previous_stages
end
@stages_for_needs_lookup
=
(
previous_stages
+
[
current_stage
]).
compact
@needs_attributes
=
dig
(
:needs_attributes
)
@resource_group_key
=
attributes
.
delete
(
:resource_group_key
)
@job_variables
=
@seed_attributes
.
delete
(
:job_variables
)
...
...
lib/gitlab/ci/yaml_processor.rb
View file @
d06de98f
...
...
@@ -47,9 +47,7 @@ module Gitlab
validate_job!
(
name
,
job
)
end
if
::
Feature
.
enabled?
(
:ci_same_stage_job_needs
,
@opts
[
:project
],
default_enabled: :yaml
)
YamlProcessor
::
Dag
.
check_circular_dependencies!
(
@jobs
)
end
YamlProcessor
::
Dag
.
check_circular_dependencies!
(
@jobs
)
end
def
validate_job!
(
name
,
job
)
...
...
@@ -103,16 +101,8 @@ module Gitlab
job_stage_index
=
stage_index
(
name
)
dependency_stage_index
=
stage_index
(
dependency
)
if
::
Feature
.
enabled?
(
:ci_same_stage_job_needs
,
@opts
[
:project
],
default_enabled: :yaml
)
unless
dependency_stage_index
.
present?
&&
dependency_stage_index
<=
job_stage_index
error!
(
"
#{
name
}
job:
#{
dependency_type
}
#{
dependency
}
is not defined in current or prior stages"
)
end
else
# A dependency might be defined later in the configuration
# with a stage that does not exist
unless
dependency_stage_index
.
present?
&&
dependency_stage_index
<
job_stage_index
error!
(
"
#{
name
}
job:
#{
dependency_type
}
#{
dependency
}
is not defined in prior stages"
)
end
unless
dependency_stage_index
.
present?
&&
dependency_stage_index
<=
job_stage_index
error!
(
"
#{
name
}
job:
#{
dependency_type
}
#{
dependency
}
is not defined in current or prior stages"
)
end
end
...
...
spec/frontend/lib/utils/text_markdown_spec.js
View file @
d06de98f
...
...
@@ -88,6 +88,25 @@ describe('init markdown', () => {
expect
(
textArea
.
value
).
toEqual
(
`
${
initialValue
}
\n- `
);
});
it
(
'
unescapes new line characters
'
,
()
=>
{
const
initialValue
=
''
;
textArea
.
value
=
initialValue
;
textArea
.
selectionStart
=
0
;
textArea
.
selectionEnd
=
0
;
insertMarkdownText
({
textArea
,
text
:
textArea
.
value
,
tag
:
'
```suggestion:-0+0
\n
{text}
\n
```
'
,
blockTag
:
true
,
selected
:
'
# Does not parse the /n currently.
'
,
wrap
:
false
,
});
expect
(
textArea
.
value
).
toContain
(
'
# Does not parse the
\\
n currently.
'
);
});
it
(
'
inserts the tag on the same line if the current line only contains spaces
'
,
()
=>
{
const
initialValue
=
'
'
;
...
...
spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
View file @
d06de98f
...
...
@@ -28,6 +28,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
data-uploads-path=""
>
<markdown-header-stub
data-testid="markdownHeader"
linecontent=""
suggestionstartindex="0"
/>
...
...
spec/frontend/vue_shared/components/markdown/field_spec.js
View file @
d06de98f
...
...
@@ -32,7 +32,7 @@ describe('Markdown field component', () => {
axiosMock
.
restore
();
});
function
createSubject
()
{
function
createSubject
(
lines
=
[]
)
{
// We actually mount a wrapper component so that we can force Vue to rerender classes in order to test a regression
// caused by mixing Vanilla JS and Vue.
subject
=
mount
(
...
...
@@ -60,6 +60,7 @@ describe('Markdown field component', () => {
markdownPreviewPath
,
isSubmitting
:
false
,
textareaValue
,
lines
,
},
},
);
...
...
@@ -243,4 +244,14 @@ describe('Markdown field component', () => {
});
});
});
describe
(
'
suggestions
'
,
()
=>
{
it
(
'
escapes new line characters
'
,
()
=>
{
createSubject
([{
rich_text
:
'
hello world
\\
n
'
}]);
expect
(
subject
.
find
(
'
[data-testid="markdownHeader"]
'
).
props
(
'
lineContent
'
)).
toBe
(
'
hello world/n
'
,
);
});
});
});
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
View file @
d06de98f
...
...
@@ -1140,16 +1140,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
it
'does not have errors'
do
expect
(
subject
.
errors
).
to
be_empty
end
context
'when ci_same_stage_job_needs FF is disabled'
do
before
do
stub_feature_flags
(
ci_same_stage_job_needs:
false
)
end
it
'has errors'
do
expect
(
subject
.
errors
).
to
contain_exactly
(
"'rspec' job needs 'build' job, but 'build' is not in any previous stage"
)
end
end
end
context
'when using 101 needs'
do
...
...
spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
View file @
d06de98f
...
...
@@ -34,10 +34,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Pipeline do
described_class
.
new
(
seed_context
,
stages_attributes
)
end
before
do
stub_feature_flags
(
ci_same_stage_job_needs:
false
)
end
describe
'#stages'
do
it
'returns the stage resources'
do
stages
=
seed
.
stages
...
...
spec/lib/gitlab/ci/yaml_processor_spec.rb
View file @
d06de98f
...
...
@@ -590,14 +590,6 @@ module Gitlab
end
it_behaves_like
'has warnings and expected error'
,
/build job: need test is not defined in current or prior stages/
context
'with ci_same_stage_job_needs FF disabled'
do
before
do
stub_feature_flags
(
ci_same_stage_job_needs:
false
)
end
it_behaves_like
'has warnings and expected error'
,
/build job: need test is not defined in prior stages/
end
end
end
end
...
...
@@ -1809,14 +1801,6 @@ module Gitlab
let
(
:dependencies
)
{
[
'deploy'
]
}
it_behaves_like
'returns errors'
,
'test1 job: dependency deploy is not defined in current or prior stages'
context
'with ci_same_stage_job_needs FF disabled'
do
before
do
stub_feature_flags
(
ci_same_stage_job_needs:
false
)
end
it_behaves_like
'returns errors'
,
'test1 job: dependency deploy is not defined in prior stages'
end
end
context
'when a job depends on another job that references a not-yet defined stage'
do
...
...
@@ -2053,14 +2037,6 @@ module Gitlab
let
(
:needs
)
{
[
'deploy'
]
}
it_behaves_like
'returns errors'
,
'test1 job: need deploy is not defined in current or prior stages'
context
'with ci_same_stage_job_needs FF disabled'
do
before
do
stub_feature_flags
(
ci_same_stage_job_needs:
false
)
end
it_behaves_like
'returns errors'
,
'test1 job: need deploy is not defined in prior stages'
end
end
context
'needs and dependencies that are mismatching'
do
...
...
spec/models/concerns/featurable_spec.rb
View file @
d06de98f
...
...
@@ -30,8 +30,11 @@ RSpec.describe Featurable do
describe
'.set_available_features'
do
let!
(
:klass
)
do
Class
.
new
do
Class
.
new
(
ApplicationRecord
)
do
include
Featurable
self
.
table_name
=
'project_features'
set_available_features
%i(feature1 feature2)
def
feature1_access_level
...
...
spec/models/project_feature_spec.rb
View file @
d06de98f
...
...
@@ -41,18 +41,15 @@ RSpec.describe ProjectFeature do
end
end
context
'public features'
do
features
=
ProjectFeature
::
FEATURES
-
%i(pages)
it_behaves_like
'access level validation'
,
ProjectFeature
::
FEATURES
-
%i(pages)
do
let
(
:container_features
)
{
project
.
project_feature
}
end
features
.
each
do
|
feature
|
it
"does not allow public access level for
#{
feature
}
"
do
project_feature
=
project
.
project_feature
field
=
"
#{
feature
}
_access_level"
.
to_sym
project_feature
.
update_attribute
(
field
,
ProjectFeature
::
PUBLIC
)
it
'allows public access level for :pages feature'
do
project_feature
=
project
.
project_feature
project_feature
.
pages_access_level
=
ProjectFeature
::
PUBLIC
expect
(
project_feature
.
valid?
).
to
be_falsy
,
"
#{
field
}
failed"
end
end
expect
(
project_feature
.
valid?
).
to
be_truthy
end
describe
'default pages access level'
do
...
...
spec/services/ci/after_requeue_job_service_spec.rb
View file @
d06de98f
...
...
@@ -44,16 +44,6 @@ RSpec.describe Ci::AfterRequeueJobService do
it
'marks subsequent skipped jobs as processable'
do
expect
{
execute_service
}.
to
change
{
test4
.
reload
.
status
}.
from
(
'skipped'
).
to
(
'created'
)
end
context
'with ci_same_stage_job_needs FF disabled'
do
before
do
stub_feature_flags
(
ci_same_stage_job_needs:
false
)
end
it
'does nothing with the build'
do
expect
{
execute_service
}.
not_to
change
{
test4
.
reload
.
status
}
end
end
end
context
'when the pipeline is a downstream pipeline and the bridge is depended'
do
...
...
spec/support/shared_examples/models/concerns/featurable_shared_examples.rb
0 → 100644
View file @
d06de98f
# frozen_string_literal: true
RSpec
.
shared_examples
'access level validation'
do
|
features
|
features
.
each
do
|
feature
|
it
"does not allow public access level for
#{
feature
}
"
do
field
=
"
#{
feature
}
_access_level"
.
to_sym
container_features
.
update_attribute
(
field
,
ProjectFeature
::
PUBLIC
)
expect
(
container_features
.
valid?
).
to
be_falsy
,
"
#{
field
}
failed"
end
end
end
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