From e5e799bef6f24c99c793e6cc0bb76a1639284e0f Mon Sep 17 00:00:00 2001 From: hyoseok Date: Sun, 8 Mar 2026 19:16:54 +0900 Subject: [PATCH 1/2] chore: refresh GitHub issue and PR templates --- .github/ISSUE_TEMPLATE/bug_report.yml | 116 +++++++++++++------- .github/ISSUE_TEMPLATE/config.yml | 6 +- .github/ISSUE_TEMPLATE/engineering_task.yml | 72 ++++++++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 105 +++++++++++++----- .github/ISSUE_TEMPLATE/harness_epic.yml | 67 ----------- .github/ISSUE_TEMPLATE/harness_task.yml | 63 ----------- .github/ISSUE_TEMPLATE/weekly_scorecard.yml | 58 ---------- .github/PULL_REQUEST_TEMPLATE.md | 62 +++++------ .github/workflows/harness-pr-guardrail.yml | 95 +--------------- 9 files changed, 257 insertions(+), 387 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/engineering_task.yml delete mode 100644 .github/ISSUE_TEMPLATE/harness_epic.yml delete mode 100644 .github/ISSUE_TEMPLATE/harness_task.yml delete mode 100644 .github/ISSUE_TEMPLATE/weekly_scorecard.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index da71f6c..5cb520f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,79 +1,114 @@ -name: ๐Ÿž ๋ฒ„๊ทธ ๋ฆฌํฌํŠธ (Bug Report) -description: ๋ฐœ์ƒํ•œ ๋ฒ„๊ทธ๋‚˜ ์˜ค๋ฅ˜๋ฅผ ์ œ๋ณดํ•ด ์ฃผ์„ธ์š”. -title: "[Bug]: " +name: "๐Ÿž Backend Bug Report" +description: API, ์ธ์ฆ, ๋ฐฐ์น˜, ์ ์ˆ˜ ๊ณ„์‚ฐ, ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ์ œ๋ณดํ•ฉ๋‹ˆ๋‹ค. +title: "[Bug] " labels: ["bug", "triage"] body: - type: markdown attributes: value: | - ์ด ์ด์Šˆ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ƒ์„ธํžˆ ์ ์–ด์ฃผ์„ธ์š”. + ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์ •๋ณด์™€ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ฒจ ์ฃผ์„ธ์š”. + ๋ฐฑ์—”๋“œ ์ด์Šˆ๋Š” "์–ด๋–ค ์š”์ฒญ/๋ฐฐ์น˜/๊ณ„์‚ฐ ๊ฒฝ๋กœ์—์„œ ๊นจ์กŒ๋Š”์ง€"๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. - type: textarea - id: description + id: problem attributes: - label: ์–ด๋–ค ๋ฒ„๊ทธ์ธ๊ฐ€์š”? - description: ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋ช…ํ™•ํ•˜๊ณ  ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์„ค๋ช…ํ•ด ์ฃผ์„ธ์š”. - placeholder: ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋ฐ˜์‘์ด ์—†์Šต๋‹ˆ๋‹ค. + label: ๋ฌธ์ œ ์š”์•ฝ + description: ๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ํ•œ๋‘ ๋ฌธ์žฅ์œผ๋กœ ์„ค๋ช…ํ•ด ์ฃผ์„ธ์š”. + placeholder: GitHub ๋กœ๊ทธ์ธ ํ›„ access token ์žฌ๋ฐœ๊ธ‰์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. + validations: + required: true + + - type: dropdown + id: area + attributes: + label: ์˜ํ–ฅ ์˜์—ญ + options: + - auth + - ranking + - user + - badge + - batch + - integration/github + - security + - observability + - infra/config + - unknown validations: required: true - type: textarea id: reproduction attributes: - label: ์žฌํ˜„ ๋ฐฉ๋ฒ• (Steps to Reproduce) - description: ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด์ฃผ์„ธ์š”. + label: ์žฌํ˜„ ์ ˆ์ฐจ + description: ์š”์ฒญ ์ˆœ์„œ, ์ž…๋ ฅ๊ฐ’, API ๊ฒฝ๋กœ, ๋ฐฐ์น˜ ์‹คํ–‰ ์กฐ๊ฑด์„ ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด ์ฃผ์„ธ์š”. placeholder: | - 1. ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ - 2. '๋กœ๊ทธ์ธ' ๋ฒ„ํŠผ ํด๋ฆญ - 3. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ๋ฐœ์ƒ + 1. `/api/v1/auth/refresh` ํ˜ธ์ถœ + 2. ๋งŒ๋ฃŒ๋œ refresh token ์ฟ ํ‚ค ํฌํ•จ + 3. 500 ์‘๋‹ต ๋ฐœ์ƒ validations: - required: false + required: true - type: textarea - id: expected-behavior + id: expected_behavior attributes: - label: ๊ธฐ๋Œ€ ๋™์ž‘ (Expected Behavior) - description: ์›๋ž˜ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ–ˆ๋‹ค๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™€์•ผ ํ–ˆ๋‚˜์š”? - placeholder: ๋กœ๊ทธ์ธ ๋ชจ๋‹ฌ ์ฐฝ์ด ๋– ์•ผ ํ•ฉ๋‹ˆ๋‹ค. + label: ๊ธฐ๋Œ€ ๋™์ž‘ + placeholder: 401 ๋˜๋Š” ์ •์ƒ์ ์ธ ํ† ํฐ ์žฌ๋ฐœ๊ธ‰ ์‘๋‹ต์ด ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. validations: - required: false + required: true + + - type: textarea + id: actual_behavior + attributes: + label: ์‹ค์ œ ๋™์ž‘ + placeholder: ์‘๋‹ต ๋ณธ๋ฌธ ์—†์ด 500์ด ๋ฐœ์ƒํ•˜๊ณ  ์„œ๋ฒ„ ๋กœ๊ทธ์— JWT ํŒŒ์‹ฑ ์˜ˆ์™ธ๊ฐ€ ๋‚จ์Šต๋‹ˆ๋‹ค. + validations: + required: true - type: textarea - id: intent_spec + id: evidence attributes: - label: ์˜๋„ ๋ช…์„ธ (Intent Spec) - description: ๋ฒ„๊ทธ ์ˆ˜์ •์—์„œ ๋ฐ˜๋“œ์‹œ ๋ณด์žฅํ•ด์•ผ ํ•  ๋™์ž‘๊ณผ ๋น„๋ชฉํ‘œ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”. + label: ๋กœ๊ทธ / ๋ฉ”ํŠธ๋ฆญ / ํŠธ๋ ˆ์ด์Šค / ์Šคํฌ๋ฆฐ์ƒท + description: ์„œ๋ฒ„ ๋กœ๊ทธ, actuator ์ •๋ณด, trace id, ํด๋ผ์ด์–ธํŠธ ์ฝ˜์†”, ์Šคํฌ๋ฆฐ์ƒท ๋“ฑ ์ฆ๊ฑฐ๋ฅผ ๋‚จ๊ฒจ ์ฃผ์„ธ์š”. placeholder: | - ๋ฐ˜๋“œ์‹œ ๋ณด์žฅํ•  ๋™์ž‘: - ๋น„๋ชฉํ‘œ: + - trace_id: + - log excerpt: + - metric/query: + - screenshot/link: validations: required: false - - type: input - id: related_plan + - type: textarea + id: impact attributes: - label: ๊ด€๋ จ ๊ณ„ํš ๋ฌธ์„œ ๊ฒฝ๋กœ (์„ ํƒ) - placeholder: "docs/plans/active/2026-02-25-bugfix-name.md" + label: ์˜ํ–ฅ๋„์™€ ๋ฒ”์œ„ + description: ์‚ฌ์šฉ์ž ์˜ํ–ฅ, ๋ฐ์ดํ„ฐ ์†์ƒ ๊ฐ€๋Šฅ์„ฑ, ์šฐํšŒ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: | + - ์˜ํ–ฅ ์‚ฌ์šฉ์ž: + - ๋ฐ์ดํ„ฐ ์˜ํ–ฅ: + - ์šฐํšŒ ๋ฐฉ๋ฒ•: validations: required: false - type: textarea - id: environment + id: acceptance attributes: - label: ์‹คํ–‰ ํ™˜๊ฒฝ (Environment) - description: ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•œ ํ™˜๊ฒฝ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. + label: ์ˆ˜์ • ํ›„ ํ™•์ธํ•ด์•ผ ํ•  ์กฐ๊ฑด placeholder: | - - OS: [e.g. macOS, Windows 10] - - Browser: [e.g. Chrome 98, Safari] - - Version: [e.g. 1.0.0] + - ๋งŒ๋ฃŒ ํ† ํฐ ์š”์ฒญ ์‹œ 401์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. + - ์ •์ƒ ํ† ํฐ ์š”์ฒญ ์‹œ ์žฌ๋ฐœ๊ธ‰์ด ์„ฑ๊ณตํ•œ๋‹ค. + - ๊ด€๋ จ ์—๋Ÿฌ ๋กœ๊ทธ๊ฐ€ ๋” ์ด์ƒ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. validations: - required: false + required: true - type: textarea - id: logs + id: environment attributes: - label: ์Šคํฌ๋ฆฐ์ƒท ๋˜๋Š” ๋กœ๊ทธ (Screenshots/Logs) - description: ๋ฌธ์ œ ์ƒํ™ฉ์„ ๋ณด์—ฌ์ฃผ๋Š” ์Šคํฌ๋ฆฐ์ƒท์ด๋‚˜ ์—๋Ÿฌ ๋กœ๊ทธ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ฒจ๋ถ€ํ•ด ์ฃผ์„ธ์š”. + label: ์‹คํ–‰ ํ™˜๊ฒฝ + placeholder: | + - profile: local / dev / prod + - branch or commit: + - DB: + - ์š”์ฒญ ํด๋ผ์ด์–ธํŠธ: validations: required: false @@ -83,4 +118,7 @@ body: label: ํ™•์ธ ์‚ฌํ•ญ options: - label: ์ด ์ด์Šˆ์™€ ๋™์ผํ•œ ๊ธฐ์กด ์ด์Šˆ๊ฐ€ ์žˆ๋Š”์ง€ ๊ฒ€์ƒ‰ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. - required: false + required: true + - label: ์žฌํ˜„ ์ ˆ์ฐจ ๋˜๋Š” ๋กœ๊ทธ ๋“ฑ ๋””๋ฒ„๊น… ๊ฐ€๋Šฅํ•œ ์ฆ๊ฑฐ๋ฅผ ๋‚จ๊ฒผ์Šต๋‹ˆ๋‹ค. + required: true + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 74750f4..7f989d7 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,6 @@ blank_issues_enabled: false contact_links: - - name: ๐Ÿ’ฌ ์งˆ๋ฌธ ๋ฐ ํ† ๋ก  (Discussions) - url: https://github.com/alexization/git-ranker/discussions - about: ๋ฒ„๊ทธ๋‚˜ ๊ธฐ๋Šฅ ์š”์ฒญ์ด ์•„๋‹Œ ์ผ๋ฐ˜์ ์ธ ์งˆ๋ฌธ์ด๋‚˜ ์˜๊ฒฌ์€ ์ด๊ณณ์„ ์ด์šฉํ•ด ์ฃผ์„ธ์š”. - name: ๐Ÿ”’ ๋ณด์•ˆ ์ทจ์•ฝ์  ์ œ๋ณด url: mailto:alexizationy@gmail.com - about: ๋ฏผ๊ฐํ•œ ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ๊ณต๊ฐœ ์ด์Šˆ ๋Œ€์‹  ์ด๋ฉ”์ผ๋กœ ์ œ๋ณดํ•ด ์ฃผ์„ธ์š”. \ No newline at end of file + about: ์ธ์ฆ, ๊ถŒํ•œ, ํ† ํฐ, ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ๊ด€๋ จ ๋ฏผ๊ฐ ์ด์Šˆ๋Š” ๊ณต๊ฐœ ์ด์Šˆ ๋Œ€์‹  ์ด๋ฉ”์ผ๋กœ ์ œ๋ณดํ•ด ์ฃผ์„ธ์š”. + diff --git a/.github/ISSUE_TEMPLATE/engineering_task.yml b/.github/ISSUE_TEMPLATE/engineering_task.yml new file mode 100644 index 0000000..c3a6f52 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/engineering_task.yml @@ -0,0 +1,72 @@ +name: "๐Ÿ› ๏ธ Backend Engineering Task" +description: ๋ฆฌํŒฉํ„ฐ๋ง, ์„ฑ๋Šฅ, ํ…Œ์ŠคํŠธ, ๋ณด์•ˆ, ๊ด€์ธก์„ฑ, ์šด์˜ ๊ฐœ์„  ์ž‘์—…์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. +title: "[Task] " +labels: ["task", "triage"] +body: + - type: dropdown + id: task_type + attributes: + label: ์ž‘์—… ์œ ํ˜• + options: + - refactor + - performance + - testing + - security + - observability + - infra/config + - documentation + validations: + required: true + + - type: textarea + id: reason + attributes: + label: ์™œ ํ•„์š”ํ•œ๊ฐ€์š”? + description: ์ง€๊ธˆ ์ด ์ž‘์—…์ด ํ•„์š”ํ•œ ์ด์œ ์™€ ๋ฐฉ์น˜ ๋น„์šฉ์„ ์ ์–ด ์ฃผ์„ธ์š”. + validations: + required: true + + - type: textarea + id: scope + attributes: + label: ์ž‘์—… ๋ฒ”์œ„ + description: ๋ณ€๊ฒฝํ•  ํŒจํ‚ค์ง€, ์„ค์ •, ํ…Œ์ŠคํŠธ ๋ฒ”์œ„๋ฅผ ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: | + - `domain/ranking` + - `global/logging` + - `src/test/...` + validations: + required: true + + - type: textarea + id: done + attributes: + label: ์™„๋ฃŒ ์กฐ๊ฑด + placeholder: | + - [ ] ... + - [ ] ... + validations: + required: true + + - type: textarea + id: validation + attributes: + label: ๊ฒ€์ฆ ๋ฐฉ๋ฒ• + placeholder: | + - `./gradlew test` + - `./gradlew integrationTest` + - ๋กœ๊ทธ/๋ฉ”ํŠธ๋ฆญ ํ™•์ธ + validations: + required: true + + - type: textarea + id: risks + attributes: + label: ๋ฆฌ์Šคํฌ ๋ฐ ์˜์กด์„ฑ + placeholder: | + - ๋ฆฌ์Šคํฌ: + - ์˜์กด์„ฑ: + - ํ›„์† ์ž‘์—…: + validations: + required: false + diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index ffda77e..4f243a6 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,64 +1,111 @@ -name: ๐Ÿš€ ๊ธฐ๋Šฅ ์š”์ฒญ (Feature Request) -description: ํ”„๋กœ์ ํŠธ์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ œ์•ˆํ•ด ์ฃผ์„ธ์š”. -title: "[Feat]: " +name: "๐Ÿš€ Backend Feature Request" +description: API, ๋ฐฐ์น˜, ์ ์ˆ˜ ๊ณ„์‚ฐ, ์ธ์ฆ, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. +title: "[Feature] " labels: ["enhancement", "feature"] body: - type: markdown attributes: value: | - ํ”„๋กœ์ ํŠธ ๋ฐœ์ „์„ ์œ„ํ•œ ์•„์ด๋””์–ด๋ฅผ ์ œ์•ˆํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! + ๊ธฐ๋Šฅ ์š”์ฒญ์€ "๋ฌด์—‡์„ ๋งŒ๋“ค๊ณ  ์‹ถ์€์ง€"๋ณด๋‹ค "์–ด๋–ค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š”์ง€"๊ฐ€ ๋จผ์ €์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. - type: textarea id: problem attributes: - label: ๊ด€๋ จ๋œ ๋ฌธ์ œ ์ƒํ™ฉ (Is your feature request related to a problem?) - description: ์–ด๋–ค ๋ถˆํŽธํ•จ์ด๋‚˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ์€์ง€ ์„ค๋ช…ํ•ด ์ฃผ์„ธ์š”. - placeholder: "์˜ˆ: ๋งค๋ฒˆ ์ˆ˜๋™์œผ๋กœ ์„ค์ •์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค." + label: ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ + description: ํ˜„์žฌ ์–ด๋–ค ๋ถˆํŽธ, ๋ˆ„๋ฝ, ์šด์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋Š”์ง€ ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: ํ˜„์žฌ ๋žญํ‚น ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ์˜ค๋ž˜๋œ ์ƒํƒœ๋กœ ์œ ์ง€๋˜์–ด ์‚ฌ์šฉ์ž ํ˜ผ๋ž€์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. validations: required: true - type: textarea - id: solution + id: outcome attributes: - label: ์ œ์•ˆํ•˜๋Š” ํ•ด๊ฒฐ์ฑ… (Describe the solution you'd like) - description: ๊ธฐ๋Šฅ์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ตฌ์ฒด์ ์œผ๋กœ ๋ฌ˜์‚ฌํ•ด ์ฃผ์„ธ์š”. - placeholder: "์„ค์ • ํŒŒ์ผ ์ž๋™ ๋กœ๋“œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค." + label: ์›ํ•˜๋Š” ๊ฒฐ๊ณผ + description: ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๋ฉด ์‚ฌ์šฉ์ž๋‚˜ ์šด์˜์ž๊ฐ€ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜๋™ ๊ฐฑ์‹ ์„ ์š”์ฒญํ•˜๋ฉด ์ตœ์‹  ์ง‘๊ณ„ ์ƒํƒœ์™€ ์™„๋ฃŒ ์‹œ์ ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + validations: + required: true + + - type: dropdown + id: area + attributes: + label: ์˜ํ–ฅ ์˜์—ญ + options: + - auth + - ranking + - user + - badge + - batch + - integration/github + - security + - observability + - infra/config validations: required: true - type: textarea - id: intent_spec + id: desired_behavior attributes: - label: ์˜๋„ ๋ช…์„ธ (Intent Spec) - description: ๋ฌธ์ œ, ๋ชฉํ‘œ ๋™์ž‘, ๋น„๋ชฉํ‘œ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”. + label: ์›ํ•˜๋Š” ๋™์ž‘ + description: API, ๋ฐฐ์น˜, ๊ณ„์‚ฐ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ด€์ ์—์„œ ์›ํ•˜๋Š” ๋™์ž‘์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์ ์–ด ์ฃผ์„ธ์š”. placeholder: | - ๋ฌธ์ œ: - ๋ชฉํ‘œ ๋™์ž‘: - ๋น„๋ชฉํ‘œ: + - ์–ด๋–ค ์ž…๋ ฅ์„ ๋ฐ›๋Š”์ง€ + - ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ + - ์‹คํŒจ ์‹œ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ validations: required: true - - type: input - id: plan_path + - type: textarea + id: acceptance attributes: - label: ๊ณ„ํš ๋ฌธ์„œ ๊ฒฝ๋กœ (์„ ํƒ) - description: ํฐ ๋ณ€๊ฒฝ์ด๋ฉด docs/plans/active ๊ฒฝ๋กœ๋ฅผ ์—ฐ๊ฒฐํ•ด ์ฃผ์„ธ์š”. - placeholder: "docs/plans/active/2026-02-25-feature-name.md" + label: ์ˆ˜์šฉ ๊ธฐ์ค€ + description: ์™„๋ฃŒ ํŒ์ •์ด ๊ฐ€๋Šฅํ•œ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: | + - [ ] ... + - [ ] ... validations: - required: false + required: true - type: textarea - id: alternatives + id: contract_impact attributes: - label: ๊ณ ๋ คํ•ด ๋ณธ ๋Œ€์•ˆ (Alternatives considered) - description: ์œ„ ํ•ด๊ฒฐ์ฑ… ์™ธ์— ๊ณ ๋ คํ•ด ๋ณธ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ์ ์–ด์ฃผ์„ธ์š”. + label: API / ์Šคํ‚ค๋งˆ / ๋ฐฐ์น˜ ์˜ํ–ฅ + description: ์—”๋“œํฌ์ธํŠธ, DTO, ์ด๋ฒคํŠธ, DB, ์บ์‹œ, ์Šค์ผ€์ค„๋Ÿฌ ์˜ํ–ฅ์ด ์žˆ์œผ๋ฉด ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: | + - API: + - DTO/Schema: + - DB/Migration: + - Batch/Scheduler: validations: required: false - type: textarea - id: context + id: qa_evidence + attributes: + label: ํ•„์š”ํ•œ ๊ฒ€์ฆ ์ฆ๊ฑฐ + description: ๊ตฌํ˜„ ํ›„ ์–ด๋–ค ํ…Œ์ŠคํŠธ, ๋กœ๊ทธ, ๋ฉ”ํŠธ๋ฆญ, trace ํ™•์ธ์ด ํ•„์š”ํ•œ์ง€ ์ ์–ด ์ฃผ์„ธ์š”. + placeholder: | + - `./gradlew test` + - `./gradlew integrationTest` + - actuator/prometheus ํ™•์ธ + - ๊ด€๋ จ ๋กœ๊ทธ ํ™•์ธ + validations: + required: true + + - type: textarea + id: non_goals_and_risks + attributes: + label: ๋น„๋ชฉํ‘œ์™€ ๋ฆฌ์Šคํฌ + placeholder: | + ๋น„๋ชฉํ‘œ: + ๋ฆฌ์Šคํฌ: + validations: + required: false + + - type: input + id: related_client_issue attributes: - label: ์ถ”๊ฐ€ ์ •๋ณด (Additional context) - description: ์Šคํฌ๋ฆฐ์ƒท์ด๋‚˜ ์ฐธ๊ณ ํ•  ๋งŒํ•œ ๋งํฌ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š”. + label: ์—ฐ๊ด€๋œ ํ”„๋ก ํŠธ์—”๋“œ ์ด์Šˆ ๋˜๋Š” PR (์„ ํƒ) + placeholder: "alexization/git-ranker-client#123" validations: required: false diff --git a/.github/ISSUE_TEMPLATE/harness_epic.yml b/.github/ISSUE_TEMPLATE/harness_epic.yml deleted file mode 100644 index 21b23f3..0000000 --- a/.github/ISSUE_TEMPLATE/harness_epic.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: ๐Ÿงญ Harness Epic -description: ์—์ด์ „ํŠธ ์šด์˜์ฒด๊ณ„(legibility, observability, system of record, feedback loop)์šฉ ์ƒ์œ„ ์ด์Šˆ -title: "[Harness Epic]: " -labels: ["harness", "epic"] -body: - - type: markdown - attributes: - value: | - ์ด ์ด์Šˆ๋Š” ํ•˜๋‚˜์˜ ๋‹จ๊ณ„(Phase)๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ƒ์œ„ Epic์ž…๋‹ˆ๋‹ค. - ํ•˜์œ„ Task ์ด์Šˆ๋กœ ๋ถ„ํ•ดํ•ด์„œ ์ง„ํ–‰ํ•ด ์ฃผ์„ธ์š”. - - - type: input - id: phase - attributes: - label: Phase - description: ์˜ˆ) M1 Legibility / M2 Observability / M3 System of Record / M4 Feedback Loop / M5 Quality Automation - placeholder: "M1 Legibility" - validations: - required: true - - - type: textarea - id: objective - attributes: - label: ๋ชฉํ‘œ (Objective) - description: ์ด๋ฒˆ Epic์ด ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š” ์šด์˜ ๋ฌธ์ œ๋ฅผ ๋ช…ํ™•ํžˆ ์ž‘์„ฑํ•˜์„ธ์š”. - placeholder: "์˜ˆ: ์‹ ๊ทœ ๊ธฐ์—ฌ์ž์™€ AI agent๊ฐ€ ์ €์žฅ์†Œ ๊ตฌ์กฐ๋ฅผ 10๋ถ„ ๋‚ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ" - validations: - required: true - - - type: textarea - id: success_criteria - attributes: - label: ์™„๋ฃŒ ๊ธฐ์ค€ (Success Criteria) - description: ์ธก์ • ๊ฐ€๋Šฅํ•œ ์™„๋ฃŒ ๊ธฐ์ค€์„ ์ž‘์„ฑํ•˜์„ธ์š”. - placeholder: | - - AGENTS.md ์ •์ฐฉ - - docs index ๊ตฌ์ถ• - - PR ํ…œํ”Œ๋ฆฟ ๊ฐ•์ œ ํ•ญ๋ชฉ ์šด์˜ - validations: - required: true - - - type: textarea - id: planned_tasks - attributes: - label: ์˜ˆ์ •๋œ ํ•˜์œ„ Task ์ด์Šˆ - description: ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋กœ ๋ถ„ํ•ดํ•˜์„ธ์š”. - placeholder: | - - [ ] M1-1 ... - - [ ] M1-2 ... - validations: - required: true - - - type: textarea - id: risks - attributes: - label: ๋ฆฌ์Šคํฌ ๋ฐ ๋Œ€์‘ - description: ์‹คํŒจ ๊ฐ€๋Šฅ์„ฑ๊ณผ ์™„ํ™” ์ „๋žต์„ ์ž‘์„ฑํ•˜์„ธ์š”. - validations: - required: false - - - type: textarea - id: out_of_scope - attributes: - label: ๋ฒ”์œ„ ์ œ์™ธ (Out of Scope) - description: ์ด๋ฒˆ Epic์—์„œ ํ•˜์ง€ ์•Š์„ ํ•ญ๋ชฉ์„ ๋ช…ํ™•ํžˆ ์ž‘์„ฑํ•˜์„ธ์š”. - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/harness_task.yml b/.github/ISSUE_TEMPLATE/harness_task.yml deleted file mode 100644 index cc6359f..0000000 --- a/.github/ISSUE_TEMPLATE/harness_task.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: โœ… Harness Task -description: Epic ํ•˜์œ„ ์‹คํ–‰ ๋‹จ์œ„ ์ด์Šˆ (ํ•˜๋‚˜์˜ ๋ชฉํ‘œ, ํ•˜๋‚˜์˜ PR) -title: "[Harness Task]: " -labels: ["harness", "task"] -body: - - type: input - id: epic_link - attributes: - label: ์ƒ์œ„ Epic ์ด์Šˆ ๋งํฌ - placeholder: "์˜ˆ: #123" - validations: - required: true - - - type: input - id: plan_doc - attributes: - label: Plan ๋ฌธ์„œ ๊ฒฝ๋กœ - description: docs/plans/active/ ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”. - placeholder: "docs/plans/active/2026-02-25-.md" - validations: - required: true - - - type: textarea - id: intent - attributes: - label: ์˜๋„ ๋ช…์„ธ (Intent Spec) - description: ๋ฌธ์ œ, ๋ชฉํ‘œ ๋™์ž‘, ๋น„๋ชฉํ‘œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. - placeholder: | - ๋ฌธ์ œ: - ๋ชฉํ‘œ ๋™์ž‘: - ๋น„๋ชฉํ‘œ: - validations: - required: true - - - type: textarea - id: scope - attributes: - label: ๊ตฌํ˜„ ๋ฒ”์œ„ - description: ์ด๋ฒˆ Task์—์„œ ์‹ค์ œ๋กœ ๋ฐ”๊ฟ€ ํŒŒ์ผ/๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. - validations: - required: true - - - type: textarea - id: validation - attributes: - label: ๊ฒ€์ฆ ๋ฐฉ๋ฒ• - description: ์‹คํ–‰ํ•  ๋ช…๋ น๊ณผ ํ™•์ธํ•  ๊ด€์ธก ํฌ์ธํŠธ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. - placeholder: | - ๋ช…๋ น: - - ./gradlew test --tests "..." - ๊ด€์ธก: - - actuator/metrics ํ™•์ธ - - ๋กœ๊ทธ ํ•„๋“œ ํ™•์ธ - validations: - required: true - - - type: textarea - id: done - attributes: - label: ์™„๋ฃŒ ์กฐ๊ฑด - description: ์ด Task๊ฐ€ ๋๋‚ฌ๋‹ค๊ณ  ํŒ๋‹จํ•  ๊ธฐ์ค€์„ ์ž‘์„ฑํ•˜์„ธ์š”. - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/weekly_scorecard.yml b/.github/ISSUE_TEMPLATE/weekly_scorecard.yml deleted file mode 100644 index 3797c96..0000000 --- a/.github/ISSUE_TEMPLATE/weekly_scorecard.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: ๐Ÿ“Š ์ฃผ๊ฐ„ Scorecard -description: ํ•œ ์ฃผ๊ฐ„์˜ ํ’ˆ์งˆ/๋“œ๋ฆฌํ”„ํŠธ ์ ๊ฒ€์„ ๊ธฐ๋กํ•˜๋Š” ์ด์Šˆ -title: "[Weekly Scorecard]: " -labels: ["harness", "scorecard"] -body: - - type: input - id: week - attributes: - label: Review Week - placeholder: "2026-W09" - validations: - required: true - - - type: input - id: owner - attributes: - label: Owner - placeholder: "@username" - validations: - required: true - - - type: input - id: scorecard_doc - attributes: - label: Scorecard Document Path - placeholder: "docs/scorecards/2026-W09-scorecard.md" - validations: - required: true - - - type: textarea - id: summary - attributes: - label: Week Summary - description: ํ•ต์‹ฌ ๋ณ€ํ™”์™€ ํ’ˆ์งˆ ์ƒํƒœ๋ฅผ 3~5์ค„๋กœ ์š”์•ฝํ•ด ์ฃผ์„ธ์š”. - validations: - required: true - - - type: textarea - id: risks - attributes: - label: Top Risks Next Week - placeholder: | - 1) ... - 2) ... - 3) ... - validations: - required: true - - - type: textarea - id: action_items - attributes: - label: Action Items - description: ๋‹ค์Œ ์ฃผ ์‹คํ–‰ ํ•ญ๋ชฉ๊ณผ ๋‹ด๋‹น์ž๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”. - placeholder: | - - [ ] #123 ... (@owner) - - [ ] #124 ... (@owner) - validations: - required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e803115..90079d7 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,54 +4,46 @@ ## 2) ์—ฐ๊ด€ ์ด์Šˆ - Closes # +- ๊ด€๋ จ frontend ์ด์Šˆ/PR: -## 3) ์˜๋„ ๋ช…์„ธ +## 3) ๋ฌธ์ œ์™€ ๋ชฉํ‘œ - ๋ฌธ์ œ: -- ๋ชฉํ‘œ ๋™์ž‘: +- ์‚ฌ์šฉ์ž/์šด์˜์ž ๊ด€์ ์˜ ๊ฒฐ๊ณผ: - ๋น„๋ชฉํ‘œ: -## 4) System of Record ๋งํฌ -- Plan (๋จธ์ง€ ์ „ ์ตœ์ข… ์ƒํƒœ): `docs/plans/completed/YYYY-MM-DD-.md` -- ADR (ํ•„์š” ์‹œ): `docs/adr/...` -- ๊ด€๋ จ runbook/docs ์—…๋ฐ์ดํŠธ: +## 4) ์˜ํ–ฅ ๋ฒ”์œ„ +- ๋ณ€๊ฒฝ๋œ ํŒจํ‚ค์ง€/๋ชจ๋“ˆ: +- API/DTO/Schema ์˜ํ–ฅ: +- DB/Cache/Batch/Scheduler ์˜ํ–ฅ: +- ๋ณด์•ˆ/๊ถŒํ•œ ์˜ํ–ฅ: -## 5) ๋ณ€๊ฒฝ ๋ฒ”์œ„ -- ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ/ํŒจํ‚ค์ง€: -- API/์Šคํ‚ค๋งˆ/๋™์ž‘ ์˜ํ–ฅ: +## 5) ๊ฒ€์ฆ ์ฆ๊ฑฐ -## 6) ๊ฒ€์ฆ ์ฆ๊ฑฐ - -| ์œ ํ˜• | ๋ช…๋ น์–ด | ๊ฒฐ๊ณผ | +| ์œ ํ˜• | ๋ช…๋ น์–ด / ์ฆ๊ฑฐ | ๊ฒฐ๊ณผ | | --- | --- | --- | | Build | `./gradlew build -x test` | | | Unit | `./gradlew test` | | -| Integration | `./gradlew integrationTest` ๋˜๋Š” `๋ฏธ์‹คํ–‰(์‚ฌ์œ )` | | -| Quality (Coverage) | `./gradlew test jacocoTestCoverageVerification` ๋˜๋Š” `๋ฏธ์‹คํ–‰(์‚ฌ์œ )` | | - -## 7) AI ๋ฆฌ๋ทฐ ๋ฃจํ”„ ์ฆ๊ฑฐ - -| ๋ฆฌ๋ทฐ์–ด | ๋ผ์šด๋“œ | ์ตœ์ข… ๊ฒฐ๊ณผ | ์ฆ๊ฑฐ ๋งํฌ | -| --- | --- | --- | --- | -| Codex | | | | -| CodeRabbitAI | | | | +| Integration | `./gradlew integrationTest` ๋˜๋Š” `๋ฏธ์‹คํ–‰(<์‚ฌ์œ >)` | | +| Coverage | `./gradlew test jacocoTestCoverageVerification` ๋˜๋Š” `๋ฏธ์‹คํ–‰(<์‚ฌ์œ >)` | | +| API/Manual Smoke | `curl ...` / Postman / ๋ฐฐ์น˜ ์‹คํ–‰ ๊ธฐ๋ก ๋˜๋Š” `๋ฏธ์‹คํ–‰(<์‚ฌ์œ >)` | | -## 8) ๊ด€์ธก์„ฑ ํ™•์ธ +## 6) ๊ด€์ธก์„ฑ ํ™•์ธ - ํ™•์ธํ•œ ๋กœ๊ทธ: - ํ™•์ธํ•œ ๋ฉ”ํŠธ๋ฆญ: -- ํ™•์ธํ•œ ๋Œ€์‹œ๋ณด๋“œ/์ฟผ๋ฆฌ: +- ํ™•์ธํ•œ trace/dashboard/query: -## 9) ๋ฆฌ์Šคํฌ ๋ฐ ๋กค๋ฐฑ +## 7) AI ๋ฆฌ๋ทฐ ๋ฉ”๋ชจ (์„ ํƒ) +- Codex: +- CodeRabbitAI: + +## 8) ๋ฆฌ์Šคํฌ ๋ฐ ๋กค๋ฐฑ - ๋ฆฌ์Šคํฌ: - ๋กค๋ฐฑ ๊ณ„ํš: -## 10) Merge Ready Gate -- [ ] Codex/CodeRabbit final re-reviews completed -- [ ] All review findings triaged (fixed or justified) -- [ ] Plan moved to `docs/plans/completed/...` in this PR -- [ ] Risk and rollback section updated - -## 11) ์ฒดํฌ๋ฆฌ์ŠคํŠธ -- [ ] ์ด์Šˆ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Œ -- [ ] Plan ๋ฌธ์„œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Œ -- [ ] ๊ฒ€์ฆ ์ฆ๊ฑฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Œ -- [ ] ๋ฌธ์„œ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์—ˆ๊ฑฐ๋‚˜ ๋ถˆํ•„์š” ์‚ฌ์œ ๊ฐ€ ๋ช…์‹œ๋˜์–ด ์žˆ์Œ +## 9) ์ฒดํฌ๋ฆฌ์ŠคํŠธ +- [ ] ์—ฐ๊ด€ ์ด์Šˆ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Œ +- [ ] Build / Unit / Integration ๊ฒฐ๊ณผ๊ฐ€ ๊ธฐ์ž…๋˜์–ด ์žˆ์Œ +- [ ] API/์Šคํ‚ค๋งˆ/๋ฐฐ์น˜ ์˜ํ–ฅ์ด ๋ฐ˜์˜๋˜์—ˆ๊ฑฐ๋‚˜ ์—†์Œ์„ ๋ช…์‹œํ•จ +- [ ] ๋กœ๊ทธ/๋ฉ”ํŠธ๋ฆญ/trace ํ™•์ธ ๋‚ด์šฉ์„ ์ ์—ˆ๊ฑฐ๋‚˜ ๋ถˆํ•„์š” ์‚ฌ์œ ๋ฅผ ์ ์Œ +- [ ] ๋ฌธ์„œ ๋˜๋Š” ํ›„์† ์ด์Šˆ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์—ˆ๊ฑฐ๋‚˜ ๋ถˆํ•„์š” ์‚ฌ์œ ๋ฅผ ์ ์Œ + diff --git a/.github/workflows/harness-pr-guardrail.yml b/.github/workflows/harness-pr-guardrail.yml index 2ee7665..b4e5caf 100644 --- a/.github/workflows/harness-pr-guardrail.yml +++ b/.github/workflows/harness-pr-guardrail.yml @@ -12,7 +12,7 @@ jobs: name: Validate PR Contract runs-on: ubuntu-latest steps: - - name: Check plan link, validation evidence, and AI review loop + - name: Check validation evidence and risk section env: PR_BODY: ${{ github.event.pull_request.body }} PR_IS_DRAFT: ${{ github.event.pull_request.draft }} @@ -25,15 +25,10 @@ jobs: fi if [ "${PR_IS_DRAFT:-false}" = "true" ]; then - echo "Draft PR detected; skipping strict merge-ready checks." + echo "Draft PR detected; skipping strict checks." exit 0 fi - if ! echo "$PR_BODY" | grep -Eiq 'docs/plans/completed/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9._-]+\.md'; then - echo "Missing completed plan doc path (docs/plans/completed/YYYY-MM-DD-.md)." - exit 1 - fi - if ! validation_errors="$(printf '%s\n' "$PR_BODY" | awk -F'|' ' function trim(s) { gsub(/^[ \t]+|[ \t]+$/, "", s); return s } { @@ -84,94 +79,10 @@ jobs: exit 1 fi - if ! ai_review_errors="$(printf '%s\n' "$PR_BODY" | awk -F'|' ' - function trim(s) { gsub(/^[ \t]+|[ \t]+$/, "", s); return s } - { - reviewer = trim($2) - round = trim($3) - result = trim($4) - evidence = trim($5) - - if (reviewer == "Codex" || reviewer == "CodeRabbitAI") { - found[reviewer] = 1 - - if (round == "") { - empty_round[reviewer] = 1 - } - - if (result == "") { - empty_result[reviewer] = 1 - } - - if (evidence == "" || evidence == "-") { - empty_evidence[reviewer] = 1 - } - - if (result ~ /^Not run/ || result ~ /^๋ฏธ์‹คํ–‰/) { - if (result !~ /^Not run[[:space:]]*\([^()[:space:]].+\)$/ && - result !~ /^๋ฏธ์‹คํ–‰[[:space:]]*\([^()[:space:]].+\)$/) { - invalid_not_run[reviewer] = result - } - } - } - } - END { - bad = 0 - required[1] = "Codex" - required[2] = "CodeRabbitAI" - - for (i = 1; i <= 2; i++) { - r = required[i] - if (!(r in found)) { - print "Missing AI review row for: " r - bad = 1 - } else if (r in empty_round) { - print "Missing AI review round for: " r - bad = 1 - } else if (r in empty_result) { - print "Missing AI review result for: " r - bad = 1 - } else if (r in empty_evidence) { - print "Missing AI review evidence link for: " r - bad = 1 - } else if (r in invalid_not_run) { - print "Invalid AI not-run format for " r ": " invalid_not_run[r] - bad = 1 - } - } - - exit bad - } - ')"; then - echo "$ai_review_errors" - echo "AI review loop evidence must include round/result/evidence for Codex and CodeRabbitAI." - echo "If not run, use: Not run() or ๋ฏธ์‹คํ–‰(<์‚ฌ์œ >)." - exit 1 - fi - - if ! echo "$PR_BODY" | grep -Fq -- "- [x] Codex/CodeRabbit final re-reviews completed"; then - echo "Merge Ready Gate missing checked item: Codex/CodeRabbit final re-reviews completed." - exit 1 - fi - - if ! echo "$PR_BODY" | grep -Fq -- "- [x] All review findings triaged (fixed or justified)"; then - echo "Merge Ready Gate missing checked item: All review findings triaged (fixed or justified)." - exit 1 - fi - - if ! echo "$PR_BODY" | grep -Fq -- '- [x] Plan moved to `docs/plans/completed/...` in this PR'; then - echo "Merge Ready Gate missing checked item: Plan moved to docs/plans/completed in this PR." - exit 1 - fi - - if ! echo "$PR_BODY" | grep -Fq -- "- [x] Risk and rollback section updated"; then - echo "Merge Ready Gate missing checked item: Risk and rollback section updated." - exit 1 - fi - if ! echo "$PR_BODY" | grep -Eiq 'Risk and Rollback|Rollback|๋ฆฌ์Šคํฌ ๋ฐ ๋กค๋ฐฑ|๋กค๋ฐฑ'; then echo "Missing risk/rollback section." exit 1 fi echo "PR contract passed." + From 3a5f37f1a06d756de5bd58ca3afb1a9ba3b9d2c6 Mon Sep 17 00:00:00 2001 From: hyoseok Date: Sun, 8 Mar 2026 20:42:14 +0900 Subject: [PATCH 2/2] chore: remove legacy harness PR guardrail --- .github/workflows/harness-pr-guardrail.yml | 88 ---------------------- 1 file changed, 88 deletions(-) delete mode 100644 .github/workflows/harness-pr-guardrail.yml diff --git a/.github/workflows/harness-pr-guardrail.yml b/.github/workflows/harness-pr-guardrail.yml deleted file mode 100644 index b4e5caf..0000000 --- a/.github/workflows/harness-pr-guardrail.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: Harness PR Guardrail - -on: - pull_request: - types: [opened, edited, reopened, synchronize, ready_for_review] - branches: - - main - - develop - -jobs: - pr-contract: - name: Validate PR Contract - runs-on: ubuntu-latest - steps: - - name: Check validation evidence and risk section - env: - PR_BODY: ${{ github.event.pull_request.body }} - PR_IS_DRAFT: ${{ github.event.pull_request.draft }} - run: | - set -eu - - if [ -z "${PR_BODY:-}" ]; then - echo "PR body is empty." - exit 1 - fi - - if [ "${PR_IS_DRAFT:-false}" = "true" ]; then - echo "Draft PR detected; skipping strict checks." - exit 0 - fi - - if ! validation_errors="$(printf '%s\n' "$PR_BODY" | awk -F'|' ' - function trim(s) { gsub(/^[ \t]+|[ \t]+$/, "", s); return s } - { - type = trim($2) - result = trim($4) - - if (type == "Build" || type == "Unit" || type == "Integration") { - found[type] = 1 - - if (result == "") { - empty_result[type] = 1 - } - - if (result ~ /^Not run/ || result ~ /^๋ฏธ์‹คํ–‰/) { - if (result !~ /^Not run[[:space:]]*\([^()[:space:]].+\)$/ && - result !~ /^๋ฏธ์‹คํ–‰[[:space:]]*\([^()[:space:]].+\)$/) { - invalid_not_run[type] = result - } - } - } - } - END { - bad = 0 - required[1] = "Build" - required[2] = "Unit" - required[3] = "Integration" - - for (i = 1; i <= 3; i++) { - t = required[i] - if (!(t in found)) { - print "Missing validation table row for: " t - bad = 1 - } else if (t in empty_result) { - print "Missing validation result for: " t - bad = 1 - } else if (t in invalid_not_run) { - print "Invalid not-run format for " t ": " invalid_not_run[t] - bad = 1 - } - } - - exit bad - } - ')"; then - echo "$validation_errors" - echo "Validation evidence must include non-empty results for Build/Unit/Integration." - echo "If not run, use: Not run() or ๋ฏธ์‹คํ–‰(<์‚ฌ์œ >)." - exit 1 - fi - - if ! echo "$PR_BODY" | grep -Eiq 'Risk and Rollback|Rollback|๋ฆฌ์Šคํฌ ๋ฐ ๋กค๋ฐฑ|๋กค๋ฐฑ'; then - echo "Missing risk/rollback section." - exit 1 - fi - - echo "PR contract passed." -