InfoGrab DocsInfoGrab Docs

Danger bot

요약

GitLab CI/CD 파이프라인에는 Danger를 사용해 테스트 대상 코드에 다양한 자동 검사를 수행하는 danger-review job이 있습니다. Danger는 다른 분석 도구와 마찬가지로 CI 환경에서 실행되는 gem입니다.

GitLab CI/CD 파이프라인에는 Danger를 사용해 테스트 대상 코드에 다양한 자동 검사를 수행하는 danger-review job이 있습니다.

Danger는 다른 분석 도구와 마찬가지로 CI 환경에서 실행되는 gem입니다. RuboCop 같은 도구와 다른 점은, 코드나 변경 사항의 속성을 검사하는 임의의 코드를 쉽게 작성할 수 있도록 설계되었다는 것입니다. 이를 위해 공통 헬퍼 모음과 환경에서 실제로 무엇이 변경되었는지에 관한 정보를 제공하고, 작성한 코드를 실행합니다.

Danger가 머지 리퀘스트의 무언가를 바꾸라고 요청한다면 그대로 변경하는 편이 좋습니다. Danger의 동작 방식을 알고 싶거나 기존 규칙을 변경하려는 경우에는 이 문서가 도움이 됩니다.

머지 리퀘스트에서의 Danger 코멘트#

Danger는 코멘트를 하나만 게시하고, 이후 danger-review 실행에서는 그 내용을 업데이트합니다. 그래서 대개 머지 리퀘스트의 첫 코멘트이거나 앞쪽 코멘트 중 하나입니다. 코멘트를 찾지 못했다면 머지 리퀘스트의 처음부터 살펴봅니다.

장점#

  • danger-review가 실행될 때마다 이메일 알림을 받지 않습니다.

단점#

  • Danger가 기존 코멘트를 업데이트한다는 점이 분명하게 드러나지 않으므로, 코멘트가 업데이트되었는지 직접 확인해야 합니다.
  • Danger 토큰을 교체하면 기존 코멘트를 업데이트할 수 없어 혼란과 불필요한 코멘트가 생깁니다.

Danger 로컬 실행#

현재 검사 중 일부는 다음 Rake 태스크로 로컬에서 실행할 수 있습니다:

bin/rake danger_local

동작 방식#

Danger는 시작할 때 프로젝트 루트에서 Dangerfile 을 읽습니다. GitLab의 Danger 코드는 헬퍼와 플러그인으로 나뉘어 있고 모두 danger/ 하위 디렉터리에 있으므로, GitLab의 Dangerfile은 이를 모두 로드하도록 지시하기만 합니다. 그러면 Danger가 머지 리퀘스트에 대해 각 플러그인을 실행하고 각 플러그인의 출력을 수집합니다. 플러그인은 알림, 경고, 오류를 출력할 수 있으며 모두 CI job 로그에 복사됩니다. 오류가 발생하면 CI job과 전체 파이프라인이 실패합니다.

머지 리퀘스트에서는 Danger가 출력을 MR 코멘트에도 복사해 가시성을 높입니다.

개발 가이드라인#

Danger 코드는 Ruby 코드이므로 일반적인 백엔드 가이드라인이 그대로 적용됩니다. 다만 특별히 강조할 몇 가지가 있습니다.

Danger 사용 시점#

Danger는 강력하고 유연한 도구이지만, 주어진 문제나 워크플로를 해결하는 데 항상 가장 적합한 방법은 아닙니다.

먼저 GitLab의 도그푸딩 원칙을 염두에 둡니다. Danger를 위해 작성하는 코드는 GitLab 전용이므로, 마주한 필요를 해결하는 기능을 구현하기에 가장 적합한 위치가 아닐 수 있습니다. 사용자와 고객, 그리고 Gitaly 같은 GitLab 자체 위성 프로젝트도 결국 비슷한 문제를 겪습니다. 모두가 그 결과물의 이점을 누리면서 같은 필요를 충족할 방법을 생각해 보고, 가능하다면 그 방법을 택합니다.

어떤 작업에 표준 도구(예: RuboCop)가 있다면 Danger로 호출하기보다 그 도구를 직접 사용하는 편이 좋습니다. Danger가 개입하지 않으면 그런 도구의 결과를 로컬에서 실행하고 디버깅하기가 더 쉬우며, Danger 고유 기능을 사용하는 경우가 아니라면 Danger 실행에 포함해서 얻는 이점이 없습니다.

Danger는 프로토타이핑과 빠른 반복에 적합합니다. 무엇을 만들지 아직 불분명하다면 Danger로 만든 해결책을 제품 영역에 관한 정보를 모으는 시험 실행으로 볼 수 있습니다. 이렇게 진행할 때는 해결하려는 문제와 프로토타이핑의 결과를 이슈나 에픽에 기록해 둡니다. 그러면 이후 GitLab 버전에서 그 필요를 제품의 일부로 다루는 데 도움이 됩니다.

구현 세부 사항#

각 작업은 독립된 기능 단위로 구현하고, danger 아래에 각자의 디렉터리를 두어 danger/<task-name>/Dangerfile 형태로 배치합니다.

각 작업은 서로 분리되어 있어야 하며 단독으로 동작할 수 있어야 합니다. 여러 작업에서 공유해야 하는 코드가 있다면 danger/plugins/...에 플러그인을 추가하고 필요한 각 작업에서 require 합니다. 단일 작업에만 해당하는 플러그인을 만들 수도 있으며, 해당 작업과 관련된 복잡한 로직을 두기에 자연스러운 자리입니다.

Danger 코드는 그저 Ruby 코드입니다. 코드베이스의 다른 Ruby 코드와 마찬가지로 코딩 표준을 따라야 하고 테스트가 필요합니다. 다만 Dangerfile은 직접 테스트할 수 없습니다. 그러므로 테스트 커버리지를 최대한 확보하려면 danger/의 코드 줄 수를 최소화합니다. 단순하지 않은 Dangerfile이라면 대부분 Danger가 제공하는 메서드에서 얻은 인자로 플러그인 코드를 호출하는 형태여야 합니다. 플러그인 코드 자체에는 단위 테스트가 있어야 합니다.

현재는 코드를 tooling/danger/...의 모듈에 두고, 대응하는 danger/plugins/... 파일에서 include 하는 방식을 사용합니다. 스펙은 spec/tooling/danger/...에 추가할 수 있습니다.

작성한 Dangerfile이 동작하는지 확인하려면 해당 파일이 포함된 브랜치를 GitLab에 푸시합니다. 이 방식은 새 작업을 개발하거나 기존 작업을 디버깅할 때 사이클 타임을 크게 늘리므로 상당히 번거롭습니다. 위 가이드라인을 따랐다면 대부분의 코드를 로컬 RSpec에서 실행할 수 있어 CI에서 반복해야 하는 횟수를 줄일 수 있습니다. 여기에 더해 머지 리퀘스트에서 .gitlab/ci/rails.gitlab-ci.yml 파일을 비우면 이 사이클을 어느 정도 단축할 수 있습니다. 다만 머지하기 전에 그 변경을 되돌리는 것을 잊지 않습니다.

Danger를 통한 레이블 추가#

Note

이 내용은 gitlab-dangerfiles gem을 사용하는 모든 프로젝트에 적용됩니다.

Danger는 레이블을 추가해 MR 위생을 개선하는 데 자주 사용됩니다. Dangerfile에서 API를 직접 호출하는 대신 helper.labels_to_add 배열에 레이블을 추가합니다(helper.labels_to_add << label 또는 helper.labels_to_add.concat(array_of_labels) 사용). 그러면 모든 규칙이 helper.labels_to_add에 추가할 기회를 가진 뒤, gitlab-dangerfiles가 API 호출 한 번으로 MR에 레이블을 추가합니다.

공유 규칙 및 플러그인#

구현한 규칙이나 플러그인이 다른 프로젝트에도 유용할 수 있다면 gitlab-dangerfiles 프로젝트에 업스트림으로 추가하는 방안을 고려합니다.

프로젝트에서 Danger 활성화#

기존의 다른 GitLab 프로젝트에서 Dangerfile을 활성화하려면 다음 단계를 완료합니다:

  1. Gemfile에 gitlab-dangerfiles를 추가합니다.

  2. 다음 내용으로 Dangerfile을 만듭니다:

    require "gitlab-dangerfiles"
    
    Gitlab::Dangerfiles.for_project(self, &:import_defaults)
    
  3. CI/CD 설정에 다음을 추가합니다:

    include:
      - component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.2.0
        rules:
          - if: $CI_SERVER_HOST == "gitlab.com"
    
  4. api 범위와 Developer 권한(레이블을 추가할 수 있도록)을 가지며 만료일이 없는(실제로는 1년) 프로젝트 액세스 토큰을 만듭니다.

  5. 이 토큰을 DANGER_GITLAB_API_TOKEN이라는 이름의 CI/CD 프로젝트 변수로 추가합니다.

머지 리퀘스트를 검토에 보내기 전에 ~"Danger bot" 레이블을 추가하는 것이 좋습니다.

현재 사용 사례#

지금까지 GitLab에서 Danger를 사용해 온 영역의 목록은 다음과 같습니다(전체는 아닙니다):

  • 코딩 스타일
  • 데이터베이스 검토
  • 문서 검토
  • 머지 리퀘스트 지표
  • 리뷰어 룰렛
  • 단일 코드베이스 작업

알려진 문제#

개인 포크에서 작업하면 Danger는 실행되지만 그 출력이 머지 리퀘스트 코멘트에 추가되지 않고 레이블도 적용되지 않습니다. 정본 프로젝트의 시크릿 변수가 포크에는 공유되지 않기 때문입니다.

가장 좋은 권장 방식은 Danger가 이미 구성되어 있는 커뮤니티 포크에서 작업하는 것입니다.

개인 포크에서 Danger 구성#

기여자는 다음 단계로 자신의 포크에 Danger를 구성할 수 있습니다:

  1. api 범위가 설정된 개인 API 토큰을 만듭니다(클립보드에 복사하는 것을 잊지 않습니다).
  2. 포크에서 이전 단계에서 복사한 토큰으로 DANGER_GITLAB_API_TOKEN이라는 프로젝트 CI/CD 변수를 추가합니다.
  3. job 로그에 노출되지 않도록 변수를 마스킹 처리합니다. 이 변수는 모든 브랜치에서 사용할 수 있어야 하므로 보호 처리할 수는 없습니다.

Danger bot

GitLab v19.4
원문 보기

요약

GitLab CI/CD 파이프라인에는 Danger를 사용해 테스트 대상 코드에 다양한 자동 검사를 수행하는 danger-review job이 있습니다. Danger는 다른 분석 도구와 마찬가지로 CI 환경에서 실행되는 gem입니다.

GitLab CI/CD 파이프라인에는 Danger를 사용해 테스트 대상 코드에 다양한 자동 검사를 수행하는 danger-review job이 있습니다.

Danger는 다른 분석 도구와 마찬가지로 CI 환경에서 실행되는 gem입니다. RuboCop 같은 도구와 다른 점은, 코드나 변경 사항의 속성을 검사하는 임의의 코드를 쉽게 작성할 수 있도록 설계되었다는 것입니다. 이를 위해 공통 헬퍼 모음과 환경에서 실제로 무엇이 변경되었는지에 관한 정보를 제공하고, 작성한 코드를 실행합니다.

Danger가 머지 리퀘스트의 무언가를 바꾸라고 요청한다면 그대로 변경하는 편이 좋습니다. Danger의 동작 방식을 알고 싶거나 기존 규칙을 변경하려는 경우에는 이 문서가 도움이 됩니다.

머지 리퀘스트에서의 Danger 코멘트#

Danger는 코멘트를 하나만 게시하고, 이후 danger-review 실행에서는 그 내용을 업데이트합니다. 그래서 대개 머지 리퀘스트의 첫 코멘트이거나 앞쪽 코멘트 중 하나입니다. 코멘트를 찾지 못했다면 머지 리퀘스트의 처음부터 살펴봅니다.

장점#

  • danger-review가 실행될 때마다 이메일 알림을 받지 않습니다.

단점#

  • Danger가 기존 코멘트를 업데이트한다는 점이 분명하게 드러나지 않으므로, 코멘트가 업데이트되었는지 직접 확인해야 합니다.
  • Danger 토큰을 교체하면 기존 코멘트를 업데이트할 수 없어 혼란과 불필요한 코멘트가 생깁니다.

Danger 로컬 실행#

현재 검사 중 일부는 다음 Rake 태스크로 로컬에서 실행할 수 있습니다:

bin/rake danger_local

동작 방식#

Danger는 시작할 때 프로젝트 루트에서 Dangerfile 을 읽습니다. GitLab의 Danger 코드는 헬퍼와 플러그인으로 나뉘어 있고 모두 danger/ 하위 디렉터리에 있으므로, GitLab의 Dangerfile은 이를 모두 로드하도록 지시하기만 합니다. 그러면 Danger가 머지 리퀘스트에 대해 각 플러그인을 실행하고 각 플러그인의 출력을 수집합니다. 플러그인은 알림, 경고, 오류를 출력할 수 있으며 모두 CI job 로그에 복사됩니다. 오류가 발생하면 CI job과 전체 파이프라인이 실패합니다.

머지 리퀘스트에서는 Danger가 출력을 MR 코멘트에도 복사해 가시성을 높입니다.

개발 가이드라인#

Danger 코드는 Ruby 코드이므로 일반적인 백엔드 가이드라인이 그대로 적용됩니다. 다만 특별히 강조할 몇 가지가 있습니다.

Danger 사용 시점#

Danger는 강력하고 유연한 도구이지만, 주어진 문제나 워크플로를 해결하는 데 항상 가장 적합한 방법은 아닙니다.

먼저 GitLab의 도그푸딩 원칙을 염두에 둡니다. Danger를 위해 작성하는 코드는 GitLab 전용이므로, 마주한 필요를 해결하는 기능을 구현하기에 가장 적합한 위치가 아닐 수 있습니다. 사용자와 고객, 그리고 Gitaly 같은 GitLab 자체 위성 프로젝트도 결국 비슷한 문제를 겪습니다. 모두가 그 결과물의 이점을 누리면서 같은 필요를 충족할 방법을 생각해 보고, 가능하다면 그 방법을 택합니다.

어떤 작업에 표준 도구(예: RuboCop)가 있다면 Danger로 호출하기보다 그 도구를 직접 사용하는 편이 좋습니다. Danger가 개입하지 않으면 그런 도구의 결과를 로컬에서 실행하고 디버깅하기가 더 쉬우며, Danger 고유 기능을 사용하는 경우가 아니라면 Danger 실행에 포함해서 얻는 이점이 없습니다.

Danger는 프로토타이핑과 빠른 반복에 적합합니다. 무엇을 만들지 아직 불분명하다면 Danger로 만든 해결책을 제품 영역에 관한 정보를 모으는 시험 실행으로 볼 수 있습니다. 이렇게 진행할 때는 해결하려는 문제와 프로토타이핑의 결과를 이슈나 에픽에 기록해 둡니다. 그러면 이후 GitLab 버전에서 그 필요를 제품의 일부로 다루는 데 도움이 됩니다.

구현 세부 사항#

각 작업은 독립된 기능 단위로 구현하고, danger 아래에 각자의 디렉터리를 두어 danger/<task-name>/Dangerfile 형태로 배치합니다.

각 작업은 서로 분리되어 있어야 하며 단독으로 동작할 수 있어야 합니다. 여러 작업에서 공유해야 하는 코드가 있다면 danger/plugins/...에 플러그인을 추가하고 필요한 각 작업에서 require 합니다. 단일 작업에만 해당하는 플러그인을 만들 수도 있으며, 해당 작업과 관련된 복잡한 로직을 두기에 자연스러운 자리입니다.

Danger 코드는 그저 Ruby 코드입니다. 코드베이스의 다른 Ruby 코드와 마찬가지로 코딩 표준을 따라야 하고 테스트가 필요합니다. 다만 Dangerfile은 직접 테스트할 수 없습니다. 그러므로 테스트 커버리지를 최대한 확보하려면 danger/의 코드 줄 수를 최소화합니다. 단순하지 않은 Dangerfile이라면 대부분 Danger가 제공하는 메서드에서 얻은 인자로 플러그인 코드를 호출하는 형태여야 합니다. 플러그인 코드 자체에는 단위 테스트가 있어야 합니다.

현재는 코드를 tooling/danger/...의 모듈에 두고, 대응하는 danger/plugins/... 파일에서 include 하는 방식을 사용합니다. 스펙은 spec/tooling/danger/...에 추가할 수 있습니다.

작성한 Dangerfile이 동작하는지 확인하려면 해당 파일이 포함된 브랜치를 GitLab에 푸시합니다. 이 방식은 새 작업을 개발하거나 기존 작업을 디버깅할 때 사이클 타임을 크게 늘리므로 상당히 번거롭습니다. 위 가이드라인을 따랐다면 대부분의 코드를 로컬 RSpec에서 실행할 수 있어 CI에서 반복해야 하는 횟수를 줄일 수 있습니다. 여기에 더해 머지 리퀘스트에서 .gitlab/ci/rails.gitlab-ci.yml 파일을 비우면 이 사이클을 어느 정도 단축할 수 있습니다. 다만 머지하기 전에 그 변경을 되돌리는 것을 잊지 않습니다.

Danger를 통한 레이블 추가#

Note

이 내용은 gitlab-dangerfiles gem을 사용하는 모든 프로젝트에 적용됩니다.

Danger는 레이블을 추가해 MR 위생을 개선하는 데 자주 사용됩니다. Dangerfile에서 API를 직접 호출하는 대신 helper.labels_to_add 배열에 레이블을 추가합니다(helper.labels_to_add << label 또는 helper.labels_to_add.concat(array_of_labels) 사용). 그러면 모든 규칙이 helper.labels_to_add에 추가할 기회를 가진 뒤, gitlab-dangerfiles가 API 호출 한 번으로 MR에 레이블을 추가합니다.

공유 규칙 및 플러그인#

구현한 규칙이나 플러그인이 다른 프로젝트에도 유용할 수 있다면 gitlab-dangerfiles 프로젝트에 업스트림으로 추가하는 방안을 고려합니다.

프로젝트에서 Danger 활성화#

기존의 다른 GitLab 프로젝트에서 Dangerfile을 활성화하려면 다음 단계를 완료합니다:

  1. Gemfile에 gitlab-dangerfiles를 추가합니다.

  2. 다음 내용으로 Dangerfile을 만듭니다:

    require "gitlab-dangerfiles"
    
    Gitlab::Dangerfiles.for_project(self, &:import_defaults)
    
  3. CI/CD 설정에 다음을 추가합니다:

    include:
      - component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.2.0
        rules:
          - if: $CI_SERVER_HOST == "gitlab.com"
    
  4. api 범위와 Developer 권한(레이블을 추가할 수 있도록)을 가지며 만료일이 없는(실제로는 1년) 프로젝트 액세스 토큰을 만듭니다.

  5. 이 토큰을 DANGER_GITLAB_API_TOKEN이라는 이름의 CI/CD 프로젝트 변수로 추가합니다.

머지 리퀘스트를 검토에 보내기 전에 ~"Danger bot" 레이블을 추가하는 것이 좋습니다.

현재 사용 사례#

지금까지 GitLab에서 Danger를 사용해 온 영역의 목록은 다음과 같습니다(전체는 아닙니다):

  • 코딩 스타일
  • 데이터베이스 검토
  • 문서 검토
  • 머지 리퀘스트 지표
  • 리뷰어 룰렛
  • 단일 코드베이스 작업

알려진 문제#

개인 포크에서 작업하면 Danger는 실행되지만 그 출력이 머지 리퀘스트 코멘트에 추가되지 않고 레이블도 적용되지 않습니다. 정본 프로젝트의 시크릿 변수가 포크에는 공유되지 않기 때문입니다.

가장 좋은 권장 방식은 Danger가 이미 구성되어 있는 커뮤니티 포크에서 작업하는 것입니다.

개인 포크에서 Danger 구성#

기여자는 다음 단계로 자신의 포크에 Danger를 구성할 수 있습니다:

  1. api 범위가 설정된 개인 API 토큰을 만듭니다(클립보드에 복사하는 것을 잊지 않습니다).
  2. 포크에서 이전 단계에서 복사한 토큰으로 DANGER_GITLAB_API_TOKEN이라는 프로젝트 CI/CD 변수를 추가합니다.
  3. job 로그에 노출되지 않도록 변수를 마스킹 처리합니다. 이 변수는 모든 브랜치에서 사용할 수 있어야 하므로 보호 처리할 수는 없습니다.