Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/atlassian')
-rw-r--r--lib/atlassian/jira_connect/client.rb75
-rw-r--r--lib/atlassian/jira_connect/serializers/base_entity.rb6
-rw-r--r--lib/atlassian/jira_connect/serializers/build_entity.rb94
3 files changed, 156 insertions, 19 deletions
diff --git a/lib/atlassian/jira_connect/client.rb b/lib/atlassian/jira_connect/client.rb
index f81ed462174..da24d0e20ee 100644
--- a/lib/atlassian/jira_connect/client.rb
+++ b/lib/atlassian/jira_connect/client.rb
@@ -12,31 +12,68 @@ module Atlassian
@shared_secret = shared_secret
end
+ def send_info(project:, update_sequence_id: nil, **args)
+ common = { project: project, update_sequence_id: update_sequence_id }
+ dev_info = args.slice(:commits, :branches, :merge_requests)
+ build_info = args.slice(:pipelines)
+
+ responses = []
+
+ responses << store_dev_info(**common, **dev_info) if dev_info.present?
+ responses << store_build_info(**common, **build_info) if build_info.present?
+ raise ArgumentError, 'Invalid arguments' if responses.empty?
+
+ responses.compact
+ end
+
+ private
+
+ def store_build_info(project:, pipelines:, update_sequence_id: nil)
+ return unless Feature.enabled?(:jira_sync_builds, project)
+
+ builds = pipelines.map do |pipeline|
+ build = Serializers::BuildEntity.represent(
+ pipeline,
+ update_sequence_id: update_sequence_id
+ )
+ next if build.issue_keys.empty?
+
+ build
+ end.compact
+ return if builds.empty?
+
+ post('/rest/builds/0.1/bulk', { builds: builds })
+ end
+
def store_dev_info(project:, commits: nil, branches: nil, merge_requests: nil, update_sequence_id: nil)
- dev_info_json = {
- repositories: [
- Serializers::RepositoryEntity.represent(
- project,
- commits: commits,
- branches: branches,
- merge_requests: merge_requests,
- user_notes_count: user_notes_count(merge_requests),
- update_sequence_id: update_sequence_id
- )
- ]
- }.to_json
-
- uri = URI.join(@base_uri, '/rest/devinfo/0.10/bulk')
-
- headers = {
+ repo = Serializers::RepositoryEntity.represent(
+ project,
+ commits: commits,
+ branches: branches,
+ merge_requests: merge_requests,
+ user_notes_count: user_notes_count(merge_requests),
+ update_sequence_id: update_sequence_id
+ )
+
+ post('/rest/devinfo/0.10/bulk', { repositories: [repo] })
+ end
+
+ def post(path, payload)
+ uri = URI.join(@base_uri, path)
+
+ self.class.post(uri, headers: headers(uri), body: metadata.merge(payload).to_json)
+ end
+
+ def headers(uri)
+ {
'Authorization' => "JWT #{jwt_token('POST', uri)}",
'Content-Type' => 'application/json'
}
-
- self.class.post(uri, headers: headers, body: dev_info_json)
end
- private
+ def metadata
+ { providerMetadata: { product: "GitLab #{Gitlab::VERSION}" } }
+ end
def user_notes_count(merge_requests)
return unless merge_requests
diff --git a/lib/atlassian/jira_connect/serializers/base_entity.rb b/lib/atlassian/jira_connect/serializers/base_entity.rb
index 94deb174a45..640337c0399 100644
--- a/lib/atlassian/jira_connect/serializers/base_entity.rb
+++ b/lib/atlassian/jira_connect/serializers/base_entity.rb
@@ -11,6 +11,12 @@ module Atlassian
expose :update_sequence_id, as: :updateSequenceId
+ def eql(other)
+ other.is_a?(self.class) && to_json == other.to_json
+ end
+
+ alias_method :==, :eql
+
private
def update_sequence_id
diff --git a/lib/atlassian/jira_connect/serializers/build_entity.rb b/lib/atlassian/jira_connect/serializers/build_entity.rb
new file mode 100644
index 00000000000..3eb8b1f1978
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/build_entity.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ # A Jira 'build' represents what we call a 'pipeline'
+ class BuildEntity < Grape::Entity
+ include Gitlab::Routing
+
+ format_with(:iso8601, &:iso8601)
+
+ expose :schema_version, as: :schemaVersion
+ expose :pipeline_id, as: :pipelineId
+ expose :iid, as: :buildNumber
+ expose :update_sequence_id, as: :updateSequenceNumber
+ expose :source_ref, as: :displayName
+ expose :url
+ expose :state
+ expose :updated_at, as: :lastUpdated, format_with: :iso8601
+ expose :issue_keys, as: :issueKeys
+ expose :test_info, as: :testInfo
+ expose :references
+
+ def issue_keys
+ # extract Jira issue keys from either the source branch/ref or the
+ # merge request title.
+ @issue_keys ||= begin
+ src = "#{pipeline.source_ref} #{pipeline.merge_request&.title}"
+ JiraIssueKeyExtractor.new(src).issue_keys
+ end
+ end
+
+ private
+
+ alias_method :pipeline, :object
+ delegate :project, to: :object
+
+ def url
+ project_pipeline_url(project, pipeline)
+ end
+
+ # translate to Jira status
+ def state
+ case pipeline.status
+ when 'scheduled', 'created', 'pending', 'preparing', 'waiting_for_resource' then 'pending'
+ when 'running' then 'in_progress'
+ when 'success' then 'successful'
+ when 'failed' then 'failed'
+ when 'canceled', 'skipped' then 'cancelled'
+ else
+ 'unknown'
+ end
+ end
+
+ def pipeline_id
+ pipeline.ensure_ci_ref!
+
+ pipeline.ci_ref.id.to_s
+ end
+
+ def schema_version
+ '1.0'
+ end
+
+ def test_info
+ builds = pipeline.builds.pluck(:status) # rubocop: disable CodeReuse/ActiveRecord
+ n = builds.size
+ passed = builds.count { |s| s == 'success' }
+ failed = builds.count { |s| s == 'failed' }
+
+ {
+ totalNumber: n,
+ numberPassed: passed,
+ numberFailed: failed,
+ numberSkipped: n - (passed + failed)
+ }
+ end
+
+ def references
+ ref = pipeline.source_ref
+
+ [{
+ commit: { id: pipeline.sha, repositoryUri: project_url(project) },
+ ref: { name: ref, uri: project_commits_url(project, ref) }
+ }]
+ end
+
+ def update_sequence_id
+ options[:update_sequence_id] || Client.generate_update_sequence_id
+ end
+ end
+ end
+ end
+end