Files
OrcaSlicer_WIKI/.github/workflows/validate_list_indentation.yml
dependabot[bot] 7e5e2ca296 Bump actions/github-script from 8 to 9 (#222)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-01 14:29:03 -03:00

141 lines
4.7 KiB
YAML

name: Validate List Indentation
on:
pull_request:
paths:
- '**/*.md'
- '**/*.markdown'
- '**/*.mdown'
- '**/*.mkd'
- '**/*.mkdn'
- '**/*.mdx'
workflow_dispatch:
jobs:
list-indentation:
runs-on: ubuntu-latest
permissions:
contents: read
env:
ERROR_BLOCK: ''
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Validate list indentation
uses: actions/github-script@v9
with:
script: |
const fs = require('fs');
const path = require('path');
const workspace = process.cwd();
const allowedExt = new Set(['.md', '.markdown', '.mdown', '.mkd', '.mkdn', '.mdx']);
// Get changed files if running in PR context
let filesToCheck = [];
if (context.eventName === 'pull_request') {
const response = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
filesToCheck = response.data
.filter(file => {
const ext = path.extname(file.filename).toLowerCase();
return allowedExt.has(ext);
})
.map(file => file.filename);
} else {
// For workflow_dispatch, check all markdown files
filesToCheck = collectAllMarkdownFiles('');
}
if (!filesToCheck.length) {
core.info('No Markdown files found; skipping list indentation validation.');
return;
}
const failures = [];
for (const relPath of filesToCheck) {
const absolutePath = path.join(workspace, relPath);
if (!fs.existsSync(absolutePath)) {
continue;
}
const text = fs.readFileSync(absolutePath, 'utf8');
const lines = text.split('\n');
lines.forEach((line, index) => {
const lineNum = index + 1;
// Match ALL list patterns: "- ", "* ", "[number]. "
const listPattern = /^(\s*)(?:[-*]|\d+\.)\s+/;
const match = line.match(listPattern);
if (match) {
const indentation = match[1].length;
// Check if indentation is 0 or a multiple of 4
if (indentation !== 0 && indentation % 4 !== 0) {
failures.push({
filePath: relPath,
line: lineNum,
indentation: indentation,
content: line.trim(),
});
}
}
});
}
if (failures.length) {
const lines = failures.map((failure) => {
return `${failure.filePath} line ${failure.line}: indentation is ${failure.indentation} spaces (must be 0 or a multiple of 4)`;
});
const block = lines.join('\n');
core.exportVariable('ERROR_BLOCK', block);
return;
}
core.exportVariable('ERROR_BLOCK', '');
core.info(`Validated list indentation in ${filesToCheck.length} file(s). All valid.`);
function collectAllMarkdownFiles(relativeDir) {
const files = [];
const absoluteDir = relativeDir ? path.join(workspace, relativeDir) : workspace;
let entries;
try {
entries = fs.readdirSync(absoluteDir, { withFileTypes: true });
} catch (_) {
return files;
}
for (const entry of entries) {
if (entry.name === '.git' || entry.name === 'node_modules' || entry.name.startsWith('.')) {
continue;
}
const relPath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
if (entry.isDirectory()) {
files.push(...collectAllMarkdownFiles(relPath));
} else if (entry.isFile()) {
const ext = path.extname(entry.name).toLowerCase();
if (allowedExt.has(ext)) {
files.push(relPath.replace(/\\/g, '/'));
}
}
}
return files;
}
- name: Show invalid list indentation
if: env.ERROR_BLOCK != ''
run: |
echo 'Invalid list indentation:'
printf "\`\`\`\n%s\n\`\`\`\n" "${{ env.ERROR_BLOCK }}"
exit 1