diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 023790f7d87..5aff12621b5 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -381,6 +381,14 @@ module ProjectsHelper @project.grafana_integration&.enabled? end + def project_license_name(project) + project.repository.license&.name + rescue GRPC::Unavailable, GRPC::DeadlineExceeded, Gitlab::Git::CommandError => e + Gitlab::ErrorTracking.track_exception(e) + + nil + end + private def get_project_nav_tabs(project, current_user) diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 07a61b71b8e..144bb04e2a8 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -14,6 +14,7 @@ - updated_tooltip = time_ago_with_tooltip(project.last_activity_date) - css_controls_class = compact_mode ? [] : ["flex-lg-row", "justify-content-lg-between"] - avatar_container_class = project.creator && use_creator_avatar ? '' : 'rect-avatar' +- license_name = project_license_name(project) %li.project-row.d-flex{ class: css_class } = cache(cache_key) do @@ -40,10 +41,10 @@ %span.metadata-info.visibility-icon.append-right-10.prepend-top-8.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) } = visibility_level_icon(project.visibility_level, fw: true) - - if explore_projects_tab? && project.repository.license + - if explore_projects_tab? && license_name %span.metadata-info.d-inline-flex.align-items-center.append-right-10.prepend-top-8 = sprite_icon('scale', size: 14, css_class: 'append-right-4') - = project.repository.license.name + = license_name - if !explore_projects_tab? && access&.nonzero? -# haml-lint:disable UnnecessaryStringOutput diff --git a/changelogs/unreleased/199442-explore-projects.yml b/changelogs/unreleased/199442-explore-projects.yml new file mode 100644 index 00000000000..4acfae2da04 --- /dev/null +++ b/changelogs/unreleased/199442-explore-projects.yml @@ -0,0 +1,5 @@ +--- +title: Handle Gitaly failure when fetching license +merge_request: 24310 +author: +type: fixed diff --git a/config/application.rb b/config/application.rb index be7d366c927..2f4d271322f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -285,6 +285,13 @@ module Gitlab g.factory_bot false end + # This empty initializer forces the :let_zeitwerk_take_over initializer to run before we load + # initializers in config/initializers. This is done because autoloading before Zeitwerk takes + # over is deprecated but our initializers do a lot of autoloading. + # See https://gitlab.com/gitlab-org/gitlab/issues/197346 for more details + initializer :move_initializers, before: :load_config_initializers, after: :let_zeitwerk_take_over do + end + config.after_initialize do Rails.application.reload_routes! diff --git a/config/environments/test.rb b/config/environments/test.rb index d8235c6220c..0ee2c6a2a20 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,3 +1,6 @@ +require 'gitlab/testing/request_blocker_middleware' +require 'gitlab/testing/request_inspector_middleware' + Rails.application.configure do # Make sure the middleware is inserted first in middleware chain config.middleware.insert_before(ActionDispatch::Static, Gitlab::Testing::RequestBlockerMiddleware) diff --git a/config/initializers/graphql.rb b/config/initializers/graphql.rb index 44a9644f481..81317a3d87a 100644 --- a/config/initializers/graphql.rb +++ b/config/initializers/graphql.rb @@ -6,8 +6,6 @@ GraphQL::Field.accepts_definitions(authorize: GraphQL::Define.assign_metadata_ke GraphQL::Schema::Object.accepts_definition(:authorize) GraphQL::Schema::Field.accepts_definition(:authorize) -Gitlab::Application.config.after_initialize do - GitlabSchema.middleware << GraphQL::Schema::TimeoutMiddleware.new(max_seconds: Gitlab.config.gitlab.graphql_timeout) do |timeout_error, query| - Gitlab::GraphqlLogger.error(message: timeout_error.to_s, query: query.query_string, query_variables: query.provided_variables) - end +GitlabSchema.middleware << GraphQL::Schema::TimeoutMiddleware.new(max_seconds: Gitlab.config.gitlab.graphql_timeout) do |timeout_error, query| + Gitlab::GraphqlLogger.error(message: timeout_error.to_s, query: query.query_string, query_variables: query.provided_variables) end diff --git a/db/migrate/20200211174946_add_auto_renew_to_gitlab_subscriptions.rb b/db/migrate/20200211174946_add_auto_renew_to_gitlab_subscriptions.rb new file mode 100644 index 00000000000..6bce74bb8f8 --- /dev/null +++ b/db/migrate/20200211174946_add_auto_renew_to_gitlab_subscriptions.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddAutoRenewToGitlabSubscriptions < ActiveRecord::Migration[6.0] + DOWNTIME = false + + def change + add_column :gitlab_subscription_histories, :auto_renew, :boolean + add_column :gitlab_subscriptions, :auto_renew, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 9d3ba5f3645..33724ef59b5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1912,6 +1912,7 @@ ActiveRecord::Schema.define(version: 2020_02_14_034836) do t.bigint "gitlab_subscription_id", null: false t.datetime_with_timezone "created_at" t.date "trial_starts_on" + t.boolean "auto_renew" t.index ["gitlab_subscription_id"], name: "index_gitlab_subscription_histories_on_gitlab_subscription_id" end @@ -1927,6 +1928,7 @@ ActiveRecord::Schema.define(version: 2020_02_14_034836) do t.integer "seats", default: 0 t.boolean "trial", default: false t.date "trial_starts_on" + t.boolean "auto_renew" t.index ["hosted_plan_id"], name: "index_gitlab_subscriptions_on_hosted_plan_id" t.index ["namespace_id"], name: "index_gitlab_subscriptions_on_namespace_id", unique: true end diff --git a/doc/api/merge_trains.md b/doc/api/merge_trains.md index 7fff09474df..d8446ed445f 100644 --- a/doc/api/merge_trains.md +++ b/doc/api/merge_trains.md @@ -3,7 +3,7 @@ > - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36146) in GitLab 12.9. > - Using this API you can consume GitLab's [Merge Train](../ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md) entries. -Every API call to merge trains must be authenticated with Developer or higher [permissions](link-to-permissions-doc). +Every API call to merge trains must be authenticated with Developer or higher [permissions](../user/permissions.md). If a user is not a member of a project and the project is private, a `GET` request on that project will result to a `404` status code. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c5b7e6f6baa..fd1661f227b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6303,6 +6303,9 @@ msgstr "" msgid "Dependency List" msgstr "" +msgid "Dependency List has no entries" +msgstr "" + msgid "Dependency Proxy" msgstr "" @@ -10822,6 +10825,9 @@ msgstr "" msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected." msgstr "" +msgid "It seems like the Dependency Scanning job ran successfully, but no dependencies have been detected in your project." +msgstr "" + msgid "It's you" msgstr "" @@ -21516,6 +21522,9 @@ msgstr "" msgid "View replaced file @ " msgstr "" +msgid "View supported languages and frameworks" +msgstr "" + msgid "View the documentation" msgstr "" diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 37bc2b382cb..17e3f8f9c06 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -994,4 +994,56 @@ describe ProjectsHelper do it { is_expected.to eq(grafana_integration.enabled) } end end + + describe '#project_license_name(project)' do + let_it_be(:project) { create(:project) } + let_it_be(:repository) { project.repository } + + subject { project_license_name(project) } + + context 'gitaly is working appropriately' do + it 'returns the license name' do + license = Licensee::License.new('mit') + allow(repository).to receive(:license).and_return(license) + + expect(subject).to eq(license.name) + end + end + + context 'gitaly is unreachable' do + shared_examples 'returns nil and tracks exception' do + it { is_expected.to be_nil } + + it 'tracks the exception' do + expect(Gitlab::ErrorTracking).to receive(:track_exception).with( + an_instance_of(exception) + ) + + subject + end + end + + before do + allow(repository).to receive(:license).and_raise(exception) + end + + context "Gitlab::Git::CommandError" do + let(:exception) { Gitlab::Git::CommandError } + + it_behaves_like 'returns nil and tracks exception' + end + + context "GRPC::Unavailable" do + let(:exception) { GRPC::Unavailable } + + it_behaves_like 'returns nil and tracks exception' + end + + context "GRPC::DeadlineExceeded" do + let(:exception) { GRPC::DeadlineExceeded } + + it_behaves_like 'returns nil and tracks exception' + end + end + end end