summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-01-05 03:09:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-01-05 03:09:46 +0000
commit6cb2a797bf152af1f6627cde7876871831b9c639 (patch)
treeb34ff67013f7fc1bfab478b548b7c1a664eb7725 /app
parent86af4d6a04a1c30ebfe2377cdc3270ade911b2fe (diff)
downloadgitlab-ce-6cb2a797bf152af1f6627cde7876871831b9c639.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/ide/lib/gitlab_web_ide/get_base_config.js9
-rw-r--r--app/controllers/concerns/integrations/params.rb3
-rw-r--r--app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb5
-rw-r--r--app/graphql/types/issue_type.rb9
-rw-r--r--app/models/ci/build.rb9
-rw-r--r--app/models/integration.rb5
-rw-r--r--app/models/integrations/apple_app_store.rb111
-rw-r--r--app/models/integrations/field.rb7
-rw-r--r--app/models/project.rb1
9 files changed, 151 insertions, 8 deletions
diff --git a/app/assets/javascripts/ide/lib/gitlab_web_ide/get_base_config.js b/app/assets/javascripts/ide/lib/gitlab_web_ide/get_base_config.js
index fbd2ce4ce69..dbb68b7facd 100644
--- a/app/assets/javascripts/ide/lib/gitlab_web_ide/get_base_config.js
+++ b/app/assets/javascripts/ide/lib/gitlab_web_ide/get_base_config.js
@@ -1,7 +1,12 @@
-import { cleanEndingSeparator } from '~/lib/utils/url_utility';
+import { cleanEndingSeparator, joinPaths } from '~/lib/utils/url_utility';
const getBaseUrl = () => {
- const baseUrlObj = new URL(process.env.GITLAB_WEB_IDE_PUBLIC_PATH, window.location.origin);
+ const path = joinPaths(
+ '/',
+ window.gon.relative_url_root || '',
+ process.env.GITLAB_WEB_IDE_PUBLIC_PATH,
+ );
+ const baseUrlObj = new URL(path, window.location.origin);
return cleanEndingSeparator(baseUrlObj.href);
};
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index 74d998503b7..1da612893ce 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -5,6 +5,9 @@ module Integrations
extend ActiveSupport::Concern
ALLOWED_PARAMS_CE = [
+ :app_store_issuer_id,
+ :app_store_key_id,
+ :app_store_private_key,
:active,
:alert_events,
:api_key,
diff --git a/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb b/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb
index c6e32be245d..2ea7a02bf15 100644
--- a/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb
+++ b/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb
@@ -20,7 +20,7 @@ module Issues
end
def preloads
- {
+ preload_hash = {
alert_management_alert: [:alert_management_alert],
assignees: [:assignees],
participants: Issue.participant_includes,
@@ -28,6 +28,9 @@ module Issues
customer_relations_contacts: { customer_relations_contacts: [:group] },
escalation_status: [:incident_management_issuable_escalation_status]
}
+ preload_hash[:type] = :work_item_type if Feature.enabled?(:issue_type_uses_work_item_types_table)
+
+ preload_hash
end
end
end
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index dd2ad26ce49..4948063610a 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -117,7 +117,6 @@ module Types
description: 'Collection of design images associated with this issue.'
field :type, Types::IssueTypeEnum, null: true,
- method: :issue_type,
description: 'Type of the issue.'
field :alert_management_alert,
@@ -198,6 +197,14 @@ module Types
def escalation_status
object.supports_escalation? ? object.escalation_status&.status_name : nil
end
+
+ def type
+ if Feature.enabled?(:issue_type_uses_work_item_types_table)
+ object.work_item_type.base_type
+ else
+ object.issue_type
+ end
+ end
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 111d2797fed..d45f770a0d2 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -68,6 +68,7 @@ module Ci
delegate :service_specification, to: :runner_session, allow_nil: true
delegate :gitlab_deploy_token, to: :project
delegate :harbor_integration, to: :project
+ delegate :apple_app_store_integration, to: :project
delegate :trigger_short_token, to: :trigger_request, allow_nil: true
delegate :ensure_persistent_ref, to: :pipeline
delegate :enable_debug_trace!, to: :metadata
@@ -587,6 +588,7 @@ module Ci
.append(key: 'CI_REPOSITORY_URL', value: repo_url.to_s, public: false)
.concat(deploy_token_variables)
.concat(harbor_variables)
+ .concat(apple_app_store_variables)
end
end
@@ -630,6 +632,13 @@ module Ci
Gitlab::Ci::Variables::Collection.new(harbor_integration.ci_variables)
end
+ def apple_app_store_variables
+ return [] unless apple_app_store_integration.try(:activated?)
+ return [] unless pipeline.protected_ref?
+
+ Gitlab::Ci::Variables::Collection.new(apple_app_store_integration.ci_variables)
+ end
+
def features
{
trace_sections: true,
diff --git a/app/models/integration.rb b/app/models/integration.rb
index 290bee6537e..df1560b87a5 100644
--- a/app/models/integration.rb
+++ b/app/models/integration.rb
@@ -281,10 +281,13 @@ class Integration < ApplicationRecord
# Returns a list of available integration names.
# Example: ["asana", ...]
# @deprecated
- def self.available_integration_names(include_project_specific: true, include_dev: true)
+ # @param [Boolean] include_feature_flagged used only in specs
+ # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/386731
+ def self.available_integration_names(include_project_specific: true, include_dev: true, include_feature_flagged: false)
names = integration_names
names += project_specific_integration_names if include_project_specific
names += dev_integration_names if include_dev
+ names << 'apple_app_store' if Feature.enabled?(:apple_app_store_integration) || include_feature_flagged
names.sort_by(&:downcase)
end
diff --git a/app/models/integrations/apple_app_store.rb b/app/models/integrations/apple_app_store.rb
new file mode 100644
index 00000000000..84185542939
--- /dev/null
+++ b/app/models/integrations/apple_app_store.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require 'app_store_connect'
+
+module Integrations
+ class AppleAppStore < Integration
+ ISSUER_ID_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/.freeze
+ KEY_ID_REGEX = /\A(?=.*[A-Z])(?=.*[0-9])[A-Z0-9]+\z/.freeze
+
+ with_options if: :activated? do
+ validates :app_store_issuer_id, presence: true, format: { with: ISSUER_ID_REGEX }
+ validates :app_store_key_id, presence: true, format: { with: KEY_ID_REGEX }
+ validates :app_store_private_key, presence: true, certificate_key: true
+ end
+
+ field :app_store_issuer_id,
+ section: SECTION_TYPE_CONNECTION,
+ required: true,
+ title: -> { s_('AppleAppStore|The Apple App Store Connect Issuer ID.') }
+
+ field :app_store_key_id,
+ section: SECTION_TYPE_CONNECTION,
+ required: true,
+ title: -> { s_('AppleAppStore|The Apple App Store Connect Key ID.') },
+ is_secret: false
+
+ field :app_store_private_key,
+ section: SECTION_TYPE_CONNECTION,
+ required: true,
+ type: 'textarea',
+ title: -> { s_('AppleAppStore|The Apple App Store Connect Private Key.') },
+ is_secret: false
+
+ def title
+ 'Apple App Store Connect'
+ end
+
+ def description
+ s_('AppleAppStore|Use GitLab to build and release an app in the Apple App Store.')
+ end
+
+ def help
+ variable_list = [
+ '<code>APP_STORE_CONNECT_API_KEY_ISSUER_ID</code>',
+ '<code>APP_STORE_CONNECT_API_KEY_KEY_ID</code>',
+ '<code>APP_STORE_CONNECT_API_KEY_KEY</code>'
+ ]
+
+ # rubocop:disable Layout/LineLength
+ texts = [
+ s_("Use the Apple App Store Connect integration to easily connect to the Apple App Store with Fastlane in CI/CD pipelines."),
+ s_("After the Apple App Store Connect integration is activated, the following protected variables will be created for CI/CD use."),
+ variable_list.join('<br>'),
+ s_(format("To get started, see the <a href='%{url}' target='_blank'>integration documentation</a> for instructions on how to generate App Store Connect credentials, and how to use this integration.", url: "https://docs.gitlab.com/ee/integration/apple_app_store.html")).html_safe
+ ]
+ # rubocop:enable Layout/LineLength
+
+ texts.join('<br><br>'.html_safe)
+ end
+
+ def self.to_param
+ 'apple_app_store'
+ end
+
+ def self.supported_events
+ []
+ end
+
+ def sections
+ [
+ {
+ type: SECTION_TYPE_CONNECTION,
+ title: s_('Integrations|Integration details'),
+ description: help
+ }
+ ]
+ end
+
+ def test(*_args)
+ response = client.apps
+ if response.has_key?(:errors)
+ { success: false, message: response[:errors].first[:title] }
+ else
+ { success: true }
+ end
+ end
+
+ def ci_variables
+ return [] unless activated?
+
+ [
+ { key: 'APP_STORE_CONNECT_API_KEY_ISSUER_ID', value: app_store_issuer_id, masked: true, public: false },
+ { key: 'APP_STORE_CONNECT_API_KEY_KEY', value: Base64.encode64(app_store_private_key), masked: true,
+ public: false },
+ { key: 'APP_STORE_CONNECT_API_KEY_KEY_ID', value: app_store_key_id, masked: true, public: false }
+ ]
+ end
+
+ private
+
+ def client
+ config = {
+ issuer_id: app_store_issuer_id,
+ key_id: app_store_key_id,
+ private_key: app_store_private_key
+ }
+
+ AppStoreConnect::Client.new(config)
+ end
+ end
+end
diff --git a/app/models/integrations/field.rb b/app/models/integrations/field.rb
index 53c8f5f623e..329c046075f 100644
--- a/app/models/integrations/field.rb
+++ b/app/models/integrations/field.rb
@@ -4,7 +4,7 @@ module Integrations
class Field
SECRET_NAME = %r/token|key|password|passphrase|secret/.freeze
- BOOLEAN_ATTRIBUTES = %i[required api_only exposes_secrets].freeze
+ BOOLEAN_ATTRIBUTES = %i[required api_only is_secret exposes_secrets].freeze
ATTRIBUTES = %i[
section type placeholder choices value checkbox_label
@@ -17,12 +17,13 @@ module Integrations
attr_reader :name, :integration_class
- def initialize(name:, integration_class:, type: 'text', api_only: false, **attributes)
+ def initialize(name:, integration_class:, type: 'text', is_secret: true, api_only: false, **attributes)
@name = name.to_s.freeze
@integration_class = integration_class
- attributes[:type] = SECRET_NAME.match?(@name) ? 'password' : type
+ attributes[:type] = SECRET_NAME.match?(@name) && is_secret ? 'password' : type
attributes[:api_only] = api_only
+ attributes[:is_secret] = is_secret
@attributes = attributes.freeze
invalid_attributes = attributes.keys - ATTRIBUTES
diff --git a/app/models/project.rb b/app/models/project.rb
index 217e801e07f..116f81207f6 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -170,6 +170,7 @@ class Project < ApplicationRecord
end
# Project integrations
+ has_one :apple_app_store_integration, class_name: 'Integrations::AppleAppStore'
has_one :asana_integration, class_name: 'Integrations::Asana'
has_one :assembla_integration, class_name: 'Integrations::Assembla'
has_one :bamboo_integration, class_name: 'Integrations::Bamboo'