@@ -19,15 +19,16 @@ jobs:
1919 script : |
2020 const pr = context.payload.pull_request;
2121 const title = pr.title;
22+ let body = pr.body || "";
2223
23- console.log(`[분석] PR 제목: ${title}`);
24+ console.log(`[분석 시작 ] PR 제목: ${title}`);
2425
25- // 1. PR 제목에서 주차 숫자 추출
26+ // 1. PR 제목에서 주차 숫자와 문제 번호 추출
2627 const weekMatch = title.match(/Week\s*(\d+)/i);
2728 const probNumMatch = title.match(/\d{4,}/);
2829
2930 if (!weekMatch || !probNumMatch) {
30- console.log("❌ 제목에서 주차 또는 문제번호를 추출하지 못했습니다.");
31+ console.log("❌ 제목에서 주차(Week) 또는 문제번호를 추출하지 못했습니다.");
3132 return;
3233 }
3334
@@ -43,53 +44,65 @@ jobs:
4344 per_page: 100
4445 });
4546
46- // 3. 이슈 제목 매칭 로직 (특수문자 무시하고 'week' + '숫자'만 확인 )
47+ // 3. 이슈 제목 매칭 ([Week15] 등 대괄호와 공백 무시 )
4748 const targetIssue = issues.data.find(i => {
4849 if (i.pull_request) return false;
49- const cleanTitle = i.title.replace(/[\s\[\]]/g, '').toLowerCase(); // 공백, [, ] 모두 제거
50+ const cleanTitle = i.title.replace(/[\s\[\]]/g, '').toLowerCase();
5051 return cleanTitle.includes(`week${weekNum}`);
5152 });
5253
5354 if (!targetIssue) {
5455 console.log(`❌ [Week${weekNum}] 이슈를 찾지 못했습니다.`);
55- // 디버깅용: 현재 레포에 있는 이슈 제목들 출력
56- console.log("현재 탐색된 이슈 목록:");
57- issues.data.slice(0, 10).forEach(i => console.log(`- ${i.title}`));
5856 return;
5957 }
6058 console.log(`✅ 이슈 발견: #${targetIssue.number} (${targetIssue.title})`);
6159
6260 // 4. 이슈 본문에서 해당 문제 섹션 찾기
6361 const issueBody = targetIssue.body || "";
64- // '문제 1', '문제 2' 등으로 섹션 분할
65- const sections = issueBody.split(/문제\s*\d/);
62+ // '#### 문제 1' 또는 '문제 1' 패턴으로 섹션 분할
63+ const sections = issueBody.split(/####\s* 문제\s*\d+|문제\s*\d+ /);
6664 const targetSection = sections.find(s => s.includes(targetProbNum));
6765
6866 if (!targetSection) {
69- console.log(`❌ 이슈 내에 ${targetProbNum}번 문제 정보가 없습니다 .`);
67+ console.log(`❌ 이슈 본문에서 ${targetProbNum}번 문제 정보를 찾지 못했습니다 .`);
7068 return;
7169 }
7270
73- // 5. 정규표현식으로 상세 정보 추출 (줄바꿈/공백 대응)
74- const getVal = (regex) => targetSection.match(regex)?.[1]?.trim() || "정보 없음";
75-
76- const platform = getVal(/플랫폼:\s*(.+)/);
77- const probName = getVal(/문제 이름:\s*(.+)/);
78- const probLink = getVal(/링크:\s*(https?:\/\/[^\s]+)/);
79- const difficulty = getVal(/난이도:\s*(.+)/);
71+ // 5. 상세 정보 추출 함수 (마크다운 볼드체 ** 기호 대응)
72+ const getVal = (key) => {
73+ // '**키워드**: 값' 형태에서 값을 추출 (볼드 기호가 있어도 작동)
74+ const regex = new RegExp(`(?:\\*\\*|)${key}(?:\\*\\*|)\\s*:\\s*([^\\r\\n]+)`, 'i');
75+ const match = targetSection.match(regex);
76+ return match ? match[1].trim() : "정보 없음";
77+ };
78+
79+ const platform = getVal("플랫폼");
80+ const probName = getVal("문제 이름");
81+ const difficulty = getVal("난이도");
82+ // 링크는 별도로 URL 패턴으로 추출
83+ const probLinkMatch = targetSection.match(/(?:https?:\/\/[^\s\r\n]+)/);
84+ const probLink = probLinkMatch ? probLinkMatch[0].trim() : "정보 없음";
8085
81- // 6. PR 본문 업데이트
82- let newBody = (pr.body || "")
86+ console.log(`[데이터 추출] 플랫폼: ${platform}, 이름: ${probName}, 난이도: ${difficulty}`);
87+
88+ // 6. PR 본문 업데이트 (기존 템플릿의 빈 항목을 치환)
89+ // 정규표현식을 사용하여 해당 라인 전체를 교체합니다.
90+ let newBody = body
8391 .replace(/- \*\*플랫폼\*\*:.*$/m, `- **플랫폼**: ${platform}`)
8492 .replace(/- \*\*문제 번호\*\*:.*$/m, `- **문제 번호**: ${targetProbNum}`)
8593 .replace(/- \*\*문제 이름\*\*:.*$/m, `- **문제 이름**: ${probName}`)
8694 .replace(/- \*\*문제 링크\*\*:.*$/m, `- **문제 링크**: ${probLink}`)
8795 .replace(/- \*\*난이도\*\*:.*$/m, `- **난이도**: ${difficulty}`);
8896
89- await github.rest.pulls.update({
90- owner: context.repo.owner,
91- repo: context.repo.repo,
92- pull_number: pr.number,
93- body: newBody
94- });
95- console.log("🚀 PR 본문 업데이트 성공!");
97+ // 변경사항이 있을 때만 업데이트 실행
98+ if (newBody !== body) {
99+ await github.rest.pulls.update({
100+ owner: context.repo.owner,
101+ repo: context.repo.repo,
102+ pull_number: pr.number,
103+ body: newBody
104+ });
105+ console.log("🚀 PR 본문이 성공적으로 업데이트되었습니다.");
106+ } else {
107+ console.log("⚠️ 변경할 내용이 없거나 이미 정보가 채워져 있습니다.");
108+ }
0 commit comments