Dependabot 수정
실패하는 Dependabot PR을 체계적으로 수정합니다. 사용자가 PR 번호(예: /dependabot-fix 42)를 제공합니다.
이 스킬은 6단계(A~F) 로 구성됩니다. Phase D가 완료될 때까지 코드 편집을 시작하지 마십시오. Phase B가 완료될 때까지 로그를 분석하지 마십시오.
시작할 때 한 번 스크래치 공간을 설정하세요:
mkdir -p ./tmp && touch ./tmp/null
PR_NUM=<사용자 프롬프트에서>
REPO=EthicalML/ethical
Phase A — 컨텍스트
1단계 · PR 컨텍스트
메타데이터를 가져와 PR에 대한 한 단락 분량의 요약을 작성합니다(생태계, 그룹화, 크기, 보안 업데이트 여부, 변경된 파일). 아직 소스 파일을 열지 마십시오.
gh pr view $PR_NUM --repo $REPO --json title,body,headRefName,labels,files,mergeable,createdAt
gh pr diff $PR_NUM --repo $REPO | head -200
다음을 식별합니다:
- 생태계:
npm|github-actions— 이 저장소에는 이 두 가지뿐입니다. - 그룹화: 그룹화됨(
all,all-security) vs 단일 npm 주요(major) 버전(주요 버전은 설계상all그룹에서 제외되므로 각각 독립적으로 도착합니다). - 크기: 파일 수 및 대략적인 LOC 변경량; npm의 경우
package.json만 변경되었는지package-lock.json만 변경되었는지. - 변경된 종속성이 렌더링된 출력에 전혀 영향을 줄 수 있는지 여부 — 이는 Phase E(8.5단계 참조)를 결정합니다.
2단계 · 고수준 오류 조사
실패한 검사를 나열하고 각 실패한 작업 로그의 첫 번째와 마지막 오류 줄을 캡처합니다. 아직 그 의미를 조사하지 마십시오 — 증상만 열거하십시오.
CI(.github/workflows/ci.yml)에는 정확히 세 가지 필수 작업이 있습니다: lint (ESLint + Prettier), typecheck (npm run check:ratchet), build (데모 모드의 프로덕션 Astro 빌드, FORM_ENDPOINT 없음). 그 외 빨간색으로 표시된 것은 필수 검사가 아닙니다.
gh pr checks $PR_NUM --repo $REPO
# 각 실패한 검사에 대해 URL에서 작업 ID를 가져와 로그를 가져옵니다
gh run view --job <JOB_ID> --repo $REPO --log 2>./tmp/null \
| grep -iE "error|exit code|##\[error\]|FAILED|assert|timed ?out" \
| head -20 > ./tmp/pr-${PR_NUM}-symptoms.txt
출력은 다음과 같은 글머리 기호 목록이어야 합니다:
lint:Prettier check failed: package.jsontypecheck:astro check reported 3 errors, baseline is 0build:[vite] Rollup failed to resolve import "..."
CI가 볼 수 없는 것에 주목하십시오. Lint, astro-check ratchet 및 성공적인 빌드는 페이지의 모양에 대해 아무 것도 말하지 않습니다. 이 격차는 Phase E의 역할이며, 이 저장소에서 이 스킬의 가장 가치 있는 부분입니다.
Phase B — 서브에이전트를 통한 컨텍스트 수집
PR이 건드리는 범위에 대해 두세 개의 병렬 explore 서브에이전트를 실행합니다. 미리 직접 읽지 말고 위임하십시오.
3단계 · 규칙 서브에이전트
.github/copilot-instructions.md는 이 저장소의 단일 표준 에이전트 진입점입니다(루트 AGENTS.md와 CLAUDE.md는 이 파일에 대한 심볼릭 링크입니다). 서브에이전트에게 이를 읽고 다음을 반환하도록 요청하십시오: 변경 워크플로우, 로컬 검사, 커밋/PR 규칙, 그리고 건드리는 경로와 관련된 주의사항. PR이 스타일링이나 토큰 ratchet을 건드릴 수 있는 경우 STYLES.md도 가리키고, 컴포넌트 API가 관련된 경우 REUSABLE.md도 가리키십시오.
4단계 · 테스트 하네스 서브에이전트
scripts/verify/README.md를 읽고 로컬 검증 하네스에 대한 브리핑(~40줄)을 반환하도록 요청하십시오: verify:dom, verify:shots, verify:parity, verify:typewriter 및 check:ratchet가 각각 무엇을 검증하는지, 테마 플래그와 뷰포트 플래그가 어떻게 작동하는지, 출력이 어디에 저장되는지, 그리고 패리티 허용 목록 메커니즘이 무엇이고 무엇이 아닌지. 이 브리핑은 Phase E가 실행할 대상입니다.
5단계 · 코드베이스 서브에이전트
건드리는 영역에 대한 대상 맵을 생성하도록 요청하십시오:
- diff에 있는 패키지 중 실제로
src/**또는scripts/**에 의해 가져와지는 것은 무엇이고 어디에 있는지(아무 것도 가져오지 않는 패키지의 범프는astro의 범프와 다른 위험 등급입니다). - 빌드 및 검사 명령어 (
npm run build,npm run lint,npm run format:check,npm run check:ratchet) - 범프가 빌드 파이프라인(
astro,vite,@astrojs/*,pagefind,mdx/rehype/remark플러그인)에 영향을 미치는지, 아니면 도구(eslint,prettier,typescript)에만 영향을 미치는지. github-actionsPR의 경우: 어떤 워크플로우가 변경되고 변경 사항이 CI가 아닌 배포 경로(.github/workflows/deploy.yml)에 영향을 미치는지.
서브에이전트 브리핑은 함께 Phase C의 작업 컨텍스트를 구성합니다.
Phase C — 심층 근본 원인 진단
6단계 · 진단
이제 — 그리고 지금만 — Phase B의 전체 컨텍스트로 실패한 작업 로그를 분석하십시오. 각 실패한 검사에 대해 첫 번째 의미 있는 오류를 다음 중 하나로 추적합니다:
- 범프된 종속성의 직접적인 회귀(제거된 내보내기, 서명 변경, 더 엄격한 유효성 검사, 변경된 기본값)
- 전이적 도구 체인 문제(
.tool-versions가 고정한 것보다 최신 Node가 필요한 종속성; 최신 런타임이 필요한 사후 설치; 확인되지 않는 선택적 네이티브 바인딩) - 무해한 범프로 인해 노출된 기존 취약점(astro-check 기준선,
-a###토큰 ratchet, 또는 형식 변경으로 인해 문제를 일으키는STYLES.md해시) - 인프라 결함(레지스트리 속도 제한, 취소된 작업,
npm ci네트워크 실패)
그룹화된 PR의 경우 각 실패 검사를 별도로 진단하십시오 — 실패는 독립적인 원인이 있을 수 있으며, 배치에서는 일반적으로 다른 패키지로 추적됩니다. 결과를 ./tmp/pr-${PR_NUM}-diagnosis.md에 기록하십시오.
Phase D — 수정 설계
6.5단계 · 범위 분류 — 이것은 수정인가, 아니면 Dependabot 설정 문제인가?
수정을 계획하기 전에 PR이 전혀 수정 범위 내에 있는지 확인하십시오. .github/dependabot.yml은 일상적인 npm의 부/패치 업데이트를 생태계당 하나의 all 그룹에 배치하고, all-security 그룹을 추가하며, npm 주요(major) 버전을 all 그룹에서 의도적으로 제외하여 각 주요 버전이 독립적으로 도착하도록 합니다. 이 형태는 두 가지 뚜렷한 실패 상황을 의미합니다:
하나의 패키지에서 실패하는 그룹화된 PR. 이것은 일반적인 경우이며 범위 내입니다. 배치를 포기하지 마십시오. 문제가 되는 단일 패키지를 찾아 해당 패키지에 대한 코드를 수정하거나, 해당 패키지 하나를 고정(package.json에서 범위를 좁히거나 해당 패키지와 버전에 대한 Dependabot ignore 항목)하여 나머지 배치가 통과할 수 있도록 하십시오. 하나를 제외하고 모두 통과하는 배치를 포기하는 것은 하나의 잘못된 업데이트를 위해 수십 개의 좋은 업데이트를 버리는 것입니다.
범위 거부 트리거(하나만으로 충분 — PR은 수정이 아니라 설정 문제입니다):
- 단일 그룹 PR에 2개 이상의 주요 범프가 포함됨 — 현재 npm 그룹 설정 하에서 불가능해야 하므로, 발생하면 설정 자체가 변경된 것이며 실제 버그입니다.
- 프레임워크 계층 패키지(
astro,vite,@astrojs/*,typescript,eslint,prettier,preact,pagefind)의 단독 주요 버전으로, 실제 마이그레이션인 경우 — 수정이 아니라 프로젝트입니다. - 배치가 대부분 일상적이지만 고정할 수 없는 하나의 패키지에 대한 마이그레이션이 필요한 실패입니다.
트리거되면 수정을 시도하지 말고 직접 PR을 닫지 마십시오 — 소유자를 위해 열어 두십시오. 대신:
- 원인이 설정 변경인 경우,
.github/dependabot.yml수정 사항을 별도의 작은 PR로 준비하십시오(소유자가 검토하고 병합할 수 있도록 남겨 둠). 그렇지 않으면 설정 변경이 필요하지 않으며 권장 사항은 마이그레이션이 자체 작업으로 예약되어야 한다는 것입니다. - 범위 거부 결정을 Dependabot PR에 댓글로 설명하십시오: 한 번에 수정할 수 없는 이유, 설정 PR이 있는 경우 링크, 마이그레이션이 수반하는 작업에 대해 설명하십시오. PR을 열어 두십시오 — 결정을 기다리지 말고, 닫지 마십시오.
- Phase F의 커밋 흐름을 건너뛰십시오 — 수정 사항이 없습니다. 보고서 내용은 해당 댓글에 포함됩니다.
보안 업데이트 그룹(all-security)은 묶어 둡니다: 보안 범프는 시간에 민감하고 충분히 드물어 분할하는 것이 절약하는 것보다 더 많은 비용이 듭니다. 구체적인 차단 요인이 강제하는 경우에만 분할하십시오.
7단계 · 포괄적인 계획
다음을 포함하는 계획을 작성하십시오; 위험에 따라 깊이를 조정하십시오:
| 섹션 | 항상 | 위험 ≥ 중간인 경우 |
|---|---|---|
| 근본 원인 | ✅ | ✅ |
| 변경될 것으로 예상되는 파일 | ✅ | ✅ |
| 수정 방법(및 고려된 대안) | ✅ | ✅ |
| 위험 등급(낮음/중간/높음) | ✅ | ✅ |
| 재현 단계 | ✅ | ✅ (실행 가능해야 함) |
| 수동 테스트 전략 | ✅ | ✅ 확장됨 |
| 롤백 계획 | ✅ | |
| 폭발 반경(렌더링된 출력 / 배포 / URL) | ✅ |
위험이 중간 이상인 경우 다음 중 하나라도 해당:
- 범프가 빌드 파이프라인(
astro,vite,@astrojs/*, MDX/rehype/remark 플러그인,pagefind)에 영향을 미칩니다. - 수정 사항이 설정이나 잠금 파일이 아닌
src/아래의 파일을 편집합니다. - 범프가 방출된 HTML, CSS 순서, 글꼴 로딩 또는 하이드레이션 동작을 변경할 수 있습니다.
github-actions변경이deploy.yml에 영향을 미칩니다(배포 실패는 사이트 중단이며 빨간색 검사가 아닙니다).
모든 npm 주요(major) 버전은 기본적으로 최소 중간입니다. 주요 버전이 독립적으로 도착하는 것은 읽고 테스트할 가치가 있기 때문입니다; 동일한 크기의 배치보다 더 주의해서 취급하십시오.
8단계 · 수동 테스트 전략(계층화)
7단계의 위험 등급에 따라 노력을 계층화하십시오:
- 낮음(도구만 해당) — 수정 사항을 적용하고 가장 좁은 관련 게이트(
npm run lint,npm run format:check, 또는npm run check:ratchet)를 실행하십시오. 재현 단계가 필요하지 않습니다. - 중간(빌드 파이프라인 또는
src/편집) — 먼저 PR 브랜치에서 실패를 로컬로 재현하여 회귀가 실제임을 증명하십시오(CI 아티팩트가 아님). 그런 다음 수정 사항을 적용하고 전체 로컬 검사를 다시 실행하십시오:npm run lint && npm run format:check && npm run check:ratchet && npm run build. 그런 다음 Phase E. - 높음(주요 버전, 렌더링된 출력을 변경할 수 있는 모든 것, 배포 변경) — 중간의 모든 것, 추가로 Phase E의 패리티 스윕은 필수, 빌드된 PR 헤드에 대해
npm run verify:dom:all, 히어로 또는 모션 토큰이 관련된 경우npm run verify:typewriter.
모든 스크래치 출력을 ./tmp/(gitignore됨) 아래에 유지하십시오. 출력을 억제해야 할 때 싱크로 ./tmp/null를 사용하십시오:
npm run build 2>./tmp/null
Phase E — 병합 기준에 대한 시각적 패리티
CI는 사이트가 여전히 빌드됨을 증명합니다. 사이트가 여전히 동일하게 보인다는 것을 증명하지는 않습니다. 종속성 범프는 정의상 픽셀 중립적이어야 합니다 — 그렇지 않다면 무언가 다르게 렌더링되었으며 아무도 보지 못했을 것입니다. 이 단계가 이 저장소에 이 스킬이 존재하는 이유입니다.
픽셀 기준선이 커밋되지 않았으므로(scripts/verify/out/ 및 tmp/는 gitignore됨), 비교는 실행 중에 생성되어야 합니다: 병합 기준 캡처, PR 헤드 캡처, 비교.
8.5단계 · 실행 여부 결정
스윕은 PR당 약 4-5분이 소요됩니다(37개 경로 × 2개 뷰포트에 대한 두 번의 빌드 및 두 번의 스크린샷 스윕). 변경이 렌더링에 영향을 줄 수 없는 경우에만 건너뛰십시오. 다음 모두 해당하는 경우 건너뛸 수 있습니다:
- PR이
github-actions전용이거나.github/**만 건드립니다. src/,public/,astro.config.mjs또는package.jsondependencies아래의 파일이 변경되지 않았습니다.- diff가
dist/에 도달하지 않는 devDependencies(eslint*,prettier,@types/*,typescript(ratchet이 변경되지 않은 경우))로 제한됩니다.
그 외의 모든 것 — 모든 astro, vite, @astrojs/*, preact, pagefind, MDX/rehype/remark, 글꼴 또는 CSS 도구 범프, 그리고 모든 npm 주요 버전 — 스윕을 실행합니다. 의심스러우면 실행하십시오; 5분은 라이브 사이트에서 조용한 시각적 회귀보다 저렴합니다.
이 결정의 어느 분기가 채택되었는지와 그 이유를 보고서에 명시적으로 언급하십시오.
9단계 · 캡처 및 비교
Playwright는 저장소 종속성이 아닙니다; 하네스는 이미 스크립트에 연결된 npx 캐시 경로에서 이를 구동합니다. 각 빌드를 일반 정적 서버로 제공하십시오.
BASE_SHA=$(git merge-base origin/master HEAD)
mkdir -p ./tmp/parity
# --- 병합 기준 ---
git checkout $BASE_SHA
npm ci
npm run build
cp dist/index.html ./tmp/parity/base-index.html # 제공하는 항목의 지문
nohup npx --yes http-server dist -p 4126 --silent < ./tmp/null > ./tmp/parity/base-server.log 2>&1 &
BASE_SERVER=$!
npm run verify:shots:all
kill $BASE_SERVER
cp -R scripts/verify/out ./tmp/parity/base
# --- PR 헤드 ---
gh pr checkout $PR_NUM --repo $REPO
npm ci
npm run build
cp dist/index.html ./tmp/parity/head-index.html
nohup npx --yes http-server dist -p 4126 --silent < ./tmp/null > ./tmp/parity/head-server.log 2>&1 &
HEAD_SERVER=$!
npm run verify:shots:all
kill $HEAD_SERVER
cp -R scripts/verify/out ./tmp/parity/head
# --- 뷰포트별 비교 ---
npm run verify:parity -- ./tmp/parity/base/1440 ./tmp/parity/head/1440 > ./tmp/parity/1440.json
npm run verify:parity -- ./tmp/parity/base/420 ./tmp/parity/head/420 > ./tmp/parity/420.json
오래된 dist 함정. 두 빌드에 걸쳐 포트 4126을 재사용하는 것은 자신감 있지만 무의미한 녹색을 생성할 가장 가능성 높은 방법입니다: 이전 서버가 실제로 종료되지 않았거나 dist가 다시 빌드되지 않은 경우, 두 번째 스윕은 첫 번째 빌드를 촬영하고 패리티는 빌드를 자체와 비교했기 때문에 통과합니다. 매 실행마다 이를 방지하십시오:
- 다음 서버를 시작하기 전에 이전 서버가 사라졌는지 확인하십시오(
lsof -i :4126에서 아무 것도 반환되지 않음). - 두 지문을 비교하십시오 —
src/또는 빌드 파이프라인 종속성을 변경한 PR에 대해cmp ./tmp/parity/base-index.html ./tmp/parity/head-index.html가 "identical"을 반환하면 실행을 신뢰하지 말아야 한다는 신호이며, 결과가 아닙니다. - 스윕 자체의 JSON이
compared: 0을 보고하거나 모든 경로가 누락된 경우, 서버가 작동하지 않은 것입니다. 실행은 무효이며 통과가 아닙니다.
verify:shots는 다크 테마 출력을 out/<width>/에 씁니다. 범프가 라이트 테마에 다르게 영향을 미칠 가능성이 있는 경우(CSS 도구, 색상 처리, 토큰 방출), --theme light로 스윕을 반복하면 out/light/<width>/에 기록되며 다크 트리를 덮어쓰지 않습니다.
10단계 · 결과 해석
verify-parity는 경로당 두 개의 숫자를 보고하며 둘 다 중요합니다
...(번역을 위해 잘렸습니다)