Specnote
문서 홈으로
사용 가이드
Markdown 원문

CI 자동 검증 연결하기

코드를 올릴 때마다 검증이 저절로 돌게 만드는 방법이에요. AI에게 붙여넣기 한 번이면 연결이 끝나고, 결과는 GitHub와 테스트 실행 탭에 함께 남아요. 직접 연결하는 법과 자주 묻는 질문까지 정리했어요.

이게 뭔가요

배포하기 전에 자동으로 리허설을 한 번 돌리는 것이라고 생각하면 쉬워요. 지금까지는 검증을 사람이 직접 눌러서 돌렸어요. CI 연동을 해 두면, 코드가 바뀔 때마다(예: 새 코드를 올리거나 검토 요청을 열 때) Specnote가 알아서 테스트를 한 번 검증해요.

여기서 CI란 코드를 올릴 때마다 정해진 검사를 자동으로 돌려 주는 장치예요. GitHub를 쓰신다면 GitHub Actions가 그 역할을 해요. Specnote는 그 자동 검사 한 자리에 "테스트 검증"을 끼워 넣는 거예요.

한 가지 안심하셔도 되는 점이 있어요. 검증을 실제로 돌리는 건 Specnote 서버예요. 여러분의 코드가 도는 자리(CI)에서는 브라우저를 띄우거나 무거운 일을 하지 않아요. CI는 그저 "지금 검증해 줘" 하고 방아쇠만 당기고, 결과가 나올 때까지 기다렸다가 받아 오는 역할만 해요. 그래서 여러분 쪽 설정은 가볍고, 운영 비밀번호나 키가 넘어갈 일도 없어요.

검증이 끝나면 결과는 두 곳에 남아요.

  • 검토 요청(PR) 화면 — 통과·실패 요약이 한국어로 붙어서, 코드를 합치기 전에 무엇이 깨졌는지 바로 보여요.
  • 테스트 실행 탭 — 이번 검증이 하나의 실행 묶음으로 쌓여, 나중에 되짚어 볼 수 있어요.

Specnote 서버가 여는 것은 공개된 사이트 주소여야 해요. 내 PC에서만 도는 localhost 주소는 서버가 접속할 수 없어 검증할 수 없습니다. 배포·미리보기 주소가 없다면 아래 "로컬에서만 앱이 도는데도 되나요?"를 봐 주세요.

어떤 테스트를 CI에 넣을지 고르기

만든 테스트를 전부 CI에서 돌릴 필요는 없어요. "이건 배포 전마다 꼭 통과해야 해" 싶은 것만 골라 넣으면 됩니다. 테스트마다 CI 포함 스위치를 켜면 그 테스트가 CI 검증 대상이 돼요.

이 켜고 끄기는 바로 반영돼요. 다음 검증부터 새로 켠 테스트는 자동으로 포함되고, 끈 테스트는 빠져요. 따로 저장하거나 다시 연결할 필요가 없어요. 코드를 올렸을 때 CI가 도는 순간, 그때 켜져 있는 테스트만 검증해요.

이 켜고 끄기는 사람만 할 수 있어요. 연결한 AI는 테스트를 만들고 돌릴 수는 있어도, 무엇을 CI 검증에 넣을지는 정하지 않습니다. "배포를 막을 수도 있는 기준"은 사람이 정한다는 원칙이에요.

CI 포함으로 켠 테스트는 작업실 보드의 CI 탭에 한데 모여요. 여기서 각 테스트가 어떻게 흘러왔는지 한눈에 볼 수 있어요.

  • 마지막 검증 결과 — 가장 최근 회차가 통과였는지 실패였는지.
  • 최근 5회 판정 — 최근 다섯 번이 각각 통과였는지 실패였는지를 나란히.
  • 통과율 — 지금까지 몇 퍼센트나 통과했는지.
  • 널뛰기 배지 — 통과와 실패를 오락가락하는(불안정한) 테스트에 붙어요. 이 배지가 붙은 테스트는 "진짜 버그"보다 "테스트 자체가 흔들리는" 경우가 많아, 먼저 다듬어 두면 좋아요.

AI에게 맡기기 (권장)

가장 쉬운 방법이에요. 아래 내용을 복사해서 평소 쓰는 AI 코딩 도구(Claude Code·Cursor 등)에 붙여넣기만 하면, AI가 연결에 필요한 일을 대신해요. 토큰 발급, 워크플로우 파일 만들기, 커밋까지 전부요.

Specnote 자동 검증을 이 저장소의 GitHub Actions에 연결해줘. 1) specnote_get_ci_workflow 도구로 워크플로우 파일 내용을 받아 .github/workflows/specnote-verify.yml 로 저장해줘 (specId 는 "<내 워크스페이스 ID>", 배포/스테이징 주소가 있으면 standard, 로컬 개발 서버만 있으면 local 모드). 2) specnote_issue_ci_token 도구로 CI 전용 토큰을 발급해줘. 3) 발급된 토큰을 GitHub 저장소 비밀값 SPECNOTE_TOKEN 으로 등록해줘 — gh CLI 가 있으면 gh secret set SPECNOTE_TOKEN, 없으면 GitHub 저장소 → Settings → Secrets and variables → Actions 경로를 나에게 안내해줘. 4) 검증 대상 주소(스테이징/프리뷰)가 필요하면 나에게 물어보고 gh variable set SPECNOTE_TARGET_URL 로 등록해줘. 5) 워크플로우 파일을 커밋·푸시하고, 무엇을 연결했는지 알려줘.

<내 워크스페이스 ID>는 지금 이 워크스페이스의 ID로 바꿔 주세요. AI가 물어보면 그대로 알려 주면 돼요. (테스트 실행 탭의 "CI 연동" 카드에서 복사하면 워크스페이스 ID가 이미 채워져 있어요.)

직접 연결하기

손수 연결하고 싶다면, 테스트 실행 탭의 "CI 연동" 카드에서 [직접 연결하기] 버튼을 누르면 웹에서 3단계로 끝낼 수 있어요. 토큰 발급, 값이 채워진 워크플로우 파일 복사·다운로드, 연결 확인까지 한 자리에서 해요. 명령까지 값이 채워진 채로 나오니 그대로 복사해 쓰면 됩니다.

버튼 없이 손으로 하고 싶다면 절차는 이래요.

  1. 토큰 발급 — 마이페이지 → MCP 연결에서 CI 전용 토큰을 발급해요. 이 토큰은 검증을 시작하는 열쇠예요.
  2. 워크플로우 파일 만들기 — 저장소에 .github/workflows/specnote-verify.yml 파일을 만들어요. 내용은 위 AI 프롬프트의 specnote_get_ci_workflow 도구가 워크스페이스 값이 채워진 상태로 그대로 내려줘요.
  3. 비밀값 등록 — GitHub 저장소 → Settings → Secrets and variables → Actions 에서, 방금 발급한 토큰을 SPECNOTE_TOKEN 이라는 이름의 비밀값(secret)으로 등록해요.
  4. 검증 주소 등록 — 같은 화면의 Variables 탭에서 SPECNOTE_TARGET_URL 이라는 변수(variable)에, 검증할 사이트 주소(스테이징이나 미리보기 주소)를 넣어요.

이 네 가지가 끝나면, 코드를 올릴 때마다 워크플로우가 저절로 돌면서 검증을 시작해요.

GitHub Actions가 아니어도 돼요 — API로 직접 연결

GitLab·Jenkins·CircleCI·Bitbucket, 심지어 짧은 셸 스크립트까지 — 어떤 CI든 붙일 수 있어요. 특별한 플러그인은 필요 없고, 딱 세 가지만 있으면 돼요.

  1. CI 토큰 — 마이페이지나 "직접 연결하기" 마법사, 또는 연결한 AI(MCP)로 발급해 CI 비밀값으로 넣어요. 요청할 때 Authorization: Bearer <토큰> 헤더로 보냅니다.
  2. 검증 시작POST /api/ci/runs 에 워크스페이스 ID(specId)와 검증할 공개 주소(targetUrl)를 담아 보내면, 그 자리에서 검증이 시작되고 실행 묶음 ID를 돌려줘요.
  3. 결과 기다리기GET /api/ci/runs/{실행 묶음 ID} 를 10초 간격으로 확인해요. 상태(status)가 COMPLETED·ERROR·CANCELED 중 하나가 되면 끝난 거예요. 응답의 summaryMarkdown 은 사람이 바로 읽을 수 있는 한국어 요약이고, failCount 가 0보다 크면 실패로 처리하면 됩니다.

GitLab을 쓰신다면 전용 템플릿(.gitlab-ci.yml)이 따로 있어요. "직접 연결하기" 마법사에서 GitLab CI를 고르거나, 연결한 AI에게 specnote_get_ci_workflow 의 provider를 gitlab으로 요청하면 값이 채워진 파일을 그대로 받을 수 있어요.

아무 CI에나 붙이는 스크립트

아래는 GitHub·GitLab 전용 값 없이 어디서나 돌아가는 최소 예시예요(필요한 건 curljq뿐). <워크스페이스 ID>는 이 워크스페이스의 ID로, SPECNOTE_TOKEN·TARGET_URL은 CI 비밀값·변수로 넣으세요.

#!/usr/bin/env bash
set -euo pipefail

API="https://specnote.io"
SPEC_ID="<워크스페이스 ID>"
TARGET_URL="${TARGET_URL:-<검증할 공개 주소>}"
: "${SPECNOTE_TOKEN:?SPECNOTE_TOKEN 이 필요해요}"

# 1) 검증 시작(트리거)
BODY=$(jq -nc --arg specId "$SPEC_ID" --arg targetUrl "$TARGET_URL" \
  '{specId: $specId, targetUrl: $targetUrl, meta: {provider: "generic"}}')
CREATE=$(curl -sS --fail-with-body -X POST "$API/api/ci/runs" \
  -H "Authorization: Bearer $SPECNOTE_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$BODY")
RUN_ID=$(echo "$CREATE" | jq -r ".runGroupId // empty")
if [ -z "$RUN_ID" ]; then
  echo "검증을 시작하지 못했어요:"; echo "$CREATE"
  exit 1
fi

# 2) 완료까지 폴링(10초 간격)
for i in $(seq 1 180); do
  RES=$(curl -sS --fail-with-body "$API/api/ci/runs/$RUN_ID" \
    -H "Authorization: Bearer $SPECNOTE_TOKEN")
  STATUS=$(echo "$RES" | jq -r ".status // empty")
  case "$STATUS" in COMPLETED|ERROR|CANCELED) break ;; esac
  sleep 10
done

# 3) 사람이 읽는 요약 + 실패 시 종료 코드 1
echo "$RES" | jq -r ".summaryMarkdown // \"결과를 가져오지 못했어요.\""
FAIL=$(echo "$RES" | jq -r ".failCount // 0")
[ "$FAIL" -gt 0 ] && exit 1 || exit 0

몇 가지 기억할 점이 있어요. 이건 CI 종류와 상관없이 똑같아요.

  • 공개 주소가 필요해요. Specnote 서버가 접속할 수 있는 주소여야 해요. 내 PC에서만 도는 localhost 주소는 안 되고, 그럴 땐 임시 통로(터널)로 공개 주소를 만들어 TARGET_URL로 넘기세요.
  • 처음엔 보고 모드로. 위 예시는 실패하면 종료 코드 1을 돌려줘요. 익숙해지기 전까지는 그 줄을 빼서, 실패해도 파이프라인을 막지 않게 두는 걸 권해요.
  • 켠 테스트만 돌아요. 실행 결과에서 [CI 포함]으로 켠 시나리오만 검증돼요. 이 규칙은 GitHub든 GitLab이든 직접 API든 똑같아요.

보고 모드 ↔ 차단 모드

연결하면 처음에는 보고 모드로 시작해요. 검증이 실패하더라도 코드를 합치는 걸 막지는 않고, 결과만 알려 주는 방식이에요. 워크플로우 파일 안의 continue-on-error: true 한 줄이 이 역할을 해요.

익숙해지고 통과율이 안정된 뒤에는, 그 한 줄을 지워서 차단 모드로 바꿀 수 있어요. 차단 모드에서는 검증이 실패하면 코드 합치기가 막혀요. 처음부터 차단 모드로 두면 잠깐의 오탐에도 발이 묶일 수 있으니, 통과율이 안정된 뒤에 차단 모드로 전환하는 것을 권해요.

자주 묻는 질문

로컬에서만 앱이 도는데도 되나요? 네. 배포된 주소가 없어도 돼요. 이 경우 CI가 잠깐 앱을 띄우고 임시 통로(터널)를 열어, 그동안만 공개 주소처럼 접속할 수 있게 해요. AI 프롬프트에서 "local 모드"라고 알려 주면 그 방식으로 만들어 줘요. 다만 임시 통로는 속도·수명이 보장되지 않아서, 배포나 미리보기 주소가 있다면 그쪽이 더 안정적이에요.

비용이 드나요? CI로 도는 검증도 일반 검증과 똑같이 크레딧이 들어요. 한 번 재생할 때 실제로 걸린 시간만큼 아주 작은 크레딧이 조금씩 쌓여 청구돼요. 한 번에 여러 테스트를 돌리면 그만큼 더 쌓이고, 잔액이 1크레딧에 못 미치면 그 회차는 실행되지 않아요(충전 후 다시 돌리면 됩니다). AI를 새로 부르지는 않아 자동 추출처럼 많이 들지는 않지만, "완전 무료"는 아니라는 점만 기억해 주세요.

토큰을 다시 발급하면 어떻게 되나요? CI 토큰은 이름이 하나로 고정돼 있어서, 다시 발급하면 이전 토큰은 자동으로 폐기되고 새 토큰만 살아 있어요. 토큰을 잃어버렸거나 새로 돌리고 싶을 때 부담 없이 재발급하면 돼요. (재발급하면 GitHub 비밀값 SPECNOTE_TOKEN도 새 값으로 바꿔 주세요.)

검증이 안 돌아요. 가장 흔한 원인은 검증 대상 주소예요. SPECNOTE_TARGET_URL 변수에 넣은 사이트 주소가 지금 접속되는 공개 주소인지 확인해 주세요. 주소가 바뀌었다면 그 값을 새 주소로 고쳐 주면 돼요.

검증을 직접 눌러 돌리는 기본 방법은 검증 돌리고 결과 읽기에서, 코드 연결이 아직이라면 내 코드와 연결하기를 먼저 봐 주세요.