From 55ccd81a580e8082f503de5192346423b4dcca01 Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro <noreply@pedro.pombei.ro> Date: Tue, 12 Apr 2022 09:35:25 +0000 Subject: [PATCH] GraphQL: Implement CiRunnerType.upgradeStatus Add `CiRunnerUpgradeStatusType` to allow determining what type of upgrade can be applied to a runner --- .../ci/runner_upgrade_status_type_enum.rb | 21 ++++++ doc/api/graphql/reference/index.md | 9 +++ ee/app/graphql/ee/types/ci/runner_type.rb | 8 +++ ee/spec/graphql/types/ci/runner_type_spec.rb | 2 +- .../requests/api/graphql/ci/runner_spec.rb | 64 +++++++++++++++++++ spec/requests/api/graphql/ci/runner_spec.rb | 4 ++ spec/requests/api/graphql/ci/runners_spec.rb | 2 + 7 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 app/graphql/types/ci/runner_upgrade_status_type_enum.rb create mode 100644 ee/spec/requests/api/graphql/ci/runner_spec.rb diff --git a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb b/app/graphql/types/ci/runner_upgrade_status_type_enum.rb new file mode 100644 index 000000000000..e3d77e485bc6 --- /dev/null +++ b/app/graphql/types/ci/runner_upgrade_status_type_enum.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Types + module Ci + class RunnerUpgradeStatusTypeEnum < BaseEnum + graphql_name 'CiRunnerUpgradeStatusType' + + value 'NOT_AVAILABLE', + description: "An update is not available for the runner.", + value: :not_available + + value 'AVAILABLE', + description: "An update is available for the runner.", + value: :available + + value 'RECOMMENDED', + description: "An update is available and recommended for the runner.", + value: :recommended + end + end +end diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index f1cdf46625d1..879d836bc7a8 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -9450,6 +9450,7 @@ Represents the total number of issues and their weights for a particular day. | <a id="cirunnershortsha"></a>`shortSha` | [`String`](#string) | First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID. | | <a id="cirunnertaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. | | <a id="cirunnertokenexpiresat"></a>`tokenExpiresAt` | [`Time`](#time) | Runner token expiration time. | +| <a id="cirunnerupgradestatus"></a>`upgradeStatus` **{warning-solid}** | [`CiRunnerUpgradeStatusType`](#cirunnerupgradestatustype) | **Deprecated** in 14.10. This feature is in Alpha, and can be removed or changed at any point. | | <a id="cirunneruserpermissions"></a>`userPermissions` | [`RunnerPermissions!`](#runnerpermissions) | Permissions for the current user on the resource. | | <a id="cirunnerversion"></a>`version` | [`String`](#string) | Version of the runner. | @@ -17841,6 +17842,14 @@ Values for sorting runners. | <a id="cirunnertypeinstance_type"></a>`INSTANCE_TYPE` | A runner that is instance type. | | <a id="cirunnertypeproject_type"></a>`PROJECT_TYPE` | A runner that is project type. | +### `CiRunnerUpgradeStatusType` + +| Value | Description | +| ----- | ----------- | +| <a id="cirunnerupgradestatustypeavailable"></a>`AVAILABLE` | An update is available for the runner. | +| <a id="cirunnerupgradestatustypenot_available"></a>`NOT_AVAILABLE` | An update is not available for the runner. | +| <a id="cirunnerupgradestatustyperecommended"></a>`RECOMMENDED` | An update is available and recommended for the runner. | + ### `CodeQualityDegradationSeverity` | Value | Description | diff --git a/ee/app/graphql/ee/types/ci/runner_type.rb b/ee/app/graphql/ee/types/ci/runner_type.rb index ae59b74bcf81..d882353b4101 100644 --- a/ee/app/graphql/ee/types/ci/runner_type.rb +++ b/ee/app/graphql/ee/types/ci/runner_type.rb @@ -11,6 +11,14 @@ module RunnerType description: 'Public projects\' "minutes cost factor" associated with the runner (GitLab.com only).' field :private_projects_minutes_cost_factor, GraphQL::Types::Float, null: true, description: 'Private projects\' "minutes cost factor" associated with the runner (GitLab.com only).' + + field :upgrade_status, ::Types::Ci::RunnerUpgradeStatusTypeEnum, null: true, + description: 'Availability of upgrades for the runner.', + deprecated: { milestone: '14.10', reason: :alpha } + + def upgrade_status + ::Gitlab::Ci::RunnerUpgradeCheck.instance.check_runner_upgrade_status(object.version) + end end end end diff --git a/ee/spec/graphql/types/ci/runner_type_spec.rb b/ee/spec/graphql/types/ci/runner_type_spec.rb index 9d986ac9d13e..999e5024ec93 100644 --- a/ee/spec/graphql/types/ci/runner_type_spec.rb +++ b/ee/spec/graphql/types/ci/runner_type_spec.rb @@ -6,7 +6,7 @@ it { expect(described_class.graphql_name).to eq('CiRunner') } it 'includes the ee specific fields' do - expected_fields = %w[public_projects_minutes_cost_factor private_projects_minutes_cost_factor] + expected_fields = %w[public_projects_minutes_cost_factor private_projects_minutes_cost_factor upgrade_status] expect(described_class).to include_graphql_fields(*expected_fields) end diff --git a/ee/spec/requests/api/graphql/ci/runner_spec.rb b/ee/spec/requests/api/graphql/ci/runner_spec.rb new file mode 100644 index 000000000000..3e954695d0c0 --- /dev/null +++ b/ee/spec/requests/api/graphql/ci/runner_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Query.runner(id)' do + include GraphqlHelpers + + let_it_be(:user) { create(:user, :admin) } + + shared_examples 'runner details fetch operation returning expected upgradeStatus' do + let(:query) do + wrap_fields(query_graphql_path(query_path, all_graphql_fields_for('CiRunner'))) + end + + let(:query_path) do + [ + [:runner, { id: runner.to_global_id.to_s }] + ] + end + + it 'retrieves expected fields' do + post_graphql(query, current_user: user) + + runner_data = graphql_data_at(:runner) + expect(runner_data).not_to be_nil + + expect(runner_data).to match a_hash_including( + 'id' => runner.to_global_id.to_s, + 'upgradeStatus' => expected_upgrade_status + ) + end + end + + describe 'upgradeStatus' do + let_it_be(:runner) { create(:ci_runner, description: 'Runner 1', version: 'adfe156', revision: 'a') } + + before do + expect(::Gitlab::Ci::RunnerUpgradeCheck.instance).to receive(:check_runner_upgrade_status) + .and_return(upgrade_status) + .once + end + + context 'with RunnerUpgradeCheck returning :not_available' do + let(:upgrade_status) { :not_available } + let(:expected_upgrade_status) { 'NOT_AVAILABLE' } + + it_behaves_like('runner details fetch operation returning expected upgradeStatus') + end + + context 'with RunnerUpgradeCheck returning :available' do + let(:upgrade_status) { :available } + let(:expected_upgrade_status) { 'AVAILABLE' } + + it_behaves_like('runner details fetch operation returning expected upgradeStatus') + end + + context 'with RunnerUpgradeCheck returning :recommended' do + let(:upgrade_status) { :recommended } + let(:expected_upgrade_status) { 'RECOMMENDED' } + + it_behaves_like('runner details fetch operation returning expected upgradeStatus') + end + end +end diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb index 6102e15012b9..39f0f696b081 100644 --- a/spec/requests/api/graphql/ci/runner_spec.rb +++ b/spec/requests/api/graphql/ci/runner_spec.rb @@ -27,6 +27,10 @@ let_it_be(:active_project_runner) { create(:ci_runner, :project) } + before do + allow(Gitlab::Ci::RunnerUpgradeCheck.instance).to receive(:check_runner_upgrade_status) + end + shared_examples 'runner details fetch' do let(:query) do wrap_fields(query_graphql_path(query_path, all_graphql_fields_for('CiRunner'))) diff --git a/spec/requests/api/graphql/ci/runners_spec.rb b/spec/requests/api/graphql/ci/runners_spec.rb index 267dd1b5e6fd..6b88c82b025c 100644 --- a/spec/requests/api/graphql/ci/runners_spec.rb +++ b/spec/requests/api/graphql/ci/runners_spec.rb @@ -34,6 +34,8 @@ end before do + allow(Gitlab::Ci::RunnerUpgradeCheck.instance).to receive(:check_runner_upgrade_status) + post_graphql(query, current_user: current_user) end -- GitLab