diff --git a/.build/generate-icons-comment.mjs b/.build/generate-icons-comment.mjs new file mode 100644 index 000000000..f7a6d165a --- /dev/null +++ b/.build/generate-icons-comment.mjs @@ -0,0 +1,104 @@ +import { execSync } from 'child_process' +import { basename, join } from 'path' +import { ICONS_SRC_DIR, parseMatter } from './helpers.mjs' + +// Check icon files added relative to main branch (for PR) +function getAddedIconsFromMain() { + try { + const output = execSync('git diff origin/main...HEAD --name-status', { encoding: 'utf-8' }) + const addedIcons = [] + + output.split('\n').forEach(line => { + if (line.startsWith('A\t')) { + const filePath = line.substring(2) + // Filter only SVG files from icons/outline/ or icons/filled/ directories + if (filePath.match(/^icons\/(outline|filled)\/.+\.svg$/)) { + const iconPath = filePath.replace(/^icons\//, '') + addedIcons.push(iconPath) + } + } + }) + + return addedIcons + } catch (error) { + // Fallback: check relative to HEAD if origin/main doesn't exist + try { + const output = execSync('git diff --diff-filter=A --name-only', { encoding: 'utf-8' }) + const addedIcons = [] + + output.split('\n').forEach(filePath => { + if (filePath && filePath.match(/^icons\/(outline|filled)\/.+\.svg$/)) { + const iconPath = filePath.replace(/^icons\//, '') + addedIcons.push(iconPath) + } + }) + + return addedIcons + } catch { + return [] + } + } +} + +// Get GitHub raw file URL for icon +function getIconRawUrl(iconPath) { + const repo = process.env.GITHUB_REPOSITORY || 'tabler/tabler-icons' + const ref = process.env.GITHUB_HEAD_REF || process.env.GITHUB_SHA || 'main' + return `https://raw.githubusercontent.com/${repo}/${ref}/icons/${iconPath}` +} + +// Generate markdown table for icons +function generateIconsTable(icons, type) { + if (icons.length === 0) { + return '' + } + + const typeName = type === 'outline' ? 'Outline' : 'Filled' + let markdown = `### ${typeName} Icons (${icons.length})\n\n` + markdown += `| Icon | Name | Category | Tags |\n` + markdown += `|------|------|------|------|\n` + + icons.forEach(iconPath => { + const iconName = basename(iconPath, '.svg') + const rawUrl = getIconRawUrl(iconPath) + + const { data } = parseMatter(join(ICONS_SRC_DIR, iconPath)) + const category = data.category || '' + const tags = data.tags || [] + + // Use GitHub raw file URL - GitHub Comments support external image URLs + markdown += `| ${iconName} | \`${iconName}.svg\` | ${category || '❌ No category'} | ${tags.join(', ') || '❌ No tags' } |\n` + }) + markdown += `\n` + + return markdown +} + +// Generate markdown comment with table of added icons +function generateIconsComment(icons) { + if (icons.length === 0) { + return '' + } + + // Group icons by type (outline/filled) with full paths + const outlineIcons = icons.filter(icon => icon.startsWith('outline/')) + const filledIcons = icons.filter(icon => icon.startsWith('filled/')) + + let markdown = `## 📦 Added Icons\n\n` + markdown += `This PR adds **${icons.length}** new icon${icons.length > 1 ? 's' : ''}.\n\n` + + markdown += generateIconsTable(outlineIcons, 'outline') + markdown += generateIconsTable(filledIcons, 'filled') + + return markdown +} + +const addedIcons = getAddedIconsFromMain() + +if (addedIcons.length > 0) { + const comment = generateIconsComment(addedIcons) + console.log(comment) +} else { + process.exit(0) +} + diff --git a/.build/helpers.mjs b/.build/helpers.mjs index 2528cb96f..ecb0fa00c 100644 --- a/.build/helpers.mjs +++ b/.build/helpers.mjs @@ -20,6 +20,50 @@ export const strokes = { 400: 2, } +export const categories = [ + 'Animals', + 'Arrows', + 'Badges', + 'Brand', + 'Buildings', + 'Charts', + 'Communication', + 'Computers', + 'Currencies', + 'Database', + 'Design', + 'Development', + 'Devices', + 'Document', + 'E-commerce', + 'Electrical', + 'Extensions', + 'Food', + 'Games', + 'Gender', + 'Gestures', + 'Health', + 'Laundry', + 'Letters', + 'Logic', + 'Map', + 'Math', + 'Media', + 'Mood', + 'Nature', + 'Numbers', + 'Photography', + 'Shapes', + 'Sport', + 'Symbols', + 'System', + 'Text', + 'Vehicles', + 'Version control', + 'Weather', + 'Zodiac' +] + export const iconTemplate = (type) => type === 'outline' ? ` ./comment-icons.md || true + continue-on-error: true + + - name: Check if icons were added + id: check-icons + run: | + if [ -s ./comment-icons.md ]; then + echo "has_icons=true" >> $GITHUB_OUTPUT + else + echo "has_icons=false" >> $GITHUB_OUTPUT + fi + + - name: Comment PR with added icons + if: steps.check-icons.outputs.has_icons == 'true' + uses: thollander/actions-comment-pull-request@v3 + with: + file-path: ./comment-icons.md + comment-tag: added-icons + mode: upsert + + - name: Remove comment with added icons + if: steps.check-icons.outputs.has_icons == 'false' + uses: thollander/actions-comment-pull-request@v3 + with: + comment-tag: added-icons + mode: delete \ No newline at end of file diff --git a/comment-icons.md b/comment-icons.md new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json index b39db5fc4..a221c402c 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,8 @@ "build:webfont": "pnpm --filter @tabler/icons-webfont build", "update-readme": "node ./.build/update-readme.mjs", "zip": "node ./.build/zip-files.mjs", - "validate-pr": "node ./.build/validate-pr.mjs" + "validate-pr": "node ./.build/validate-pr.mjs", + "generate-icons-comment": "node ./.build/generate-icons-comment.mjs" }, "devDependencies": { "@11ty/eleventy": "^2.0.1",