@@ -2,7 +2,7 @@ name: Auto Fill PR from Weekly Issue
22
33on :
44 pull_request :
5- types : [opened, edited]
5+ types : [opened, edited, synchronized ]
66
77jobs :
88 fill-pr-info :
@@ -13,83 +13,83 @@ jobs:
1313 contents : read
1414
1515 steps :
16- - name : Extract info and Update PR
16+ - name : Update PR with Issue Info
1717 uses : actions/github-script@v7
1818 with :
1919 script : |
2020 const pr = context.payload.pull_request;
2121 const title = pr.title;
22- let body = pr.body || "";
2322
24- // 1. 제목에서 주차와 문제번호 추출
23+ console.log(`[분석] PR 제목: ${title}`);
24+
25+ // 1. PR 제목에서 주차 숫자 추출
2526 const weekMatch = title.match(/Week\s*(\d+)/i);
2627 const probNumMatch = title.match(/\d{4,}/);
2728
2829 if (!weekMatch || !probNumMatch) {
29- console.log("주차(Week) 또는 문제번호를 제목에서 찾을 수 없습니다 .");
30+ console.log("❌ 제목에서 주차 또는 문제번호를 추출하지 못했습니다 .");
3031 return;
3132 }
3233
33- const targetWeek = `Week ${ weekMatch[1]}` ;
34+ const weekNum = weekMatch[1];
3435 const targetProbNum = probNumMatch[0];
36+ console.log(`[추출 성공] 주차: ${weekNum}, 문제번호: ${targetProbNum}`);
3537
36- // 2. 해당 주차 이슈 찾기
38+ // 2. 이슈 검색 (상태 상관없이 최근 100개 스캔)
3739 const issues = await github.rest.issues.listForRepo({
3840 owner: context.repo.owner,
3941 repo: context.repo.repo,
40- state: 'open'
42+ state: 'all',
43+ per_page: 100
44+ });
45+
46+ // 3. 이슈 제목 매칭 로직 (특수문자 무시하고 'week' + '숫자'만 확인)
47+ const targetIssue = issues.data.find(i => {
48+ if (i.pull_request) return false;
49+ const cleanTitle = i.title.replace(/[\s\[\]]/g, '').toLowerCase(); // 공백, [, ] 모두 제거
50+ return cleanTitle.includes(`week${weekNum}`);
4151 });
4252
43- const targetIssue = issues.data.find(issue => issue.title.includes(targetWeek));
4453 if (!targetIssue) {
45- console.log(`${targetWeek} 이슈를 찾지 못했습니다.`);
54+ console.log(`❌ [Week${weekNum}] 이슈를 찾지 못했습니다.`);
55+ // 디버깅용: 현재 레포에 있는 이슈 제목들 출력
56+ console.log("현재 탐색된 이슈 목록:");
57+ issues.data.slice(0, 10).forEach(i => console.log(`- ${i.title}`));
4658 return;
4759 }
60+ console.log(`✅ 이슈 발견: #${targetIssue.number} (${targetIssue.title})`);
4861
49- // 3. 이슈에서 문제 섹션 추출
50- const sections = targetIssue.body.split(/문제 \d/);
62+ // 4. 이슈 본문에서 해당 문제 섹션 찾기
63+ const issueBody = targetIssue.body || "";
64+ // '문제 1', '문제 2' 등으로 섹션 분할
65+ const sections = issueBody.split(/문제\s*\d/);
5166 const targetSection = sections.find(s => s.includes(targetProbNum));
5267
5368 if (!targetSection) {
54- console.log(`이슈 내에서 ${targetProbNum}번 정보를 찾지 못했습니다 .`);
69+ console.log(`❌ 이슈 내에 ${targetProbNum}번 문제 정보가 없습니다 .`);
5570 return;
5671 }
5772
58- // 4. 정보 추출
59- const platform = targetSection.match(/플랫폼:\s*(.+)/)?.[1]?.trim() || "";
60- const probName = targetSection.match(/문제 이름:\s*(.+)/)?.[1]?.trim() || "";
61- const probLink = targetSection.match(/링크:\s*(https?:\/\/[^\s]+)/)?.[1]?.trim() || "";
62- const difficulty = targetSection.match(/난이도:\s*(.+)/)?.[1]?.trim() || "";
63-
64- // 5. PR 템플릿의 빈 칸 채우기 (정규표현식 치환)
65- // 템플릿에 있는 기본 문구들을 이슈에서 가져온 실제 데이터로 교체합니다.
66- let newBody = body
67- .replace(/- \*\*플랫폼\*\*:\s*.*$/m, `- **플랫폼**: ${platform}`)
68- .replace(/- \*\*문제 번호\*\*:\s*.*$/m, `- **문제 번호**: ${targetProbNum}`)
69- .replace(/- \*\*문제 이름\*\*:\s*.*$/m, `- **문제 이름**: ${probName}`)
70- .replace(/- \*\*문제 링크\*\*:\s*.*$/m, `- **문제 링크**: ${probLink}`)
71- .replace(/- \*\*난이도\*\*:\s*.*$/m, `- **난이도**: ${difficulty}`);
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*(.+)/);
7280
73- // 6. 변경사항이 있을 때만 업데이트
74- if (newBody !== body) {
75- await github.rest.pulls.update({
76- owner: context.repo.owner,
77- repo: context.repo.repo,
78- pull_number: pr.number,
79- body: newBody
80- });
81- console.log("PR 본문이 성공적으로 업데이트되었습니다.");
82- }
81+ // 6. PR 본문 업데이트
82+ let newBody = (pr.body || "")
83+ .replace(/- \*\*플랫폼\*\*:.*$/m, `- **플랫폼**: ${platform}`)
84+ .replace(/- \*\*문제 번호\*\*:.*$/m, `- **문제 번호**: ${targetProbNum}`)
85+ .replace(/- \*\*문제 이름\*\*:.*$/m, `- **문제 이름**: ${probName}`)
86+ .replace(/- \*\*문제 링크\*\*:.*$/m, `- **문제 링크**: ${probLink}`)
87+ .replace(/- \*\*난이도\*\*:.*$/m, `- **난이도**: ${difficulty}`);
8388
84- // 7. 라벨 추가
85- const labels = [];
86- if (platform.includes("프로그래머스") || title.includes("PGS")) labels.push("프로그래머스");
87- if (platform.includes("백준") || title.includes("BOJ")) labels.push("백준");
88- if (labels.length > 0) {
89- await github.rest.issues.addLabels({
90- owner: context.repo.owner,
91- repo: context.repo.repo,
92- issue_number: pr.number,
93- labels: labels
94- });
95- }
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 본문 업데이트 성공!");
0 commit comments