Skip to content
代码片段 群组 项目
提交 27507316 编辑于 作者: Shinya Maeda's avatar Shinya Maeda
浏览文件

Add GraphQL query for deployment details

This commit adds GraphQL query for fetching deployment details.

Changelog: added
上级 64be1a13
No related branches found
No related tags found
无相关合并请求
# frozen_string_literal: true
module Resolvers
class DeploymentResolver < BaseResolver
argument :iid,
GraphQL::Types::ID,
required: true,
description: 'Project-level internal ID of the Deployment.'
type Types::DeploymentType, null: true
alias_method :project, :object
def resolve(iid:)
return unless project.present? && project.is_a?(::Project)
Deployment.for_iid(project, iid)
end
end
end
# frozen_string_literal: true
module Types
class DeploymentDetailsType < DeploymentType
graphql_name 'DeploymentDetails'
description 'The details of the deployment'
authorize :read_deployment
end
end
# frozen_string_literal: true
module Types
# If you're considering to add a new field in DeploymentType, please follow this guideline:
# - If the field is preloadable in batch, define it in DeploymentType.
# In this case, you should extend DeploymentsResolver logic to preload the field. Also, add a new test that
# fetching the specific field for multiple deployments doesn't cause N+1 query problem.
# - If the field is NOT preloadable in batch, define it in DeploymentDetailsType.
# This type can be only fetched for a single deployment, so you don't need to take care of the preloading.
class DeploymentType < BaseObject
graphql_name 'Deployment'
description 'The deployment of an environment'
......
......@@ -179,6 +179,12 @@ class ProjectType < BaseObject
description: 'A single environment of the project.',
resolver: Resolvers::EnvironmentsResolver.single
field :deployment,
Types::DeploymentDetailsType,
null: true,
description: 'Details of the deployment of the project.',
resolver: Resolvers::DeploymentResolver.single
field :issue,
Types::IssueType,
null: true,
......
......@@ -36,6 +36,7 @@ class Deployment < ApplicationRecord
delegate :name, to: :environment, prefix: true
delegate :kubernetes_namespace, to: :deployment_cluster, allow_nil: true
scope :for_iid, -> (project, iid) { where(project: project, iid: iid) }
scope :for_environment, -> (environment) { where(environment_id: environment) }
scope :for_environment_name, -> (project, name) do
where('deployments.environment_id = (?)',
......
......@@ -10991,6 +10991,24 @@ The deployment of an environment.
| <a id="deploymenttag"></a>`tag` | [`Boolean`](#boolean) | True or false if the deployment ran on a Git-tag. |
| <a id="deploymentupdatedat"></a>`updatedAt` | [`Time`](#time) | When the deployment record was updated. |
 
### `DeploymentDetails`
The details of the deployment.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="deploymentdetailscreatedat"></a>`createdAt` | [`Time`](#time) | When the deployment record was created. |
| <a id="deploymentdetailsfinishedat"></a>`finishedAt` | [`Time`](#time) | When the deployment finished. |
| <a id="deploymentdetailsid"></a>`id` | [`ID`](#id) | Global ID of the deployment. |
| <a id="deploymentdetailsiid"></a>`iid` | [`ID`](#id) | Project-level internal ID of the deployment. |
| <a id="deploymentdetailsref"></a>`ref` | [`String`](#string) | Git-Ref that the deployment ran on. |
| <a id="deploymentdetailssha"></a>`sha` | [`String`](#string) | Git-SHA that the deployment ran on. |
| <a id="deploymentdetailsstatus"></a>`status` | [`DeploymentStatus`](#deploymentstatus) | Status of the deployment. |
| <a id="deploymentdetailstag"></a>`tag` | [`Boolean`](#boolean) | True or false if the deployment ran on a Git-tag. |
| <a id="deploymentdetailsupdatedat"></a>`updatedAt` | [`Time`](#time) | When the deployment record was updated. |
### `Design`
 
A single design.
......@@ -15871,6 +15889,18 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectdastsitevalidationsnormalizedtargeturls"></a>`normalizedTargetUrls` | [`[String!]`](#string) | Normalized URL of the target to be scanned. |
| <a id="projectdastsitevalidationsstatus"></a>`status` | [`DastSiteValidationStatusEnum`](#dastsitevalidationstatusenum) | Status of the site validation. |
 
##### `Project.deployment`
Details of the deployment of the project.
Returns [`DeploymentDetails`](#deploymentdetails).
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectdeploymentiid"></a>`iid` | [`ID!`](#id) | Project-level internal ID of the Deployment. |
##### `Project.environment`
 
A single environment of the project.
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::DeploymentResolver do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :private) }
let_it_be(:environment) { create(:environment, project: project) }
let_it_be(:deployment) { create(:deployment, :created, environment: environment, project: project) }
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
let(:current_user) { developer }
describe '#resolve' do
it 'finds the deployment' do
expect(resolve_deployments(iid: deployment.iid)).to contain_exactly(deployment)
end
it 'does not find the deployment if the IID does not match' do
expect(resolve_deployments(iid: non_existing_record_id)).to be_empty
end
end
def resolve_deployments(args = {}, context = { current_user: current_user })
resolve(described_class, obj: project, args: args, ctx: context)
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['DeploymentDetails'] do
specify { expect(described_class.graphql_name).to eq('DeploymentDetails') }
it 'has the expected fields' do
expected_fields = %w[
id iid ref tag sha created_at updated_at finished_at status
]
expect(described_class).to have_graphql_fields(*expected_fields)
end
specify { expect(described_class).to require_graphql_authorizations(:read_deployment) }
end
......@@ -74,6 +74,27 @@
end
end
describe '.for_iid' do
subject { described_class.for_iid(project, iid) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:deployment) { create(:deployment, project: project) }
let(:iid) { deployment.iid }
it 'finds the deployment' do
is_expected.to contain_exactly(deployment)
end
context 'when iid does not match' do
let(:iid) { non_existing_record_id }
it 'does not find the deployment' do
is_expected.to be_empty
end
end
end
describe '.for_environment_name' do
subject { described_class.for_environment_name(project, environment_name) }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Project Deployment query' do
let_it_be(:project) { create(:project, :private, :repository) }
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
let_it_be(:guest) { create(:user).tap { |u| project.add_guest(u) } }
let_it_be(:environment) { create(:environment, project: project) }
let_it_be(:deployment) { create(:deployment, environment: environment, project: project) }
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
let(:user) { developer }
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
deployment(iid: #{deployment.iid}) {
id
iid
ref
tag
sha
createdAt
updatedAt
finishedAt
status
}
}
}
)
end
it 'returns the deployment of the project' do
deployment_data = subject.dig('data', 'project', 'deployment')
expect(deployment_data['iid']).to eq(deployment.iid.to_s)
end
context 'when user is guest' do
let(:user) { guest }
it 'returns nothing' do
deployment_data = subject.dig('data', 'project', 'deployment')
expect(deployment_data).to be_nil
end
end
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册