summaryrefslogtreecommitdiff
path: root/lib/atlassian
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 01:45:44 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 01:45:44 +0000
commit85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch)
tree9160f299afd8c80c038f08e1545be119f5e3f1e1 /lib/atlassian
parent15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff)
downloadgitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'lib/atlassian')
-rw-r--r--lib/atlassian/jira_connect.rb21
-rw-r--r--lib/atlassian/jira_connect/client.rb47
-rw-r--r--lib/atlassian/jira_connect/serializers/author_entity.rb24
-rw-r--r--lib/atlassian/jira_connect/serializers/base_entity.rb22
-rw-r--r--lib/atlassian/jira_connect/serializers/branch_entity.rb32
-rw-r--r--lib/atlassian/jira_connect/serializers/commit_entity.rb45
-rw-r--r--lib/atlassian/jira_connect/serializers/file_entity.rb38
-rw-r--r--lib/atlassian/jira_connect/serializers/pull_request_entity.rb42
-rw-r--r--lib/atlassian/jira_connect/serializers/repository_entity.rb29
-rw-r--r--lib/atlassian/jira_issue_key_extractor.rb17
10 files changed, 317 insertions, 0 deletions
diff --git a/lib/atlassian/jira_connect.rb b/lib/atlassian/jira_connect.rb
new file mode 100644
index 00000000000..7f693eff59b
--- /dev/null
+++ b/lib/atlassian/jira_connect.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ class << self
+ def app_name
+ "GitLab for Jira (#{gitlab_host})"
+ end
+
+ def app_key
+ "gitlab-jira-connect-#{gitlab_host}"
+ end
+
+ private
+
+ def gitlab_host
+ Gitlab.config.gitlab.host
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/client.rb b/lib/atlassian/jira_connect/client.rb
new file mode 100644
index 00000000000..0b578c03782
--- /dev/null
+++ b/lib/atlassian/jira_connect/client.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ class Client < Gitlab::HTTP
+ def initialize(base_uri, shared_secret)
+ @base_uri = base_uri
+ @shared_secret = shared_secret
+ end
+
+ def store_dev_info(project:, commits: nil, branches: nil, merge_requests: nil)
+ dev_info_json = {
+ repositories: [
+ Serializers::RepositoryEntity.represent(
+ project,
+ commits: commits,
+ branches: branches,
+ merge_requests: merge_requests
+ )
+ ]
+ }.to_json
+
+ uri = URI.join(@base_uri, '/rest/devinfo/0.10/bulk')
+
+ headers = {
+ 'Authorization' => "JWT #{jwt_token('POST', uri)}",
+ 'Content-Type' => 'application/json'
+ }
+
+ self.class.post(uri, headers: headers, body: dev_info_json)
+ end
+
+ private
+
+ def jwt_token(http_method, uri)
+ claims = Atlassian::Jwt.build_claims(
+ Atlassian::JiraConnect.app_key,
+ uri,
+ http_method,
+ @base_uri
+ )
+
+ Atlassian::Jwt.encode(claims, @shared_secret)
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/author_entity.rb b/lib/atlassian/jira_connect/serializers/author_entity.rb
new file mode 100644
index 00000000000..9ab8e34c14b
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/author_entity.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class AuthorEntity < Grape::Entity
+ include Gitlab::Routing
+
+ expose :name
+ expose :email
+
+ with_options(unless: -> (user) { user.is_a?(CommitEntity::CommitAuthor) }) do
+ expose :username
+ expose :url do |user|
+ user_url(user)
+ end
+ expose :avatar do |user|
+ user.avatar_url(only_path: false)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/base_entity.rb b/lib/atlassian/jira_connect/serializers/base_entity.rb
new file mode 100644
index 00000000000..c5490aa3f54
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/base_entity.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class BaseEntity < Grape::Entity
+ include Gitlab::Routing
+ include GitlabRoutingHelper
+
+ format_with(:string) { |value| value.to_s }
+
+ expose :monotonic_time, as: :updateSequenceId
+
+ private
+
+ def monotonic_time
+ Gitlab::Metrics::System.monotonic_time.to_i
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/branch_entity.rb b/lib/atlassian/jira_connect/serializers/branch_entity.rb
new file mode 100644
index 00000000000..c663575b7a8
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/branch_entity.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class BranchEntity < BaseEntity
+ expose :id do |branch|
+ Digest::SHA256.hexdigest(branch.name)
+ end
+ expose :issueKeys do |branch|
+ JiraIssueKeyExtractor.new(branch.name).issue_keys
+ end
+ expose :name
+ expose :lastCommit, using: JiraConnect::Serializers::CommitEntity do |branch, options|
+ options[:project].commit(branch.dereferenced_target)
+ end
+
+ expose :url do |branch, options|
+ project_commits_url(options[:project], branch.name)
+ end
+ expose :createPullRequestUrl do |branch, options|
+ project_new_merge_request_url(
+ options[:project],
+ merge_request: {
+ source_branch: branch.name
+ }
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/commit_entity.rb b/lib/atlassian/jira_connect/serializers/commit_entity.rb
new file mode 100644
index 00000000000..12eb1ed15ea
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/commit_entity.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class CommitEntity < BaseEntity
+ CommitAuthor = Struct.new(:name, :email)
+
+ expose :id
+ expose :issueKeys do |commit|
+ JiraIssueKeyExtractor.new(commit.safe_message).issue_keys
+ end
+ expose :id, as: :hash
+ expose :short_id, as: :displayId
+ expose :safe_message, as: :message
+ expose :flags do |commit|
+ if commit.merge_commit?
+ ['MERGE_COMMIT']
+ else
+ []
+ end
+ end
+ expose :author, using: JiraConnect::Serializers::AuthorEntity
+ expose :fileCount do |commit|
+ commit.stats.total
+ end
+ expose :files do |commit, options|
+ files = commit.diffs(max_files: 10).diff_files
+ JiraConnect::Serializers::FileEntity.represent files, options.merge(commit: commit)
+ end
+ expose :created_at, as: :authorTimestamp
+
+ expose :url do |commit, options|
+ project_commit_url(options[:project], commit.id)
+ end
+
+ private
+
+ def author
+ object.author || CommitAuthor.new(object.author_name, object.author_email)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/file_entity.rb b/lib/atlassian/jira_connect/serializers/file_entity.rb
new file mode 100644
index 00000000000..50d31965f93
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/file_entity.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class FileEntity < Grape::Entity
+ include Gitlab::Routing
+
+ expose :path do |file|
+ file.deleted_file? ? file.old_path : file.new_path
+ end
+ expose :changeType do |file|
+ if file.new_file?
+ 'ADDED'
+ elsif file.deleted_file?
+ 'DELETED'
+ elsif file.renamed_file?
+ 'MOVED'
+ else
+ 'MODIFIED'
+ end
+ end
+ expose :added_lines, as: :linesAdded
+ expose :removed_lines, as: :linesRemoved
+
+ expose :url do |file, options|
+ file_path = if file.deleted_file?
+ File.join(options[:commit].parent_id, file.old_path)
+ else
+ File.join(options[:commit].id, file.new_path)
+ end
+
+ project_blob_url(options[:project], file_path)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/pull_request_entity.rb b/lib/atlassian/jira_connect/serializers/pull_request_entity.rb
new file mode 100644
index 00000000000..0ddfcbf52ea
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/pull_request_entity.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class PullRequestEntity < BaseEntity
+ STATUS_MAPPING = {
+ 'opened' => 'OPEN',
+ 'locked' => 'OPEN',
+ 'merged' => 'MERGED',
+ 'closed' => 'DECLINED'
+ }.freeze
+
+ expose :id, format_with: :string
+ expose :issueKeys do |mr|
+ JiraIssueKeyExtractor.new(mr.title, mr.description).issue_keys
+ end
+ expose :displayId do |mr|
+ mr.to_reference(full: true)
+ end
+ expose :title
+ expose :author, using: JiraConnect::Serializers::AuthorEntity
+ expose :user_notes_count, as: :commentCount
+ expose :source_branch, as: :sourceBranch
+ expose :target_branch, as: :destinationBranch
+ expose :lastUpdate do |mr|
+ mr.last_edited_at || mr.created_at
+ end
+ expose :status do |mr|
+ STATUS_MAPPING[mr.state] || 'UNKNOWN'
+ end
+
+ expose :sourceBranchUrl do |mr|
+ project_commits_url(mr.project, mr.source_branch)
+ end
+ expose :url do |mr|
+ merge_request_url(mr)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_connect/serializers/repository_entity.rb b/lib/atlassian/jira_connect/serializers/repository_entity.rb
new file mode 100644
index 00000000000..819ca2b62e0
--- /dev/null
+++ b/lib/atlassian/jira_connect/serializers/repository_entity.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Serializers
+ class RepositoryEntity < BaseEntity
+ expose :id, format_with: :string
+ expose :name
+ expose :description
+ expose :url do |project|
+ project_url(project)
+ end
+ expose :avatar do |project|
+ project.avatar_url(only_path: false)
+ end
+
+ expose :commits do |project, options|
+ JiraConnect::Serializers::CommitEntity.represent options[:commits], project: project
+ end
+ expose :branches do |project, options|
+ JiraConnect::Serializers::BranchEntity.represent options[:branches], project: project
+ end
+ expose :pullRequests do |project, options|
+ JiraConnect::Serializers::PullRequestEntity.represent options[:merge_requests], project: project
+ end
+ end
+ end
+ end
+end
diff --git a/lib/atlassian/jira_issue_key_extractor.rb b/lib/atlassian/jira_issue_key_extractor.rb
new file mode 100644
index 00000000000..f1b432787ac
--- /dev/null
+++ b/lib/atlassian/jira_issue_key_extractor.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Atlassian
+ class JiraIssueKeyExtractor
+ def self.has_keys?(*text)
+ new(*text).issue_keys.any?
+ end
+
+ def initialize(*text)
+ @text = text.join(' ')
+ end
+
+ def issue_keys
+ @text.scan(Gitlab::Regex.jira_issue_key_regex).uniq
+ end
+ end
+end