통합 개발 지침
이 페이지에서는 GitLab 통합을 구현하기 위한 개발 지침을 제공합니다. 이는 주요 Rails 프로젝트의 일부입니다.
또한 통합에 대한 전략에 대한 개요를 보려면 방향 페이지를 참조하세요.
이 가이드는 진행 중인 작업입니다. 궁금한 사항이 있거나 오래된 정보를 발견하면 @gitlab-org/manage/import-and-integrate
에 문의하십시오.
새로운 통합 추가
통합 정의
-
Integration
에서 확장된 새 모델을app/models/integrations
에 추가합니다.- 예를 들어,
app/models/integrations/foo_bar.rb
에Integrations::FooBar
를 추가합니다. - 일부 유형의 통합의 경우 이러한 기본 클래스에서도 작성할 수 있습니다:
Integrations::BaseChatNotification
Integrations::BaseCi
Integrations::BaseIssueTracker
Integrations::BaseMonitoring
Integrations::BaseSlashCommands
Integrations::BaseThirdPartyWiki
- 주로 외부 서비스로의 HTTP 호출을 트리거하는 통합인 경우,
Integrations::HasWebHook
concern을 사용할 수도 있습니다. 이는 연결된ServiceHook
모델을 통해 GitLab의 웹훅 기능을 재사용하고 요청 로그를 자동으로 기록하여 통합 설정에서 볼 수 있습니다.
- 예를 들어,
- 통합의 언더스코어 이름(
'foo_bar'
)을Integration::INTEGRATION_NAMES
에 추가합니다. -
Project
에서 통합을 연관으로 추가합니다:has_one :foo_bar_integration, class_name: 'Integrations::FooBar'
필드 정의
통합은 Integration.field
클래스 메서드를 사용하여 구성을 저장하는 임의의 필드를 정의할 수 있습니다. 값은 integrations.encrypted_properties
열에 암호화된 JSON 해시로 저장됩니다.
예를 들어:
module Integrations
class FooBar < Integration
field :url
field :tags
end
end
Integration.field
는 클래스에 액서서 메서드를 설치합니다. 여기에는 #url
, #url=
, #url_changed?
가 포함되어 있어 url
필드를 관리합니다. 이러한 액서서는 다른 ActiveRecord
속성과 마찬가지로 모델의 Integration#properties
에 직접 액세스해야 합니다.
필드는 반드시 그들의 게터
를 통해 액세스해야 하며, properties
해시와 직접 상호작용해서는 안 됩니다. 게터
를 통해 필드에 항상 접근해야 합니다. properties
해시에 직접 쓰면 안 되며, 대신 생성된 setter 메서드를 사용해야 합니다. 이 해시에 직접 쓰는 것은 영속적이지 않습니다.
이러한 필드가 프론트엔드 양식에서 어떻게 노출되는지 보려면 프론트엔드 양식 사용자 정의을 참조하세요.
Integration.prop_accessor
또는 Integration.data_field
를 사용하는 다른 접근 방법이 있지만, 이는 통합의 이전 버전에서 볼 수 있습니다. 새로운 통합에는 이러한 접근 방식을 사용하면 안 됩니다.
유효성 정의
모든 필드에 대해 Rails 유효성을 정의해야 합니다.
유효성은 #activated?
메서드를 테스트하여 통합이 활성화된 경우에만 적용해야 합니다.
required:
속성을 가진 필드는 프론트엔드 전용이기 때문에 presence
에 대한 해당 유효성도 있어야 합니다.
예를 들어:
module Integrations
class FooBar < Integration
with_options if: :activated? do
validates :key, presence: true, format: { with: KEY_REGEX }
validates :bar, inclusion: [true, false]
end
field :key, required: true
field :bar, type: :checkbox
end
end
트리거 이벤트 정의
통합은 GitLab의 이벤트에 대한 응답으로 #execute
메서드를 호출하여 트리거됩니다. 이 메서드는 이벤트에 대한 세부 정보를 포함하는 페이로드 해시를 전달받습니다.
지원되는 이벤트는 웹훅 이벤트와 일부 중복이 있으며, 동일한 페이로드를 받습니다. 모델에서 클래스 메서드 Integration.supported_events
를 재정의하여 관심 있는 이벤트를 지정할 수 있습니다.
다음의 이벤트는 통합에서 지원됩니다:
이벤트 유형 | 기본값 | 값 | 트리거 |
---|---|---|---|
경고 이벤트 | alert
| 새로운 고유 경고가 기록될 때. | |
커밋 이벤트 | ✓ | commit
| 커밋이 생성되거나 업데이트될 때. |
배포 이벤트 | deployment
| 배포가 시작되거나 완료될 때. | |
이슈 이벤트 | ✓ | issue
| 이슈가 생성, 업데이트되거나 닫힐 때. |
기밀 이슈 이벤트 | ✓ | confidential_issue
| 기밀 이슈가 생성, 업데이트되거나 닫힐 때. |
작업 이벤트 | job
| ||
병합 요청 이벤트 | ✓ | merge_request
| 병합 요청이 생성, 업데이트되거나 병합될 때. |
댓글 이벤트 | comment
| 새로운 댓글이 추가될 때. | |
기밀 댓글 이벤트 | confidential_note
| 기밀 이슈에 대한 새로운 댓글이 추가될 때. | |
파이프라인 이벤트 | pipeline
| 파이프라인 상태가 변경될 때. | |
푸시 이벤트 | ✓ | push
| 저장소로 푸시가 이루어질 때. |
태그 푸시 이벤트 | ✓ | tag_push
| 새로운 태그가 저장소로 푸시될 때. |
취약점 이벤트 | vulnerability
| 새로운 고유 취약점이 기록될 때. Ultimate 전용. | |
위키 페이지 이벤트 | ✓ | wiki_page
| 위키 페이지가 생성되거나 업데이트될 때. |
이벤트 예시
이 예시는 commit
및 merge_request
이벤트에 응답하는 통합을 정의합니다.
module Integrations
class FooBar < Integration
def self.supported_events
%w[commit merge_request]
end
end
end
통합은 또한 이벤트에 응답하지 않고 다른 방식으로 사용자 정의 기능을 구현할 수도 있습니다.
module Integrations
class FooBar < Integration
def self.supported_events
[]
end
end
end
보안 향상 기능
채널 값 마스킹
Integrations::BaseChatNotification
에서 상속받은 통합은 채널 입력 필드의 값을 숨길 수 있습니다. 통합은 채널이 인증 토큰과 같은 민감한 정보를 포함할 때 해당 값들을 숨겨야 합니다.
기본적으로 #mask_configurable_channels?
는 false
를 반환합니다. 채널 값을 마스킹하려면 통합에 있는 #mask_configurable_channels?
메서드를 오버라이드하여 true
를 반환하도록 해야 합니다.
override :mask_configurable_channels?
def mask_configurable_channels?
true
end
구성 테스트 정의
선택적으로, 통합의 설정에 대한 구성 테스트를 정의할 수 있습니다. 테스트는 통합 양식의 테스트 버튼에서 실행되며 결과가 사용자에게 반환됩니다.
좋은 구성 테스트:
- 서비스에서 데이터를 변경하지 않습니다. 예를 들어 CI 빌드를 트리거하지 않아야 합니다. 메시지를 보내는 것은 괜찮습니다.
- 의미가 있고 가능한 한 철저해야 합니다.
위의 지침을 따르는 것이 불가능하다면 구성 테스트를 추가하지 않는 것을 고려해 보세요.
구성 테스트를 추가하려면, 통합 모델에 #test
메서드를 정의하면 됩니다.
이 메서드는 테스트 푸시 이벤트 페이로드인 data
를 받습니다.
테스트가 통과했는지를 나타내는 부울 값을 포함하는 success
키와
구성 테스트가 실패했을 때 사용자에게 반환되는 메시지를 포함하는 result
라는 키를 가진 해시를 반환해야 합니다.
예를 들어:
module Integrations
class FooBar < Integration
def test(data)
success = test_api_key(data)
{ success: success, result: 'API 키가 유효하지 않습니다' }
end
end
end
프론트엔드 양식 사용자 정의
프론트엔드 양식은 모델에 정의된 메타데이터를 기반으로 동적으로 생성됩니다.
기본적으로, 통합 양식은 다음을 제공합니다:
- 통합을 활성화하거나 비활성화하는 확인란.
-
Integration#configurable_events
에서 반환된 각 트리거 이벤트에 대한 확인란.
또한, 양식 상단에 도움말 텍스트를 추가하거나 Integration#help
를 오버라이드하거나
app/views/shared/integrations/$INTEGRATION_NAME/_help.html.haml
에서 템플릿을 제공하여 사용자 정의 속성을 양식에 추가할 수 있습니다.
양식에 사용자 지정 속성을 추가하려면 이러한 속성에 대한 메타데이터를 Integration#fields
에 정의하면 됩니다.
이 메서드는 각 필드에 대한 해시 배열을 반환해야 하며, 키는 다음과 같을 수 있습니다:
키 | 유형 | 필수 여부 | 기본값 | 설명 |
---|---|---|---|---|
type:
| symbol | true | :text
| 양식 필드의 유형입니다. :text , :textarea , :password , :checkbox , 또는 :select 일 수 있습니다.
|
name:
| string | true | 양식 필드의 속성 이름입니다. | |
required:
| boolean | false | false
| 양식 필드가 필수인지 선택 사항인지를 지정합니다. 그러나 여전히 존재 여부를 확인하기 위해 백엔드 유효성 검사가 필요합니다. |
title:
| string | false |
name: 의 대문자화된 값
| 양식 필드의 레이블입니다. |
placeholder:
| string | false | 양식 필드의 플레이스홀더입니다. | |
help:
| string | false | 양식 필드 아래에 표시되는 도움말 텍스트입니다. | |
api_only:
| boolean | false | false
| 양식 필드를 API를 통해서만 사용할 수 있고 프론트엔드 양식에서는 제외해야 하는지를 지정합니다. |
if:
| boolean 또는 람다 | false | true
| 필드가 사용 가능해야 하는지를 지정합니다. 값은 부울 또는 람다일 수 있습니다. |
type: :checkbox
에 대한 추가 키
키 | 유형 | 필수 여부 | 기본값 | 설명 |
---|---|---|---|---|
checkbox_label:
| string | false |
title: 의 값
| 확인란 옆에 표시되는 사용자 정의 레이블입니다. |
type: :select
에 대한 추가 키
키 | 유형 | 필수 여부 | 기본값 | 설명 |
---|---|---|---|---|
choices:
| 배열 | true |
[라벨, 값] 튜플의 중첩된 배열입니다.
|
type: :password
에 대한 추가 키
키 | 유형 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
non_empty_password_title:
| 문자열 | false |
title: 의 값
| 값이 이미 저장되어 있는 경우에 표시되는 대체 레이블입니다. |
non_empty_password_help:
| 문자열 | false |
help: 의 값
| 값이 이미 저장되어 있는 경우에 표시되는 대체 도움말 텍스트입니다. |
프론트엔드 폼 예시
이 예시에서는 필수 url
필드와 선택적인 username
및 password
필드를 정의합니다:
module Integrations
class FooBar < Integration
field :url,
type: :text,
title: s_('FooBarIntegration|Server URL'),
placeholder: 'https://example.com/',
required: true
field :username,
type: :text,
title: s_('FooBarIntegration|Username')
field :password,
type: 'password',
title: s_('FoobarIntegration|Password'),
non_empty_password_title: s_('FooBarIntegration|새 암호를 입력하세요')
end
end
REST API에서 통합 노출
통합을 REST API에서 노출하려면:
- 통합 클래스(
::Integrations::FooBar
)를API::Helpers::IntegrationsHelpers.integration_classes
에 추가합니다. - 노출되어야 하는 모든 속성을
API::Helpers::IntegrationsHelpers.integrations
에 추가합니다. -
doc/api/integrations.md
에 참조 문서를 업데이트하고, 통합에 대한 새 섹션을 추가하고 모든 속성을 문서화합니다.
또한 REST API 스타일 가이드를 참조할 수 있습니다.
민감한 필드는 API를 통해 노출되지 않습니다. 민감한 필드는 이름에 다음 중 하나를 포함하는 필드입니다:
key
passphrase
password
secret
token
webhook
통합 가능성
기본적으로 통합은 프로젝트, 그룹 및 인스턴스 수준에서 사용할 수 있습니다. 대부분의 통합은 프로젝트 컨텍스트에서만 작동하지만 그룹 및 인스턴스 수준에서도 구성할 수 있습니다.
일부 통합에는 프로젝트 수준에서만 사용할 수 있도록 하는 것이 유용할 수 있습니다.
이를 위해 통합은 Integration::INTEGRATION_NAMES
에서 제거되고,
대신 Integration::PROJECT_SPECIFIC_INTEGRATION_NAMES
에 추가해야 합니다.
새로운 통합을 개발할 때도 기능 플래그에 따라 사용 가능 여부를 제한하는 것이 좋습니다.
문서화
통합 폼에 링크를 포함하여 통합에 대한 도움말 텍스트를 제공할 수 있습니다. 프론트엔드 폼 사용자 정의에서 설명한 내용을 참조하세요. 도움 텍스트에 대한 자세한 내용은 사용성 가이드를 참조하세요.
더 자세한 문서에 대해서는 doc/user/project/integrations
에 페이지를 제공하고,
통합 개요에서 해당 페이지로 링크를 제공하세요.
일반적인 문서 작성 가이드도 참조할 수 있습니다.
테스트
테스트는 구성 테스트 정의와 혼동해서는 안 됩니다.
통합 모델에 대한 테스트를 spec/models/integrations
에 추가하고,
spec/factories/integrations.rb
에 예시 설정을 가진 팩토리를 추가하는 것이 종종 충분합니다.
각 통합은 일반화된 테스트의 일환으로도 테스트됩니다. 예를 들어, 모든 통합에 대해 설정 폼이 올바르게 렌더링되는지 검증하는 기능 스펙이 있습니다.
통합이 특정한 동작을 구현하는 경우, 특히 프론트엔드에서, 해당 동작을 추가로 테스트해야 합니다.
일반적인 테스트 가이드를 참조할 수도 있습니다.
국제화
모든 UI 문자열은 국제화 가이드라인을 따라 번역을 위해 준비되어야 합니다.
문자열은 통합 이름을 네임스페이스로 사용해야 합니다. 예를 들어, s_('FooBarIntegration|내 문자열')
.
통합 폐기 및 삭제
통합을 삭제하려면 먼저 통합을 폐기해야 합니다. 자세한 내용은 기능 폐기 가이드라인을 참조하세요.
통합 폐기
통합을 폐기하려면 삭제할 의도의 제품으로부터 3개의 마일스톤 전까지 반드시 폐기를 공지해야 합니다:
- 폐기 항목 추가.
- 통합 문서를 폐기된 것으로 표시합니다(../../development/documentation/versions.md#deprecate-a-page-or-topic).
- 선택사항. 새로운 프로젝트 수준 레코드가 생성되는 것을 막으려면
Project#disabled_integrations
에 통합을 추가하세요 (예시: 병합 요청).
통합 제거하기
통합을 안전하게 제거하려면 두 단계의 마일스톤을 거쳐 제거를 진행해야 합니다.
의도한 제거의 주요한 마일스톤(M.0)에서 통합을 비활성화하고 데이터베이스에서 레코드를 삭제하세요:
-
Integration::INTEGRATION_NAMES
에서 통합 제거합니다. - 통합 모델의
#execute
와#test
메서드(if defined)를 삭제하지만, 모델은 유지합니다. - PostgreSQL에서 통합 레코드를 삭제하기 위한 포스트 마이그레이션을 추가합니다(자세한 내용은 예시 병합 요청 참조).
- 통합 문서를 제거로 표시합니다.
- 통합 API 문서를 업데이트합니다.
다음 소규모 릴리스(M.1)에서:
- 통합 모델과 잔여 코드를 모두 제거합니다.
- 통합의 레이블(
~Integration::<name>
)을 가진 모든 이슈, 병합 요청 및 이픽을 닫습니다. -
gitlab-org
에서 통합 레이블(~Integration::<name>
)을 삭제합니다.
계속되는 마이그레이션 및 리팩터링
개발자들은 통합 팀이 통합 속성의 정의 방식을 통일하도록 진행 중임을 인지해야 합니다.
통합 예시
새로운 통합 추가에 대한 예시를 확인하려면 다음 이슈들을 참조할 수 있습니다:
- Datadog: 프로메테우스 통합과 유사한 메트릭 수집기.
- EWM/RTC: 외부 이슈 트래커.
- Webex Teams: 채팅 알림.
- ZenTao: Jira 통합과 유사한 사용자 정의 이슈 뷰를 가진 외부 이슈 트래커.