Commit 4e0a98b0 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 8bf50608 0e7c92cc
...@@ -11,10 +11,4 @@ export function resetServiceWorkersPublicPath() { ...@@ -11,10 +11,4 @@ export function resetServiceWorkersPublicPath() {
const relativeRootPath = (gon && gon.relative_url_root) || ''; const relativeRootPath = (gon && gon.relative_url_root) || '';
const webpackAssetPath = joinPaths(relativeRootPath, '/assets/webpack/'); const webpackAssetPath = joinPaths(relativeRootPath, '/assets/webpack/');
__webpack_public_path__ = webpackAssetPath; // eslint-disable-line babel/camelcase __webpack_public_path__ = webpackAssetPath; // eslint-disable-line babel/camelcase
// monaco-editor-webpack-plugin currently (incorrectly) references the
// public path as a property of `window`. Once this is fixed upstream we
// can remove this line
// see: https://github.com/Microsoft/monaco-editor-webpack-plugin/pull/63
window.__webpack_public_path__ = webpackAssetPath; // eslint-disable-line
} }
...@@ -11,17 +11,3 @@ ...@@ -11,17 +11,3 @@
background: $blue-400; background: $blue-400;
} }
} }
.runner-status {
&.runner-status-online {
background-color: $green-600;
}
&.runner-status-offline {
background-color: $gray-darkest;
}
&.runner-status-paused {
background-color: $red-500;
}
}
...@@ -4,18 +4,33 @@ module Ci ...@@ -4,18 +4,33 @@ module Ci
module RunnersHelper module RunnersHelper
include IconsHelper include IconsHelper
def runner_status_icon(runner) def runner_status_icon(runner, size: 16, icon_class: '')
status = runner.status status = runner.status
title = ''
icon = 'warning-solid'
span_class = ''
case status case status
when :not_connected when :not_connected
content_tag(:span, title: _("New runner. Has not connected yet")) do title = s_("Runners|New runner, has not connected yet")
sprite_icon("warning-solid", size: 24, css_class: "gl-vertical-align-bottom!") icon = 'warning-solid'
end when :online
title = s_("Runners|Runner is online, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) }
icon = 'status-active'
span_class = 'gl-text-green-500'
when :offline
title = s_("Runners|Runner is offline, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) }
icon = 'status-failed'
span_class = 'gl-text-red-500'
when :paused
title = s_("Runners|Runner is paused, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) }
icon = 'status-paused'
span_class = 'gl-text-gray-600'
end
when :online, :offline, :paused content_tag(:span, class: span_class, title: title, data: { toggle: 'tooltip', container: 'body', testid: 'runner_status_icon', qa_selector: "runner_status_#{status}_content" }) do
content_tag :span, nil, sprite_icon(icon, size: size, css_class: icon_class)
class: "gl-display-inline-block gl-avatar gl-avatar-s16 gl-avatar-circle runner-status runner-status-#{status}",
title: _("Runner is %{status}, last contact was %{runner_contact} ago") % { status: status, runner_contact: time_ago_in_words(runner.contacted_at) }
end end
end end
......
...@@ -22,6 +22,7 @@ module Namespaces ...@@ -22,6 +22,7 @@ module Namespaces
object_hierarchy(self.class.where(id: id)) object_hierarchy(self.class.where(id: id))
.all_objects .all_objects
end end
alias_method :recursive_self_and_hierarchy, :self_and_hierarchy
# Returns all the ancestors of the current namespaces. # Returns all the ancestors of the current namespaces.
def ancestors def ancestors
...@@ -30,6 +31,7 @@ module Namespaces ...@@ -30,6 +31,7 @@ module Namespaces
object_hierarchy(self.class.where(id: parent_id)) object_hierarchy(self.class.where(id: parent_id))
.base_and_ancestors .base_and_ancestors
end end
alias_method :recursive_ancestors, :ancestors
# returns all ancestors upto but excluding the given namespace # returns all ancestors upto but excluding the given namespace
# when no namespace is given, all ancestors upto the top are returned # when no namespace is given, all ancestors upto the top are returned
...@@ -44,17 +46,20 @@ module Namespaces ...@@ -44,17 +46,20 @@ module Namespaces
object_hierarchy(self.class.where(id: id)) object_hierarchy(self.class.where(id: id))
.base_and_ancestors(hierarchy_order: hierarchy_order) .base_and_ancestors(hierarchy_order: hierarchy_order)
end end
alias_method :recursive_self_and_ancestors, :self_and_ancestors
# Returns all the descendants of the current namespace. # Returns all the descendants of the current namespace.
def descendants def descendants
object_hierarchy(self.class.where(parent_id: id)) object_hierarchy(self.class.where(parent_id: id))
.base_and_descendants .base_and_descendants
end end
alias_method :recursive_descendants, :descendants
def self_and_descendants def self_and_descendants
object_hierarchy(self.class.where(id: id)) object_hierarchy(self.class.where(id: id))
.base_and_descendants .base_and_descendants
end end
alias_method :recursive_self_and_descendants, :self_and_descendants
def object_hierarchy(ancestors_base) def object_hierarchy(ancestors_base)
Gitlab::ObjectHierarchy.new(ancestors_base, options: { use_distinct: Feature.enabled?(:use_distinct_in_object_hierarchy, self) }) Gitlab::ObjectHierarchy.new(ancestors_base, options: { use_distinct: Feature.enabled?(:use_distinct_in_object_hierarchy, self) })
......
%li.runner{ id: dom_id(runner) } %li.runner{ id: dom_id(runner) }
%h4.gl-font-weight-normal %h4.gl-font-weight-normal
= runner_status_icon(runner) = runner_status_icon(runner, size: 16, icon_class: "gl-vertical-align-middle!")
- if @project_runners.include?(runner) - if @project_runners.include?(runner)
= link_to _("%{token}...") % { token: runner.short_sha }, project_runner_path(@project, runner), class: 'commit-sha has-tooltip', title: _("Partial token for reference only") = link_to _("%{token}...") % { token: runner.short_sha }, project_runner_path(@project, runner), class: 'commit-sha has-tooltip', title: _("Partial token for reference only")
......
...@@ -2377,7 +2377,7 @@ ...@@ -2377,7 +2377,7 @@
:idempotent: :idempotent:
:tags: [] :tags: []
- :name: update_highest_role - :name: update_highest_role
:feature_category: :authentication_and_authorization :feature_category: :utilization
:has_external_dependencies: :has_external_dependencies:
:urgency: :high :urgency: :high
:resource_boundary: :unknown :resource_boundary: :unknown
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class UpdateHighestRoleWorker class UpdateHighestRoleWorker
include ApplicationWorker include ApplicationWorker
feature_category :authentication_and_authorization feature_category :utilization
urgency :high urgency :high
weight 2 weight 2
......
---
title: Improve runners status icon usability and accessibility in the project settings
view
merge_request: 58781
author:
type: changed
...@@ -162,7 +162,7 @@ class EpicsFinder < IssuableFinder ...@@ -162,7 +162,7 @@ class EpicsFinder < IssuableFinder
elsif include_ancestors elsif include_ancestors
group.self_and_ancestors group.self_and_ancestors
elsif include_descendants elsif include_descendants
group.self_and_descendants group.recursive_self_and_descendants
else else
Group.id_in(group.id) Group.id_in(group.id)
end end
......
...@@ -21134,9 +21134,6 @@ msgstr "" ...@@ -21134,9 +21134,6 @@ msgstr ""
msgid "New response for issue #%{issue_iid}:" msgid "New response for issue #%{issue_iid}:"
msgstr "" msgstr ""
msgid "New runner. Has not connected yet"
msgstr ""
msgid "New runners registration token has been generated!" msgid "New runners registration token has been generated!"
msgstr "" msgstr ""
...@@ -27032,9 +27029,6 @@ msgstr "" ...@@ -27032,9 +27029,6 @@ msgstr ""
msgid "Runner API" msgid "Runner API"
msgstr "" msgstr ""
msgid "Runner is %{status}, last contact was %{runner_contact} ago"
msgstr ""
msgid "Runner token" msgid "Runner token"
msgstr "" msgstr ""
...@@ -27113,6 +27107,9 @@ msgstr "" ...@@ -27113,6 +27107,9 @@ msgstr ""
msgid "Runners|Name" msgid "Runners|Name"
msgstr "" msgstr ""
msgid "Runners|New runner, has not connected yet"
msgstr ""
msgid "Runners|Platform" msgid "Runners|Platform"
msgstr "" msgstr ""
...@@ -27128,6 +27125,15 @@ msgstr "" ...@@ -27128,6 +27125,15 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}" msgid "Runners|Runner #%{runner_id}"
msgstr "" msgstr ""
msgid "Runners|Runner is offline, last contact was %{runner_contact} ago"
msgstr ""
msgid "Runners|Runner is online, last contact was %{runner_contact} ago"
msgstr ""
msgid "Runners|Runner is paused, last contact was %{runner_contact} ago"
msgstr ""
msgid "Runners|Shared" msgid "Runners|Shared"
msgstr "" msgstr ""
......
...@@ -10,12 +10,9 @@ module QA ...@@ -10,12 +10,9 @@ module QA
element :coordinator_address, '%code#coordinator_address' # rubocop:disable QA/ElementWithPattern element :coordinator_address, '%code#coordinator_address' # rubocop:disable QA/ElementWithPattern
end end
##
# TODO, phase-out CSS classes added in Ruby helpers.
#
view 'app/helpers/ci/runners_helper.rb' do view 'app/helpers/ci/runners_helper.rb' do
# rubocop:disable Lint/InterpolationCheck # rubocop:disable Lint/InterpolationCheck
element :runner_status, 'runner-status-#{status}' # rubocop:disable QA/ElementWithPattern element :runner_status_icon, 'qa_selector: "runner_status_#{status}_content"' # rubocop:disable QA/ElementWithPattern
# rubocop:enable Lint/InterpolationCheck # rubocop:enable Lint/InterpolationCheck
end end
...@@ -28,7 +25,7 @@ module QA ...@@ -28,7 +25,7 @@ module QA
end end
def has_online_runner? def has_online_runner?
page.has_css?('.runner-status-online') has_element?(:runner_status_online_content)
end end
end end
end end
......
...@@ -3,19 +3,26 @@ ...@@ -3,19 +3,26 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Ci::RunnersHelper do RSpec.describe Ci::RunnersHelper do
it "returns - not contacted yet" do describe '#runner_status_icon', :clean_gitlab_redis_cache do
runner = FactoryBot.build :ci_runner it "returns - not contacted yet" do
expect(runner_status_icon(runner)).to include("not connected yet") runner = create(:ci_runner)
end expect(runner_status_icon(runner)).to include("not connected yet")
end
it "returns offline text" do it "returns offline text" do
runner = FactoryBot.build(:ci_runner, contacted_at: 1.day.ago, active: true) runner = create(:ci_runner, contacted_at: 1.day.ago, active: true)
expect(runner_status_icon(runner)).to include("Runner is offline") expect(runner_status_icon(runner)).to include("Runner is offline")
end end
it "returns online text" do it "returns online text" do
runner = FactoryBot.build(:ci_runner, contacted_at: 1.second.ago, active: true) runner = create(:ci_runner, contacted_at: 1.second.ago, active: true)
expect(runner_status_icon(runner)).to include("Runner is online") expect(runner_status_icon(runner)).to include("Runner is online")
end
it "returns paused text" do
runner = create(:ci_runner, contacted_at: 1.second.ago, active: false)
expect(runner_status_icon(runner)).to include("Runner is paused")
end
end end
describe '#runner_contacted_at' do describe '#runner_contacted_at' do
......
...@@ -875,7 +875,7 @@ module Gitlab ...@@ -875,7 +875,7 @@ module Gitlab
config = YAML.dump({ image: "ruby:2.7", config = YAML.dump({ image: "ruby:2.7",
services: ["mysql"], services: ["mysql"],
before_script: ["pwd"], before_script: ["pwd"],
rspec: { image: { name: "ruby:2.5", entrypoint: ["/usr/local/bin/init", "run"] }, rspec: { image: { name: "ruby:3.0", entrypoint: ["/usr/local/bin/init", "run"] },
services: [{ name: "postgresql", alias: "db-pg", services: [{ name: "postgresql", alias: "db-pg",
entrypoint: ["/usr/local/bin/init", "run"], entrypoint: ["/usr/local/bin/init", "run"],
command: ["/usr/local/bin/init", "run"] }, "docker:dind"], command: ["/usr/local/bin/init", "run"] }, "docker:dind"],
...@@ -892,7 +892,7 @@ module Gitlab ...@@ -892,7 +892,7 @@ module Gitlab
options: { options: {
before_script: ["pwd"], before_script: ["pwd"],
script: ["rspec"], script: ["rspec"],
image: { name: "ruby:2.5", entrypoint: ["/usr/local/bin/init", "run"] }, image: { name: "ruby:3.0", entrypoint: ["/usr/local/bin/init", "run"] },
services: [{ name: "postgresql", alias: "db-pg", entrypoint: ["/usr/local/bin/init", "run"], services: [{ name: "postgresql", alias: "db-pg", entrypoint: ["/usr/local/bin/init", "run"],
command: ["/usr/local/bin/init", "run"] }, command: ["/usr/local/bin/init", "run"] },
{ name: "docker:dind" }] { name: "docker:dind" }]
...@@ -941,7 +941,7 @@ module Gitlab ...@@ -941,7 +941,7 @@ module Gitlab
config = YAML.dump({ image: "ruby:2.7", config = YAML.dump({ image: "ruby:2.7",
services: ["mysql"], services: ["mysql"],
before_script: ["pwd"], before_script: ["pwd"],
rspec: { image: "ruby:2.5", services: ["postgresql", "docker:dind"], script: "rspec" } }) rspec: { image: "ruby:3.0", services: ["postgresql", "docker:dind"], script: "rspec" } })
config_processor = Gitlab::Ci::YamlProcessor.new(config).execute config_processor = Gitlab::Ci::YamlProcessor.new(config).execute
...@@ -954,7 +954,7 @@ module Gitlab ...@@ -954,7 +954,7 @@ module Gitlab
options: { options: {
before_script: ["pwd"], before_script: ["pwd"],
script: ["rspec"], script: ["rspec"],
image: { name: "ruby:2.5" }, image: { name: "ruby:3.0" },
services: [{ name: "postgresql" }, { name: "docker:dind" }] services: [{ name: "postgresql" }, { name: "docker:dind" }]
}, },
allow_failure: false, allow_failure: false,
......
...@@ -132,7 +132,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do ...@@ -132,7 +132,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do
{ before_script: %w[ls pwd], { before_script: %w[ls pwd],
script: 'sleep 100', script: 'sleep 100',
tags: ['webide'], tags: ['webide'],
image: 'ruby:2.5', image: 'ruby:3.0',
services: ['mysql'], services: ['mysql'],
variables: { KEY: 'value' } } variables: { KEY: 'value' } }
end end
...@@ -144,7 +144,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do ...@@ -144,7 +144,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do
yaml_variables: [{ key: 'KEY', value: 'value', public: true }], yaml_variables: [{ key: 'KEY', value: 'value', public: true }],
job_variables: [{ key: 'KEY', value: 'value', public: true }], job_variables: [{ key: 'KEY', value: 'value', public: true }],
options: { options: {
image: { name: "ruby:2.5" }, image: { name: "ruby:3.0" },
services: [{ name: "mysql" }], services: [{ name: "mysql" }],
before_script: %w[ls pwd], before_script: %w[ls pwd],
script: ['sleep 100'] script: ['sleep 100']
......
# frozen_string_literal: true # frozen_string_literal: true
RSpec.shared_examples 'namespace traversal' do RSpec.shared_examples 'namespace traversal' do
shared_examples 'recursive version' do |method|
let(:recursive_method) { "recursive_#{method}" }
it "is equivalent to ##{method}" do
groups.each do |group|
expect(group.public_send(method)).to match_array group.public_send(recursive_method)
end
end
it "makes a recursive query" do
groups.each do |group|
expect { group.public_send(recursive_method).load }.to make_queries_matching(/WITH RECURSIVE/)
end
end
end
describe '#self_and_hierarchy' do describe '#self_and_hierarchy' do
let!(:group) { create(:group, path: 'git_lab') } let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) } let!(:nested_group) { create(:group, parent: group) }
...@@ -14,6 +30,12 @@ RSpec.shared_examples 'namespace traversal' do ...@@ -14,6 +30,12 @@ RSpec.shared_examples 'namespace traversal' do
expect(nested_group.self_and_hierarchy).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group) expect(nested_group.self_and_hierarchy).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group)
expect(very_deep_nested_group.self_and_hierarchy).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group) expect(very_deep_nested_group.self_and_hierarchy).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group)
end end
describe '#recursive_self_and_hierarchy' do
let(:groups) { [group, nested_group, very_deep_nested_group] }
it_behaves_like 'recursive version', :self_and_hierarchy
end
end end
describe '#ancestors' do describe '#ancestors' do
...@@ -28,6 +50,12 @@ RSpec.shared_examples 'namespace traversal' do ...@@ -28,6 +50,12 @@ RSpec.shared_examples 'namespace traversal' do
expect(nested_group.ancestors).to include(group) expect(nested_group.ancestors).to include(group)
expect(group.ancestors).to eq([]) expect(group.ancestors).to eq([])
end end
describe '#recursive_ancestors' do
let(:groups) { [nested_group, deep_nested_group, very_deep_nested_group] }
it_behaves_like 'recursive version', :ancestors
end
end end
describe '#self_and_ancestors' do describe '#self_and_ancestors' do
...@@ -42,6 +70,12 @@ RSpec.shared_examples 'namespace traversal' do ...@@ -42,6 +70,12 @@ RSpec.shared_examples 'namespace traversal' do
expect(nested_group.self_and_ancestors).to contain_exactly(group, nested_group) expect(nested_group.self_and_ancestors).to contain_exactly(group, nested_group)
expect(group.self_and_ancestors).to contain_exactly(group) expect(group.self_and_ancestors).to contain_exactly(group)
end end
describe '#recursive_self_and_ancestors' do
let(:groups) { [nested_group, deep_nested_group, very_deep_nested_group] }
it_behaves_like 'recursive version', :self_and_ancestors
end
end end
describe '#descendants' do describe '#descendants' do
...@@ -58,6 +92,12 @@ RSpec.shared_examples 'namespace traversal' do ...@@ -58,6 +92,12 @@ RSpec.shared_examples 'namespace traversal' do
expect(nested_group.descendants.to_a).to include(deep_nested_group, very_deep_nested_group) expect(nested_group.descendants.to_a).to include(deep_nested_group, very_deep_nested_group)
expect(group.descendants.to_a).to include(nested_group, deep_nested_group, very_deep_nested_group) expect(group.descendants.to_a).to include(nested_group, deep_nested_group, very_deep_nested_group)
end end
describe '#recursive_descendants' do
let(:groups) { [group, nested_group, deep_nested_group, very_deep_nested_group] }
it_behaves_like 'recursive version', :descendants
end
end end
describe '#self_and_descendants' do describe '#self_and_descendants' do
...@@ -74,5 +114,11 @@ RSpec.shared_examples 'namespace traversal' do ...@@ -74,5 +114,11 @@ RSpec.shared_examples 'namespace traversal' do
expect(nested_group.self_and_descendants).to contain_exactly(nested_group, deep_nested_group, very_deep_nested_group) expect(nested_group.self_and_descendants).to contain_exactly(nested_group, deep_nested_group, very_deep_nested_group)
expect(group.self_and_descendants).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group) expect(group.self_and_descendants).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group)
end end
describe '#recursive_self_and_descendants' do
let(:groups) { [group, nested_group, deep_nested_group, very_deep_nested_group] }
it_behaves_like 'recursive version', :self_and_descendants
end
end end
end end
...@@ -8462,10 +8462,10 @@ moment-mini@^2.22.1: ...@@ -8462,10 +8462,10 @@ moment-mini@^2.22.1:
resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.22.1.tgz#bc32d73e43a4505070be6b53494b17623183420d" resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.22.1.tgz#bc32d73e43a4505070be6b53494b17623183420d"
integrity sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw== integrity sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw==
monaco-editor-webpack-plugin@^1.9.0: monaco-editor-webpack-plugin@^1.9.1:
version "1.9.0" version "1.9.1"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.0.tgz#5b547281b9f404057dc5d8c5722390df9ac90be6" resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.1.tgz#eb4bbb1c5e5bfb554541c1ae1542e74c2a9f43fd"
integrity sha512-tOiiToc94E1sb50BgZ8q8WK/bxus77SRrwCqIpAB5er3cpX78SULbEBY4YPOB8kDolOzKRt30WIHG/D6gz69Ww== integrity sha512-x7fx1w3i/uwZERIgztHAAK3VQMsL8+ku0lFXXbO81hKDg8IieACqjGEa2mqEueg0c/fX+wd0oI+75wB19KJAsA==
dependencies: dependencies:
loader-utils "^1.2.3" loader-utils "^1.2.3"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment