Skip to content

Commit 6ef79e0

Browse files
committed
chore: develop
1 parent 20548fc commit 6ef79e0

File tree

3 files changed

+54
-40
lines changed

3 files changed

+54
-40
lines changed

.github/workflows/run_tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424

2525
- name: Run tests with coverage
2626
run: yarn vitest run --coverage
27+
2728

2829
# - name: Upload coverage to Codecov
2930
# uses: codecov/codecov-action@v5

.github/workflows/todo.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,22 @@ jobs:
4343
git add TODO_REPORT.md
4444
git commit -m "chore(report): update TODO report" || echo "No changes"
4545
git push
46+
47+
- name: Generate Changelog from TODOs
48+
run: |
49+
yarn changelog
50+
git diff --quiet CHANGELOG.md || echo "Changelog updated"
51+
52+
- name: Commit CHANGELOG.md if changed
53+
if: success()
54+
run: |
55+
if git diff --quiet CHANGELOG.md; then
56+
echo "No changelog changes to commit."
57+
else
58+
git config --global user.name "github-actions[bot]"
59+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
60+
git add CHANGELOG.md
61+
git commit -m "chore(changelog): update CHANGELOG from TODOs"
62+
git push
63+
fi
64+

src/generateChangelog.ts

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,55 @@
1-
// scripts/generateChangelog.ts
2-
31
import fs from 'fs';
42
import path from 'path';
5-
import { extractTodosFromDir } from '../src/parser/extractTodosFromDir';
6-
import { labelsFromTodo } from '../src/core/labelManager';
7-
import { TodoItem } from '../src/parser/types';
3+
import { extractTodosFromDir } from './core/extractTodosFromDir';
4+
import { classifyTodoText } from './core/classifier';
5+
import { TodoItem } from './parser/types';
6+
7+
function formatGroupHeader(tag: string, semantic: string, metadataKey?: string, metadataValue?: string): string {
8+
const parts = [tag];
9+
if (semantic) parts.push(semantic);
10+
if (metadataKey && metadataValue) parts.push(`${metadataKey}:${metadataValue}`);
11+
return `## ${parts.join(' · ')}`;
12+
}
813

9-
// Util: agrupador por chave composta
10-
function groupTodos(todos: TodoItem[]): Record<string, TodoItem[]> {
11-
const groups: Record<string, TodoItem[]> = {};
14+
function generateChangelogContent(todos: TodoItem[]): string {
15+
type GroupKey = string;
16+
const groups: Record<GroupKey, TodoItem[]> = {};
1217

1318
for (const todo of todos) {
14-
const semanticLabels = labelsFromTodo(todo);
15-
const meta = todo.metadata ?? {};
16-
17-
for (const label of semanticLabels) {
18-
const metaKeys = Object.entries(meta)
19-
.map(([k, v]) => `${k}:${v}`)
20-
.join(', ');
21-
22-
const key = `[${todo.tag}] + [${label}]${metaKeys ? ` + [${metaKeys}]` : ''}`;
23-
24-
if (!groups[key]) groups[key] = [];
25-
groups[key].push(todo);
19+
const semantics = classifyTodoText(todo.text);
20+
const metadataEntries = Object.entries(todo.metadata || {}) || [['', '']];
21+
const tag = todo.tag.toUpperCase();
22+
23+
for (const semantic of semantics.length ? semantics : ['']) {
24+
for (const [metaKey, metaValue] of metadataEntries.length ? metadataEntries : [['', '']]) {
25+
const key = JSON.stringify({ tag, semantic, metaKey, metaValue });
26+
if (!groups[key]) groups[key] = [];
27+
groups[key].push(todo);
28+
}
2629
}
2730
}
2831

29-
return groups;
30-
}
31-
32-
// Util: gera string formatada para cada grupo
33-
function formatChangelog(groups: Record<string, TodoItem[]>): string {
34-
const lines: string[] = [];
32+
const output: string[] = ['# 📝 Changelog (from TODOs)', ''];
3533

36-
for (const key of Object.keys(groups).sort()) {
37-
lines.push(`## ${key}\n`);
34+
for (const key of Object.keys(groups)) {
35+
const { tag, semantic, metaKey, metaValue } = JSON.parse(key);
36+
output.push(formatGroupHeader(tag, semantic, metaKey, metaValue));
3837

3938
for (const todo of groups[key]) {
40-
lines.push(`- (${todo.file}:${todo.line}) ${todo.text}`);
39+
output.push(`- ${todo.text} (\`${todo.file}:${todo.line}\`)`);
4140
}
4241

43-
lines.push('');
42+
output.push('');
4443
}
4544

46-
return lines.join('\n');
45+
return output.join('\n');
4746
}
4847

4948
async function main() {
50-
const todos = await extractTodosFromDir('./');
51-
const grouped = groupTodos(todos);
52-
const changelog = formatChangelog(grouped);
53-
54-
const filePath = path.resolve('CHANGELOG.md');
55-
fs.writeFileSync(filePath, changelog, 'utf-8');
56-
57-
console.log(`📦 Changelog gerado com ${todos.length} TODOs agrupados → ${filePath}`);
49+
const todos = await extractTodosFromDir('src');
50+
const changelog = generateChangelogContent(todos);
51+
fs.writeFileSync('CHANGELOG.md', changelog, 'utf8');
52+
console.log('✅ Changelog saved to CHANGELOG.md');
5853
}
5954

6055
main();
61-

0 commit comments

Comments
 (0)