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
de2bb111
Commit
de2bb111
authored
Oct 07, 2021
by
Jeremy Jackson
Committed by
Olena Horal-Koretska
Oct 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a checkbox for adding SAST to a new project
parent
e8989fc6
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
241 additions
and
44 deletions
+241
-44
app/assets/stylesheets/pages/settings.scss
app/assets/stylesheets/pages/settings.scss
+20
-11
app/controllers/projects_controller.rb
app/controllers/projects_controller.rb
+8
-0
app/experiments/new_project_sast_enabled_experiment.rb
app/experiments/new_project_sast_enabled_experiment.rb
+15
-0
app/services/projects/create_service.rb
app/services/projects/create_service.rb
+6
-0
app/services/security/ci_configuration/base_create_service.rb
...services/security/ci_configuration/base_create_service.rb
+5
-1
app/services/security/ci_configuration/sast_create_service.rb
...services/security/ci_configuration/sast_create_service.rb
+15
-2
app/views/projects/_new_project_fields.html.haml
app/views/projects/_new_project_fields.html.haml
+30
-9
config/feature_flags/experiment/new_project_sast_enabled.yml
config/feature_flags/experiment/new_project_sast_enabled.yml
+8
-0
locale/gitlab.pot
locale/gitlab.pot
+12
-0
spec/controllers/projects_controller_spec.rb
spec/controllers/projects_controller_spec.rb
+45
-21
spec/experiments/new_project_sast_enabled_experiment_spec.rb
spec/experiments/new_project_sast_enabled_experiment_spec.rb
+15
-0
spec/features/projects/user_creates_project_spec.rb
spec/features/projects/user_creates_project_spec.rb
+23
-0
spec/services/projects/create_service_spec.rb
spec/services/projects/create_service_spec.rb
+16
-0
spec/services/security/ci_configuration/sast_create_service_spec.rb
...ces/security/ci_configuration/sast_create_service_spec.rb
+23
-0
No files found.
app/assets/stylesheets/pages/settings.scss
View file @
de2bb111
...
...
@@ -192,19 +192,28 @@
}
}
.
initialize-with-readme-setting
{
.form-check
{
margin-bottom
:
10px
;
.
nested-settings
{
padding-left
:
20px
;
}
.option-title
{
font-weight
:
$gl-font-weight-normal
;
display
:
inline-block
;
color
:
$gl-text-color
;
.input-btn-group
{
display
:
flex
;
.input-large
{
flex
:
1
;
}
.option-descriptio
n
{
color
:
$project-option-descr-color
;
.bt
n
{
margin-left
:
10px
;
}
}
.content-list
>
.settings-flex-row
{
display
:
flex
;
align-items
:
center
;
.float-right
{
margin-left
:
auto
;
}
}
...
...
app/controllers/projects_controller.rb
View file @
de2bb111
...
...
@@ -73,6 +73,13 @@ class ProjectsController < Projects::ApplicationController
@project
=
::
Projects
::
CreateService
.
new
(
current_user
,
project_params
(
attributes:
project_params_create_attributes
)).
execute
if
@project
.
saved?
experiment
(
:new_project_sast_enabled
,
user:
current_user
).
track
(
:created
,
property:
active_new_project_tab
,
checked:
Gitlab
::
Utils
.
to_boolean
(
project_params
[
:initialize_with_sast
]),
project:
@project
,
namespace:
@project
.
namespace
)
redirect_to
(
project_path
(
@project
,
custom_import_params
),
notice:
_
(
"Project '%{project_name}' was successfully created."
)
%
{
project_name:
@project
.
name
}
...
...
@@ -436,6 +443,7 @@ class ProjectsController < Projects::ApplicationController
:template_name
,
:template_project_id
,
:merge_method
,
:initialize_with_sast
,
:initialize_with_readme
,
:autoclose_referenced_issues
,
:suggestion_commit_message
,
...
...
app/experiments/new_project_sast_enabled_experiment.rb
0 → 100644
View file @
de2bb111
# frozen_string_literal: true
class
NewProjectSastEnabledExperiment
<
ApplicationExperiment
# rubocop:disable Gitlab/NamespacedClass
def
publish
(
_result
=
nil
)
super
publish_to_database
end
def
candidate_behavior
end
def
free_indicator_behavior
end
end
app/services/projects/create_service.rb
View file @
de2bb111
...
...
@@ -8,6 +8,7 @@ module Projects
@current_user
=
user
@params
=
params
.
dup
@skip_wiki
=
@params
.
delete
(
:skip_wiki
)
@initialize_with_sast
=
Gitlab
::
Utils
.
to_boolean
(
@params
.
delete
(
:initialize_with_sast
))
@initialize_with_readme
=
Gitlab
::
Utils
.
to_boolean
(
@params
.
delete
(
:initialize_with_readme
))
@import_data
=
@params
.
delete
(
:import_data
)
@relations_block
=
@params
.
delete
(
:relations_block
)
...
...
@@ -118,6 +119,7 @@ module Projects
Projects
::
PostCreationWorker
.
perform_async
(
@project
.
id
)
create_readme
if
@initialize_with_readme
create_sast_commit
if
@initialize_with_sast
end
# Add an authorization for the current user authorizations inline
...
...
@@ -160,6 +162,10 @@ module Projects
Files
::
CreateService
.
new
(
@project
,
current_user
,
commit_attrs
).
execute
end
def
create_sast_commit
::
Security
::
CiConfiguration
::
SastCreateService
.
new
(
@project
,
current_user
,
{},
commit_on_default:
true
).
execute
end
def
readme_content
@readme_template
.
presence
||
experiment
(
:new_project_readme_content
,
namespace:
@project
.
namespace
).
run_with
(
@project
)
end
...
...
app/services/security/ci_configuration/base_create_service.rb
View file @
de2bb111
...
...
@@ -25,7 +25,7 @@ module Security
rescue
Gitlab
::
Git
::
PreReceiveError
=>
e
ServiceResponse
.
error
(
message:
e
.
message
)
rescue
StandardError
project
.
repository
.
rm_branch
(
current_user
,
branch_name
)
if
project
.
repository
.
branch_exists?
(
branch_name
)
remove_branch_on_exception
raise
end
...
...
@@ -50,6 +50,10 @@ module Security
Gitlab
::
Routing
.
url_helpers
.
project_new_merge_request_url
(
project
,
merge_request:
merge_request_params
)
end
def
remove_branch_on_exception
project
.
repository
.
rm_branch
(
current_user
,
branch_name
)
if
project
.
repository
.
branch_exists?
(
branch_name
)
end
def
track_event
(
attributes_for_commit
)
action
=
attributes_for_commit
[
:actions
].
first
...
...
app/services/security/ci_configuration/sast_create_service.rb
View file @
de2bb111
...
...
@@ -5,15 +5,28 @@ module Security
class
SastCreateService
<
::
Security
::
CiConfiguration
::
BaseCreateService
attr_reader
:params
def
initialize
(
project
,
current_user
,
params
)
def
initialize
(
project
,
current_user
,
params
,
commit_on_default:
false
)
super
(
project
,
current_user
)
@params
=
params
@commit_on_default
=
commit_on_default
@branch_name
=
project
.
default_branch
if
@commit_on_default
end
private
def
remove_branch_on_exception
super
unless
@commit_on_default
end
def
action
Security
::
CiConfiguration
::
SastBuildAction
.
new
(
project
.
auto_devops_enabled?
,
params
,
existing_gitlab_ci_content
).
generate
existing_content
=
begin
existing_gitlab_ci_content
# this can fail on the very first commit
rescue
StandardError
nil
end
Security
::
CiConfiguration
::
SastBuildAction
.
new
(
project
.
auto_devops_enabled?
,
params
,
existing_content
).
generate
end
def
next_branch
...
...
app/views/projects/_new_project_fields.html.haml
View file @
de2bb111
...
...
@@ -53,15 +53,36 @@
=
render
'shared/visibility_level'
,
f:
f
,
visibility_level:
visibility_level
.
to_i
,
can_change_visibility_level:
true
,
form_model:
@project
,
with_label:
false
-
if
!
hide_init_with_readme
.form-group.row.initialize-with-readme-setting
%div
{
:class
=>
"col-sm-12"
}
.form-check
=
check_box_tag
'project[initialize_with_readme]'
,
'1'
,
true
,
class:
'form-check-input'
,
data:
{
qa_selector:
"initialize_with_readme_checkbox"
,
track_label:
"
#{
track_label
}
"
,
track_action:
"activate_form_input"
,
track_property:
"init_with_readme"
,
track_value:
""
}
=
label_tag
'project[initialize_with_readme]'
,
class:
'form-check-label'
do
.option-title
%strong
=
s_
(
'ProjectsNew|Initialize repository with a README'
)
.option-description
=
f
.
label
:project_configuration
,
class:
'label-bold'
do
=
s_
(
'ProjectsNew|Project Configuration'
)
.form-group
.form-check.gl-mb-3
=
check_box_tag
'project[initialize_with_readme]'
,
'1'
,
true
,
class:
'form-check-input'
,
data:
{
qa_selector:
'initialize_with_readme_checkbox'
,
track_label:
track_label
,
track_action:
'activate_form_input'
,
track_property:
'init_with_readme'
}
=
label_tag
'project[initialize_with_readme]'
,
s_
(
'ProjectsNew|Initialize repository with a README'
),
class:
'form-check-label'
.form-text.text-muted
=
s_
(
'ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.'
)
-
experiment
(
:new_project_sast_enabled
,
user:
current_user
)
do
|
e
|
-
e
.
try
do
.form-group
.form-check.gl-mb-3
=
check_box_tag
'project[initialize_with_sast]'
,
'1'
,
true
,
class:
'form-check-input'
,
data:
{
track_experiment:
e
.
name
,
track_label:
track_label
,
track_action:
'activate_form_input'
,
track_property:
'init_with_sast'
}
=
label_tag
'project[initialize_with_sast]'
,
class:
'form-check-label'
do
=
s_
(
'ProjectsNew|Enable Static Application Security Testing (SAST)'
)
.form-text.text-muted
=
s_
(
'ProjectsNew|Analyze your source code for known security vulnerabilities.'
)
=
link_to
_
(
'Learn more.'
),
help_page_path
(
'user/application_security/sast/index'
),
target:
'_blank'
,
rel:
'noopener noreferrer'
,
data:
{
track_action:
'followed'
,
track_experiment:
e
.
name
}
-
e
.
try
(
:free_indicator
)
do
.form-group
.form-check.gl-mb-3
=
check_box_tag
'project[initialize_with_sast]'
,
'1'
,
true
,
class:
'form-check-input'
,
data:
{
track_experiment:
e
.
name
,
track_label:
track_label
,
track_action:
'activate_form_input'
,
track_property:
'init_with_sast'
}
=
label_tag
'project[initialize_with_sast]'
,
class:
'form-check-label'
do
=
s_
(
'ProjectsNew|Enable Static Application Security Testing (SAST)'
)
%span
.badge.badge-info.badge-pill.gl-badge.sm
=
_
(
'Free'
)
.form-text.text-muted
=
s_
(
'ProjectsNew|Analyze your source code for known security vulnerabilities.'
)
=
link_to
_
(
'Learn more.'
),
help_page_path
(
'user/application_security/sast/index'
),
target:
'_blank'
,
rel:
'noopener noreferrer'
,
data:
{
track_action:
'followed'
,
track_experiment:
e
.
name
}
=
f
.
submit
_
(
'Create project'
),
class:
"btn gl-button btn-confirm"
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_action:
"click_button"
,
track_property:
"create_project"
,
track_value:
""
}
=
link_to
_
(
'Cancel'
),
dashboard_projects_path
,
class:
'btn gl-button btn-default btn-cancel'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_action:
"click_button"
,
track_property:
"cancel"
,
track_value:
""
}
config/feature_flags/experiment/new_project_sast_enabled.yml
0 → 100644
View file @
de2bb111
---
name
:
new_project_sast_enabled
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70548
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/340929
milestone
:
'
14.4'
type
:
experiment
group
:
group::adoption
default_enabled
:
false
locale/gitlab.pot
View file @
de2bb111
...
...
@@ -14854,6 +14854,9 @@ msgstr ""
msgid "Framework successfully deleted"
msgstr ""
msgid "Free"
msgstr ""
msgid "Free Trial of GitLab.com Ultimate"
msgstr ""
...
...
@@ -27040,6 +27043,9 @@ msgstr ""
msgid "ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository."
msgstr ""
msgid "ProjectsNew|Analyze your source code for known security vulnerabilities."
msgstr ""
msgid "ProjectsNew|Connect your external repository to GitLab CI/CD."
msgstr ""
...
...
@@ -27067,6 +27073,9 @@ msgstr ""
msgid "ProjectsNew|Description format"
msgstr ""
msgid "ProjectsNew|Enable Static Application Security Testing (SAST)"
msgstr ""
msgid "ProjectsNew|Import"
msgstr ""
...
...
@@ -27082,6 +27091,9 @@ msgstr ""
msgid "ProjectsNew|No import options available"
msgstr ""
msgid "ProjectsNew|Project Configuration"
msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
...
...
spec/controllers/projects_controller_spec.rb
View file @
de2bb111
...
...
@@ -420,21 +420,22 @@ RSpec.describe ProjectsController do
end
describe
'POST create'
do
let!
(
:params
)
do
{
path:
'foo'
,
description:
'bar'
,
import_url:
project
.
http_url_to_repo
,
namespace_id:
user
.
namespace
.
id
}
end
subject
{
post
:create
,
params:
{
project:
params
}
}
before
do
sign_in
(
user
)
end
context
'on import'
do
let
(
:params
)
do
{
path:
'foo'
,
description:
'bar'
,
namespace_id:
user
.
namespace
.
id
,
import_url:
project
.
http_url_to_repo
}
end
context
'when import by url is disabled'
do
before
do
stub_application_setting
(
import_sources:
[])
...
...
@@ -460,6 +461,29 @@ RSpec.describe ProjectsController do
end
end
context
'with new_project_sast_enabled'
,
:experiment
do
let
(
:params
)
do
{
path:
'foo'
,
description:
'bar'
,
namespace_id:
user
.
namespace
.
id
,
initialize_with_sast:
'1'
}
end
it
'tracks an event on project creation'
do
expect
(
experiment
(
:new_project_sast_enabled
)).
to
track
(
:created
,
property:
'blank'
,
checked:
true
,
project:
an_instance_of
(
Project
),
namespace:
user
.
namespace
).
on_next_instance
.
with_context
(
user:
user
)
post
:create
,
params:
{
project:
params
}
end
end
end
describe
'GET edit'
do
it
'allows an admin user to access the page'
,
:enable_admin_mode
do
sign_in
(
create
(
:user
,
:admin
))
...
...
spec/experiments/new_project_sast_enabled_experiment_spec.rb
0 → 100644
View file @
de2bb111
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
NewProjectSastEnabledExperiment
do
it
"defines the expected behaviors and variants"
do
expect
(
subject
.
behaviors
.
keys
).
to
match_array
(
%w[control candidate free_indicator]
)
end
it
"publishes to the database"
do
expect
(
subject
).
to
receive
(
:publish_to_database
)
subject
.
publish
end
end
spec/features/projects/user_creates_project_spec.rb
View file @
de2bb111
...
...
@@ -33,6 +33,29 @@ RSpec.describe 'User creates a project', :js do
expect
(
page
).
to
have_content
(
project
.
url_to_repo
)
end
it
'creates a new project that is not blank'
do
stub_experiments
(
new_project_sast_enabled:
'candidate'
)
visit
(
new_project_path
)
find
(
'[data-qa-panel-name="blank_project"]'
).
click
# rubocop:disable QA/SelectorUsage
fill_in
(
:project_name
,
with:
'With initial commits'
)
expect
(
page
).
to
have_checked_field
'Initialize repository with a README'
expect
(
page
).
to
have_checked_field
'Enable Static Application Security Testing (SAST)'
page
.
within
(
'#content-body'
)
do
click_button
(
'Create project'
)
end
project
=
Project
.
last
expect
(
current_path
).
to
eq
(
project_path
(
project
))
expect
(
page
).
to
have_content
(
'With initial commits'
)
expect
(
page
).
to
have_content
(
'Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist'
)
expect
(
page
).
to
have_content
(
'README.md Initial commit'
)
end
context
'in a subgroup they do not own'
do
let
(
:parent
)
{
create
(
:group
)
}
let!
(
:subgroup
)
{
create
(
:group
,
parent:
parent
)
}
...
...
spec/services/projects/create_service_spec.rb
View file @
de2bb111
...
...
@@ -622,6 +622,22 @@ RSpec.describe Projects::CreateService, '#execute' do
end
end
context
'when SAST initialization is requested'
do
let
(
:project
)
{
create_project
(
user
,
opts
)
}
before
do
opts
[
:initialize_with_sast
]
=
'1'
allow
(
Gitlab
::
CurrentSettings
).
to
receive
(
:default_branch_name
).
and_return
(
'main'
)
end
it
'creates a commit for SAST'
,
:aggregate_failures
do
expect
(
project
.
repository
.
commit_count
).
to
be
(
1
)
expect
(
project
.
repository
.
commit
.
message
).
to
eq
(
'Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist'
)
end
end
describe
'create integration for the project'
do
subject
(
:project
)
{
create_project
(
user
,
opts
)
}
...
...
spec/services/security/ci_configuration/sast_create_service_spec.rb
View file @
de2bb111
...
...
@@ -23,4 +23,27 @@ RSpec.describe Security::CiConfiguration::SastCreateService, :snowplow do
end
include_examples
'services security ci configuration create service'
context
"when committing to the default branch"
,
:aggregate_failures
do
subject
(
:result
)
{
described_class
.
new
(
project
,
user
,
params
,
commit_on_default:
true
).
execute
}
let
(
:params
)
{
{}
}
before
do
project
.
add_developer
(
user
)
end
it
"doesn't try to remove that branch on raised exceptions"
do
expect
(
Files
::
MultiService
).
to
receive
(
:new
).
and_raise
(
StandardError
,
'_exception_'
)
expect
(
project
.
repository
).
not_to
receive
(
:rm_branch
)
expect
{
result
}.
to
raise_error
(
StandardError
,
'_exception_'
)
end
it
"commits directly to the default branch"
do
expect
(
result
.
status
).
to
eq
(
:success
)
expect
(
result
.
payload
[
:success_path
]).
to
match
(
/
#{
Gitlab
::
Routing
.
url_helpers
.
project_new_merge_request_url
(
project
,
{
}
)}(.*)description(.*)source_branch/
)
expect
(
result
.
payload
[
:branch
]).
to
eq
(
'master'
)
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