Files
blog/scripts/search/prepare-index.js
Gabriel Vidal e97299f282 chore: add a repeatable zipgo deploy + fix the one-build-stale search index
There was no deploy path in the repo at all — the site is served by zipgo on
raspy2, but that was done by hand, so `search-project -u blog.dev.gabvdl.xyz`
found nothing and each deploy was ad-hoc. Add `scripts/deploy.sh` (zipgo deploy
CLI, same shape as the other projects), an `npm run deploy`, and the
`zipgo.deploy` host→folder map. Deliberately no og-screenshot step: the site
ships a curated public/og-image.png that a screenshot would only degrade.

Also fix a real bug this surfaced. `prepare-index.js` runs as `postbuild`, i.e.
AFTER astro copies public/ into dist/, so it only ever updated public/ — and
dist/search-index.json (the one that actually ships) held the PREVIOUS build's
index. Every deploy shipped a search index one post behind. It now mirrors the
index into dist/ as well, tolerating a missing dist/ for a bare postbuild run.

Document the deploy and the Gitea/GitHub remote split in the README.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 12:59:18 +02:00

50 lines
2.0 KiB
JavaScript

import path from 'path'
import { promises as fs } from 'fs'
import { globby } from 'globby'
import grayMatter from 'gray-matter'
(async function () {
// prepare the dirs
const srcDir = path.join(process.cwd(), 'src')
const publicDir = path.join(process.cwd(), 'public')
const contentBlogDir = path.join(srcDir, 'content', 'blog')
const contentFilePattern = path.join(contentBlogDir, '*.md')
const indexFile = path.join(publicDir, 'search-index.json')
const getSlugFromPathname = (pathname) => path.basename(pathname, path.extname(pathname))
const contentFilePaths = await globby([ contentFilePattern ])
if(contentFilePaths.length) {
const files = contentFilePaths.map(async(filePath) => await fs.readFile(filePath, 'utf8'))
const index = []
let i = 0
for await (let file of files){
const { data: { title, description, tags }, content } = grayMatter(file)
index.push({
slug: getSlugFromPathname(contentFilePaths[i]),
category: 'blog',
title,
description,
tags,
body: content
})
i++
}
await fs.writeFile(indexFile, JSON.stringify(index))
console.log(`Indexed ${index.length} documents from ${contentBlogDir} to ${indexFile}`)
// This runs as `postbuild`, i.e. AFTER astro has already copied public/
// into dist/ — so writing only to public/ leaves dist/ holding the
// PREVIOUS run's index, and every deploy ships a search index one build
// behind. Mirror it into dist/ when that exists.
const distIndexFile = path.join(process.cwd(), 'dist', 'search-index.json')
try {
await fs.writeFile(distIndexFile, JSON.stringify(index))
console.log(`Mirrored the index into ${distIndexFile}`)
} catch (err) {
if (err.code !== 'ENOENT') throw err // no dist/ = a bare postbuild run
}
}
})();