From 5d3cee4271b9c736dbd774ae406ea338af5bf544 Mon Sep 17 00:00:00 2001 From: Timo <6156589+Shik3i@users.noreply.github.com> Date: Sun, 19 Jul 2026 21:41:45 +0200 Subject: [PATCH] fix: update sitemap dates for dirty sources --- scripts/test-website-theme.mjs | 6 +++- website/build.cjs | 58 ++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/scripts/test-website-theme.mjs b/scripts/test-website-theme.mjs index bab02e3..c4630de 100644 --- a/scripts/test-website-theme.mjs +++ b/scripts/test-website-theme.mjs @@ -85,7 +85,11 @@ for (const metadata of requiredSupportSocialMetadata) { } if (!websiteBuild.includes("['log', '-1', '--format=%cs', '--', ...sourceFiles]") || !websiteBuild.includes("lastmod(['website/site-access-help.html'])") - || /const today = new Date\(\)/.test(websiteBuild)) { + || !websiteBuild.includes("['rev-parse', '--is-shallow-repository']") + || !websiteBuild.includes("['diff', '--name-only', '--']") + || !websiteBuild.includes("['diff', '--cached', '--name-only', '--']") + || !websiteBuild.includes("['ls-files', '--others', '--exclude-standard', '--']") + || !websiteBuild.includes('sourceFiles.some(file => dirtySourceFiles.has(file))')) { throw new Error('Sitemap lastmod values must come from the mapped source files in Git'); } const documentedRelayUrls = [...llmsText.matchAll(/`(wss:\/\/[^`\s]+)`/g)].map(([, value]) => new URL(value)); diff --git a/website/build.cjs b/website/build.cjs index 57c4a46..0b5d78d 100644 --- a/website/build.cjs +++ b/website/build.cjs @@ -719,18 +719,61 @@ function generateSitemap(websiteDir, wwwDir) { const repoRoot = path.resolve(websiteDir, '..'); const lastModifiedCache = new Map(); + const dirtySourceFiles = new Set(); + let gitHistoryAvailable = false; + let usedDirtySourceDate = false; + + try { + const isInsideWorkTree = execFileSync( + 'git', ['rev-parse', '--is-inside-work-tree'], + { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] } + ).trim() === 'true'; + const isShallow = execFileSync( + 'git', ['rev-parse', '--is-shallow-repository'], + { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] } + ).trim() === 'true'; + gitHistoryAvailable = isInsideWorkTree && !isShallow; + + if (gitHistoryAvailable) { + const dirtyCommands = [ + ['diff', '--name-only', '--'], + ['diff', '--cached', '--name-only', '--'], + ['ls-files', '--others', '--exclude-standard', '--'] + ]; + for (const args of dirtyCommands) { + const output = execFileSync( + 'git', args, + { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] } + ); + for (const file of output.split(/\r?\n/).filter(Boolean)) { + dirtySourceFiles.add(file.replaceAll('\\', '/')); + } + } + } + } catch (_) { + gitHistoryAvailable = false; + } function getLastModified(sourceFiles) { const cacheKey = sourceFiles.slice().sort().join('\0'); if (lastModifiedCache.has(cacheKey)) return lastModifiedCache.get(cacheKey); + if (!gitHistoryAvailable) { + lastModifiedCache.set(cacheKey, null); + return null; + } let date = null; try { - const output = execFileSync( - 'git', - ['log', '-1', '--format=%cs', '--', ...sourceFiles], - { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] } - ).trim(); - if (/^\d{4}-\d{2}-\d{2}$/.test(output)) date = output; + if (sourceFiles.some(file => dirtySourceFiles.has(file))) { + usedDirtySourceDate = true; + date = new Date().toISOString().slice(0, 10); + } else { + const output = execFileSync( + 'git', + ['log', '-1', '--format=%cs', '--', ...sourceFiles], + { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] } + ).trim(); + if (/^\d{4}-\d{2}-\d{2}$/.test(output)) date = output; + } } catch (_) { // Source archives and minimal deployment environments may not contain // Git metadata. Omitting lastmod is more accurate than inventing a date. @@ -816,6 +859,7 @@ function generateSitemap(websiteDir, wwwDir) { fs.writeFileSync(path.join(wwwDir, 'sitemap.xml'), xml.trim() + '\n', 'utf8'); const datedEntries = (xml.match(//g) || []).length; - console.log(` ✓ Dynamically generated sitemap.xml with ${datedEntries} Git-derived modification dates`); + const dateSource = usedDirtySourceDate ? 'Git/working-tree-derived' : 'Git-derived'; + console.log(` ✓ Dynamically generated sitemap.xml with ${datedEntries} ${dateSource} modification dates`); } compile().catch(err => { console.error('Build failed:', err); process.exit(1); });