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
3b17bba1
Commit
3b17bba1
authored
Feb 19, 2018
by
Clement Ho
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into dispatcher-mr-haml
parents
da521875
fb2a76ac
Changes
89
Show whitespace changes
Inline
Side-by-side
Showing
89 changed files
with
591 additions
and
438 deletions
+591
-438
Gemfile
Gemfile
+1
-0
Gemfile.lock
Gemfile.lock
+2
-0
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+0
-155
app/assets/javascripts/pages/admin/jobs/index/index.js
app/assets/javascripts/pages/admin/jobs/index/index.js
+2
-4
app/assets/javascripts/pages/admin/projects/index/index.js
app/assets/javascripts/pages/admin/projects/index/index.js
+2
-2
app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
...cripts/pages/admin/users/components/delete_user_modal.vue
+0
-0
app/assets/javascripts/pages/admin/users/index.js
app/assets/javascripts/pages/admin/users/index.js
+2
-2
app/assets/javascripts/pages/dashboard/issues/index.js
app/assets/javascripts/pages/dashboard/issues/index.js
+2
-2
app/assets/javascripts/pages/dashboard/merge_requests/index.js
...ssets/javascripts/pages/dashboard/merge_requests/index.js
+2
-2
app/assets/javascripts/pages/dashboard/milestones/show/index.js
...sets/javascripts/pages/dashboard/milestones/show/index.js
+2
-2
app/assets/javascripts/pages/dashboard/projects/index.js
app/assets/javascripts/pages/dashboard/projects/index.js
+1
-1
app/assets/javascripts/pages/dashboard/todos/index/index.js
app/assets/javascripts/pages/dashboard/todos/index/index.js
+1
-1
app/assets/javascripts/pages/explore/groups/index.js
app/assets/javascripts/pages/explore/groups/index.js
+2
-2
app/assets/javascripts/pages/explore/projects/index.js
app/assets/javascripts/pages/explore/projects/index.js
+1
-1
app/assets/javascripts/pages/groups/issues/index.js
app/assets/javascripts/pages/groups/issues/index.js
+2
-2
app/assets/javascripts/pages/groups/merge_requests/index.js
app/assets/javascripts/pages/groups/merge_requests/index.js
+2
-2
app/assets/javascripts/pages/groups/milestones/edit/index.js
app/assets/javascripts/pages/groups/milestones/edit/index.js
+1
-1
app/assets/javascripts/pages/groups/milestones/new/index.js
app/assets/javascripts/pages/groups/milestones/new/index.js
+1
-1
app/assets/javascripts/pages/groups/milestones/show/index.js
app/assets/javascripts/pages/groups/milestones/show/index.js
+1
-1
app/assets/javascripts/pages/projects/branches/index/index.js
...assets/javascripts/pages/projects/branches/index/index.js
+2
-2
app/assets/javascripts/pages/projects/branches/new/index.js
app/assets/javascripts/pages/projects/branches/new/index.js
+3
-1
app/assets/javascripts/pages/projects/compare/show/index.js
app/assets/javascripts/pages/projects/compare/show/index.js
+2
-2
app/assets/javascripts/pages/projects/environments/metrics/index.js
.../javascripts/pages/projects/environments/metrics/index.js
+1
-1
app/assets/javascripts/pages/projects/issues/edit/index.js
app/assets/javascripts/pages/projects/issues/edit/index.js
+1
-3
app/assets/javascripts/pages/projects/issues/new/index.js
app/assets/javascripts/pages/projects/issues/new/index.js
+1
-3
app/assets/javascripts/pages/projects/merge_requests/creations/index.js
...ascripts/pages/projects/merge_requests/creations/index.js
+1
-1
app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js
...ipts/pages/projects/merge_requests/creations/new/index.js
+2
-2
app/assets/javascripts/pages/projects/merge_requests/edit/index.js
...s/javascripts/pages/projects/merge_requests/edit/index.js
+1
-1
app/assets/javascripts/pages/projects/milestones/edit/index.js
...ssets/javascripts/pages/projects/milestones/edit/index.js
+1
-1
app/assets/javascripts/pages/projects/milestones/index/index.js
...sets/javascripts/pages/projects/milestones/index/index.js
+1
-1
app/assets/javascripts/pages/projects/milestones/new/index.js
...assets/javascripts/pages/projects/milestones/new/index.js
+1
-1
app/assets/javascripts/pages/projects/milestones/show/index.js
...ssets/javascripts/pages/projects/milestones/show/index.js
+2
-2
app/helpers/webpack_helper.rb
app/helpers/webpack_helper.rb
+11
-4
app/models/ci/build.rb
app/models/ci/build.rb
+4
-33
app/models/commit.rb
app/models/commit.rb
+4
-4
app/models/key.rb
app/models/key.rb
+3
-4
app/models/repository.rb
app/models/repository.rb
+2
-6
app/models/user.rb
app/models/user.rb
+2
-0
app/services/issues/move_service.rb
app/services/issues/move_service.rb
+2
-1
app/workers/process_commit_worker.rb
app/workers/process_commit_worker.rb
+5
-7
changelogs/unreleased/17500-mr-multiple-issues-oxford-comma.yml
...logs/unreleased/17500-mr-multiple-issues-oxford-comma.yml
+5
-0
changelogs/unreleased/32564-fix-double-system-closing-notes.yml
...logs/unreleased/32564-fix-double-system-closing-notes.yml
+5
-0
changelogs/unreleased/40552-sanitize-extra-blank-spaces-used-when-uploading-a-ssh-key.yml
...tize-extra-blank-spaces-used-when-uploading-a-ssh-key.yml
+5
-0
changelogs/unreleased/41949-move.yml
changelogs/unreleased/41949-move.yml
+5
-0
changelogs/unreleased/dm-dont-cache-nil-root-ref.yml
changelogs/unreleased/dm-dont-cache-nil-root-ref.yml
+5
-0
changelogs/unreleased/expired-ci-artifacts.yml
changelogs/unreleased/expired-ci-artifacts.yml
+0
-5
changelogs/unreleased/flipper-caching.yml
changelogs/unreleased/flipper-caching.yml
+5
-0
changelogs/unreleased/sh-fix-geo-error-500-gpg-commit.yml
changelogs/unreleased/sh-fix-geo-error-500-gpg-commit.yml
+5
-0
changelogs/unreleased/sh-fix-squash-rebase-utf8-data.yml
changelogs/unreleased/sh-fix-squash-rebase-utf8-data.yml
+5
-0
changelogs/unreleased/sh-guard-read-only-user-updates.yml
changelogs/unreleased/sh-guard-read-only-user-updates.yml
+5
-0
config/initializers/1_settings.rb
config/initializers/1_settings.rb
+1
-1
config/initializers/flipper.rb
config/initializers/flipper.rb
+1
-1
config/webpack.config.js
config/webpack.config.js
+2
-2
doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md
...inistration/auth/how_to_configure_ldap_gitlab_ce/index.md
+8
-5
doc/ci/examples/artifactory_and_gitlab/index.md
doc/ci/examples/artifactory_and_gitlab/index.md
+5
-5
doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+5
-5
doc/development/writing_documentation.md
doc/development/writing_documentation.md
+19
-12
doc/install/openshift_and_gitlab/index.md
doc/install/openshift_and_gitlab/index.md
+8
-5
doc/topics/git/how_to_install_git/index.md
doc/topics/git/how_to_install_git/index.md
+8
-5
doc/topics/git/numerous_undo_possibilities_in_git/index.md
doc/topics/git/numerous_undo_possibilities_in_git/index.md
+8
-5
doc/user/project/pages/getting_started_part_four.md
doc/user/project/pages/getting_started_part_four.md
+8
-5
doc/user/project/pages/getting_started_part_one.md
doc/user/project/pages/getting_started_part_one.md
+8
-5
doc/user/project/pages/getting_started_part_three.md
doc/user/project/pages/getting_started_part_three.md
+5
-6
doc/user/project/pages/getting_started_part_two.md
doc/user/project/pages/getting_started_part_two.md
+8
-5
lib/gitlab/checks/change_access.rb
lib/gitlab/checks/change_access.rb
+6
-1
lib/gitlab/checks/commit_check.rb
lib/gitlab/checks/commit_check.rb
+2
-2
lib/gitlab/git/commit.rb
lib/gitlab/git/commit.rb
+1
-1
lib/gitlab/git/repository.rb
lib/gitlab/git/repository.rb
+1
-0
lib/gitlab/gpg/commit.rb
lib/gitlab/gpg/commit.rb
+3
-1
lib/gitlab/ssh_public_key.rb
lib/gitlab/ssh_public_key.rb
+22
-6
qa/qa/factory/resource/secret_variable.rb
qa/qa/factory/resource/secret_variable.rb
+0
-12
qa/qa/page/base.rb
qa/qa/page/base.rb
+4
-0
qa/qa/page/project/settings/secret_variables.rb
qa/qa/page/project/settings/secret_variables.rb
+12
-14
qa/qa/specs/features/project/add_secret_variable_spec.rb
qa/qa/specs/features/project/add_secret_variable_spec.rb
+13
-8
qa/spec/page/base_spec.rb
qa/spec/page/base_spec.rb
+5
-6
spec/factories/keys.rb
spec/factories/keys.rb
+93
-23
spec/lib/gitlab/checks/change_access_spec.rb
spec/lib/gitlab/checks/change_access_spec.rb
+2
-2
spec/lib/gitlab/closing_issue_extractor_spec.rb
spec/lib/gitlab/closing_issue_extractor_spec.rb
+14
-0
spec/lib/gitlab/git/repository_spec.rb
spec/lib/gitlab/git/repository_spec.rb
+12
-0
spec/lib/gitlab/gpg/commit_spec.rb
spec/lib/gitlab/gpg/commit_spec.rb
+25
-1
spec/lib/gitlab/ssh_public_key_spec.rb
spec/lib/gitlab/ssh_public_key_spec.rb
+58
-3
spec/models/key_spec.rb
spec/models/key_spec.rb
+29
-7
spec/models/user_spec.rb
spec/models/user_spec.rb
+8
-0
spec/requests/api/issues_spec.rb
spec/requests/api/issues_spec.rb
+1
-1
spec/requests/api/projects_spec.rb
spec/requests/api/projects_spec.rb
+2
-2
spec/requests/api/v3/issues_spec.rb
spec/requests/api/v3/issues_spec.rb
+1
-1
spec/requests/api/v3/projects_spec.rb
spec/requests/api/v3/projects_spec.rb
+1
-1
spec/services/issues/move_service_spec.rb
spec/services/issues/move_service_spec.rb
+22
-0
spec/workers/process_commit_worker_spec.rb
spec/workers/process_commit_worker_spec.rb
+36
-13
No files found.
Gemfile
View file @
3b17bba1
...
...
@@ -401,6 +401,7 @@ gem 'sys-filesystem', '~> 1.1.6'
# SSH host key support
gem
'
net-ssh
'
,
'~> 4.1.0'
gem
'
sshkey
'
,
'~> 1.9.0'
# Required for ED25519 SSH host key support
group
:ed25519
do
...
...
Gemfile.lock
View file @
3b17bba1
...
...
@@ -895,6 +895,7 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
sshkey (1.9.0)
stackprof (0.2.10)
state_machines (0.4.0)
state_machines-activemodel (0.4.0)
...
...
@@ -1192,6 +1193,7 @@ DEPENDENCIES
spring-commands-rspec (~> 1.0.4)
spring-commands-spinach (~> 1.1.0)
sprockets (~> 3.7.0)
sshkey (~> 1.9.0)
stackprof (~> 0.2.10)
state_machines-activerecord (~> 0.4.0)
sys-filesystem (~> 1.1.6)
...
...
app/assets/javascripts/dispatcher.js
View file @
3b17bba1
...
...
@@ -43,169 +43,14 @@ var Dispatcher;
});
switch
(
page
)
{
case
'
projects:environments:metrics
'
:
import
(
'
./pages/projects/environments/metrics
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:merge_requests:index
'
:
case
'
projects:issues:index
'
:
case
'
projects:issues:show
'
:
shortcut_handler
=
true
;
break
;
case
'
projects:milestones:index
'
:
import
(
'
./pages/projects/milestones/index
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:milestones:show
'
:
import
(
'
./pages/projects/milestones/show
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
groups:milestones:show
'
:
import
(
'
./pages/groups/milestones/show
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
dashboard:milestones:show
'
:
import
(
'
./pages/dashboard/milestones/show
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
dashboard:issues
'
:
import
(
'
./pages/dashboard/issues
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
dashboard:merge_requests
'
:
import
(
'
./pages/dashboard/merge_requests
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
groups:issues
'
:
import
(
'
./pages/groups/issues
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
groups:merge_requests
'
:
import
(
'
./pages/groups/merge_requests
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
dashboard:todos:index
'
:
import
(
'
./pages/dashboard/todos/index
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
admin:jobs:index
'
:
import
(
'
./pages/admin/jobs/index
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
admin:projects:index
'
:
import
(
'
./pages/admin/projects/index/index
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
admin:users:index
'
:
import
(
'
./pages/admin/users/shared
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
admin:users:show
'
:
import
(
'
./pages/admin/users/shared
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
dashboard:projects:index
'
:
case
'
dashboard:projects:starred
'
:
import
(
'
./pages/dashboard/projects
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
explore:projects:index
'
:
case
'
explore:projects:trending
'
:
case
'
explore:projects:starred
'
:
import
(
'
./pages/explore/projects
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
explore:groups:index
'
:
import
(
'
./pages/explore/groups
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:milestones:new
'
:
case
'
projects:milestones:create
'
:
import
(
'
./pages/projects/milestones/new
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:milestones:edit
'
:
case
'
projects:milestones:update
'
:
import
(
'
./pages/projects/milestones/edit
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
groups:milestones:new
'
:
case
'
groups:milestones:create
'
:
import
(
'
./pages/groups/milestones/new
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
groups:milestones:edit
'
:
case
'
groups:milestones:update
'
:
import
(
'
./pages/groups/milestones/edit
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:compare:show
'
:
import
(
'
./pages/projects/compare/show
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:branches:new
'
:
import
(
'
./pages/projects/branches/new
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:branches:create
'
:
import
(
'
./pages/projects/branches/new
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:branches:index
'
:
import
(
'
./pages/projects/branches/index
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
projects:issues:new
'
:
import
(
'
./pages/projects/issues/new
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
shortcut_handler
=
true
;
break
;
case
'
projects:issues:edit
'
:
import
(
'
./pages/projects/issues/edit
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
shortcut_handler
=
true
;
break
;
case
'
projects:merge_requests:creations:new
'
:
import
(
'
./pages/projects/merge_requests/creations/new
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
case
'
projects:merge_requests:creations:diffs
'
:
import
(
'
./pages/projects/merge_requests/creations/diffs
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
shortcut_handler
=
true
;
break
;
case
'
projects:merge_requests:edit
'
:
import
(
'
./pages/projects/merge_requests/edit
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
shortcut_handler
=
true
;
break
;
case
'
projects:tags:new
'
:
...
...
app/assets/javascripts/pages/admin/jobs/index/index.js
View file @
3b17bba1
import
Vue
from
'
vue
'
;
import
Translate
from
'
~/vue_shared/translate
'
;
import
stopJobsModal
from
'
./components/stop_jobs_modal.vue
'
;
Vue
.
use
(
Translate
);
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
stopJobsButton
=
document
.
getElementById
(
'
stop-jobs-button
'
);
if
(
stopJobsButton
)
{
// eslint-disable-next-line no-new
...
...
@@ -27,4 +25,4 @@ export default () => {
},
});
}
};
}
)
;
app/assets/javascripts/pages/admin/projects/index/index.js
View file @
3b17bba1
...
...
@@ -5,7 +5,7 @@ import csrf from '~/lib/utils/csrf';
import
deleteProjectModal
from
'
./components/delete_project_modal.vue
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
Vue
.
use
(
Translate
);
const
deleteProjectModalEl
=
document
.
getElementById
(
'
delete-project-modal
'
);
...
...
@@ -34,4 +34,4 @@ export default () => {
deleteModal
.
projectName
=
buttonProps
.
projectName
;
}
});
};
}
)
;
app/assets/javascripts/pages/admin/users/
shared/
components/delete_user_modal.vue
→
app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
View file @
3b17bba1
File moved
app/assets/javascripts/pages/admin/users/
shared/
index.js
→
app/assets/javascripts/pages/admin/users/index.js
View file @
3b17bba1
...
...
@@ -5,7 +5,7 @@ import csrf from '~/lib/utils/csrf';
import
deleteUserModal
from
'
./components/delete_user_modal.vue
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
Vue
.
use
(
Translate
);
const
deleteUserModalEl
=
document
.
getElementById
(
'
delete-user-modal
'
);
...
...
@@ -40,4 +40,4 @@ export default () => {
deleteModal
.
username
=
buttonProps
.
username
;
}
});
};
}
)
;
app/assets/javascripts/pages/dashboard/issues/index.js
View file @
3b17bba1
import
projectSelect
from
'
~/project_select
'
;
import
initLegacyFilters
from
'
~/init_legacy_filters
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
projectSelect
();
initLegacyFilters
();
};
}
)
;
app/assets/javascripts/pages/dashboard/merge_requests/index.js
View file @
3b17bba1
import
projectSelect
from
'
~/project_select
'
;
import
initLegacyFilters
from
'
~/init_legacy_filters
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
projectSelect
();
initLegacyFilters
();
};
}
)
;
app/assets/javascripts/pages/dashboard/milestones/show/index.js
View file @
3b17bba1
import
Milestone
from
'
~/milestone
'
;
import
Sidebar
from
'
~/right_sidebar
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
new
Milestone
();
// eslint-disable-line no-new
new
Sidebar
();
// eslint-disable-line no-new
};
}
)
;
app/assets/javascripts/pages/dashboard/projects/index.js
View file @
3b17bba1
import
ProjectsList
from
'
~/projects_list
'
;
export
default
()
=>
new
ProjectsList
(
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
new
ProjectsList
()
);
app/assets/javascripts/pages/dashboard/todos/index/index.js
View file @
3b17bba1
import
Todos
from
'
./todos
'
;
export
default
()
=>
new
Todos
(
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
new
Todos
()
);
app/assets/javascripts/pages/explore/groups/index.js
View file @
3b17bba1
...
...
@@ -2,7 +2,7 @@ import GroupsList from '~/groups_list';
import
Landing
from
'
~/landing
'
;
import
initGroupsList
from
'
../../../groups
'
;
export
default
function
()
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
new
GroupsList
();
// eslint-disable-line no-new
initGroupsList
();
const
landingElement
=
document
.
querySelector
(
'
.js-explore-groups-landing
'
);
...
...
@@ -13,4 +13,4 @@ export default function () {
'
explore_groups_landing_dismissed
'
,
);
exploreGroupsLanding
.
toggle
();
}
}
);
app/assets/javascripts/pages/explore/projects/index.js
View file @
3b17bba1
import
ProjectsList
from
'
~/projects_list
'
;
export
default
()
=>
new
ProjectsList
(
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
new
ProjectsList
()
);
app/assets/javascripts/pages/groups/issues/index.js
View file @
3b17bba1
...
...
@@ -2,9 +2,9 @@ import projectSelect from '~/project_select';
import
initFilteredSearch
from
'
~/pages/search/init_filtered_search
'
;
import
{
FILTERED_SEARCH
}
from
'
~/pages/constants
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
initFilteredSearch
({
page
:
FILTERED_SEARCH
.
ISSUES
,
});
projectSelect
();
};
}
)
;
app/assets/javascripts/pages/groups/merge_requests/index.js
View file @
3b17bba1
...
...
@@ -2,9 +2,9 @@ import projectSelect from '~/project_select';
import
initFilteredSearch
from
'
~/pages/search/init_filtered_search
'
;
import
{
FILTERED_SEARCH
}
from
'
~/pages/constants
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
initFilteredSearch
({
page
:
FILTERED_SEARCH
.
MERGE_REQUESTS
,
});
projectSelect
();
};
}
)
;
app/assets/javascripts/pages/groups/milestones/edit/index.js
View file @
3b17bba1
import
initForm
from
'
../../../../shared/milestones/form
'
;
export
default
()
=>
initForm
(
false
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
initForm
(
false
)
);
app/assets/javascripts/pages/groups/milestones/new/index.js
View file @
3b17bba1
import
initForm
from
'
../../../../shared/milestones/form
'
;
export
default
()
=>
initForm
(
false
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
initForm
(
false
)
);
app/assets/javascripts/pages/groups/milestones/show/index.js
View file @
3b17bba1
import
initMilestonesShow
from
'
~/pages/milestones/shared/init_milestones_show
'
;
export
default
initMilestonesShow
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initMilestonesShow
)
;
app/assets/javascripts/pages/projects/branches/index/index.js
View file @
3b17bba1
import
AjaxLoadingSpinner
from
'
~/ajax_loading_spinner
'
;
import
DeleteModal
from
'
~/branches/branches_delete_modal
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
AjaxLoadingSpinner
.
init
();
new
DeleteModal
();
// eslint-disable-line no-new
};
}
)
;
app/assets/javascripts/pages/projects/branches/new/index.js
View file @
3b17bba1
import
NewBranchForm
from
'
~/new_branch_form
'
;
export
default
()
=>
new
NewBranchForm
(
$
(
'
.js-create-branch-form
'
),
JSON
.
parse
(
document
.
getElementById
(
'
availableRefs
'
).
innerHTML
));
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
(
new
NewBranchForm
(
$
(
'
.js-create-branch-form
'
),
JSON
.
parse
(
document
.
getElementById
(
'
availableRefs
'
).
innerHTML
))
));
app/assets/javascripts/pages/projects/compare/show/index.js
View file @
3b17bba1
import
Diff
from
'
~/diff
'
;
import
initChangesDropdown
from
'
~/init_changes_dropdown
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
new
Diff
();
// eslint-disable-line no-new
const
paddingTop
=
16
;
initChangesDropdown
(
document
.
querySelector
(
'
.navbar-gitlab
'
).
offsetHeight
-
paddingTop
);
};
}
)
;
app/assets/javascripts/pages/projects/environments/metrics/index.js
View file @
3b17bba1
import
monitoringBundle
from
'
~/monitoring/monitoring_bundle
'
;
export
default
monitoringBundle
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
monitoringBundle
)
;
app/assets/javascripts/pages/projects/issues/edit/index.js
View file @
3b17bba1
import
initForm
from
'
../form
'
;
export
default
()
=>
{
initForm
();
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initForm
);
app/assets/javascripts/pages/projects/issues/new/index.js
View file @
3b17bba1
import
initForm
from
'
../form
'
;
export
default
()
=>
{
initForm
();
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initForm
);
app/assets/javascripts/pages/projects/merge_requests/creations/
diffs/
index.js
→
app/assets/javascripts/pages/projects/merge_requests/creations/index.js
View file @
3b17bba1
import
initMergeRequest
from
'
~/pages/projects/merge_requests/init_merge_request
'
;
export
default
initMergeRequest
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initMergeRequest
)
;
app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js
View file @
3b17bba1
import
Compare
from
'
~/compare
'
;
import
MergeRequest
from
'
~/merge_request
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
mrNewCompareNode
=
document
.
querySelector
(
'
.js-merge-request-new-compare
'
);
if
(
mrNewCompareNode
)
{
new
Compare
({
// eslint-disable-line no-new
...
...
@@ -15,4 +15,4 @@ export default () => {
action
:
mrNewSubmitNode
.
dataset
.
mrSubmitAction
,
});
}
};
}
)
;
app/assets/javascripts/pages/projects/merge_requests/edit/index.js
View file @
3b17bba1
import
initMergeRequest
from
'
~/pages/projects/merge_requests/init_merge_request
'
;
export
default
initMergeRequest
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initMergeRequest
)
;
app/assets/javascripts/pages/projects/milestones/edit/index.js
View file @
3b17bba1
import
initForm
from
'
../../../../shared/milestones/form
'
;
export
default
()
=>
initForm
(
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
initForm
()
);
app/assets/javascripts/pages/projects/milestones/index/index.js
View file @
3b17bba1
import
milestones
from
'
~/pages/milestones/shared
'
;
export
default
milestones
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
milestones
)
;
app/assets/javascripts/pages/projects/milestones/new/index.js
View file @
3b17bba1
import
initForm
from
'
../../../../shared/milestones/form
'
;
export
default
()
=>
initForm
(
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
initForm
()
);
app/assets/javascripts/pages/projects/milestones/show/index.js
View file @
3b17bba1
import
initMilestonesShow
from
'
~/pages/milestones/shared/init_milestones_show
'
;
import
milestones
from
'
~/pages/milestones/shared
'
;
export
default
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
initMilestonesShow
();
milestones
();
};
}
)
;
app/helpers/webpack_helper.rb
View file @
3b17bba1
...
...
@@ -7,17 +7,24 @@ module WebpackHelper
def
webpack_controller_bundle_tags
bundles
=
[]
segments
=
[
*
controller
.
controller_path
.
split
(
'/'
),
controller
.
action_name
].
compact
until
segments
.
empty?
action
=
case
controller
.
action_name
when
'create'
then
'new'
when
'update'
then
'edit'
else
controller
.
action_name
end
route
=
[
*
controller
.
controller_path
.
split
(
'/'
),
action
].
compact
until
route
.
empty?
begin
asset_paths
=
gitlab_webpack_asset_paths
(
"pages.
#{
segments
.
join
(
'.'
)
}
"
,
extension:
'js'
)
asset_paths
=
gitlab_webpack_asset_paths
(
"pages.
#{
route
.
join
(
'.'
)
}
"
,
extension:
'js'
)
bundles
.
unshift
(
*
asset_paths
)
rescue
Webpack
::
Rails
::
Manifest
::
EntryPointMissingError
# no bundle exists for this path
end
segments
.
pop
route
.
pop
end
javascript_include_tag
(
*
bundles
)
...
...
app/models/ci/build.rb
View file @
3b17bba1
...
...
@@ -41,41 +41,12 @@ module Ci
scope
:unstarted
,
->
()
{
where
(
runner_id:
nil
)
}
scope
:ignore_failures
,
->
()
{
where
(
allow_failure:
false
)
}
# This convoluted mess is because we need to handle two cases of
# artifact files during the migration. And a simple OR clause
# makes it impossible to optimize.
# Instead we want to use UNION ALL and do two carefully
# constructed disjoint queries. But Rails cannot handle UNION or
# UNION ALL queries so we do the query in a subquery and wrap it
# in an otherwise redundant WHERE IN query (IN is fine for
# non-null columns).
# This should all be ripped out when the migration is finished and
# replaced with just the new storage to avoid the extra work.
scope
:with_artifacts
,
->
()
do
old
=
Ci
::
Build
.
select
(
:id
).
where
(
%q[artifacts_file <> '']
)
new
=
Ci
::
Build
.
select
(
:id
).
where
(
%q[(artifacts_file IS NULL OR artifacts_file = '') AND EXISTS (?)]
,
Ci
::
JobArtifact
.
select
(
1
).
where
(
'ci_builds.id = ci_job_artifacts.job_id'
))
where
(
'ci_builds.id IN (? UNION ALL ?)'
,
old
,
new
)
where
(
'(artifacts_file IS NOT NULL AND artifacts_file <> ?) OR EXISTS (?)'
,
''
,
Ci
::
JobArtifact
.
select
(
1
).
where
(
'ci_builds.id = ci_job_artifacts.job_id'
))
end
scope
:with_artifacts_not_expired
,
->
()
do
old
=
Ci
::
Build
.
select
(
:id
).
where
(
%q[artifacts_file <> '' AND (artifacts_expire_at IS NULL OR artifacts_expire_at > ?)]
,
Time
.
now
)
new
=
Ci
::
Build
.
select
(
:id
).
where
(
%q[(artifacts_file IS NULL OR artifacts_file = '') AND EXISTS (?)]
,
Ci
::
JobArtifact
.
select
(
1
).
where
(
'ci_builds.id = ci_job_artifacts.job_id AND (expire_at IS NULL OR expire_at > ?)'
,
Time
.
now
))
where
(
'ci_builds.id IN (? UNION ALL ?)'
,
old
,
new
)
end
scope
:with_expired_artifacts
,
->
()
do
old
=
Ci
::
Build
.
select
(
:id
).
where
(
%q[artifacts_file <> '' AND artifacts_expire_at < ?]
,
Time
.
now
)
new
=
Ci
::
Build
.
select
(
:id
).
where
(
%q[(artifacts_file IS NULL OR artifacts_file = '') AND EXISTS (?)]
,
Ci
::
JobArtifact
.
select
(
1
).
where
(
'ci_builds.id = ci_job_artifacts.job_id AND expire_at < ?'
,
Time
.
now
))
where
(
'ci_builds.id IN (? UNION ALL ?)'
,
old
,
new
)
end
scope
:with_artifacts_not_expired
,
->
()
{
with_artifacts
.
where
(
'artifacts_expire_at IS NULL OR artifacts_expire_at > ?'
,
Time
.
now
)
}
scope
:with_expired_artifacts
,
->
()
{
with_artifacts
.
where
(
'artifacts_expire_at < ?'
,
Time
.
now
)
}
scope
:last_month
,
->
()
{
where
(
'created_at > ?'
,
Date
.
today
-
1
.
month
)
}
scope
:manual_actions
,
->
()
{
where
(
when: :manual
,
status:
COMPLETED_STATUSES
+
[
:manual
])
}
scope
:ref_protected
,
->
{
where
(
protected:
true
)
}
...
...
app/models/commit.rb
View file @
3b17bba1
...
...
@@ -417,6 +417,10 @@ class Commit
!!
(
title
=~
WIP_REGEX
)
end
def
merged_merge_request?
(
user
)
!!
merged_merge_request
(
user
)
end
private
def
commit_reference
(
from
,
referable_commit_id
,
full:
false
)
...
...
@@ -445,10 +449,6 @@ class Commit
changes
end
def
merged_merge_request?
(
user
)
!!
merged_merge_request
(
user
)
end
def
merged_merge_request_no_cache
(
user
)
MergeRequestsFinder
.
new
(
user
,
project_id:
project
.
id
).
find_by
(
merge_commit_sha:
id
)
if
merge_commit?
end
...
...
app/models/key.rb
View file @
3b17bba1
...
...
@@ -33,9 +33,8 @@ class Key < ActiveRecord::Base
after_destroy
:refresh_user_cache
def
key
=
(
value
)
value
&
.
delete!
(
"
\n\r
"
)
value
.
strip!
unless
value
.
blank?
write_attribute
(
:key
,
value
)
write_attribute
(
:key
,
value
.
present?
?
Gitlab
::
SSHPublicKey
.
sanitize
(
value
)
:
nil
)
@public_key
=
nil
end
...
...
@@ -97,7 +96,7 @@ class Key < ActiveRecord::Base
def
generate_fingerprint
self
.
fingerprint
=
nil
return
unless
self
.
key
.
present
?
return
unless
public_key
.
valid
?
self
.
fingerprint
=
public_key
.
fingerprint
end
...
...
app/models/repository.rb
View file @
3b17bba1
...
...
@@ -492,12 +492,8 @@ class Repository
end
def
root_ref
if
raw_repository
raw_repository
.
root_ref
else
# When the repo does not exist we raise this error so no data is cached.
raise
Gitlab
::
Git
::
Repository
::
NoRepository
end
# When the repo does not exist, or there is no root ref, we raise this error so no data is cached.
raw_repository
&
.
root_ref
or
raise
Gitlab
::
Git
::
Repository
::
NoRepository
# rubocop:disable Style/AndOr
end
cache_method
:root_ref
...
...
app/models/user.rb
View file @
3b17bba1
...
...
@@ -59,6 +59,8 @@ class User < ActiveRecord::Base
# Override Devise::Models::Trackable#update_tracked_fields!
# to limit database writes to at most once every hour
def
update_tracked_fields!
(
request
)
return
if
Gitlab
::
Database
.
read_only?
update_tracked_fields
(
request
)
lease
=
Gitlab
::
ExclusiveLease
.
new
(
"user_update_tracked_fields:
#{
id
}
"
,
timeout:
1
.
hour
.
to_i
)
...
...
app/services/issues/move_service.rb
View file @
3b17bba1
...
...
@@ -48,7 +48,8 @@ module Issues
new_params
=
{
id:
nil
,
iid:
nil
,
label_ids:
cloneable_label_ids
,
milestone_id:
cloneable_milestone_id
,
project:
@new_project
,
author:
@old_issue
.
author
,
description:
rewrite_content
(
@old_issue
.
description
)
}
description:
rewrite_content
(
@old_issue
.
description
),
assignee_ids:
@old_issue
.
assignee_ids
}
new_params
=
@old_issue
.
serializable_hash
.
symbolize_keys
.
merge
(
new_params
)
CreateService
.
new
(
@new_project
,
@current_user
,
new_params
).
execute
...
...
app/workers/process_commit_worker.rb
View file @
3b17bba1
...
...
@@ -23,27 +23,25 @@ class ProcessCommitWorker
return
unless
user
commit
=
build_commit
(
project
,
commit_hash
)
author
=
commit
.
author
||
user
process_commit_message
(
project
,
commit
,
user
,
author
,
default
)
update_issue_metrics
(
commit
,
author
)
end
def
process_commit_message
(
project
,
commit
,
user
,
author
,
default
=
false
)
closed_issues
=
default
?
commit
.
closes_issues
(
user
)
:
[]
# this is a GitLab generated commit message, ignore it.
return
if
commit
.
merged_merge_request?
(
user
)
unless
closed_issues
.
empty?
close_issues
(
project
,
user
,
author
,
commit
,
closed_issues
)
end
closed_issues
=
default
?
commit
.
closes_issues
(
user
)
:
[]
close_issues
(
project
,
user
,
author
,
commit
,
closed_issues
)
if
closed_issues
.
any?
commit
.
create_cross_references!
(
author
,
closed_issues
)
end
def
close_issues
(
project
,
user
,
author
,
commit
,
issues
)
# We don't want to run permission related queries for every single issue,
# therefor we use IssueCollection here and skip the authorization check in
# therefor
e
we use IssueCollection here and skip the authorization check in
# Issues::CloseService#execute.
IssueCollection
.
new
(
issues
).
updatable_by_user
(
user
).
each
do
|
issue
|
Issues
::
CloseService
.
new
(
project
,
author
)
...
...
changelogs/unreleased/17500-mr-multiple-issues-oxford-comma.yml
0 → 100644
View file @
3b17bba1
---
title
:
Update issue closing pattern to allow variations in punctuation
merge_request
:
17198
author
:
Vicky Chijwani
type
:
changed
changelogs/unreleased/32564-fix-double-system-closing-notes.yml
0 → 100644
View file @
3b17bba1
---
title
:
Fix duplicate system notes when merging a merge request.
merge_request
:
17035
author
:
type
:
fixed
changelogs/unreleased/40552-sanitize-extra-blank-spaces-used-when-uploading-a-ssh-key.yml
0 → 100644
View file @
3b17bba1
---
title
:
Sanitize extra blank spaces used when uploading a SSH key
merge_request
:
40552
author
:
type
:
fixed
changelogs/unreleased/41949-move.yml
0 → 100644
View file @
3b17bba1
---
title
:
Remember assignee when moving an issue
merge_request
:
author
:
type
:
fixed
changelogs/unreleased/dm-dont-cache-nil-root-ref.yml
0 → 100644
View file @
3b17bba1
---
title
:
Don't cache a nil repository root ref to prevent caching issues
merge_request
:
author
:
type
:
fixed
changelogs/unreleased/expired-ci-artifacts.yml
deleted
100644 → 0
View file @
da521875
---
title
:
Change SQL for expired artifacts to use new ci_job_artifacts.expire_at
merge_request
:
16578
author
:
type
:
performance
changelogs/unreleased/flipper-caching.yml
0 → 100644
View file @
3b17bba1
---
title
:
Increase feature flag cache TTL to one hour
merge_request
:
author
:
type
:
performance
changelogs/unreleased/sh-fix-geo-error-500-gpg-commit.yml
0 → 100644
View file @
3b17bba1
---
title
:
Fix Error 500 when viewing a commit with a GPG signature in Geo
merge_request
:
author
:
type
:
fixed
changelogs/unreleased/sh-fix-squash-rebase-utf8-data.yml
0 → 100644
View file @
3b17bba1
---
title
:
Fix squash not working when diff contained non-ASCII data
merge_request
:
author
:
type
:
fixed
changelogs/unreleased/sh-guard-read-only-user-updates.yml
0 → 100644
View file @
3b17bba1
---
title
:
Don't attempt to update user tracked fields if database is in read-only
merge_request
:
author
:
type
:
fixed
config/initializers/1_settings.rb
View file @
3b17bba1
...
...
@@ -262,7 +262,7 @@ Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].
Settings
.
gitlab
[
'signin_enabled'
]
||=
true
if
Settings
.
gitlab
[
'signin_enabled'
].
nil?
Settings
.
gitlab
[
'restricted_visibility_levels'
]
=
Settings
.
__send__
(
:verify_constant_array
,
Gitlab
::
VisibilityLevel
,
Settings
.
gitlab
[
'restricted_visibility_levels'
],
[])
Settings
.
gitlab
[
'username_changing_enabled'
]
=
true
if
Settings
.
gitlab
[
'username_changing_enabled'
].
nil?
Settings
.
gitlab
[
'issue_closing_pattern'
]
=
'((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)|[Ii]mplement(?:s|ed|ing)?)(:?) +(?:(?:issues? +)?%{issue_ref}(?:(?:
, *| +and +
)?)|([A-Z][A-Z0-9_]+-\d+))+)'
if
Settings
.
gitlab
[
'issue_closing_pattern'
].
nil?
Settings
.
gitlab
[
'issue_closing_pattern'
]
=
'((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)|[Ii]mplement(?:s|ed|ing)?)(:?) +(?:(?:issues? +)?%{issue_ref}(?:(?:
*,? +and +| *, *
)?)|([A-Z][A-Z0-9_]+-\d+))+)'
if
Settings
.
gitlab
[
'issue_closing_pattern'
].
nil?
Settings
.
gitlab
[
'default_projects_features'
]
||=
{}
Settings
.
gitlab
[
'webhook_timeout'
]
||=
10
Settings
.
gitlab
[
'max_attachment_size'
]
||=
10
...
...
config/initializers/flipper.rb
View file @
3b17bba1
...
...
@@ -8,7 +8,7 @@ Flipper.configure do |config|
cached_adapter
=
Flipper
::
Adapters
::
ActiveSupportCacheStore
.
new
(
adapter
,
Rails
.
cache
,
expires_in:
1
0
.
seconds
)
expires_in:
1
.
hour
)
Flipper
.
new
(
cached_adapter
)
end
...
...
config/webpack.config.js
View file @
3b17bba1
...
...
@@ -27,11 +27,11 @@ var pageEntries = glob.sync('pages/**/index.js', { cwd: path.join(ROOT_PATH, 'ap
// filter out entries currently imported dynamically in dispatcher.js
var
dispatcher
=
fs
.
readFileSync
(
path
.
join
(
ROOT_PATH
,
'
app/assets/javascripts/dispatcher.js
'
)).
toString
();
var
dispatcherChunks
=
dispatcher
.
match
(
/
(?!
import
\(
'
.
\/)
pages
\/[^
'
]
+/g
);
var
dispatcherChunks
=
dispatcher
.
match
(
/
(?!
import
\(
'
)\.\/
pages
\/[^
'
]
+/g
);
pageEntries
.
forEach
((
path
)
=>
{
let
chunkPath
=
path
.
replace
(
/
\/
index
\.
js$/
,
''
);
if
(
!
dispatcherChunks
.
includes
(
chunkPath
))
{
if
(
!
dispatcherChunks
.
includes
(
'
./
'
+
chunkPath
))
{
let
chunkName
=
chunkPath
.
replace
(
/
\/
/g
,
'
.
'
);
autoEntries
[
chunkName
]
=
'
./
'
+
path
;
}
...
...
doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md
View file @
3b17bba1
# How to configure LDAP with GitLab CE
---
author
:
Chris Wilson
author_gitlab
:
MrChrisW
level
:
intermediary
article_type
:
admin guide
date
:
2017-05-03
---
> **[Article Type](../../../development/writing_documentation.html#types-of-technical-articles):** admin guide ||
> **Level:** intermediary ||
> **Author:** [Chris Wilson](https://gitlab.com/MrChrisW) ||
> **Publication date:** 2017-05-03
# How to configure LDAP with GitLab CE
## Introduction
...
...
doc/ci/examples/artifactory_and_gitlab/index.md
View file @
3b17bba1
---
redirect_from
:
'
https://docs.gitlab.com/ee/articles/artifactory_and_gitlab/index.html'
author
:
Fabio Busatto
author_gitlab
:
bikebilly
level
:
intermediary
article_type
:
tutorial
date
:
2017-08-15
---
# How to deploy Maven projects to Artifactory with GitLab CI/CD
> **[Article Type](../../../development/writing_documentation.md#types-of-technical-articles):** tutorial ||
> **Level:** intermediary ||
> **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) ||
> **Publication date:** 2017-08-15
## Introduction
In this article, we will show how you can leverage the power of
[
GitLab CI/CD
](
https://about.gitlab.com/features/gitlab-ci-cd/
)
...
...
doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
View file @
3b17bba1
---
redirect_from
:
'
https://docs.gitlab.com/ee/articles/laravel_with_gitlab_and_envoy/index.html'
author
:
Mehran Rasulian
author_gitlab
:
mehranrasulian
level
:
intermediary
article_type
:
tutorial
date
:
2017-08-31
---
# Test and deploy Laravel applications with GitLab CI/CD and Envoy
> **[Article Type](../../../development/writing_documentation.md#types-of-technical-articles):** tutorial ||
> **Level:** intermediary ||
> **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) ||
> **Publication date:** 2017-08-31
## Introduction
GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want.
...
...
doc/development/writing_documentation.md
View file @
3b17bba1
...
...
@@ -254,18 +254,25 @@ through the process of how to use it systematically.
#### Special format
Every
**Technical Article**
contains, in the very beginning, a blockquote with the following information:
-
A reference to the
**type of article**
(user guide, admin guide, tech overview, tutorial)
-
A reference to the
**knowledge level**
expected from the reader to be able to follow through (beginner, intermediate, advanced)
-
A reference to the
**author's name**
and
**GitLab.com handle**
-
A reference of the
**publication date**
```
md
> **[Article Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial ||
> **Level:** intermediary ||
> **Author:** [Name Surname](https://gitlab.com/username) ||
> **Publication date:** AAAA-MM-DD
Every
**Technical Article**
contains a frontmatter at the beginning of the doc
with the following information:
-
**Type of article**
(user guide, admin guide, tech overview, tutorial)
-
**Knowledge level**
expected from the reader to be able to follow through (beginner, intermediate, advanced)
-
**Author's name**
and
**GitLab.com handle**
-
**Publication date**
For example:
```yaml
---
author: John Doe
author_gitlab: johnDoe
level: beginner
article_type: user guide
date: 2017-02-01
---
```
#### Technical Articles - Writing Method
...
...
doc/install/openshift_and_gitlab/index.md
View file @
3b17bba1
# Getting started with OpenShift Origin 3 and GitLab
---
author
:
Achilleas Pipinellis
author_gitlab
:
axil
level
:
intermediary
article_type
:
tutorial
date
:
2016-06-28
---
> **[Article Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial ||
> **Level:** intermediary ||
> **Author:** [Achilleas Pipinellis](https://gitlab.com/axil) ||
> **Publication date:** 2016-06-28
# Getting started with OpenShift Origin 3 and GitLab
## Introduction
...
...
doc/topics/git/how_to_install_git/index.md
View file @
3b17bba1
# Installing Git
---
author
:
Sean Packham
author_gitlab
:
SeanPackham
level
:
beginner
article_type
:
user guide
date
:
2017-05-15
---
> **[Article Type](../../../development/writing_documentation.html#types-of-technical-articles):** user guide ||
> **Level:** beginner ||
> **Author:** [Sean Packham](https://gitlab.com/SeanPackham) ||
> **Publication date:** 2017-05-15
# Installing Git
To begin contributing to GitLab projects
you will need to install the Git client on your computer.
...
...
doc/topics/git/numerous_undo_possibilities_in_git/index.md
View file @
3b17bba1
# Numerous undo possibilities in Git
---
author
:
Crt Mori
author_gitlab
:
Letme
level
:
intermediary
article_type
:
tutorial
date
:
2017-05-15
---
> **[Article Type](../../../development/writing_documentation.md#types-of-technical-articles):** tutorial ||
> **Level:** intermediary ||
> **Author:** [Crt Mori](https://gitlab.com/Letme) ||
> **Publication date:** 2017-08-17
# Numerous undo possibilities in Git
## Introduction
...
...
doc/user/project/pages/getting_started_part_four.md
View file @
3b17bba1
# GitLab Pages from A to Z: Part 4
---
author
:
Marcia Ramos
author_gitlab
:
marcia
level
:
intermediate
article_type
:
user guide
date
:
2017-02-22
---
> **Article [Type](../../../development/writing_documentation.html#types-of-technical-articles)**: user guide ||
> **Level**: intermediate ||
> **Author**: [Marcia Ramos](https://gitlab.com/marcia) ||
> **Publication date:** 2017/02/22
# GitLab Pages from A to Z: Part 4
-
[
Part 1: Static sites and GitLab Pages domains
](
getting_started_part_one.md
)
-
[
Part 2: Quick start guide - Setting up GitLab Pages
](
getting_started_part_two.md
)
...
...
doc/user/project/pages/getting_started_part_one.md
View file @
3b17bba1
# GitLab Pages from A to Z: Part 1
---
author
:
Marcia Ramos
author_gitlab
:
marcia
level
:
beginner
article_type
:
user guide
date
:
2017-02-22
---
> **Article [Type](../../../development/writing_documentation.html#types-of-technical-articles)**: user guide ||
> **Level**: beginner ||
> **Author**: [Marcia Ramos](https://gitlab.com/marcia) ||
> **Publication date:** 2017/02/22
# GitLab Pages from A to Z: Part 1
-
**Part 1: Static sites and GitLab Pages domains**
-
[
Part 2: Quick start guide - Setting up GitLab Pages
](
getting_started_part_two.md
)
...
...
doc/user/project/pages/getting_started_part_three.md
View file @
3b17bba1
---
last_updated
:
2017-09-28
author
:
Marcia Ramos
author_gitlab
:
marcia
level
:
beginner
article_type
:
user guide
date
:
2017-02-22
---
# GitLab Pages from A to Z: Part 3
> **[Article Type](../../../development/writing_documentation.md#types-of-technical-articles)**: user guide ||
> **Level**: beginner ||
> **Author**: [Marcia Ramos](https://gitlab.com/marcia) ||
> **Publication date:** 2017-02-22 ||
> **Last updated**: 2017-09-28
-
[
Part 1: Static sites and GitLab Pages domains
](
getting_started_part_one.md
)
-
[
Part 2: Quick start guide - Setting up GitLab Pages
](
getting_started_part_two.md
)
-
**Part 3: Setting Up Custom Domains - DNS Records and SSL/TLS Certificates**
...
...
doc/user/project/pages/getting_started_part_two.md
View file @
3b17bba1
# GitLab Pages from A to Z: Part 2
---
author
:
Marcia Ramos
author_gitlab
:
marcia
level
:
beginner
article_type
:
user guide
date
:
2017-02-22
---
> **Article [Type](../../../development/writing_documentation.html#types-of-technical-articles)**: user guide ||
> **Level**: beginner ||
> **Author**: [Marcia Ramos](https://gitlab.com/marcia) ||
> **Publication date:** 2017/02/22
# GitLab Pages from A to Z: Part 2
-
[
Part 1: Static sites and GitLab Pages domains
](
getting_started_part_one.md
)
-
**Part 2: Quick start guide - Setting up GitLab Pages**
...
...
lib/gitlab/checks/change_access.rb
View file @
3b17bba1
...
...
@@ -121,6 +121,7 @@ module Gitlab
def
commits_check
return
if
deletion?
||
newrev
.
nil?
return
unless
should_run_commit_validations?
# n+1: https://gitlab.com/gitlab-org/gitlab-ee/issues/3593
::
Gitlab
::
GitalyClient
.
allow_n_plus_1_calls
do
...
...
@@ -139,6 +140,10 @@ module Gitlab
private
def
should_run_commit_validations?
commit_check
.
validate_lfs_file_locks?
end
def
updated_from_web?
protocol
==
'web'
end
...
...
@@ -176,7 +181,7 @@ module Gitlab
end
def
commits
project
.
repository
.
new_commits
(
newrev
)
@commits
||=
project
.
repository
.
new_commits
(
newrev
)
end
end
end
...
...
lib/gitlab/checks/commit_check.rb
View file @
3b17bba1
...
...
@@ -35,14 +35,14 @@ module Gitlab
end
end
private
def
validate_lfs_file_locks?
strong_memoize
(
:validate_lfs_file_locks
)
do
project
.
lfs_enabled?
&&
project
.
lfs_file_locks
.
any?
&&
newrev
&&
oldrev
end
end
private
def
lfs_file_locks_validation
lambda
do
|
paths
|
lfs_lock
=
project
.
lfs_file_locks
.
where
(
path:
paths
).
where
.
not
(
user_id:
user
.
id
).
first
...
...
lib/gitlab/git/commit.rb
View file @
3b17bba1
...
...
@@ -508,7 +508,7 @@ module Gitlab
@committed_date
=
Time
.
at
(
commit
.
committer
.
date
.
seconds
).
utc
@committer_name
=
commit
.
committer
.
name
.
dup
@committer_email
=
commit
.
committer
.
email
.
dup
@parent_ids
=
commit
.
parent_ids
@parent_ids
=
Array
(
commit
.
parent_ids
)
end
def
serialize_keys
...
...
lib/gitlab/git/repository.rb
View file @
3b17bba1
...
...
@@ -2195,6 +2195,7 @@ module Gitlab
# Apply diff of the `diff_range` to the worktree
diff
=
run_git!
(
%W(diff --binary
#{
diff_range
}
)
)
run_git!
(
%w(apply --index)
,
chdir:
squash_path
,
env:
env
)
do
|
stdin
|
stdin
.
binmode
stdin
.
write
(
diff
)
end
...
...
lib/gitlab/gpg/commit.rb
View file @
3b17bba1
...
...
@@ -60,7 +60,9 @@ module Gitlab
def
create_cached_signature!
using_keychain
do
|
gpg_key
|
GpgSignature
.
create!
(
attributes
(
gpg_key
))
signature
=
GpgSignature
.
new
(
attributes
(
gpg_key
))
signature
.
save!
unless
Gitlab
::
Database
.
read_only?
signature
end
end
...
...
lib/gitlab/ssh_public_key.rb
View file @
3b17bba1
...
...
@@ -21,6 +21,22 @@ module Gitlab
technology
(
name
)
&
.
supported_sizes
end
def
self
.
sanitize
(
key_content
)
ssh_type
,
*
parts
=
key_content
.
strip
.
split
return
key_content
if
parts
.
empty?
parts
.
each_with_object
(
"
#{
ssh_type
}
"
).
with_index
do
|
(
part
,
content
),
index
|
content
<<
part
if
Gitlab
::
SSHPublicKey
.
new
(
content
).
valid?
break
[
content
,
parts
[
index
+
1
]].
compact
.
join
(
' '
)
# Add the comment part if present
elsif
parts
.
size
==
index
+
1
# return original content if we've reached the last element
break
key_content
end
end
end
attr_reader
:key_text
,
:key
# Unqualified MD5 fingerprint for compatibility
...
...
@@ -37,23 +53,23 @@ module Gitlab
end
def
valid?
key
.
present?
SSHKey
.
valid_ssh_public_key?
(
key_text
)
end
def
type
technology
.
name
if
valid
?
technology
.
name
if
key
.
present
?
end
def
bits
return
unless
valid
?
return
if
key
.
blank
?
case
type
when
:rsa
key
.
n
.
num_bits
key
.
n
&
.
num_bits
when
:dsa
key
.
p
.
num_bits
key
.
p
&
.
num_bits
when
:ecdsa
key
.
group
.
order
.
num_bits
key
.
group
.
order
&
.
num_bits
when
:ed25519
256
else
...
...
qa/qa/factory/resource/secret_variable.rb
View file @
3b17bba1
...
...
@@ -4,18 +4,6 @@ module QA
class
SecretVariable
<
Factory
::
Base
attr_accessor
:key
,
:value
product
:key
do
Page
::
Project
::
Settings
::
CICD
.
act
do
expand_secret_variables
(
&
:variable_key
)
end
end
product
:value
do
Page
::
Project
::
Settings
::
CICD
.
act
do
expand_secret_variables
(
&
:variable_value
)
end
end
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-secret-variables'
project
.
description
=
'project for adding secret variable test'
...
...
qa/qa/page/base.rb
View file @
3b17bba1
...
...
@@ -98,6 +98,10 @@ module QA
views
.
map
(
&
:errors
).
flatten
end
def
self
.
elements
views
.
map
(
&
:elements
).
flatten
end
class
DSL
attr_reader
:views
...
...
qa/qa/page/project/settings/secret_variables.rb
View file @
3b17bba1
...
...
@@ -6,39 +6,37 @@ module QA
include
Common
view
'app/views/ci/variables/_variable_row.html.haml'
do
element
:variable_row
,
'.ci-variable-row-body'
element
:variable_key
,
'.js-ci-variable-input-key'
element
:variable_value
,
'.js-ci-variable-input-value'
element
:key_placeholder
,
'Input variable key'
element
:value_placeholder
,
'Input variable value'
end
view
'app/views/ci/variables/_index.html.haml'
do
element
:save_variables
,
'.js-secret-variables-save-button'
element
:reveal_values
,
'.js-secret-value-reveal-button'
end
def
fill_variable_key
(
key
)
page
.
within
(
'.js-ci-variable-list-section .js-row:nth-child(1)'
)
do
page
.
find
(
'.js-ci-variable-input-key'
).
set
(
key
)
end
fill_in
(
'Input variable key'
,
with:
key
,
match: :first
)
end
def
fill_variable_value
(
value
)
page
.
within
(
'.js-ci-variable-list-section .js-row:nth-child(1)'
)
do
page
.
find
(
'.js-ci-variable-input-value'
).
set
(
value
)
end
fill_in
(
'Input variable value'
,
with:
value
,
match: :first
)
end
def
save_variables
click_button
(
'Save variables'
)
find
(
'.js-secret-variables-save-button'
).
click
end
def
variable_key
page
.
within
(
'.js-ci-variable-list-section .js-row:nth-child(1)'
)
do
page
.
find
(
'.js-ci-variable-input-key'
).
value
end
def
reveal_variables
find
(
'.js-secret-value-reveal-button'
).
click
end
def
variable_value
page
.
within
(
'.js-ci-variable-list-section .js-row:nth-child(1)'
)
do
page
.
find
(
'.js-ci-variable-input-value'
).
value
def
variable_value
(
key
)
within
(
'.ci-variable-row-body'
,
text:
key
)
do
find
(
'.js-ci-variable-input-value'
).
value
end
end
end
...
...
qa/qa/specs/features/project/add_secret_variable_spec.rb
View file @
3b17bba1
...
...
@@ -4,16 +4,21 @@ module QA
Runtime
::
Browser
.
visit
(
:gitlab
,
Page
::
Main
::
Login
)
Page
::
Main
::
Login
.
act
{
sign_in_using_credentials
}
variable_key
=
'VARIABLE_KEY'
variable_value
=
'variable value'
variable
=
Factory
::
Resource
::
SecretVariable
.
fabricate!
do
|
resource
|
resource
.
key
=
variable_key
resource
.
value
=
variable_value
Factory
::
Resource
::
SecretVariable
.
fabricate!
do
|
resource
|
resource
.
key
=
'VARIABLE_KEY'
resource
.
value
=
'some secret variable'
end
expect
(
variable
.
key
).
to
eq
(
variable_key
)
expect
(
variable
.
value
).
to
eq
(
variable_value
)
Page
::
Project
::
Settings
::
CICD
.
perform
do
|
settings
|
settings
.
expand_secret_variables
do
|
page
|
expect
(
page
).
to
have_field
(
with:
'VARIABLE_KEY'
)
expect
(
page
).
not_to
have_field
(
with:
'some secret variable'
)
page
.
reveal_variables
expect
(
page
).
to
have_field
(
with:
'some secret variable'
)
end
end
end
end
end
qa/spec/page/base_spec.rb
View file @
3b17bba1
...
...
@@ -14,7 +14,7 @@ describe QA::Page::Base do
end
view
'path/to/some/_partial.html.haml'
do
element
:
something
,
'string pattern'
element
:
another_element
,
'string pattern'
end
end
end
...
...
@@ -25,11 +25,10 @@ describe QA::Page::Base do
end
it
'populates views objects with data about elements'
do
subject
.
views
.
first
.
elements
.
tap
do
|
elements
|
expect
(
elements
.
size
).
to
eq
2
expect
(
elements
).
to
all
(
be_an_instance_of
QA
::
Page
::
Element
)
expect
(
elements
.
map
(
&
:name
)).
to
eq
[
:something
,
:something_else
]
end
expect
(
subject
.
elements
.
size
).
to
eq
3
expect
(
subject
.
elements
).
to
all
(
be_an_instance_of
QA
::
Page
::
Element
)
expect
(
subject
.
elements
.
map
(
&
:name
))
.
to
eq
[
:something
,
:something_else
,
:another_element
]
end
end
...
...
spec/factories/keys.rb
View file @
3b17bba1
...
...
@@ -5,6 +5,10 @@ FactoryBot.define do
title
key
{
Spec
::
Support
::
Helpers
::
KeyGeneratorHelper
.
new
(
1024
).
generate
+
' dummy@gitlab.com'
}
factory
:key_without_comment
do
key
{
Spec
::
Support
::
Helpers
::
KeyGeneratorHelper
.
new
(
1024
).
generate
}
end
factory
:deploy_key
,
class:
'DeployKey'
factory
:personal_key
do
...
...
@@ -18,38 +22,104 @@ FactoryBot.define do
factory
:rsa_key_2048
do
key
do
<<~
KEY
.
delete
(
"
\n
"
)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ
DFf6RYK3qu/RKF/3ndJmL5xgMLp3O9
6x8lTay+QGZ0+9FnnAXMdUqBq/ZU6d/gyMB4IaW3nHzM1w049++yAB6UPCzMB8Uo27K
5
/jyZCtj7Vm9PFNjF/8am1kp46c/SeYicQgQaSBdzIW3UDEa1Ef68qroOlvpi9PYZ/tA7
M0YP0K5PXX+E36zaIRnJVMPT3f2k+GnrxtjafZrwFdpOP/Fol5BQLBgcsyiU+LM1SuaC
rzd8c9vyaTA1CxrkxaZh+buAi0PmdDtaDrHd42gqZkXCKavyvgM5o2CkQ5LJHCgzpXy0
5qNFzmThBSkb+XtoxbyagBiGbVZtSVow6Xa7qewz=
dummy@gitlab.com
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ
C98dbu7gxcbmAvwMqz/6AALhSr1jiX
G0UC8FQMvoDt+ciB+uSJhg7KlxinKjYJnPGfhX+q2K+mmCGAmI/D6q7rFxE+bn09O+7
5
qgkTHi+suDVE6KG7L3n0alGd/qSevfomR77Snh6fQPdG6sEAZz3kehcpfVnq5/IuLFq9
FBrgmu52Jd4XZLQZKkDq6zYOJ69FUkGf93LZIV/OOaS+f+qkOGPCUkdKl7oEcgpVNY9S
RjBCduXnvi2CyQnnJVkBguGL5VlXwFXH+17Whs7oFWmdiG+4jzBRLIMz4EuIW09b8Su5
PW6+bBuXOifHA8KG5TMmjs5LYdCMPFnhTyDyO3a1
dummy@gitlab.com
KEY
end
factory
:rsa_deploy_key_2048
,
class:
'DeployKey'
end
factory
:rsa_key_4096
do
key
do
<<~
KEY
.
delete
(
"
\n
"
)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDGSD77lLtjmzewiBs6nu2R5nu6oNkrA
kH/0co1fHHosKfRr+sWkSTKXOVcL7bhRu+tniGBmB5pn+i1qX7BXtrcnv//bCXWIp+me0
27L4RJa5/Ep077iiTJlzTpcV664xNUXC8mzBr601HR/Z2TzX5DWJvnyqqFkN7qHTYo/+I
oKECnKqNzI5SQrAxgi6sbWA5DFQ/nwcqsUSBo5gCCJ/0QPrR19yVV5lJA19EY2LawOb1S
JNOFo4mQupSlBZwvERZJ7IqhBTPtQIfrqqz5VJbI13jK3ViZTugIZqydWAhosUyejP3Sd
Cj1KMexrvV95tjUtmhVFlph4tKThQO0p9pXKZNCzYsbQTye6O6Hk2rojOJLyFWqNBVKtI
8Ymfu7OQWppRnuUFuhuuS515H1s888bZFMPsC74mPyo0Y7Q9wAoTnQ9Hw6b0J6OfY3PIR
VphaCmxh6b7dgSPFdD7TA6j0xk6PCTOIEzBKuc85B3GQc8Nt4sTv6fW8lGeuYWqepW74i
geC4qB6U3/3+p3nPdq/bTM1txrhnQsl1r4dv6TLZ51EtHp6sXayp0qd0pRaiavebXFC0i
aETLraQpye4FWbBL/8xTjQ/0VPrYVuUCDvDSMIIS3/9g7Kp7ERUDC9jUqOVonm4pTXL9i
ItiUBlK7Mob9C4fQIRFnVR00DCmkmVgw== dummy@gitlab.com
KEY
end
end
factory
:rsa_key_5120
do
key
do
<<~
KEY
.
delete
(
"
\n
"
)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACgQDxnZP0TucLH3zcrvt75DPNq+xKqOmJk
CEzTytKq4S5MDH0nlx+xOZ9WykhwDHXU0iZBJF7yRdLkZweYDJVKnBzr4t7QP5Sw2/ZdL
elvUMWGJjuz28x8Z+8NZ+IxL/exDz7itrhCsLupQhGO1obiIwf8xVzzPoxrQ9dxaN4x96
5N+QdQcld8O6xfpSE0p5Y3sRn3kp57aHWoNa/bUGZy0OHLr/ig0uc6EKyWsTmEESOgDyV
94wOyHR0KNGEENyxQt4BwAbEBn3Y41HKqD358KKh+XjbECebrrBFigdDL/eYFIUlstJ07
SK/HtYjZbiUZCPs8bJA+SBaLK0pGGqguM2LXRoMeMUZFwKKKS2LpRqjKGj3Qt7qMnp1Sk
VhiMnxNqL4nJnDOOVo07xDIPKqIBYO67/cp4Icv3IjKxy6K3EIpLr+iRCxcllpDogxolz
FC+pEDVpmEvcrGEv1ON6HcCdk/6Q8Iekr8rYDHpKCU5FF2uBHkqq7yNJ1/+NFC4dgyOo0
xCVL4D3DvDKNxFYkrzW4ICt0f5XcMnU10yS/OFXz8JwA3jvuLvMRe5JdFiIjb/l86+TgY
yvK8Y8N/UWgSgyjXUCv8nxdvpsxdz5h7HBF8E2DIxCVMC23655e5rp5eJW9EU9X5YFZc3
u6uWJ1f1aO+1ViTtqkPrqxovNDD+gVel8Ny6MJ4MvmDKY+eM8beNMSSf1n1Oyh/SvCffh
ZpUqrXdTr9qwZEOaC75T74AJ7KBl9VvO3vPLZuJrt38R2OZG/4SlNEUA6bb5TWQLtdor/
qpPN5jAskkAUzOh5L/M+dmq2jNn03U9xwORCYPZj+fFM9bL99/0knsV0ypZDZyWH dummy@gitlab.com
KEY
end
end
factory
:rsa_key_8192
do
key
do
<<~
KEY
.
delete
(
"
\n
"
)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQC5jMyGtgMOVX4t2GuXkbirJA0Edr+ql
OH9grnRBPHPo0Npt6XE6ZN3J3hDULTQo03wmekGw42dxdNSgk+F0GjsUBrMLbqrk485MM
e0cUbP4lRXNu4ao87wPVM5fAsD4E3FQiZcI6Df011ZGIL7hGTHt6eafTfr9cJheRyYSu6
g06rlnFWbbtSh9oQ7Y6sfDLBcsC9ECcXwe3mwViuQXPIVomZ02EdnBbAhbGHDtA+ZbSvT
fraxOMjkxkVvvdjLxXEykpwVuZf8eZ+R/Js8jQ5RKvTZMbfxJNsGEqHD32s43ml4VF549
Qz2GJDXF7Cld/n3CT6wvw0mMPM0LnykL2v0CMr44bjIA3KsNEs5MhkcBO8sv5hGfcPhrp
m9WwI6gd9vdZVcxarVI+iQS947owvdn4VbEZXynCDqEEv3Zh+FA5p23mf2p7DkG/swiK/
IPrjr1wmsiWmwIUsENzJNyJtibKuRsBawC4ZdL797tFilSoTzSpriegSL13joPXz3eOHC
Vu4ATHMo3QyLfIFbxrf9PQ79nyOpHoX2YeFXvei3xFkGMundkOqeI+pnJKDyqbiLV7UVl
clua11QWNQZf1ZUd0n1wZ1g89de+wl3oJSRbSA5ZpveZEPstcMC/JhogY4JBYsvCT1yHO
oNWHo90NZQsUCjNnR+/FVaACtpt2zcPTjjbXvxwCDlT3gXTmTBp/kEZq6u8p+BOlqFgxc
P/sdAR8jWTin3Iw/YAcbqNgRHdjMUzJBrPQ5NcK6xFcmkOEQahdJDZs98xozCHkD4Urx6
+auTr/uqRYobKoNUNiYqN1n7/dfZjQJJVkHtKd06JTFx+7/SqyfrTKS+/EIf2Hypdy9r9
IFR+SWAOi11N/wflS/ZbH95Qt3STifXRecmHzyYGkMOZ+mg3Hi2YU0yn7k+P1jy627xud
pT9Ak3HWT5ji8tMyn9udL7m80dYpUiEAxoYZdbSSNCDaKP4ViABnGIeZreIujabI8IdtE
IjFQTaF2d5HTYjp28/qf576CFP5L7AGydypipYqZUmsYnay5YVjdm89He3TMD71SwspJl
POC4RnM0HS87OE+U0+mVaIe8YYbcjTekpVU9mkqsE/GQ34Egw79VMNNgWq5avOzpT8msC
lTJxgfJ1agGgigTvGxUM0FB07+sIdJxxNymAGpLKZ1op8xaJI3o8D86jWgI22za1zxUB5
il9U7+KOzaWo9mp3bmhvZWGDwzTXEZhUJYMRby7o6UxSHlA6fKE63JSDD2yhXk4CjsQRN
C7Ph9cYSB+Wa3i9Am4rRlJgrF79okmEOMpj1idliHkpIsy/k2CN9Lf2EIHOD4NMuLrSUH
4qJsPUq19ZbGIMdImD3vMS5b dummy@gitlab.com
KEY
end
end
factory
:dsa_key_2048
do
key
do
<<~
KEY
.
delete
(
"
\n
"
)
ssh-dss AAAAB3NzaC1kc3MAAAEBA
O/3/NPLA/zSFkMOCaTtGo+uos1flfQ5f038Uk+G
Y9AeLGzX+Srhw59GdVXmOQLYBrOt5HdGwqYcmLnE2VurUGmhtfeO5H+3p5pGJbkS0Gxp
YH1HRO9lWsncF3Hh1w4lYsDjkclDiSTdfTuN8F4Kb3DXNnVSCieeonp+B25F/CXagyTQ
/pvNmHFeYgGCVdnBtFdi+xfxaZ8NKdPrGggzokbKHElDZQ4Xo5EpdcyLajgM7nB2r2Rz
OrmeaevKi5lV68ehRa9Yyrb7vxvwiwBwOgqR/mnN7Gnaq1jUdmJY+ct04Qwx37f5jvhv
5gA4U40SGMoiHM8RFIN7Ksz0jsyX73MAAAAVALRWOfjfzHpK7KLz4iqDvvTUAevJAAAB
AEa9NZ+6y9iQ5erGsdfLTXFrhSefTG0NhghoO/5IFkSGfd8V7kzTvCHaFrcfpEA5kP8t
poeOG0TASB6tgGOxm1Bq4Wncry5RORBPJlAVpDGRcvZ931ddH7IgltEInS6za2uH6F/1
M1QfKePSLr6xJ1ZLYfP0Og5KTp1x6yMQvfwV0a+XdA+EPgaJWLWp/pWwKWa0oLUgjsIH
MYzuOGh5c708uZrmkzqvgtW2NgXhcIroRgynT3IfI2lP2rqqb3uuuE/qH5UCUFO+Dc3H
nAFNeQDT/M25AERdPYBAY5a+iPjIgO+jT7BfmfByT+AZTqZySrCyc7nNZL3YgGLK0l6A
1GgAAAEBAN9FpFOdIXE+YEZhKl1vPmbcn+b1y5zOl6N4x1B7Q8pD/pLMziWROIS8uLzb
aZ0sMIWezHIkxuo1iROMeT+jtCubn7ragaN6AX7nMpxYUH9+mYZZs/fyElt6wCviVhTI
zM+u7VdQsnZttOOlQfogHdL+SpeAft0DsfJjlcgQnsLlHQKv6aPqCPYUST2nE7RyW/Ex
PrMxLtOWt0/j8RYHbwwqvyeZqBz3ESBgrS9c5tBdBfauwYUV/E7gPLOU3OZFw9ue7o+z
wzoTZqW6Xouy5wtWvSLQSLT5XwOslmQz8QMBxD0AQyDfEFGsBCWzmbTgKv9uqrBjubsS
Taja+Cf9kMo=
= dummy@gitlab.com
ssh-dss AAAAB3NzaC1kc3MAAAEBA
LEB3sM2kPy6LKLiyL+UlDx2vzuKrzSD2nsW2Kb7
0ivIqDNJu5CbqIQSkjdMzJiocs33ESFqXid6ezOtVdDwXHJQRxKGalW1kBbFAPjtMxlD
bf559+7qN2zfCfcQsgTmNAZ7O+wltqJmyLv5i4QqNwPDvyeBvJ4C+770DzlcQtpkflKJ
X+O7i8Ylq34h6UTCTnjry+dFVm1xz97LPf7XuzXGZcAG/eGUNQgxQ2bferKnrpYOXx6c
ocSRj9W54nrRFMWuDeOspWp4MoYK0FRMfDQYPksUayGUnm1KQTGuDbB0ahRNCOm8b3tf
P9Z+vjANAkqenzDuXCpz2PU/Oj6/N/UAAAAhAPOLyut12Mjcp3eUXLe1xSoI5IRXSLso
W9no93dcFNprAAABAQCLhpqKY+PNcwbhhPruL+f+uROghHzDwRNX+e231F4wHHeDDomf
WyLVFj31XrHdDXZnS9tTTj5D2XWLovSSxYb3H7earTctmktL0lQ3HapujzvOkn+VM0pG
s6B3j54+AM3mg50KZdYWxxv+v/lb6oEcsCjfKNyRIx/5pqX6XI3dxl9MMIxrfVWpkNX+
FI68v1LVV61DC9PkNyEHU0v9YBOfrTiS21TIlVIZcSFhuDjg52MekfZAnoKaP7YFJNF3
fdCrXaU3hYQrwB9XdskBUppwxKGhf7O6SWEZhAEfPA9kgxaWHoJvsDz8aca576UNe7BP
mjzo/SLUX+P4uvcaffd+AAABAEqzpmwjzTxB+DV8C+0LnmKf3L/UlQWyGdmhd65rnbkH
GgRMAAkoh4GBOEHL5bznNRmO7X/H6g2fR7SEabxfbvb903KI4nbfFF+3QtnwyIbTBAcH
0893D3bi5rsaJcz+c6lBob2En2nThRciefXUk2oPzCQuDyFIyHLJikqRQVcalHCdQ00c
/H/JkiJedHNqaeU4TeMk8SM53Brjplj/iiJq+ujc5MlEgACdCwWp0BviFACEoYyFaa3R
kc7Xdm9vFpclm9fzgUfPloASA0SkO945in3mIqMfODTb4yRvbjk8If9483fEPgQkczpd
ptBz1VAKg8AmRcz1GmBIxs+Stn0
= dummy@gitlab.com
KEY
end
end
...
...
spec/lib/gitlab/checks/change_access_spec.rb
View file @
3b17bba1
...
...
@@ -190,7 +190,7 @@ describe Gitlab::Checks::ChangeAccess do
context
'with LFS not enabled'
do
it
'skips the validation'
do
expect_any_instance_of
(
described_class
).
not_to
receive
(
:lfs_file_locks_validation
)
expect_any_instance_of
(
Gitlab
::
Checks
::
CommitCheck
).
not_to
receive
(
:validate
)
subject
.
exec
end
...
...
@@ -207,7 +207,7 @@ describe Gitlab::Checks::ChangeAccess do
end
end
context
'when change is sent by the author o
d
the lock'
do
context
'when change is sent by the author o
f
the lock'
do
let
(
:user
)
{
owner
}
it
"doesn't raise any error"
do
...
...
spec/lib/gitlab/closing_issue_extractor_spec.rb
View file @
3b17bba1
...
...
@@ -365,6 +365,20 @@ describe Gitlab::ClosingIssueExtractor do
.
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
it
'allows oxford commas (comma before and) when referencing multiple issues'
do
message
=
"Closes
#{
reference
}
,
#{
reference2
}
, and
#{
reference3
}
"
expect
(
subject
.
closed_by_message
(
message
))
.
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
it
'allows spaces before commas when referencing multiple issues'
do
message
=
"Closes
#{
reference
}
,
#{
reference2
}
, and
#{
reference3
}
"
expect
(
subject
.
closed_by_message
(
message
))
.
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
it
'fetches issues in multi-line message'
do
message
=
"Awesome commit (closes
#{
reference
}
)
\n
Also fixes
#{
reference2
}
"
...
...
spec/lib/gitlab/git/repository_spec.rb
View file @
3b17bba1
# coding: utf-8
require
"spec_helper"
describe
Gitlab
::
Git
::
Repository
,
seed_helper:
true
do
...
...
@@ -2221,6 +2222,17 @@ describe Gitlab::Git::Repository, seed_helper: true do
subject
end
end
context
'with an ASCII-8BIT diff'
,
:skip_gitaly_mock
do
let
(
:diff
)
{
"diff --git a/README.md b/README.md
\n
index faaf198..43c5edf 100644
\n
--- a/README.md
\n
+++ b/README.md
\n
@@ -1,4 +1,4 @@
\n
-testme
\n
+✓ testme
\n
======
\n
\n
Sample repo for testing gitlab features
\n
"
}
it
'applies a ASCII-8BIT diff'
do
allow
(
repository
).
to
receive
(
:run_git!
).
and_call_original
allow
(
repository
).
to
receive
(
:run_git!
).
with
(
%W(diff --binary
#{
start_sha
}
...
#{
end_sha
}
)
).
and_return
(
diff
.
force_encoding
(
'ASCII-8BIT'
))
expect
(
subject
.
length
).
to
eq
(
40
)
end
end
end
end
...
...
spec/lib/gitlab/gpg/commit_spec.rb
View file @
3b17bba1
...
...
@@ -49,7 +49,9 @@ describe Gitlab::Gpg::Commit do
end
it
'returns a valid signature'
do
expect
(
described_class
.
new
(
commit
).
signature
).
to
have_attributes
(
signature
=
described_class
.
new
(
commit
).
signature
expect
(
signature
).
to
have_attributes
(
commit_sha:
commit_sha
,
project:
project
,
gpg_key:
gpg_key
,
...
...
@@ -58,9 +60,31 @@ describe Gitlab::Gpg::Commit do
gpg_key_user_email:
GpgHelpers
::
User1
.
emails
.
first
,
verification_status:
'verified'
)
expect
(
signature
.
persisted?
).
to
be_truthy
end
it_behaves_like
'returns the cached signature on second call'
context
'read-only mode'
do
before
do
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
end
it
'does not create a cached signature'
do
signature
=
described_class
.
new
(
commit
).
signature
expect
(
signature
).
to
have_attributes
(
commit_sha:
commit_sha
,
project:
project
,
gpg_key:
gpg_key
,
gpg_key_primary_keyid:
GpgHelpers
::
User1
.
primary_keyid
,
gpg_key_user_name:
GpgHelpers
::
User1
.
names
.
first
,
gpg_key_user_email:
GpgHelpers
::
User1
.
emails
.
first
,
verification_status:
'verified'
)
expect
(
signature
.
persisted?
).
to
be_falsey
end
end
end
context
'commit signed with a subkey'
do
...
...
spec/lib/gitlab/ssh_public_key_spec.rb
View file @
3b17bba1
...
...
@@ -37,12 +37,61 @@ describe Gitlab::SSHPublicKey, lib: true do
end
end
describe
'.sanitize(key_content)'
do
let
(
:content
)
{
build
(
:key
).
key
}
context
'when key has blank space characters'
do
it
'removes the extra blank space characters'
do
unsanitized
=
content
.
insert
(
100
,
"
\n
"
)
.
insert
(
40
,
"
\r\n
"
)
.
insert
(
30
,
' '
)
sanitized
=
described_class
.
sanitize
(
unsanitized
)
_
,
body
=
sanitized
.
split
expect
(
sanitized
).
not_to
eq
(
unsanitized
)
expect
(
body
).
not_to
match
(
/\s/
)
end
end
context
"when key doesn't have blank space characters"
do
it
"doesn't modify the content"
do
sanitized
=
described_class
.
sanitize
(
content
)
expect
(
sanitized
).
to
eq
(
content
)
end
end
context
"when key is invalid"
do
it
'returns the original content'
do
unsanitized
=
"ssh-foo any content=="
sanitized
=
described_class
.
sanitize
(
unsanitized
)
expect
(
sanitized
).
to
eq
(
unsanitized
)
end
end
end
describe
'#valid?'
do
subject
{
public_key
}
context
'with a valid SSH key'
do
where
(
:factory
)
do
%i(rsa_key_2048
rsa_key_4096
rsa_key_5120
rsa_key_8192
dsa_key_2048
ecdsa_key_256
ed25519_key_256)
end
with_them
do
let
(
:key
)
{
attributes_for
(
factory
)[
:key
]
}
it
{
is_expected
.
to
be_valid
}
end
end
context
'with an invalid SSH key'
do
let
(
:key
)
{
'this is not a key'
}
...
...
@@ -82,6 +131,9 @@ describe Gitlab::SSHPublicKey, lib: true do
where
(
:factory
,
:bits
)
do
[
[
:rsa_key_2048
,
2048
],
[
:rsa_key_4096
,
4096
],
[
:rsa_key_5120
,
5120
],
[
:rsa_key_8192
,
8192
],
[
:dsa_key_2048
,
2048
],
[
:ecdsa_key_256
,
256
],
[
:ed25519_key_256
,
256
]
...
...
@@ -106,8 +158,11 @@ describe Gitlab::SSHPublicKey, lib: true do
where
(
:factory
,
:fingerprint
)
do
[
[
:rsa_key_2048
,
'2e:ca:dc:e0:37:29:ed:fc:f0:1d:bf:66:d4:cd:51:b1'
],
[
:dsa_key_2048
,
'bc:c1:a4:be:7e:8c:84:56:b3:58:93:53:c6:80:78:8c'
],
[
:rsa_key_2048
,
'58:a8:9d:cd:1f:70:f8:5a:d9:e4:24:8e:da:89:e4:fc'
],
[
:rsa_key_4096
,
'df:73:db:29:3c:a5:32:cf:09:17:7e:8e:9d:de:d7:f7'
],
[
:rsa_key_5120
,
'fe:fa:3a:4d:7d:51:ec:bf:c7:64:0c:96:d0:17:8a:d0'
],
[
:rsa_key_8192
,
'fb:53:7f:e9:2f:f7:17:aa:c8:32:52:06:8e:05:e2:82'
],
[
:dsa_key_2048
,
'c8:85:1e:df:44:0f:20:00:3c:66:57:2b:21:10:5a:27'
],
[
:ecdsa_key_256
,
'67:a3:a9:7d:b8:e1:15:d4:80:40:21:34:bb:ed:97:38'
],
[
:ed25519_key_256
,
'e6:eb:45:8a:3c:59:35:5f:e9:5b:80:12:be:7e:22:73'
]
]
...
...
spec/models/key_spec.rb
View file @
3b17bba1
...
...
@@ -12,6 +12,9 @@ describe Key, :mailer do
it
{
is_expected
.
to
validate_presence_of
(
:key
)
}
it
{
is_expected
.
to
validate_length_of
(
:key
).
is_at_most
(
5000
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:rsa_key_2048
)[
:key
]).
for
(
:key
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:rsa_key_4096
)[
:key
]).
for
(
:key
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:rsa_key_5120
)[
:key
]).
for
(
:key
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:rsa_key_8192
)[
:key
]).
for
(
:key
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:dsa_key_2048
)[
:key
]).
for
(
:key
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:ecdsa_key_256
)[
:key
]).
for
(
:key
)
}
it
{
is_expected
.
to
allow_value
(
attributes_for
(
:ed25519_key_256
)[
:key
]).
for
(
:key
)
}
...
...
@@ -72,16 +75,35 @@ describe Key, :mailer do
expect
(
build
(
:key
)).
to
be_valid
end
it
'accepts a key with newline charecters after stripping them'
do
key
=
build
(
:key
)
key
.
key
=
key
.
key
.
insert
(
100
,
"
\n
"
)
key
.
key
=
key
.
key
.
insert
(
40
,
"
\r\n
"
)
expect
(
key
).
to
be_valid
end
it
'rejects the unfingerprintable key (not a key)'
do
expect
(
build
(
:key
,
key:
'ssh-rsa an-invalid-key=='
)).
not_to
be_valid
end
where
(
:factory
,
:chars
,
:expected_sections
)
do
[
[
:key
,
[
"
\n
"
,
"
\r\n
"
],
3
],
[
:key
,
[
' '
,
' '
],
3
],
[
:key_without_comment
,
[
' '
,
' '
],
2
]
]
end
with_them
do
let!
(
:key
)
{
create
(
factory
)
}
let!
(
:original_fingerprint
)
{
key
.
fingerprint
}
it
'accepts a key with blank space characters after stripping them'
do
modified_key
=
key
.
key
.
insert
(
100
,
chars
.
first
).
insert
(
40
,
chars
.
last
)
_
,
content
=
modified_key
.
split
key
.
update!
(
key:
modified_key
)
expect
(
key
).
to
be_valid
expect
(
key
.
key
.
split
.
size
).
to
eq
(
expected_sections
)
expect
(
content
).
not_to
match
(
/\s/
)
expect
(
original_fingerprint
).
to
eq
(
key
.
fingerprint
)
end
end
end
context
'validate it meets key restrictions'
do
...
...
spec/models/user_spec.rb
View file @
3b17bba1
...
...
@@ -496,6 +496,14 @@ describe User do
user2
.
update_tracked_fields!
(
request
)
end
.
to
change
{
user2
.
reload
.
current_sign_in_at
}
end
it
'does not write if the DB is in read-only mode'
do
expect
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
expect
do
user
.
update_tracked_fields!
(
request
)
end
.
not_to
change
{
user
.
reload
.
current_sign_in_at
}
end
end
shared_context
'user keys'
do
...
...
spec/requests/api/issues_spec.rb
View file @
3b17bba1
...
...
@@ -1380,7 +1380,7 @@ describe API::Issues, :mailer do
end
describe
'/projects/:id/issues/:issue_iid/move'
do
let!
(
:target_project
)
{
create
(
:project
,
path:
'project2'
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let!
(
:target_project
)
{
create
(
:project
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let!
(
:target_project2
)
{
create
(
:project
,
creator_id:
non_member
.
id
,
namespace:
non_member
.
namespace
)
}
it
'moves an issue'
do
...
...
spec/requests/api/projects_spec.rb
View file @
3b17bba1
...
...
@@ -7,7 +7,7 @@ describe API::Projects do
let
(
:user3
)
{
create
(
:user
)
}
let
(
:admin
)
{
create
(
:admin
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
path:
'project2'
,
namespace:
user
.
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
:public
,
author:
user
,
project:
project
,
title:
'example'
)
}
let
(
:project_member
)
{
create
(
:project_member
,
:developer
,
user:
user3
,
project:
project
)
}
let
(
:user4
)
{
create
(
:user
)
}
...
...
@@ -315,7 +315,7 @@ describe API::Projects do
context
'and with all query parameters'
do
let!
(
:project5
)
{
create
(
:project
,
:public
,
path:
'gitlab5'
,
namespace:
create
(
:namespace
))
}
let!
(
:project6
)
{
create
(
:project
,
:public
,
path:
'project6'
,
namespace:
user
.
namespace
)
}
let!
(
:project6
)
{
create
(
:project
,
:public
,
namespace:
user
.
namespace
)
}
let!
(
:project7
)
{
create
(
:project
,
:public
,
path:
'gitlab7'
,
namespace:
user
.
namespace
)
}
let!
(
:project8
)
{
create
(
:project
,
path:
'gitlab8'
,
namespace:
user
.
namespace
)
}
let!
(
:project9
)
{
create
(
:project
,
:public
,
path:
'gitlab9'
)
}
...
...
spec/requests/api/v3/issues_spec.rb
View file @
3b17bba1
...
...
@@ -1191,7 +1191,7 @@ describe API::V3::Issues, :mailer do
end
describe
'/projects/:id/issues/:issue_id/move'
do
let!
(
:target_project
)
{
create
(
:project
,
path:
'project2'
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let!
(
:target_project
)
{
create
(
:project
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let!
(
:target_project2
)
{
create
(
:project
,
creator_id:
non_member
.
id
,
namespace:
non_member
.
namespace
)
}
it
'moves an issue'
do
...
...
spec/requests/api/v3/projects_spec.rb
View file @
3b17bba1
...
...
@@ -6,7 +6,7 @@ describe API::V3::Projects do
let
(
:user3
)
{
create
(
:user
)
}
let
(
:admin
)
{
create
(
:admin
)
}
let
(
:project
)
{
create
(
:project
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
path:
'project2'
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
:public
,
author:
user
,
project:
project
,
title:
'example'
)
}
let
(
:project_member
)
{
create
(
:project_member
,
:developer
,
user:
user3
,
project:
project
)
}
let
(
:user4
)
{
create
(
:user
)
}
...
...
spec/services/issues/move_service_spec.rb
View file @
3b17bba1
...
...
@@ -232,6 +232,28 @@ describe Issues::MoveService do
end
end
context
'issue with assignee'
do
let
(
:assignee
)
{
create
(
:user
)
}
before
do
old_issue
.
assignees
=
[
assignee
]
end
it
'preserves assignee with access to the new issue'
do
new_project
.
add_reporter
(
assignee
)
new_issue
=
move_service
.
execute
(
old_issue
,
new_project
)
expect
(
new_issue
.
assignees
).
to
eq
([
assignee
])
end
it
'ignores assignee without access to the new issue'
do
new_issue
=
move_service
.
execute
(
old_issue
,
new_project
)
expect
(
new_issue
.
assignees
).
to
be_empty
end
end
context
'notes with references'
do
before
do
create
(
:merge_request
,
source_project:
old_project
)
...
...
spec/workers/process_commit_worker_spec.rb
View file @
3b17bba1
...
...
@@ -20,6 +20,32 @@ describe ProcessCommitWorker do
worker
.
perform
(
project
.
id
,
-
1
,
commit
.
to_hash
)
end
context
'when commit is a merge request merge commit'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
description:
"Closes
#{
issue
.
to_reference
}
"
,
source_branch:
'feature-merged'
,
target_branch:
'master'
,
source_project:
project
)
end
let
(
:commit
)
do
project
.
repository
.
create_branch
(
'feature-merged'
,
'feature'
)
sha
=
project
.
repository
.
merge
(
user
,
merge_request
.
diff_head_sha
,
merge_request
,
"Closes
#{
issue
.
to_reference
}
"
)
project
.
repository
.
commit
(
sha
)
end
it
'it does not close any issues from the commit message'
do
expect
(
worker
).
not_to
receive
(
:close_issues
)
worker
.
perform
(
project
.
id
,
user
.
id
,
commit
.
to_hash
)
end
end
it
'processes the commit message'
do
expect
(
worker
).
to
receive
(
:process_commit_message
).
and_call_original
...
...
@@ -48,11 +74,9 @@ describe ProcessCommitWorker do
describe
'#process_commit_message'
do
context
'when pushing to the default branch'
do
it
'closes issues that should be closed per the commit message'
do
allow
(
commit
).
to
receive
(
:safe_message
)
.
and_return
(
"Closes
#{
issue
.
to_reference
}
"
)
allow
(
commit
).
to
receive
(
:safe_message
).
and_return
(
"Closes
#{
issue
.
to_reference
}
"
)
expect
(
worker
).
to
receive
(
:close_issues
)
.
with
(
project
,
user
,
user
,
commit
,
[
issue
])
expect
(
worker
).
to
receive
(
:close_issues
).
with
(
project
,
user
,
user
,
commit
,
[
issue
])
worker
.
process_commit_message
(
project
,
commit
,
user
,
user
,
true
)
end
...
...
@@ -60,8 +84,7 @@ describe ProcessCommitWorker do
context
'when pushing to a non-default branch'
do
it
'does not close any issues'
do
allow
(
commit
).
to
receive
(
:safe_message
)
.
and_return
(
"Closes
#{
issue
.
to_reference
}
"
)
allow
(
commit
).
to
receive
(
:safe_message
).
and_return
(
"Closes
#{
issue
.
to_reference
}
"
)
expect
(
worker
).
not_to
receive
(
:close_issues
)
...
...
@@ -102,8 +125,7 @@ describe ProcessCommitWorker do
describe
'#update_issue_metrics'
do
it
'updates any existing issue metrics'
do
allow
(
commit
).
to
receive
(
:safe_message
)
.
and_return
(
"Closes
#{
issue
.
to_reference
}
"
)
allow
(
commit
).
to
receive
(
:safe_message
).
and_return
(
"Closes
#{
issue
.
to_reference
}
"
)
worker
.
update_issue_metrics
(
commit
,
user
)
...
...
@@ -113,10 +135,10 @@ describe ProcessCommitWorker do
end
it
"doesn't execute any queries with false conditions"
do
allow
(
commit
).
to
receive
(
:safe_message
)
.
and_return
(
"Lorem Ipsum"
)
allow
(
commit
).
to
receive
(
:safe_message
).
and_return
(
"Lorem Ipsum"
)
expect
{
worker
.
update_issue_metrics
(
commit
,
user
)
}.
not_to
make_queries_matching
(
/WHERE (?:1=0|0=1)/
)
expect
{
worker
.
update_issue_metrics
(
commit
,
user
)
}
.
not_to
make_queries_matching
(
/WHERE (?:1=0|0=1)/
)
end
end
...
...
@@ -128,8 +150,9 @@ describe ProcessCommitWorker do
end
it
'parses date strings into Time instances'
do
commit
=
worker
.
build_commit
(
project
,
id:
'123'
,
authored_date:
Time
.
now
.
to_s
)
commit
=
worker
.
build_commit
(
project
,
id:
'123'
,
authored_date:
Time
.
now
.
to_s
)
expect
(
commit
.
authored_date
).
to
be_an_instance_of
(
Time
)
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