-
Notifications
You must be signed in to change notification settings - Fork 1
178 lines (146 loc) · 7.25 KB
/
create-weekly-directory.yml
File metadata and controls
178 lines (146 loc) · 7.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
name: Create Weekly Directory
on:
workflow_dispatch:
inputs:
issue_number:
description: '이슈 번호 (예: 1, 2, 3)'
required: true
type: string
jobs:
create-directory:
runs-on: ubuntu-latest
permissions:
contents: write
issues: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get issue info and create directory
id: create
uses: actions/github-script@v7
with:
script: |
const issueNumber = parseInt('${{ inputs.issue_number }}');
// 이슈 정보 가져오기
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber
});
console.log(`📋 Issue title: ${issue.title}`);
console.log(`📝 Issue body:\n${issue.body}`);
// 제목에서 주차 정보 파싱: [Week01] 2026.01.01 ~ 2026.01.07 주차 문제
const titleMatch = issue.title.match(/\[Week(\d+)\]\s*(\d{4}\.\d{2}\.\d{2})\s*~\s*(\d{4}\.\d{2}\.\d{2})/);
if (!titleMatch) {
core.setFailed('이슈 제목 형식이 올바르지 않습니다. [WeekXX] YYYY.MM.DD ~ YYYY.MM.DD 형식이어야 합니다.');
return;
}
const weekNumber = titleMatch[1];
const startDate = titleMatch[2];
const endDate = titleMatch[3];
console.log(`📅 Week: ${weekNumber}, ${startDate} ~ ${endDate}`);
// 이슈 본문에서 문제 정보 파싱
const body = issue.body || '';
const problems = [];
// 문제 섹션 파싱 (#### 문제 1, #### 문제 2, ...)
const problemRegex = /####\s*문제\s*(\d+)[^\n]*\n([\s\S]*?)(?=####\s*문제|\n---|\n###|$)/g;
let match;
while ((match = problemRegex.exec(body)) !== null) {
const problemContent = match[2];
const platform = problemContent.match(/\*\*플랫폼\*\*:\s*([^\n*]+)/)?.[1]?.trim() || '';
const problemNum = problemContent.match(/\*\*문제 번호\*\*:\s*([^\n*]+)/)?.[1]?.trim() || '';
const problemName = problemContent.match(/\*\*문제 이름\*\*:\s*([^\n*]+)/)?.[1]?.trim() || '';
const difficulty = problemContent.match(/\*\*난이도\*\*:\s*([^\n*]+)/)?.[1]?.trim() || '';
const link = problemContent.match(/\*\*링크\*\*:\s*([^\n*]+)/)?.[1]?.trim() || '';
if (platform && problemName) {
problems.push({
platform,
problemNum,
problemName,
difficulty,
link
});
}
}
console.log(`🔍 Found ${problems.length} problems`);
problems.forEach((p, i) => console.log(` ${i+1}. [${p.platform}] ${p.problemNum} - ${p.problemName}`));
// 플랫폼 약어 변환
const getPlatformPrefix = (platform) => {
const p = platform.toLowerCase();
if (p.includes('백준') || p.includes('boj') || p.includes('acmicpc')) return 'BOJ';
if (p.includes('프로그래머스') || p.includes('programmers')) return 'PGS';
if (p.includes('리트코드') || p.includes('leetcode')) return 'LTC';
return 'ETC';
};
// 폴더명 생성 함수 (문제번호가 없거나 -면 플랫폼_문제제목 형태)
const getFolderName = (problem) => {
const prefix = getPlatformPrefix(problem.platform);
const cleanName = problem.problemName.replace(/\s+/g, '');
const hasValidNum = problem.problemNum && problem.problemNum !== '-' && problem.problemNum.trim() !== '';
if (hasValidNum) {
return `${prefix}_${problem.problemNum}_${cleanName}`;
} else {
return `${prefix}_${cleanName}`;
}
};
// README.md 내용 생성
let readmeContent = `# Week ${weekNumber} (${startDate} ~ ${endDate})\n\n`;
readmeContent += `## 📝 이번 주 문제\n\n`;
const folderStructure = [];
problems.forEach((problem, index) => {
const folderName = getFolderName(problem);
folderStructure.push(folderName);
readmeContent += `### 문제 ${index + 1}: ${problem.problemName}\n`;
readmeContent += `- **플랫폼**: ${problem.platform}\n`;
if (problem.problemNum && problem.problemNum !== '-' && problem.problemNum.trim() !== '') {
readmeContent += `- **문제 번호**: ${problem.problemNum}\n`;
}
readmeContent += `- **난이도**: ${problem.difficulty}\n`;
readmeContent += `- **링크**: ${problem.link.startsWith('http') ? `[문제 링크](${problem.link})` : problem.link}\n`;
readmeContent += `\n`;
});
readmeContent += `## 💡 폴더 구조\n\n`;
readmeContent += '```\n';
readmeContent += `week${weekNumber}/\n`;
folderStructure.forEach((folder, i) => {
const prefix = i === folderStructure.length - 1 ? '└──' : '├──';
readmeContent += `${prefix} ${folder}/\n`;
});
readmeContent += '```\n\n';
readmeContent += `## ✅ 진행 현황\n\n`;
readmeContent += `- [ ] @sukangpunch\n`;
readmeContent += `- [ ] @Hexeong\n`;
readmeContent += `- [ ] @whqtker\n`;
readmeContent += `- [ ] @JAEHEE25\n`;
readmeContent += `- [ ] @Gyuhyeok99\n`;
// 출력 설정
const fs = require('fs');
const basePath = `weekly/week${weekNumber}`;
core.setOutput('week_number', weekNumber);
core.setOutput('directory_path', basePath);
core.setOutput('readme_content', readmeContent);
// 주차 디렉토리 생성
if (!fs.existsSync(basePath)) {
fs.mkdirSync(basePath, { recursive: true });
}
// README.md 저장
fs.writeFileSync(`${basePath}/README.md`, readmeContent);
console.log(`\n✅ Created ${basePath}/README.md`);
// 각 문제별 디렉토리 생성 및 응원 파일 생성
const cheerMessage = `# 이번 주도 파이팅!🔥`;
folderStructure.forEach((folder) => {
const problemPath = `${basePath}/${folder}`;
if (!fs.existsSync(problemPath)) {
fs.mkdirSync(problemPath, { recursive: true });
}
fs.writeFileSync(`${problemPath}/.gitkeep`, cheerMessage);
console.log(`✅ Created ${problemPath}/.gitkeep`);
});
- name: Commit and push
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add weekly/
git diff —staged —quiet || git commit -m "[Week${{ steps.create.outputs.week_number }}] 주차별 디렉토리 및 README 생성
🤖 Generated with GitHub Actions"
git push