diff options
64 files changed, 1161 insertions, 436 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js index 4b19f7b4188..ad8254167a2 100644 --- a/app/assets/javascripts/fly_out_nav.js +++ b/app/assets/javascripts/fly_out_nav.js @@ -148,7 +148,7 @@ export const documentMouseMove = (e) => { export const subItemsMouseLeave = (relatedTarget) => { clearTimeout(timeoutId); - if (!relatedTarget.closest(`.${IS_OVER_CLASS}`)) { + if (relatedTarget && !relatedTarget.closest(`.${IS_OVER_CLASS}`)) { hideMenu(currentOpenMenu); } }; diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index 2b6c0fc015c..cd8fdd3f2ea 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -488,6 +488,7 @@ header.navbar-gitlab-new { .breadcrumb-item-text { @include str-truncated(128px); + text-decoration: inherit; } .breadcrumbs-list-angle { diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index f71ab702e71..cd94a36a6e7 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -48,7 +48,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController ProjectsFinder .new(params: finder_params, current_user: current_user) .execute - .includes(:route, :creator, namespace: :route) + .includes(:route, :creator, namespace: [:route, :owner]) end def load_events diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index aede9b5f9da..c0cc60d5ebf 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -137,11 +137,11 @@ class ApplicationSetting < ActiveRecord::Base validates :housekeeping_full_repack_period, presence: true, - numericality: { only_integer: true, greater_than: :housekeeping_incremental_repack_period } + numericality: { only_integer: true, greater_than_or_equal_to: :housekeeping_incremental_repack_period } validates :housekeeping_gc_period, presence: true, - numericality: { only_integer: true, greater_than: :housekeeping_full_repack_period } + numericality: { only_integer: true, greater_than_or_equal_to: :housekeeping_full_repack_period } validates :terminal_max_session_time, presence: true, diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 654be927ed8..ec0ebe4d353 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -28,7 +28,7 @@ class PersonalAccessToken < ActiveRecord::Base protected def validate_scopes - unless scopes.all? { |scope| Gitlab::Auth::AVAILABLE_SCOPES.include?(scope.to_sym) } + unless revoked || scopes.all? { |scope| Gitlab::Auth::AVAILABLE_SCOPES.include?(scope.to_sym) } errors.add :scopes, "can only contain available scopes" end end diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 069f8f89e0b..703f4165128 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -111,6 +111,11 @@ GitLab API %span.pull-right = API::API::version + - if Gitlab.config.pages.enabled + %p + GitLab Pages + %span.pull-right + = Gitlab::Pages::VERSION %p Git %span.pull-right diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index b8655808d89..a16ffb433a5 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -32,7 +32,7 @@ .commiter - commit_author_link = commit_author_link(commit, avatar: false, size: 24) - - commit_timeago = time_ago_with_tooltip(commit.committed_date) + - commit_timeago = time_ago_with_tooltip(commit.committed_date, placement: 'bottom') - commit_text = _('%{commit_author_link} committed %{commit_timeago}') % { commit_author_link: commit_author_link, commit_timeago: commit_timeago } #{ commit_text.html_safe } diff --git a/changelogs/unreleased/13711-allow-same-period-housekeeping.yml b/changelogs/unreleased/13711-allow-same-period-housekeeping.yml new file mode 100644 index 00000000000..6749e22cf6a --- /dev/null +++ b/changelogs/unreleased/13711-allow-same-period-housekeeping.yml @@ -0,0 +1,6 @@ +--- +title: Allow to use same periods for different housekeeping tasks (effectively + skipping the lesser task) +merge_request: 13711 +author: @cernvcs +type: added diff --git a/changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml b/changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml new file mode 100644 index 00000000000..680ef0cef92 --- /dev/null +++ b/changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml @@ -0,0 +1,5 @@ +--- +title: Add GitLab-Pages version to Admin Dashboard +merge_request: 14040 +author: @travismiller +type: added diff --git a/changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml b/changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml new file mode 100644 index 00000000000..f3118cf0f2f --- /dev/null +++ b/changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml @@ -0,0 +1,4 @@ +--- +title: Fixed non-UTF-8 valid branch names from causing an error. +merge_request: 14090 +type: fixed diff --git a/changelogs/unreleased/consistent-tooltip-direction-on-commits.yml b/changelogs/unreleased/consistent-tooltip-direction-on-commits.yml new file mode 100644 index 00000000000..9e6a429f6f0 --- /dev/null +++ b/changelogs/unreleased/consistent-tooltip-direction-on-commits.yml @@ -0,0 +1,5 @@ +--- +title: Tooltips in the commit info box now all face the same direction +merge_request: +author: Jedidiah Broadbent +type: fixed diff --git a/changelogs/unreleased/dashboards-projects-controller.yml b/changelogs/unreleased/dashboards-projects-controller.yml new file mode 100644 index 00000000000..8b350f70a80 --- /dev/null +++ b/changelogs/unreleased/dashboards-projects-controller.yml @@ -0,0 +1,5 @@ +--- +title: Eager load namespace owners for project dashboards +merge_request: +author: +type: other diff --git a/changelogs/unreleased/detect-orphaned-repositories.yml b/changelogs/unreleased/detect-orphaned-repositories.yml new file mode 100644 index 00000000000..101c1897826 --- /dev/null +++ b/changelogs/unreleased/detect-orphaned-repositories.yml @@ -0,0 +1,5 @@ +--- +title: Scripts to detect orphaned repositories +merge_request: 14204 +author: +type: added diff --git a/changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml b/changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml new file mode 100644 index 00000000000..22ac9b9073f --- /dev/null +++ b/changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml @@ -0,0 +1,4 @@ +--- +title: Hide read_registry scope when registry is disabled on instance +merge_request: 13314 +author: Robin Bobbitt diff --git a/changelogs/unreleased/replace_milestone-feature.yml b/changelogs/unreleased/replace_milestone-feature.yml new file mode 100644 index 00000000000..effe6d65645 --- /dev/null +++ b/changelogs/unreleased/replace_milestone-feature.yml @@ -0,0 +1,5 @@ +--- +title: Replace the project/milestone.feature spinach test with an rspec analog +merge_request: 14171 +author: Vitaliy @blackst0ne Klachkov +type: other diff --git a/changelogs/unreleased/replace_project_builds_summary-feature.yml b/changelogs/unreleased/replace_project_builds_summary-feature.yml new file mode 100644 index 00000000000..48652b39b7e --- /dev/null +++ b/changelogs/unreleased/replace_project_builds_summary-feature.yml @@ -0,0 +1,5 @@ +--- +title: Replace the 'project/builds/summary.feature' spinach test with an rspec analog +merge_request: 14177 +author: Vitaliy @blackst0ne Klachkov +type: other diff --git a/changelogs/unreleased/replace_project_issues_award_emoji-feature.yml b/changelogs/unreleased/replace_project_issues_award_emoji-feature.yml new file mode 100644 index 00000000000..a4a7435d4fa --- /dev/null +++ b/changelogs/unreleased/replace_project_issues_award_emoji-feature.yml @@ -0,0 +1,5 @@ +--- +title: Replace the 'project/issues/award_emoji.feature' spinach test with an rspec analog +merge_request: 14202 +author: Vitaliy @blackst0ne Klachkov +type: other diff --git a/changelogs/unreleased/replace_project_merge_requests_revert-feature.yml b/changelogs/unreleased/replace_project_merge_requests_revert-feature.yml new file mode 100644 index 00000000000..7d1ab4566b6 --- /dev/null +++ b/changelogs/unreleased/replace_project_merge_requests_revert-feature.yml @@ -0,0 +1,6 @@ +--- +title: Replace the 'project/merge_requests/revert.feature' spinach test with an rspec + analog +merge_request: 14201 +author: Vitaliy @blackst0ne Klachkov +type: other diff --git a/db/migrate/20170830131015_swap_event_migration_tables.rb b/db/migrate/20170830131015_swap_event_migration_tables.rb index 5128d1b2fe7..a256de4a8af 100644 --- a/db/migrate/20170830131015_swap_event_migration_tables.rb +++ b/db/migrate/20170830131015_swap_event_migration_tables.rb @@ -7,6 +7,10 @@ class SwapEventMigrationTables < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = false + class Event < ActiveRecord::Base + self.table_name = 'events' + end + def up rename_tables end @@ -19,5 +23,25 @@ class SwapEventMigrationTables < ActiveRecord::Migration rename_table :events, :events_old rename_table :events_for_migration, :events rename_table :events_old, :events_for_migration + + # Once swapped we need to reset the primary key of the new "events" table to + # make sure that data created starts with the right value. This isn't + # necessary for events_for_migration since we replicate existing primary key + # values to it. + if Gitlab::Database.postgresql? + reset_primary_key_for_postgresql + else + reset_primary_key_for_mysql + end + end + + def reset_primary_key_for_postgresql + reset_pk_sequence!(Event.table_name) + end + + def reset_primary_key_for_mysql + amount = Event.pluck('COALESCE(MAX(id), 1)').first + + execute "ALTER TABLE #{Event.table_name} AUTO_INCREMENT = #{amount}" end end diff --git a/doc/development/README.md b/doc/development/README.md index eeff14819da..3096d9f25f0 100644 --- a/doc/development/README.md +++ b/doc/development/README.md @@ -43,6 +43,7 @@ - [Object state models](object_state_models.md) - [Building a package for testing purposes](build_test_package.md) - [Manage feature flags](feature_flags.md) +- [View sent emails or preview mailers](emails.md) ## Databases diff --git a/doc/development/emails.md b/doc/development/emails.md new file mode 100644 index 00000000000..18f47f44cb5 --- /dev/null +++ b/doc/development/emails.md @@ -0,0 +1,23 @@ +# Dealing with email in development + +## Sent emails + +To view rendered emails "sent" in your development instance, visit +[`/rails/letter_opener`](http://localhost:3000/rails/letter_opener). + +## Mailer previews + +Rails provides a way to preview our mailer templates in HTML and plaintext using +dummy data. + +The previews live in [`spec/mailers/previews`][previews] and can be viewed at +[`/rails/mailers`](http://localhost:3000/rails/mailers). + +See the [Rails guides] for more info. + +[previews]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/spec/mailers/previews +[Rails guides]: http://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails + +--- + +[Return to Development documentation](README.md) diff --git a/doc/install/installation.md b/doc/install/installation.md index 66eb7675896..200cd94f43c 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -299,9 +299,9 @@ sudo usermod -aG redis git ### Clone the Source # Clone GitLab repository - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-5-stable gitlab + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 10-0-stable gitlab -**Note:** You can change `9-5-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! +**Note:** You can change `10-0-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! ### Configure It diff --git a/doc/update/8.17-to-9.0.md b/doc/update/8.17-to-9.0.md index 2abc57da1a0..baab217b6b7 100644 --- a/doc/update/8.17-to-9.0.md +++ b/doc/update/8.17-to-9.0.md @@ -236,7 +236,7 @@ ActionMailer::Base.delivery_method = :smtp See [smtp_settings.rb.sample] as an example. -[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-17-stable/config/initializers/smtp_settings.rb.sample#L13 +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-0-stable/config/initializers/smtp_settings.rb.sample#L13 #### Init script diff --git a/doc/update/9.0-to-9.1.md b/doc/update/9.0-to-9.1.md index 3fd1d023d2a..6f1870a1366 100644 --- a/doc/update/9.0-to-9.1.md +++ b/doc/update/9.0-to-9.1.md @@ -236,7 +236,7 @@ ActionMailer::Base.delivery_method = :smtp See [smtp_settings.rb.sample] as an example. -[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-0-stable/config/initializers/smtp_settings.rb.sample#L13 +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-1-stable/config/initializers/smtp_settings.rb.sample#L13 #### Init script diff --git a/doc/update/9.1-to-9.2.md b/doc/update/9.1-to-9.2.md index 5f7a616cc7d..ce72b313031 100644 --- a/doc/update/9.1-to-9.2.md +++ b/doc/update/9.1-to-9.2.md @@ -194,7 +194,7 @@ ActionMailer::Base.delivery_method = :smtp See [smtp_settings.rb.sample] as an example. -[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-1-stable/config/initializers/smtp_settings.rb.sample#L13 +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-2-stable/config/initializers/smtp_settings.rb.sample#L13 #### Init script diff --git a/doc/update/9.2-to-9.3.md b/doc/update/9.2-to-9.3.md index 9d0b0da7edb..779ced0cf75 100644 --- a/doc/update/9.2-to-9.3.md +++ b/doc/update/9.2-to-9.3.md @@ -230,7 +230,7 @@ ActionMailer::Base.delivery_method = :smtp See [smtp_settings.rb.sample] as an example. -[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-2-stable/config/initializers/smtp_settings.rb.sample#L13 +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-3-stable/config/initializers/smtp_settings.rb.sample#L13 #### Init script diff --git a/doc/update/9.3-to-9.4.md b/doc/update/9.3-to-9.4.md index 9ee01bc9c51..78d8a6c7de5 100644 --- a/doc/update/9.3-to-9.4.md +++ b/doc/update/9.3-to-9.4.md @@ -243,7 +243,7 @@ ActionMailer::Base.delivery_method = :smtp See [smtp_settings.rb.sample] as an example. -[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-3-stable/config/initializers/smtp_settings.rb.sample#L13 +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-4-stable/config/initializers/smtp_settings.rb.sample#L13 #### Init script diff --git a/doc/update/9.4-to-9.5.md b/doc/update/9.4-to-9.5.md index 1b5a15589af..a7255142ef5 100644 --- a/doc/update/9.4-to-9.5.md +++ b/doc/update/9.4-to-9.5.md @@ -252,7 +252,7 @@ ActionMailer::Base.delivery_method = :smtp See [smtp_settings.rb.sample] as an example. -[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-4-stable/config/initializers/smtp_settings.rb.sample#L13 +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-5-stable/config/initializers/smtp_settings.rb.sample#L13 #### Init script diff --git a/doc/update/9.5-to-10.0.md b/doc/update/9.5-to-10.0.md new file mode 100644 index 00000000000..8581e6511f2 --- /dev/null +++ b/doc/update/9.5-to-10.0.md @@ -0,0 +1,356 @@ +# From 9.5 to 10.0 + +Make sure you view this update guide from the tag (version) of GitLab you would +like to install. In most cases this should be the highest numbered production +tag (without rc in it). You can select the tag in the version dropdown at the +top left corner of GitLab (below the menu bar). + +If the highest number stable branch is unclear please check the +[GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation +guide links by version. + +### 1. Stop server + +```bash +sudo service gitlab stop +``` + +### 2. Backup + +```bash +cd /home/git/gitlab + +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production +``` + +### 3. Update Ruby + +NOTE: GitLab 9.0 and higher only support Ruby 2.3.x and dropped support for Ruby 2.1.x. Be +sure to upgrade your interpreter if necessary. + +You can check which version you are running with `ruby -v`. + +Download and compile Ruby: + +```bash +mkdir /tmp/ruby && cd /tmp/ruby +curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.3.tar.gz +echo '1014ee699071aa2ddd501907d18cbe15399c997d ruby-2.3.3.tar.gz' | shasum -c - && tar xzf ruby-2.3.3.tar.gz +cd ruby-2.3.3 +./configure --disable-install-rdoc +make +sudo make install +``` + +Install Bundler: + +```bash +sudo gem install bundler --no-ri --no-rdoc +``` + +### 4. Update Node + +GitLab now runs [webpack](http://webpack.js.org) to compile frontend assets and +it has a minimum requirement of node v4.3.0. + +You can check which version you are running with `node -v`. If you are running +a version older than `v4.3.0` you will need to update to a newer version. You +can find instructions to install from community maintained packages or compile +from source at the nodejs.org website. + +<https://nodejs.org/en/download/> + + +Since 8.17, GitLab requires the use of yarn `>= v0.17.0` to manage +JavaScript dependencies. + +```bash +curl --silent --show-error https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - +echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list +sudo apt-get update +sudo apt-get install yarn +``` + +More information can be found on the [yarn website](https://yarnpkg.com/en/docs/install). + +### 5. Update Go + +NOTE: GitLab 9.2 and higher only supports Go 1.8.3 and dropped support for Go +1.5.x through 1.7.x. Be sure to upgrade your installation if necessary. + +You can check which version you are running with `go version`. + +Download and install Go: + +```bash +# Remove former Go installation folder +sudo rm -rf /usr/local/go + +curl --remote-name --progress https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz +echo '1862f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772 go1.8.3.linux-amd64.tar.gz' | shasum -a256 -c - && \ + sudo tar -C /usr/local -xzf go1.8.3.linux-amd64.tar.gz +sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/ +rm go1.8.3.linux-amd64.tar.gz +``` + +### 6. Get latest code + +```bash +cd /home/git/gitlab + +sudo -u git -H git fetch --all +sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically +sudo -u git -H git checkout -- locale +``` + +For GitLab Community Edition: + +```bash +cd /home/git/gitlab + +sudo -u git -H git checkout 10-0-stable +``` + +OR + +For GitLab Enterprise Edition: + +```bash +cd /home/git/gitlab + +sudo -u git -H git checkout 10-0-stable-ee +``` + +### 7. Update gitlab-shell + +```bash +cd /home/git/gitlab-shell + +sudo -u git -H git fetch --all --tags +sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_SHELL_VERSION) +sudo -u git -H bin/compile +``` + +### 8. Update gitlab-workhorse + +Install and compile gitlab-workhorse. GitLab-Workhorse uses +[GNU Make](https://www.gnu.org/software/make/). +If you are not using Linux you may have to run `gmake` instead of +`make` below. + +```bash +cd /home/git/gitlab-workhorse + +sudo -u git -H git fetch --all --tags +sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_WORKHORSE_VERSION) +sudo -u git -H make +``` + +### 9. Update Gitaly + +#### New Gitaly configuration options required + +In order to function Gitaly needs some additional configuration information. Below we assume you installed Gitaly in `/home/git/gitaly` and GitLab Shell in `/home/git/gitlab-shell'. + +```shell +echo ' +[gitaly-ruby] +dir = "/home/git/gitaly/ruby" + +[gitlab-shell] +dir = "/home/git/gitlab-shell" +' | sudo -u git tee -a /home/git/gitaly/config.toml +``` + +#### Check Gitaly configuration + +Due to a bug in the `rake gitlab:gitaly:install` script your Gitaly +configuration file may contain syntax errors. The block name +`[[storages]]`, which may occur more than once in your `config.toml` +file, should be `[[storage]]` instead. + +```shell +sudo -u git -H sed -i.pre-10.0 's/\[\[storages\]\]/[[storage]]/' /home/git/gitaly/config.toml +``` + +#### Compile Gitaly + +```shell +cd /home/git/gitaly +sudo -u git -H git fetch --all --tags +sudo -u git -H git checkout v$(</home/git/gitlab/GITALY_SERVER_VERSION) +sudo -u git -H make +``` + +### 10. Update MySQL permissions + +If you are using MySQL you need to grant the GitLab user the necessary +permissions on the database: + +```bash +mysql -u root -p -e "GRANT TRIGGER ON \`gitlabhq_production\`.* TO 'git'@'localhost';" +``` + +If you use MySQL with replication, or just have MySQL configured with binary logging, +you will need to also run the following on all of your MySQL servers: + +```bash +mysql -u root -p -e "SET GLOBAL log_bin_trust_function_creators = 1;" +``` + +You can make this setting permanent by adding it to your `my.cnf`: + +``` +log_bin_trust_function_creators=1 +``` + +### 11. Update configuration files + +#### New configuration options for `gitlab.yml` + +There might be configuration options available for [`gitlab.yml`][yaml]. View them with the command below and apply them manually to your current `gitlab.yml`: + +```sh +cd /home/git/gitlab + +git diff origin/9-5-stable:config/gitlab.yml.example origin/10-0-stable:config/gitlab.yml.example +``` + +#### Nginx configuration + +Ensure you're still up-to-date with the latest NGINX configuration changes: + +```sh +cd /home/git/gitlab + +# For HTTPS configurations +git diff origin/9-5-stable:lib/support/nginx/gitlab-ssl origin/10-0-stable:lib/support/nginx/gitlab-ssl + +# For HTTP configurations +git diff origin/9-5-stable:lib/support/nginx/gitlab origin/10-0-stable:lib/support/nginx/gitlab +``` + +If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx +configuration as GitLab application no longer handles setting it. + +If you are using Apache instead of NGINX please see the updated [Apache templates]. +Also note that because Apache does not support upstreams behind Unix sockets you +will need to let gitlab-workhorse listen on a TCP port. You can do this +via [/etc/default/gitlab]. + +[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache +[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/10-0-stable/lib/support/init.d/gitlab.default.example#L38 + +#### SMTP configuration + +If you're installing from source and use SMTP to deliver mail, you will need to add the following line +to config/initializers/smtp_settings.rb: + +```ruby +ActionMailer::Base.delivery_method = :smtp +``` + +See [smtp_settings.rb.sample] as an example. + +[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/10-0-stable/config/initializers/smtp_settings.rb.sample#L13 + +#### Init script + +There might be new configuration options available for [`gitlab.default.example`][gl-example]. View them with the command below and apply them manually to your current `/etc/default/gitlab`: + +```sh +cd /home/git/gitlab + +git diff origin/9-5-stable:lib/support/init.d/gitlab.default.example origin/10-0-stable:lib/support/init.d/gitlab.default.example +``` + +Ensure you're still up-to-date with the latest init script changes: + +```bash +cd /home/git/gitlab + +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab +``` + +For Ubuntu 16.04.1 LTS: + +```bash +sudo systemctl daemon-reload +``` + +### 12. Install libs, migrations, etc. + +```bash +cd /home/git/gitlab + +# MySQL installations (note: the line below states '--without postgres') +sudo -u git -H bundle install --without postgres development test --deployment + +# PostgreSQL installations (note: the line below states '--without mysql') +sudo -u git -H bundle install --without mysql development test --deployment + +# Optional: clean up old gems +sudo -u git -H bundle clean + +# Run database migrations +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production + +# Compile GetText PO files + +sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production + +# Update node dependencies and recompile assets +sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production + +# Clean up cache +sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production +``` + +**MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md). + +### 13. Start application + +```bash +sudo service gitlab start +sudo service nginx restart +``` + +### 14. Check application status + +Check if GitLab and its environment are configured correctly: + +```bash +cd /home/git/gitlab + +sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production +``` + +To make sure you didn't miss anything run a more thorough check: + +```bash +cd /home/git/gitlab + +sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production +``` + +If all items are green, then congratulations, the upgrade is complete! + +## Things went south? Revert to previous version (9.5) + +### 1. Revert the code to the previous version + +Follow the [upgrade guide from 9.4 to 9.5](9.4-to-9.5.md), except for the +database migration (the backup is already migrated to the previous version). + +### 2. Restore from the backup + +```bash +cd /home/git/gitlab + +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production +``` + +If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above. + +[yaml]: https://gitlab.com/gitlab-org/gitlab-ce/blob/10-0-stable/config/gitlab.yml.example +[gl-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/10-0-stable/lib/support/init.d/gitlab.default.example diff --git a/doc/user/project/merge_requests/img/group_merge_requests_list_view.png b/doc/user/project/merge_requests/img/group_merge_requests_list_view.png Binary files differindex 02a88d0112f..7d0756505db 100644 --- a/doc/user/project/merge_requests/img/group_merge_requests_list_view.png +++ b/doc/user/project/merge_requests/img/group_merge_requests_list_view.png diff --git a/doc/user/search/index.md b/doc/user/search/index.md index 21e96d8b11c..bcc3625f908 100644 --- a/doc/user/search/index.md +++ b/doc/user/search/index.md @@ -63,8 +63,6 @@ the same way as you do for projects. ![filter issues in a group](img/group_issues_filter.png) The same process is valid for merge requests. Navigate to your project's **Merge Requests** tab. -The search and filter UI currently uses dropdowns. In a future release, the same -dynamic UI as above will be carried over here. ## Search history diff --git a/features/project/builds/summary.feature b/features/project/builds/summary.feature deleted file mode 100644 index 3bf15b0cf87..00000000000 --- a/features/project/builds/summary.feature +++ /dev/null @@ -1,30 +0,0 @@ -Feature: Project Builds Summary - Background: - Given I sign in as a user - And I own a project - And project has CI enabled - And project has coverage enabled - And project has a recent build - - @javascript - Scenario: I browse build details page - When I visit recent build details page - Then I see details of a build - And I see build trace - - @javascript - Scenario: I browse project builds page - When I visit project builds page - Then I see coverage - Then I see button to CI Lint - - @javascript - Scenario: I erase a build - Given recent build is successful - And recent build has a build trace - When I visit recent build details page - And I click erase build button - Then recent build has been erased - And recent build summary does not have artifacts widget - And recent build summary contains information saying that build has been erased - And the build count cache is updated diff --git a/features/project/issues/award_emoji.feature b/features/project/issues/award_emoji.feature deleted file mode 100644 index 1d7adfdd2c2..00000000000 --- a/features/project/issues/award_emoji.feature +++ /dev/null @@ -1,45 +0,0 @@ -@project_issues -Feature: Award Emoji - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has issue "Bugfix" - And I visit "Bugfix" issue page - - @javascript - Scenario: I repeatedly add and remove thumbsup award in the issue - Given I click the thumbsup award Emoji - Then I have award added - Given I click the thumbsup award Emoji - Then I have no awards added - Given I click the thumbsup award Emoji - Then I have award added - - @javascript - Scenario: I add and remove custom award in the issue - Given I click to emoji-picker - Then The emoji menu is visible - And The search field is focused - Then I click to emoji in the picker - Then I have award added - And I can remove it by clicking to icon - - @javascript - Scenario: I can see the list of emoji categories - Given I click to emoji-picker - Then The emoji menu is visible - And The search field is focused - Then I can see the activity and food categories - - @javascript - Scenario: I can search emoji - Given I click to emoji-picker - Then The emoji menu is visible - And The search field is focused - And I search "hand" - Then I see search result for "hand" - - @javascript - Scenario: I add award emoji using regular comment - Given I leave comment with a single emoji - Then I have new comment with emoji added diff --git a/features/project/merge_requests/revert.feature b/features/project/merge_requests/revert.feature deleted file mode 100644 index aaac5fd7209..00000000000 --- a/features/project/merge_requests/revert.feature +++ /dev/null @@ -1,29 +0,0 @@ -@project_merge_requests -Feature: Revert Merge Requests - Background: - Given There is an open Merge Request - And I am signed in as a developer of the project - And I am on the Merge Request detail page - And I click on Accept Merge Request - And I am on the Merge Request detail page - - @javascript - Scenario: I revert a merge request - Given I click on the revert button - And I revert the changes directly - Then I should see the revert merge request notice - - @javascript - Scenario: I revert a merge request that was previously reverted - Given I click on the revert button - And I revert the changes directly - And I am on the Merge Request detail page - And I click on the revert button - And I revert the changes directly - Then I should see a revert error - - @javascript - Scenario: I revert a merge request in a new merge request - Given I click on the revert button - And I revert the changes in a new merge request - Then I should see the new merge request notice diff --git a/features/project/milestone.feature b/features/project/milestone.feature deleted file mode 100644 index 5e7b211fa27..00000000000 --- a/features/project/milestone.feature +++ /dev/null @@ -1,16 +0,0 @@ -Feature: Project Milestone - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has labels: "bug", "feature", "enhancement" - And project "Shop" has milestone "v2.2" - And milestone has issue "Bugfix1" with labels: "bug", "feature" - And milestone has issue "Bugfix2" with labels: "bug", "enhancement" - - @javascript - Scenario: Listing labels from labels tab - Given I visit project "Shop" milestones page - And I click link "v2.2" - And I click link "Labels" - Then I should see the list of labels - And I should see the labels "bug", "enhancement" and "feature" diff --git a/features/steps/project/builds/summary.rb b/features/steps/project/builds/summary.rb deleted file mode 100644 index 20a5c873ecd..00000000000 --- a/features/steps/project/builds/summary.rb +++ /dev/null @@ -1,43 +0,0 @@ -class Spinach::Features::ProjectBuildsSummary < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedBuilds - include RepoHelpers - - step 'I see coverage' do - page.within('td.coverage') do - expect(page).to have_content "99.9%" - end - end - - step 'I see button to CI Lint' do - page.within('.nav-controls') do - ci_lint_tool_link = page.find_link('CI lint') - expect(ci_lint_tool_link[:href]).to end_with(ci_lint_path) - end - end - - step 'I click erase build button' do - click_link 'Erase' - end - - step 'recent build has been erased' do - expect(@build).not_to have_trace - expect(@build.artifacts_file.exists?).to be_falsy - expect(@build.artifacts_metadata.exists?).to be_falsy - end - - step 'recent build summary does not have artifacts widget' do - expect(page).to have_no_css('.artifacts') - end - - step 'recent build summary contains information saying that build has been erased' do - page.within('.erased') do - expect(page).to have_content 'Job has been erased' - end - end - - step 'the build count cache is updated' do - expect(@build.project.running_or_pending_build_count).to eq @build.project.builds.running_or_pending.count(:all) - end -end diff --git a/features/steps/project/issues/award_emoji.rb b/features/steps/project/issues/award_emoji.rb deleted file mode 100644 index bbd284b4633..00000000000 --- a/features/steps/project/issues/award_emoji.rb +++ /dev/null @@ -1,107 +0,0 @@ -class Spinach::Features::AwardEmoji < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include Select2Helper - - step 'I visit "Bugfix" issue page' do - visit project_issue_path(@project, @issue) - end - - step 'I click the thumbsup award Emoji' do - page.within '.awards' do - thumbsup = page.first('.award-control') - thumbsup.click - thumbsup.hover - end - end - - step 'I click to emoji-picker' do - page.within '.awards' do - page.find('.js-add-award').click - end - end - - step 'I click to emoji in the picker' do - page.within '.emoji-menu-content' do - emoji_button = page.first('.js-emoji-btn') - emoji_button.hover - emoji_button.click - end - end - - step 'I can remove it by clicking to icon' do - page.within '.awards' do - expect do - page.find('.js-emoji-btn.active').click - wait_for_requests - end.to change { page.all(".award-control.js-emoji-btn").size }.from(3).to(2) - end - end - - step 'I can see the activity and food categories' do - page.within '.emoji-menu' do - expect(page).not_to have_selector 'Activity' - expect(page).not_to have_selector 'Food' - end - end - - step 'I have new comment with emoji added' do - expect(page).to have_selector 'gl-emoji[data-name="smile"]' - end - - step 'I have award added' do - page.within '.awards' do - expect(page).to have_selector '.js-emoji-btn' - expect(page.find('.js-emoji-btn.active .js-counter')).to have_content '1' - expect(page).to have_css(".js-emoji-btn.active[data-original-title='You']") - end - end - - step 'I have no awards added' do - page.within '.awards' do - expect(page).to have_selector '.award-control.js-emoji-btn' - expect(page.all('.award-control.js-emoji-btn').size).to eq(2) - - # Check tooltip data - page.all('.award-control.js-emoji-btn').each do |element| - expect(element['title']).to eq("") - end - - page.all('.award-control .js-counter').each do |element| - expect(element).to have_content '0' - end - end - end - - step 'project "Shop" has issue "Bugfix"' do - @project = Project.find_by(name: 'Shop') - @issue = create(:issue, title: 'Bugfix', project: project) - end - - step 'I leave comment with a single emoji' do - page.within('.js-main-target-form') do - fill_in 'note[note]', with: ':smile:' - click_button 'Comment' - end - end - - step 'I search "hand"' do - fill_in 'emoji-menu-search', with: 'hand' - end - - step 'I see search result for "hand"' do - page.within '.emoji-menu-content' do - expect(page).to have_selector '[data-name="raised_hand"]' - end - end - - step 'The emoji menu is visible' do - page.find(".emoji-menu.is-visible") - end - - step 'The search field is focused' do - expect(page).to have_selector('.js-emoji-menu-search') - expect(page.evaluate_script("document.activeElement.classList.contains('js-emoji-menu-search')")).to eq(true) - end -end diff --git a/features/steps/project/merge_requests/revert.rb b/features/steps/project/merge_requests/revert.rb deleted file mode 100644 index 25ccf5ab180..00000000000 --- a/features/steps/project/merge_requests/revert.rb +++ /dev/null @@ -1,56 +0,0 @@ -class Spinach::Features::RevertMergeRequests < Spinach::FeatureSteps - include LoginHelpers - include WaitForRequests - - step 'I click on the revert button' do - find("a[href='#modal-revert-commit']").click - end - - step 'I revert the changes directly' do - page.within('#modal-revert-commit') do - uncheck 'create_merge_request' - click_button 'Revert' - end - end - - step 'I should see the revert merge request notice' do - page.should have_content('The merge request has been successfully reverted.') - wait_for_requests - end - - step 'I should not see the revert button' do - expect(page).not_to have_selector(:xpath, "a[href='#modal-revert-commit']") - end - - step 'I am on the Merge Request detail page' do - visit merge_request_path(@merge_request) - end - - step 'I click on Accept Merge Request' do - click_button('Merge') - end - - step 'I am signed in as a developer of the project' do - @user = create(:user) { |u| @project.add_developer(u) } - sign_in(@user) - end - - step 'There is an open Merge Request' do - @merge_request = create(:merge_request, :with_diffs, :simple) - @project = @merge_request.source_project - end - - step 'I should see a revert error' do - page.should have_content('Sorry, we cannot revert this merge request automatically.') - end - - step 'I revert the changes in a new merge request' do - page.within('#modal-revert-commit') do - click_button 'Revert' - end - end - - step 'I should see the new merge request notice' do - page.should have_content('The merge request has been successfully reverted. You can now submit a merge request to get this change into the original branch.') - end -end diff --git a/features/steps/project/project_milestone.rb b/features/steps/project/project_milestone.rb deleted file mode 100644 index b2d08515e77..00000000000 --- a/features/steps/project/project_milestone.rb +++ /dev/null @@ -1,62 +0,0 @@ -class Spinach::Features::ProjectMilestone < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include WaitForRequests - - step 'milestone has issue "Bugfix1" with labels: "bug", "feature"' do - project = Project.find_by(name: "Shop") - milestone = project.milestones.find_by(title: 'v2.2') - issue = create(:issue, title: "Bugfix1", project: project, milestone: milestone) - issue.labels << project.labels.find_by(title: 'bug') - issue.labels << project.labels.find_by(title: 'feature') - end - - step 'milestone has issue "Bugfix2" with labels: "bug", "enhancement"' do - project = Project.find_by(name: "Shop") - milestone = project.milestones.find_by(title: 'v2.2') - issue = create(:issue, title: "Bugfix2", project: project, milestone: milestone) - issue.labels << project.labels.find_by(title: 'bug') - issue.labels << project.labels.find_by(title: 'enhancement') - end - - step 'project "Shop" has milestone "v2.2"' do - project = Project.find_by(name: "Shop") - milestone = create(:milestone, - title: "v2.2", - project: project, - description: "# Description header" - ) - 3.times { create(:issue, project: project, milestone: milestone) } - end - - step 'I should see the list of labels' do - expect(page).to have_selector('ul.manage-labels-list') - end - - step 'I should see the labels "bug", "enhancement" and "feature"' do - wait_for_requests - - page.within('#tab-issues') do - expect(page).to have_content 'bug' - expect(page).to have_content 'enhancement' - expect(page).to have_content 'feature' - end - end - - step 'I should see the "bug" label listed only once' do - page.within('#tab-labels') do - expect(page).to have_content('bug', count: 1) - end - end - - step 'I click link "v2.2"' do - click_link "v2.2" - end - - step 'I click link "Labels"' do - page.within('.nav-sidebar') do - page.find(:xpath, "//a[@href='#tab-labels']").click - end - end -end diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 3fd81759d25..11ace83c15c 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -2,7 +2,7 @@ module Gitlab module Auth MissingPersonalTokenError = Class.new(StandardError) - REGISTRY_SCOPES = [:read_registry].freeze + REGISTRY_SCOPES = Gitlab.config.registry.enabled ? [:read_registry].freeze : [].freeze # Scopes used for GitLab API access API_SCOPES = [:api, :read_user].freeze diff --git a/lib/gitlab/git.rb b/lib/gitlab/git.rb index 8c9acbc9fbe..b4b6326cfdd 100644 --- a/lib/gitlab/git.rb +++ b/lib/gitlab/git.rb @@ -11,7 +11,7 @@ module Gitlab include Gitlab::EncodingHelper def ref_name(ref) - encode! ref.sub(/\Arefs\/(tags|heads|remotes)\//, '') + encode_utf8(ref).sub(/\Arefs\/(tags|heads|remotes)\//, '') end def branch_name(ref) diff --git a/lib/gitlab/pages.rb b/lib/gitlab/pages.rb new file mode 100644 index 00000000000..981ef8faa9a --- /dev/null +++ b/lib/gitlab/pages.rb @@ -0,0 +1,5 @@ +module Gitlab + module Pages + VERSION = File.read(Rails.root.join("GITLAB_PAGES_VERSION")).strip.freeze + end +end diff --git a/lib/system_check/orphans/namespace_check.rb b/lib/system_check/orphans/namespace_check.rb new file mode 100644 index 00000000000..b8446300f72 --- /dev/null +++ b/lib/system_check/orphans/namespace_check.rb @@ -0,0 +1,54 @@ +module SystemCheck + module Orphans + class NamespaceCheck < SystemCheck::BaseCheck + set_name 'Orphaned namespaces:' + + def multi_check + Gitlab.config.repositories.storages.each do |storage_name, repository_storage| + $stdout.puts + $stdout.puts "* Storage: #{storage_name} (#{repository_storage['path']})".color(:yellow) + toplevel_namespace_dirs = disk_namespaces(repository_storage['path']) + + orphans = (toplevel_namespace_dirs - existing_namespaces) + print_orphans(orphans, storage_name) + end + + clear_namespaces! # releases memory when check finishes + end + + private + + def print_orphans(orphans, storage_name) + if orphans.empty? + $stdout.puts "* No orphaned namespaces for #{storage_name} storage".color(:green) + return + end + + orphans.each do |orphan| + $stdout.puts " - #{orphan}".color(:red) + end + end + + def disk_namespaces(storage_path) + fetch_disk_namespaces(storage_path).each_with_object([]) do |namespace_path, result| + namespace = File.basename(namespace_path) + next if namespace.eql?('@hashed') + + result << namespace + end + end + + def fetch_disk_namespaces(storage_path) + Dir.glob(File.join(storage_path, '*')) + end + + def existing_namespaces + @namespaces ||= Namespace.where(parent: nil).all.pluck(:path) + end + + def clear_namespaces! + @namespaces = nil + end + end + end +end diff --git a/lib/system_check/orphans/repository_check.rb b/lib/system_check/orphans/repository_check.rb new file mode 100644 index 00000000000..9b6b2429783 --- /dev/null +++ b/lib/system_check/orphans/repository_check.rb @@ -0,0 +1,68 @@ +module SystemCheck + module Orphans + class RepositoryCheck < SystemCheck::BaseCheck + set_name 'Orphaned repositories:' + attr_accessor :orphans + + def multi_check + Gitlab.config.repositories.storages.each do |storage_name, repository_storage| + $stdout.puts + $stdout.puts "* Storage: #{storage_name} (#{repository_storage['path']})".color(:yellow) + + repositories = disk_repositories(repository_storage['path']) + orphans = (repositories - fetch_repositories(storage_name)) + + print_orphans(orphans, storage_name) + end + end + + private + + def print_orphans(orphans, storage_name) + if orphans.empty? + $stdout.puts "* No orphaned repositories for #{storage_name} storage".color(:green) + return + end + + orphans.each do |orphan| + $stdout.puts " - #{orphan}".color(:red) + end + end + + def disk_repositories(storage_path) + fetch_disk_namespaces(storage_path).each_with_object([]) do |namespace_path, result| + namespace = File.basename(namespace_path) + next if namespace.eql?('@hashed') + + fetch_disk_repositories(namespace_path).each do |repo| + result << "#{namespace}/#{File.basename(repo)}" + end + end + end + + def fetch_repositories(storage_name) + sql = " + SELECT + CONCAT(n.path, '/', p.path, '.git') repo, + CONCAT(n.path, '/', p.path, '.wiki.git') wiki + FROM projects p + JOIN namespaces n + ON (p.namespace_id = n.id AND + n.parent_id IS NULL) + WHERE (p.repository_storage LIKE ?) + " + + query = ActiveRecord::Base.send(:sanitize_sql_array, [sql, storage_name]) # rubocop:disable GitlabSecurity/PublicSend + ActiveRecord::Base.connection.select_all(query).rows.try(:flatten!) || [] + end + + def fetch_disk_namespaces(storage_path) + Dir.glob(File.join(storage_path, '*')) + end + + def fetch_disk_repositories(namespace_path) + Dir.glob(File.join(namespace_path, '*')) + end + end + end +end diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 654f638c454..dfade1f3885 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -398,6 +398,35 @@ namespace :gitlab do end end + namespace :orphans do + desc 'Gitlab | Check for orphaned namespaces and repositories' + task check: :environment do + warn_user_is_not_gitlab + checks = [ + SystemCheck::Orphans::NamespaceCheck, + SystemCheck::Orphans::RepositoryCheck + ] + + SystemCheck.run('Orphans', checks) + end + + desc 'GitLab | Check for orphaned namespaces in the repositories path' + task check_namespaces: :environment do + warn_user_is_not_gitlab + checks = [SystemCheck::Orphans::NamespaceCheck] + + SystemCheck.run('Orphans', checks) + end + + desc 'GitLab | Check for orphaned repositories in the repositories path' + task check_repositories: :environment do + warn_user_is_not_gitlab + checks = [SystemCheck::Orphans::RepositoryCheck] + + SystemCheck.run('Orphans', checks) + end + end + namespace :user do desc "GitLab | Check the integrity of a specific user's repositories" task :check_repos, [:username] => :environment do |t, args| diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 745d051a5c1..5e0b57e9b2e 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -367,5 +367,20 @@ describe Projects::BranchesController do expect(parsed_response.first).to eq 'master' end end + + context 'when branch contains an invalid UTF-8 sequence' do + before do + project.repository.create_branch("wrong-\xE5-utf8-sequence") + end + + it 'return with a status 200' do + get :index, + namespace_id: project.namespace, + project_id: project, + format: :html + + expect(response).to have_http_status(200) + end + end end end diff --git a/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb b/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb new file mode 100644 index 00000000000..adff0a10f0e --- /dev/null +++ b/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb @@ -0,0 +1,104 @@ +require 'spec_helper' + +describe 'User interacts with awards in an issue', :js do + let(:issue) { create(:issue, project: project)} + let(:project) { create(:project) } + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + + visit(project_issue_path(project, issue)) + end + + it 'toggles the thumbsup award emoji' do + page.within('.awards') do + thumbsup = page.first('.award-control') + thumbsup.click + thumbsup.hover + + expect(page).to have_selector('.js-emoji-btn') + expect(page).to have_css(".js-emoji-btn.active[data-original-title='You']") + expect(page.find('.js-emoji-btn.active .js-counter')).to have_content('1') + + thumbsup = page.first('.award-control') + thumbsup.click + thumbsup.hover + + expect(page).to have_selector('.award-control.js-emoji-btn') + expect(page.all('.award-control.js-emoji-btn').size).to eq(2) + + page.all('.award-control.js-emoji-btn').each do |element| + expect(element['title']).to eq('') + end + + page.all('.award-control .js-counter').each do |element| + expect(element).to have_content('0') + end + + thumbsup = page.first('.award-control') + thumbsup.click + thumbsup.hover + + expect(page).to have_selector('.js-emoji-btn') + expect(page).to have_css(".js-emoji-btn.active[data-original-title='You']") + expect(page.find('.js-emoji-btn.active .js-counter')).to have_content('1') + end + end + + it 'toggles a custom award emoji' do + page.within('.awards') do + page.find('.js-add-award').click + end + + page.find('.emoji-menu.is-visible') + + expect(page).to have_selector('.js-emoji-menu-search') + expect(page.evaluate_script("document.activeElement.classList.contains('js-emoji-menu-search')")).to eq(true) + + page.within('.emoji-menu-content') do + emoji_button = page.first('.js-emoji-btn') + emoji_button.hover + emoji_button.click + end + + page.within('.awards') do + expect(page).to have_selector('.js-emoji-btn') + expect(page.find('.js-emoji-btn.active .js-counter')).to have_content('1') + expect(page).to have_css(".js-emoji-btn.active[data-original-title='You']") + + expect do + page.find('.js-emoji-btn.active').click + wait_for_requests + end.to change { page.all('.award-control.js-emoji-btn').size }.from(3).to(2) + end + end + + it 'shows the list of award emoji categories' do + page.within('.awards') do + page.find('.js-add-award').click + end + + page.find('.emoji-menu.is-visible') + + expect(page).to have_selector('.js-emoji-menu-search') + expect(page.evaluate_script("document.activeElement.classList.contains('js-emoji-menu-search')")).to eq(true) + + fill_in('emoji-menu-search', with: 'hand') + + page.within('.emoji-menu-content') do + expect(page).to have_selector('[data-name="raised_hand"]') + end + end + + it 'adds an award emoji by a comment' do + page.within('.js-main-target-form') do + fill_in('note[note]', with: ':smile:') + + click_button('Comment') + end + + expect(page).to have_selector('gl-emoji[data-name="smile"]') + end +end diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb new file mode 100644 index 00000000000..21c9acc7ac0 --- /dev/null +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'User browses a job', :js do + let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) } + let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') } + let(:project) { create(:project, :repository, namespace: user.namespace) } + let(:user) { create(:user) } + + before do + project.add_master(user) + project.enable_ci + build.success + build.trace.set('job trace') + + sign_in(user) + + visit(project_job_path(project, build)) + end + + it 'erases the job log' do + expect(page).to have_content("Job ##{build.id}") + expect(page).to have_css('#build-trace') + + click_link('Erase') + + expect(build).not_to have_trace + expect(build.artifacts_file.exists?).to be_falsy + expect(build.artifacts_metadata.exists?).to be_falsy + expect(page).to have_no_css('.artifacts') + + page.within('.erased') do + expect(page).to have_content('Job has been erased') + end + + expect(build.project.running_or_pending_build_count).to eq(build.project.builds.running_or_pending.count(:all)) + end +end diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb new file mode 100644 index 00000000000..767777f3bf9 --- /dev/null +++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'User browses jobs' do + let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) } + let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') } + let(:project) { create(:project, :repository, namespace: user.namespace) } + let(:user) { create(:user) } + + before do + project.add_master(user) + project.enable_ci + project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/) + + sign_in(user) + + visit(project_jobs_path(project)) + end + + it 'shows the coverage' do + page.within('td.coverage') do + expect(page).to have_content('99.9%') + end + end + + it 'shows the "CI Lint" button' do + page.within('.nav-controls') do + ci_lint_tool_link = page.find_link('CI lint') + + expect(ci_lint_tool_link[:href]).to end_with(ci_lint_path) + end + end +end diff --git a/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb b/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb new file mode 100644 index 00000000000..a41d683dbbb --- /dev/null +++ b/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' + +describe 'User reverts a merge request', :js do + let(:merge_request) { create(:merge_request, :with_diffs, :simple, source_project: project) } + let(:project) { create(:project, :public, :repository) } + let(:user) { create(:user) } + + before do + project.add_developer(user) + sign_in(user) + + visit(merge_request_path(merge_request)) + + click_button('Merge') + + visit(merge_request_path(merge_request)) + end + + it 'reverts a merge request' do + find("a[href='#modal-revert-commit']").click + + page.within('#modal-revert-commit') do + uncheck('create_merge_request') + click_button('Revert') + end + + expect(page).to have_content('The merge request has been successfully reverted.') + + wait_for_requests + end + + it 'does not revert a merge request that was previously reverted' do + find("a[href='#modal-revert-commit']").click + + page.within('#modal-revert-commit') do + uncheck('create_merge_request') + click_button('Revert') + end + + find("a[href='#modal-revert-commit']").click + + page.within('#modal-revert-commit') do + uncheck('create_merge_request') + click_button('Revert') + end + + expect(page).to have_content('Sorry, we cannot revert this merge request automatically.') + end + + it 'reverts a merge request in a new merge request' do + find("a[href='#modal-revert-commit']").click + + page.within('#modal-revert-commit') do + click_button('Revert') + end + + expect(page).to have_content('The merge request has been successfully reverted. You can now submit a merge request to get this change into the original branch.') + end +end diff --git a/spec/features/projects/milestones/user_interacts_with_labels_spec.rb b/spec/features/projects/milestones/user_interacts_with_labels_spec.rb new file mode 100644 index 00000000000..f6a82f80d65 --- /dev/null +++ b/spec/features/projects/milestones/user_interacts_with_labels_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'User interacts with labels' do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + let(:milestone) { create(:milestone, project: project, title: 'v2.2', description: '# Description header') } + let(:issue1) { create(:issue, project: project, title: 'Bugfix1', milestone: milestone) } + let(:issue2) { create(:issue, project: project, title: 'Bugfix2', milestone: milestone) } + let(:label_bug) { create(:label, project: project, title: 'bug') } + let(:label_feature) { create(:label, project: project, title: 'feature') } + let(:label_enhancement) { create(:label, project: project, title: 'enhancement') } + + before do + project.add_master(user) + sign_in(user) + + issue1.labels << [label_bug, label_feature] + issue2.labels << [label_bug, label_enhancement] + + visit(project_milestones_path(project)) + end + + it 'shows the list of labels', :js do + click_link('v2.2') + + page.within('.nav-sidebar') do + page.find(:xpath, "//a[@href='#tab-labels']").click + end + + expect(page).to have_selector('ul.manage-labels-list') + + wait_for_requests + + page.within('#tab-labels') do + expect(page).to have_content(label_bug.title) + expect(page).to have_content(label_enhancement.title) + expect(page).to have_content(label_feature.title) + end + end +end diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb index cfd6f3aa71f..1cf14204159 100644 --- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb @@ -58,18 +58,8 @@ describe 'User updates wiki page' do end context 'when wiki is not empty' do - # This facory call is shorter: - # - # create(:wiki_page, wiki: create(:project, namespace: user.namespace).wiki, attrs: { title: 'home', content: 'Home page' }) - # - # But it always fails with this: - # - # Failure/Error: click_link('Edit') - # Capybara::ElementNotFound: - # Unable to find visible link "Edit" - - let(:project) { create(:project, namespace: user.namespace) } - let!(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: 'Home page' }) } + let(:project_wiki) { create(:project_wiki, project: project, user: project.creator) } + let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, attrs: { title: 'home', content: 'Home page' }) } before do visit(project_wikis_path(project)) diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index f685bb83d0d..4f4a27e4c41 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -17,11 +17,31 @@ describe Gitlab::Auth do end it 'OPTIONAL_SCOPES contains all non-default scopes' do + stub_container_registry_config(enabled: true) + expect(subject::OPTIONAL_SCOPES).to eq %i[read_user read_registry openid] end - it 'REGISTRY_SCOPES contains all registry related scopes' do - expect(subject::REGISTRY_SCOPES).to eq %i[read_registry] + context 'REGISTRY_SCOPES' do + context 'when registry is disabled' do + before do + stub_container_registry_config(enabled: false) + end + + it 'is empty' do + expect(subject::REGISTRY_SCOPES).to eq [] + end + end + + context 'when registry is enabled' do + before do + stub_container_registry_config(enabled: true) + end + + it 'contains all registry related scopes' do + expect(subject::REGISTRY_SCOPES).to eq %i[read_registry] + end + end end end @@ -147,11 +167,17 @@ describe Gitlab::Auth do expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, full_authentication_abilities)) end - it 'succeeds for personal access tokens with the `read_registry` scope' do - personal_access_token = create(:personal_access_token, scopes: ['read_registry']) + context 'when registry is enabled' do + before do + stub_container_registry_config(enabled: true) + end + + it 'succeeds for personal access tokens with the `read_registry` scope' do + personal_access_token = create(:personal_access_token, scopes: ['read_registry']) - expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') - expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, [:read_container_image])) + expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') + expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, [:read_container_image])) + end end it 'succeeds if it is an impersonation token' do diff --git a/spec/lib/gitlab/data_builder/push_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb index cb430b47463..befdc18d1aa 100644 --- a/spec/lib/gitlab/data_builder/push_spec.rb +++ b/spec/lib/gitlab/data_builder/push_spec.rb @@ -47,7 +47,7 @@ describe Gitlab::DataBuilder::Push do include_examples 'deprecated repository hook data' it 'does not raise an error when given nil commits' do - expect { described_class.build(spy, spy, spy, spy, spy, nil) } + expect { described_class.build(spy, spy, spy, spy, 'refs/tags/v1.1.0', nil) } .not_to raise_error end end diff --git a/spec/lib/gitlab/git_spec.rb b/spec/lib/gitlab/git_spec.rb index 4702a978f19..494dfe0e595 100644 --- a/spec/lib/gitlab/git_spec.rb +++ b/spec/lib/gitlab/git_spec.rb @@ -1,3 +1,4 @@ +# coding: utf-8 require 'spec_helper' describe Gitlab::Git do @@ -29,4 +30,12 @@ describe Gitlab::Git do end end end + + describe '.ref_name' do + it 'ensure ref is a valid UTF-8 string' do + utf8_invalid_ref = Gitlab::Git::BRANCH_REF_PREFIX + "an_invalid_ref_\xE5" + + expect(described_class.ref_name(utf8_invalid_ref)).to eq("an_invalid_ref_å") + end + end end diff --git a/spec/lib/system_check/orphans/namespace_check_spec.rb b/spec/lib/system_check/orphans/namespace_check_spec.rb new file mode 100644 index 00000000000..2a61ff3ad65 --- /dev/null +++ b/spec/lib/system_check/orphans/namespace_check_spec.rb @@ -0,0 +1,61 @@ +require 'spec_helper' +require 'rake_helper' + +describe SystemCheck::Orphans::NamespaceCheck do + let(:storages) { Gitlab.config.repositories.storages.reject { |key, _| key.eql? 'broken' } } + + before do + allow(Gitlab.config.repositories).to receive(:storages).and_return(storages) + allow(subject).to receive(:fetch_disk_namespaces).and_return(disk_namespaces) + silence_output + end + + describe '#multi_check' do + context 'all orphans' do + let(:disk_namespaces) { %w(/repos/orphan1 /repos/orphan2 repos/@hashed) } + + it 'prints list of all orphaned namespaces except @hashed' do + expect_list_of_orphans(%w(orphan1 orphan2)) + + subject.multi_check + end + end + + context 'few orphans with existing namespace' do + let!(:first_level) { create(:group, path: 'my-namespace') } + let(:disk_namespaces) { %w(/repos/orphan1 /repos/orphan2 /repos/my-namespace /repos/@hashed) } + + it 'prints list of orphaned namespaces' do + expect_list_of_orphans(%w(orphan1 orphan2)) + + subject.multi_check + end + end + + context 'few orphans with existing namespace and parents with same name as orphans' do + let!(:first_level) { create(:group, path: 'my-namespace') } + let!(:second_level) { create(:group, path: 'second-level', parent: first_level) } + let(:disk_namespaces) { %w(/repos/orphan1 /repos/orphan2 /repos/my-namespace /repos/second-level /repos/@hashed) } + + it 'prints list of orphaned namespaces ignoring parents with same namespace as orphans' do + expect_list_of_orphans(%w(orphan1 orphan2 second-level)) + + subject.multi_check + end + end + + context 'no orphans' do + let(:disk_namespaces) { %w(@hashed) } + + it 'prints an empty list ignoring @hashed' do + expect_list_of_orphans([]) + + subject.multi_check + end + end + end + + def expect_list_of_orphans(orphans) + expect(subject).to receive(:print_orphans).with(orphans, 'default') + end +end diff --git a/spec/lib/system_check/orphans/repository_check_spec.rb b/spec/lib/system_check/orphans/repository_check_spec.rb new file mode 100644 index 00000000000..b0c2267d177 --- /dev/null +++ b/spec/lib/system_check/orphans/repository_check_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' +require 'rake_helper' + +describe SystemCheck::Orphans::RepositoryCheck do + let(:storages) { Gitlab.config.repositories.storages.reject { |key, _| key.eql? 'broken' } } + + before do + allow(Gitlab.config.repositories).to receive(:storages).and_return(storages) + allow(subject).to receive(:fetch_disk_namespaces).and_return(disk_namespaces) + allow(subject).to receive(:fetch_disk_repositories).and_return(disk_repositories) + # silence_output + end + + describe '#multi_check' do + context 'all orphans' do + let(:disk_namespaces) { %w(/repos/orphan1 /repos/orphan2 repos/@hashed) } + let(:disk_repositories) { %w(repo1.git repo2.git) } + + it 'prints list of all orphaned namespaces except @hashed' do + expect_list_of_orphans(%w(orphan1/repo1.git orphan1/repo2.git orphan2/repo1.git orphan2/repo2.git)) + + subject.multi_check + end + end + + context 'few orphans with existing namespace' do + let!(:first_level) { create(:group, path: 'my-namespace') } + let!(:project) { create(:project, path: 'repo', namespace: first_level) } + let(:disk_namespaces) { %w(/repos/orphan1 /repos/orphan2 /repos/my-namespace /repos/@hashed) } + let(:disk_repositories) { %w(repo.git) } + + it 'prints list of orphaned namespaces' do + expect_list_of_orphans(%w(orphan1/repo.git orphan2/repo.git)) + + subject.multi_check + end + end + + context 'few orphans with existing namespace and parents with same name as orphans' do + let!(:first_level) { create(:group, path: 'my-namespace') } + let!(:second_level) { create(:group, path: 'second-level', parent: first_level) } + let!(:project) { create(:project, path: 'repo', namespace: first_level) } + let(:disk_namespaces) { %w(/repos/orphan1 /repos/orphan2 /repos/my-namespace /repos/second-level /repos/@hashed) } + let(:disk_repositories) { %w(repo.git) } + + it 'prints list of orphaned namespaces ignoring parents with same namespace as orphans' do + expect_list_of_orphans(%w(orphan1/repo.git orphan2/repo.git second-level/repo.git)) + + subject.multi_check + end + end + + context 'no orphans' do + let(:disk_namespaces) { %w(@hashed) } + let(:disk_repositories) { %w(repo.git) } + + it 'prints an empty list ignoring @hashed' do + expect_list_of_orphans([]) + + subject.multi_check + end + end + end + + def expect_list_of_orphans(orphans) + expect(subject).to receive(:print_orphans).with(orphans, 'default') + end +end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index c7a9eabdf06..78cacf9ff5d 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -167,19 +167,33 @@ describe ApplicationSetting do context 'housekeeping settings' do it { is_expected.not_to allow_value(0).for(:housekeeping_incremental_repack_period) } - it 'wants the full repack period to be longer than the incremental repack period' do + it 'wants the full repack period to be at least the incremental repack period' do subject.housekeeping_incremental_repack_period = 2 subject.housekeeping_full_repack_period = 1 expect(subject).not_to be_valid end - it 'wants the gc period to be longer than the full repack period' do - subject.housekeeping_full_repack_period = 2 - subject.housekeeping_gc_period = 1 + it 'wants the gc period to be at least the full repack period' do + subject.housekeeping_full_repack_period = 100 + subject.housekeeping_gc_period = 90 expect(subject).not_to be_valid end + + it 'allows the same period for incremental repack and full repack, effectively skipping incremental repack' do + subject.housekeeping_incremental_repack_period = 2 + subject.housekeeping_full_repack_period = 2 + + expect(subject).to be_valid + end + + it 'allows the same period for full repack and gc, effectively skipping full repack' do + subject.housekeeping_full_repack_period = 100 + subject.housekeeping_gc_period = 100 + + expect(subject).to be_valid + end end end diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb index b2f2a3ce914..01440b15674 100644 --- a/spec/models/personal_access_token_spec.rb +++ b/spec/models/personal_access_token_spec.rb @@ -41,7 +41,7 @@ describe PersonalAccessToken do it 'revokes the token' do active_personal_access_token.revoke! - expect(active_personal_access_token.revoked?).to be true + expect(active_personal_access_token).to be_revoked end end @@ -61,10 +61,37 @@ describe PersonalAccessToken do expect(personal_access_token).to be_valid end - it "allows creating a token with read_registry scope" do - personal_access_token.scopes = [:read_registry] + context 'when registry is disabled' do + before do + stub_container_registry_config(enabled: false) + end - expect(personal_access_token).to be_valid + it "rejects creating a token with read_registry scope" do + personal_access_token.scopes = [:read_registry] + + expect(personal_access_token).not_to be_valid + expect(personal_access_token.errors[:scopes].first).to eq "can only contain available scopes" + end + + it "allows revoking a token with read_registry scope" do + personal_access_token.scopes = [:read_registry] + + personal_access_token.revoke! + + expect(personal_access_token).to be_revoked + end + end + + context 'when registry is enabled' do + before do + stub_container_registry_config(enabled: true) + end + + it "allows creating a token with read_registry scope" do + personal_access_token.scopes = [:read_registry] + + expect(personal_access_token).to be_valid + end end it "rejects creating a token with unavailable scopes" do diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb index 8d79ea3dd40..41bf43a9bce 100644 --- a/spec/requests/jwt_controller_spec.rb +++ b/spec/requests/jwt_controller_spec.rb @@ -49,6 +49,10 @@ describe JwtController do let(:pat) { create(:personal_access_token, user: user, scopes: ['read_registry']) } let(:headers) { { authorization: credentials('personal_access_token', pat.token) } } + before do + stub_container_registry_config(enabled: true) + end + subject! { get '/jwt/auth', parameters, headers } it 'authenticates correctly' do diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb index 437c009e7fa..b7b5de07380 100644 --- a/spec/services/projects/housekeeping_service_spec.rb +++ b/spec/services/projects/housekeeping_service_spec.rb @@ -75,7 +75,7 @@ describe Projects::HousekeepingService do end end - it 'uses all three kinds of housekeeping we offer' do + it 'goes through all three housekeeping tasks, executing only the highest task when there is overlap' do allow(subject).to receive(:try_obtain_lease).and_return(:the_uuid) allow(subject).to receive(:lease_key).and_return(:the_lease_key) diff --git a/spec/support/api/scopes/read_user_shared_examples.rb b/spec/support/api/scopes/read_user_shared_examples.rb index 3bd589d64b9..57e28e040d7 100644 --- a/spec/support/api/scopes/read_user_shared_examples.rb +++ b/spec/support/api/scopes/read_user_shared_examples.rb @@ -23,6 +23,10 @@ shared_examples_for 'allows the "read_user" scope' do context 'when the requesting token does not have any required scope' do let(:token) { create(:personal_access_token, scopes: ['read_registry'], user: user) } + before do + stub_container_registry_config(enabled: true) + end + it 'returns a "401" response' do get api_call.call(path, user, personal_access_token: token) diff --git a/spec/support/migrations_helpers.rb b/spec/support/migrations_helpers.rb index 4ca019c1b05..6522d74ba89 100644 --- a/spec/support/migrations_helpers.rb +++ b/spec/support/migrations_helpers.rb @@ -16,7 +16,9 @@ module MigrationsHelpers end def reset_column_in_migration_models - ActiveRecord::Base.clear_cache! + ActiveRecord::Base.connection_pool.connections.each do |conn| + conn.schema_cache.clear! + end described_class.constants.sort.each do |name| const = described_class.const_get(name) diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 78a2ff73746..9695f35bd25 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -26,9 +26,11 @@ module StubGitlabCalls end def stub_container_registry_config(registry_settings) - allow(Gitlab.config.registry).to receive_messages(registry_settings) allow(Auth::ContainerRegistryAuthenticationService) .to receive(:full_access_token).and_return('token') + + allow(Gitlab.config.registry).to receive_messages(registry_settings) + load 'lib/gitlab/auth.rb' end def stub_container_registry_tags(repository: :any, tags:) |