GitHub Code Quality 실전 가이드 — CodeQL·AI로 유지보수성을 CI에서 잡기

이번 포스팅에서는 GitHub Code Quality를 실무 관점에서 정리하고자 한다. AI 코딩 도구가 코드를 쏟아내는 속도는 빨라졌는데, 그 코드를 나중에 읽고 고치는 부담은 고스란히 팀에 남는다. 보안 취약점은 이미 여러 스캐너가 잡아 주지만, “이 코드가 6개월 뒤에도 손대기 편한가” 하는 유지보수성은 사람 눈에만 의존해 왔다. GitHub Code Quality는 바로 그 빈칸을 겨냥해 2026년 7월 20일 정식 출시(GA)됐다. CodeQL의 결정적 분석과 AI 기반 탐지를 묶어, Pull Request가 병합되기 전에 유지보수성·신뢰성 문제를 잡고 Copilot Autofix로 수정안까지 제안한다. 이 글에서는 이 도구가 정확히 무엇을 하는지, PR에서 어떻게 보이는지, 품질 게이트를 어떻게 거는지, 그리고 켜기 전에 반드시 따져야 할 비용 구조까지 공식 자료를 근거로 짚는다.

GitHub Code Quality가 뭐길래

GitHub Code Quality는 Pull Request의 코드에서 유지보수성(maintainability)과 신뢰성(reliability) 문제를 자동으로 찾아 주는 GitHub의 코드 품질 제품이다. 2026년 7월 20일 GitHub Enterprise Cloud와 GitHub Team에서 정식 출시됐고(Enterprise Server는 아직 미지원), 보안 취약점을 보던 기존 Code Scanning과 달리 “읽기 어렵고 고치기 힘든 코드”에 초점을 맞춘다.

여기서 방점은 보안이 아니라 품질이다. 그동안 GitHub의 CodeQL은 주로 SQL 인젝션 같은 보안 취약점을 잡는 데 쓰였다. Code Quality는 같은 CodeQL 엔진에 유지보수성·신뢰성 규칙을 얹고 AI 탐지를 더해, “당장 터지진 않지만 팀을 서서히 갉아먹는” 문제를 겨눈다. 구체적으로는 중복 코드, 과도하게 복잡한 로직, 미사용 변수, 코딩 관례 위반 같은 유지보수성 문제와, 코드의 안정성·신뢰성을 해칠 수 있는 패턴을 지적한다. 이미 공개 프리뷰 기간(2025년 10월 시작)에 1만 개 이상의 기업이 써 봤을 만큼 관심이 큰 영역이다.

이 관점은 AI가 짠 코드가 늘수록 더 중요해진다. 사람이 리뷰로 잡던 것을 CI 단계에서 기계가 먼저 걸러 주는 흐름은, 이전에 정리한 AI 코드 리뷰 자동화의 연장선에 있다. 다만 그쪽이 LLM 리뷰봇을 PR에 붙이는 이야기였다면, Code Quality는 GitHub이 CodeQL과 AI를 묶어 정식 제품으로 내놓은 것이라는 차이가 있다.

왜 하필 지금 나왔나 — AI가 쏟아낸 코드의 유지보수 청구서

지금 이 제품이 나온 이유는 명확하다. AI가 코드를 쏟아내는 속도는 빨라졌는데, 그 코드를 나중에 읽고 고치는 부담은 팀에 그대로 남기 때문이다. Copilot으로 코드는 빠르게 늘지만, 품질 검증은 여전히 리뷰어 몇 명의 눈에 병목이 걸린다. GitHub은 이 간극을 CI에서 메우려 한다.

전통적으로 코드 품질 관리는 두 갈래였다. 하나는 보안 스캐너(SAST)로 취약점을 잡는 것, 다른 하나는 SonarQube 같은 도구로 코드 스멜과 복잡도를 재는 것이다. 그런데 AI 생성 코드는 문법적으로 멀쩡하고 테스트도 통과하지만, 맥락 없이 중복되거나 불필요하게 복잡한 경우가 잦다. 이런 코드는 보안 스캐너에 걸리지 않고, 리뷰어도 “돌아가긴 하니까” 하고 넘기기 쉽다. 결과적으로 유지보수 부채가 조용히 쌓인다. GitHub Code Quality는 이 부채를 병합 이전 시점에, PR 단위로 가시화하는 것을 목표로 한다. 1만 개 이상 기업이 프리뷰에서 이미 “유지보수성·신뢰성 문제 탐지, 품질 게이트, 커버리지 추적”에 써 봤다는 사실이, 이 수요가 실재한다는 방증이다.

두 개의 눈으로 코드를 본다 — CodeQL과 AI 탐지

GitHub Code Quality는 코드를 두 가지 눈으로 본다. 하나는 CodeQL의 결정적(deterministic) 분석, 다른 하나는 AI 기반 탐지다. CodeQL은 정해진 규칙으로 알려진 안티패턴을 정확히 잡고, AI는 규칙에 없는 문제나 CodeQL이 아직 지원하지 않는 언어까지 최근 변경된 코드를 훑어 보완한다. 규칙의 정밀함과 AI의 넓은 커버리지를 한 번에 가져가는 구성이다.

CodeQL 규칙 기반 분석이 공식적으로 지원하는 언어는 C#, Go, Java, JavaScript, Python, Ruby, TypeScript 일곱 가지다. 이 언어들에서는 결정적 규칙이 “이건 알려진 유지보수성 문제”라고 재현 가능하게 짚어 준다. 반면 AI 기반 분석은 여기에 얽매이지 않고, 저장소에서 최근 바뀐 코드를 대상으로 규칙 바깥의 문제나 CodeQL이 아직 커버하지 않는 언어까지 살핀다. 즉 결정적 분석이 놓치는 빈틈을 AI가 메우는 이중 구조다.

동작하는 자리는 두 곳이다. Pull Request에서는 변경된 코드를 대상으로 병합 전에 문제를 잡고, 기본 브랜치(default branch)에서는 이미 쌓여 있는 기존 품질 부채를 스캔해 드러낸다. 기본 브랜치 스캔에서 발견된 문제는 직접 고치거나, Copilot 클라우드 에이전트에게 수정을 맡길 수도 있다. 사람이 짠 코드든 AI가 짠 코드든, 병합 이전과 이후를 모두 지켜보는 셈이다. Java가 지원 언어에 포함되므로, Testcontainers 통합 테스트를 돌리는 Spring 프로젝트라면 품질 신호와 커버리지를 한 파이프라인에서 함께 볼 수 있다.

PR에서 실제로 이렇게 보인다 — 인라인 코멘트와 Copilot Autofix

실무에서 개발자가 마주하는 접점은 Pull Request다. 발견한 문제는 PR에 인라인 코멘트로 붙고, 그 옆에 Copilot Autofix가 원클릭으로 적용할 수정안을 얹는다. 리뷰어가 별도 대시보드를 열지 않아도, 코드 라인 옆에서 바로 “여기가 문제이고 이렇게 고치면 된다”를 보게 된다.

동작 순서는 이렇다. PR을 올리면 변경된 파일에 대해 CodeQL 결정적 분석과 AI 탐지가 돌고, 그 결과가 github-code-quality[bot] 이름으로 “Files changed” 탭의 해당 코드 라인에 인라인 코멘트로 붙는다. 각 지적에는 심각도 라벨이 함께 달린다. Error는 버그·장애나 큰 유지보수 위험으로 이어질 가능성이 높은 고심각도, Warning은 품질·신뢰성에 영향은 있으나 당장 치명적이진 않은 중간, Note는 사소한 개선 제안이다. 그래서 리뷰어는 라벨만 보고 “Error부터 처리하고 Note는 나중에” 식으로 우선순위를 잡을 수 있다.

각 코멘트에는 Copilot Autofix가 만든 수정 제안이 딸려 오는데, 코멘트의 “Commit suggestion” 버튼을 누르면 그 패치가 곧바로 PR 브랜치에 커밋된다. 여러 지적을 한꺼번에 맡기고 싶다면 코멘트에서 @copilot을 멘션해 클라우드 에이전트가 수정 커밋을 밀어 넣게 할 수도 있다. 여기에 테스트 커버리지 정보도 함께 표시돼, 이번 변경이 커버리지를 유지하는지 떨어뜨리는지를 같은 화면에서 확인한다. 커버리지가 떨어지는 PR을 눈으로 놓치던 문제가 줄어드는 것이다.

이 경험이 중요한 이유는 마찰이 낮기 때문이다. 사람 리뷰어가 유지보수성 지적을 일일이 글로 남기던 수고를, 기계가 인라인 제안으로 대신한다. 리뷰어는 기계가 짚어 준 것을 승인하거나 반려하는 판단에 집중하면 된다. 커버리지 리포트는 MockMvc 컨트롤러 테스트 같은 테스트가 실제로 얼마나 코드를 덮는지를 PR마다 정량으로 보여주므로, “테스트 짰다”는 말이 숫자로 검증된다.

새 빚이 쌓이기 전에 막기 — 품질 게이트와 커버리지

발견만으로는 부족하다. 룰셋(rulesets) 기반 품질 게이트를 걸면 기준 미달 PR은 아예 병합되지 못한다. 유지보수성·신뢰성 기준이나 커버리지 임계값을 정해 두면, 그에 못 미치는 변경은 차단돼 새로운 품질 부채가 메인 브랜치로 흘러드는 걸 입구에서 막는다.

여기서 실무적으로 중요한 장치가 evaluate 모드다. 품질 게이트를 처음부터 “차단”으로 걸면 기존 코드가 무더기로 걸려 팀이 반발하기 쉽다. evaluate 모드는 게이트를 강제하지 않고 결과만 보여주는 관찰 단계라, 기준을 실제로 켜기 전에 “우리 저장소에서 몇 건이나 걸리나”를 먼저 가늠하고 점진적으로 도입할 수 있다. 커버리지 임계값 같은 규칙을 조직 전체 룰셋으로 걸되, 처음엔 evaluate로 두고 팀이 적응하면 차단으로 승격하는 식이다.

커버리지 지표는 별도로 만들어 내는 게 아니라, 이미 있는 테스트 리포트를 읽어 온다. Code Quality가 인식하는 형식은 Cobertura XML이다. 예를 들어 Python이라면 아래처럼 표준 형식으로 리포트를 뽑는다.

# pytest 커버리지를 Cobertura XML로 출력 (Code Quality가 읽는 형식)
pytest --cov=myapp --cov-report=xml
# → coverage.xml 생성, 이후 CI에서 리포트 위치를 Code Quality가 수집
ShellScript

위 명령은 pytest-cov로 테스트를 돌리면서 커버리지를 Cobertura XML(coverage.xml)로 내보낸다. Code Quality는 이 표준 리포트를 읽어 PR과 대시보드에 커버리지를 렌더링한다. 주의할 점은 형식이 Cobertura여야 한다는 것이다. Java의 JaCoCo처럼 자체 XML을 쓰는 도구라면 Cobertura 형식으로 변환하는 단계를 CI에 한 줄 더 넣어야 인식된다.

리포트가 실제로 어떻게 생겼는지 궁금할 테니, 작은 샘플을 짜서 직접 돌려 봤다. 함수 셋을 담은 mymath.py를 두고, 그중 둘만 테스트해서 커버리지가 어떻게 찍히는지 본다.

# mymath.py
def add(a, b):
    return a + b

def divide(a, b):          # 이 함수는 일부러 테스트하지 않는다
    if b == 0:
        raise ValueError("cannot divide by zero")
    return a / b

def is_even(n):
    return n % 2 == 0
Python

mymath.py에는 add·divide·is_even 세 함수가 들어 있다. 이 중 divide()를 테스트에서 빼면 그 본문(5-7행)이 어느 테스트에서도 실행되지 않아, 커버리지 리포트에서 미커버로 잡히는 걸 확인할 수 있다. 뒤에서 이 5-7행이 그대로 리포트에 찍히는지 대조해 보면 된다.

# test_mymath.py — add와 is_even만 검증한다
from mymath import add, is_even

def test_add():
    assert add(2, 3) == 5

def test_is_even():
    assert is_even(4) is True
    assert is_even(3) is False
Python

테스트는 addis_even만 호출하고 divide()는 부르지 않는다. 이 상태에서 pytest --cov=mymath --cov-report=xml로 돌리면, 실행 결과와 함께 Cobertura 형식의 coverage.xml이 생성된다. 그 결과가 아래다.

왼쪽 pytest --cov 실행 결과를 보면, 8개 구문 중 3개가 빠져 커버리지가 62%로 나오고 테스트되지 않은 divide()의 5-7행이 “Missing”으로 찍힌다. 오른쪽이 그때 생성된 coverage.xml이다. 루트 요소에 line-rate="0.625"가 박히고 각 줄이 <line number="5" hits="0"/>처럼 커버 여부로 기록되며, coverage-04.dtd 기반이라는 주석이 이게 Cobertura 스키마임을 말해 준다. GitHub Code Quality는 바로 이 파일을 읽어 PR과 대시보드의 커버리지 숫자를 만든다. 우리가 뭔가를 따로 계산해 넘기는 게 아니라, 평소 CI에서 뽑던 이 표준 리포트를 그대로 넘기면 된다는 뜻이다.

켜기 전에 계산기부터 — 비용 구조 뜯어보기

정식 출시와 함께 과금도 시작됐다. 켜기 전에 비용부터 계산해야 한다. 기본은 활성 커밋터(active committer) 1인당 월 $10이고, 여기에 AI 기능 사용량과 CodeQL 실행에 드는 GitHub Actions 컴퓨트 비용이 따로 붙는다. 프리뷰 때 무료로 쓰던 팀이라면, 이제 미터가 돌기 시작했다는 걸 잊으면 안 된다.

과금 구조를 뜯어보면 세 갈래다. 첫째, 기본요금은 활성 커밋터당 월 $10이다. 여기서 “활성”의 정의를 놓치기 쉽다. Code Quality가 켜진 저장소에 최근 90일 안에 커밋을 푸시한 사람만 활성 커밋터로 집계된다. 둘째, AI 기반 탐지는 사용량만큼 별도 청구된다. 다만 오토픽스는 결이 다르니 오해하지 말자. 인라인 제안을 “Commit suggestion”으로 적용하는 건 AI 크레딧도 Copilot 라이선스도 들지 않는 무료 동작이고, @copilot 멘션으로 클라우드 에이전트에게 여러 수정을 한꺼번에 위임할 때만 Copilot 라이선스와 크레딧을 소비한다. 셋째, 결정적 CodeQL 분석은 GitHub Actions 위에서 돌기 때문에 Actions 실행 시간(분)을 소비한다. 눈에 보이는 $10 뒤에 AI 사용량과 Actions 분이라는 숨은 두 축이 더 있는 것이다.

그래서 도입 판단은 단순히 “1인당 $10″으로 끝나지 않는다. 커밋터가 많은 대형 조직일수록 기본요금이 커지고, AI Autofix를 적극적으로 쓸수록 사용량 요금이 늘며, CodeQL을 자주 돌릴수록 Actions 비용이 붙는다. 앞서 말한 evaluate 모드로 먼저 규모를 재 보고, 어떤 저장소부터 켤지 좁혀 들어가는 접근이 비용 관점에서도 합리적이다. 기존 프리뷰 사용자는 마이그레이션 없이 그대로 유지되지만, 대신 과금이 자동으로 활성화된다는 점을 놓치면 안 된다.

그래서 어떻게 켜나 — 조직·저장소 단위 활성화

켜는 방법은 두 층위로 나뉜다. 조직 관리자가 여러 저장소에 한 번에 켜는 방식과, 저장소별로 하나씩 켜는 방식이다. 어느 쪽이든 전제가 하나 있다. Code Quality는 CodeQL 분석을 GitHub Actions 위에서 돌리므로, 대상 저장소에 Actions가 켜져 있어야 하고 엔터프라이즈 소유자가 먼저 조직에서 Code Quality 사용을 허용해 둬야 한다.

조직 단위로 켜는 순서는 이렇다. 조직 메인 페이지에서 Settings로 들어가(탭이 안 보이면 More 드롭다운 안에 있다), 왼쪽 사이드바의 “Security” 아래 “Code quality”를 연다. “Repository access” 드롭다운에서 적용 범위를 고르는데, 전체(All repositories)·선택한 저장소(Selected repositories)·필터 조건(Matching a filter) 셋 중 하나다. 처음 도입이라면 몇 개 저장소만 골라 파일럿으로 시작하는 편이 안전하다. 관리자가 임의로 끄지 못하게 하려면 “Enforce access”를 켠 뒤, 영향받는 저장소와 예상 비용이 표시되는 확인 대화상자를 검토하고 Confirm을 누른다. 대규모 조직은 전체 반영에 몇 분이 걸릴 수 있다.

저장소 하나만 켜려면 그 저장소의 Settings → 사이드바 “Security” → “Code quality”에서 “Enable code quality”를 누른다. 이 화면에서 언어별로 CodeQL 분석을 끄거나(체크 해제), 커스텀 라벨을 단 러너를 쓰도록 “Runner type”을 바꿀 수 있고, “Save changes”로 마무리한다. 조직 전체에 강제로 밀기 전에 대표 저장소 하나에서 이렇게 켜서, 어떤 지적이 얼마나 나오는지 evaluate 모드로 먼저 재 보는 흐름을 권한다. 참고로 저장소 활성화와 findings 조회는 Repository Enablement API로도 다룰 수 있어, 수백 개 저장소에 정책을 스크립트로 일괄 적용하기 좋다.

SonarQube랑 뭐가 다른가 — 도구 비교

가장 많이 나오는 질문이 기존 도구와의 차이다. Code Quality는 GitHub에 완전히 내장돼 별도 서버 없이 PR에 바로 붙고, CodeQL 규칙에 AI 탐지를 더해 쓴다. 이 두 가지가 다른 도구와 갈리는 지점이다. SonarQube가 오래 다듬어 온 품질 규칙 자산과 셀프호스팅 유연성을 무기로 삼는다면, Code Quality는 GitHub 워크플로와의 밀착, 그리고 AI 결합에 무게를 둔다.

아래 표는 유지보수성 관점에서 세 접근을 정리한 것이다.

구분GitHub Code QualitySonarQube순수 CodeQL(Code Scanning)
주 목적유지보수성·신뢰성코드 스멜·복잡도·버그보안 취약점
분석 방식CodeQL 규칙 + AI 탐지규칙 기반 정적 분석CodeQL 규칙(보안)
실행 위치GitHub 내장(PR)셀프호스팅/클라우드GitHub 내장(PR)
자동 수정Copilot Autofix 원클릭제한적Copilot Autofix(보안)
지원 언어(규칙)7종 + AI 확장30여 종CodeQL 언어
커버리지Cobertura XML 연동자체 연동해당 없음
비용활성 커밋터당 $10 + 사용량에디션별 라이선스플랜 포함

표로 보면 선택 기준이 분명해진다. 이미 GitHub에서 개발하고 CodeQL 보안 스캐닝을 쓰고 있다면, 같은 화면에 유지보수성·커버리지를 얹는 Code Quality가 자연스럽다. 반대로 다양한 언어를 셀프호스팅 환경에서 관리하거나 이미 SonarQube 규칙을 정교하게 다듬어 둔 팀이라면 갈아탈 이유가 크지 않을 수 있다. 도구 선택 자체를 넓게 보고 싶다면 AI 코딩 도구 비교도 함께 참고할 만하다.

FAQ

GitHub Code Quality는 무료인가요?

아니다. 2026년 7월 20일 GA와 함께 유료로 전환됐다. 기본요금은 활성 커밋터 1인당 월 $10이며, 여기서 활성 커밋터는 Code Quality가 켜진 저장소에 최근 90일 안에 커밋을 푸시한 사람을 뜻한다. AI 기반 탐지는 사용량으로, 결정적 CodeQL 분석은 GitHub Actions 컴퓨트로 각각 별도 청구된다. 다만 인라인 제안을 “Commit suggestion”으로 적용하는 오토픽스 자체는 AI 크레딧이나 Copilot 라이선스 없이 무료이고, @copilot으로 여러 수정을 한꺼번에 위임할 때만 크레딧이 든다. 공개 프리뷰 기간에 무료로 쓰던 팀도 GA 이후에는 과금이 활성화된다.

어떤 언어를 지원하나요?

CodeQL 규칙 기반 분석은 C#, Go, Java, JavaScript, Python, Ruby, TypeScript 일곱 언어를 공식 지원한다. 이 언어들에서는 결정적 규칙으로 유지보수성·신뢰성 문제를 재현 가능하게 잡는다. 그 밖의 언어는 AI 기반 분석이 최근 변경된 코드를 대상으로 커버하므로, CodeQL이 아직 지원하지 않는 언어에서도 일부 문제 탐지가 가능하다.

기존 CodeQL 보안 스캐닝과 뭐가 다른가요?

목적이 다르다. 기존 CodeQL Code Scanning은 SQL 인젝션 같은 보안 취약점을 찾는 반면, Code Quality는 같은 CodeQL 엔진에 유지보수성·신뢰성 규칙을 얹고 AI 탐지를 더해 “고치기 어렵고 깨지기 쉬운 코드”를 대상으로 한다. 보안이 아니라 품질을 본다는 점, 그리고 커버리지와 품질 게이트를 함께 제공한다는 점이 핵심 차이다.

품질 게이트를 바로 강제해도 되나요?

권장하지 않는다. 처음부터 차단으로 걸면 기존 코드가 대량으로 걸려 개발 흐름이 막힌다. evaluate 모드로 먼저 게이트를 관찰 전용으로 돌려 우리 저장소에서 몇 건이 걸리는지 규모를 파악하고, 팀이 적응한 뒤 차단으로 승격하는 점진적 도입이 안전하다. 커버리지 임계값도 같은 방식으로 서서히 올리는 편이 반발을 줄인다.

GitHub Enterprise Server에서도 쓸 수 있나요?

GA 시점 기준으로는 쓸 수 없다. GitHub Code Quality는 GitHub Enterprise Cloud와 GitHub Team에서만 정식 제공되며, 자체 호스팅형인 GitHub Enterprise Server는 출시 시점에 지원 대상이 아니다. 온프레미스 환경이 필수인 조직이라면 당장은 SonarQube 같은 셀프호스팅 대안을 유지하면서 로드맵을 지켜보는 편이 현실적이다.

마치며

지금까지 GitHub Code Quality를 실무 관점에서 짚어 보았다. 개인적으로 이 제품에서 가장 눈여겨본 건 화려한 AI 기능이 아니라 evaluate 모드였다. 새 도구를 팀에 들일 때 가장 무서운 건 “어제까지 잘 머지되던 PR이 오늘부터 죄다 빨갛게 막히는” 상황인데, 관찰 모드로 먼저 규모를 재고 천천히 조이는 길을 공식으로 열어 둔 점이 현실적이라고 느꼈다. 도구가 좋아도 도입 곡선이 가파르면 팀이 등을 돌리기 마련이다.

도입을 고민한다면 기능표보다 비용 계산기를 먼저 열어 보길 권한다. 활성 커밋터당 $10은 명료해 보이지만, AI 사용량과 Actions 분이라는 숨은 축이 조직 규모에 따라 크게 불어난다. 커밋터가 많은 조직일수록 “어느 저장소부터, 어떤 규칙으로” 좁혀 시작하는 전략이 중요하다. AI가 코드를 쏟아내는 흐름은 되돌리기 어렵고, 그 코드의 유지보수성을 CI에서 자동으로 지키려는 시도 자체는 분명 옳은 방향이다. 다만 좋은 방향과 우리 팀에 맞는 속도는 다른 문제라는 걸, evaluate 모드가 조용히 일깨워 준다.