Add one-command dev-to-prod release with clear SUCCESS/FAILED banners.
Introduce devtoprod:release orchestrator, config file, CLI result footers on deploy scripts, auto-thumb regeneration on curator fixes, and updated deploy documentation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
313666a4ab
commit
21e3e41e48
+20
-15
@@ -201,11 +201,21 @@ async function writePortraitThumb(fullPath, safeBase) {
|
||||
try {
|
||||
await generateThumbnailFromFull(fullPath, thumbDest, PORTRAIT_THUMB_WIDTH);
|
||||
return path.join('portraits', 'thumbs', `${safeBase}_thumb.jpg`).replace(/\\/g, '/');
|
||||
} catch {
|
||||
} catch (err) {
|
||||
console.warn(`Portrait thumb generation failed for ${safeBase}:`, err.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Regenerate painting thumb from the saved full image (debug fix/upload, ~400px JPEG). */
|
||||
async function writePaintingThumb(fullPath, safeBase) {
|
||||
const thumbsDir = path.join(IMAGE_DIR, 'paintings', 'thumbs');
|
||||
if (!fs.existsSync(thumbsDir)) fs.mkdirSync(thumbsDir, { recursive: true });
|
||||
const thumbDest = path.join(thumbsDir, `${safeBase}_thumb.jpg`);
|
||||
await generateThumbnailFromFull(fullPath, thumbDest);
|
||||
return path.join('paintings', 'thumbs', `${safeBase}_thumb.jpg`).replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
async function updateArtistPortraitPaths(artistId, portraitPath, portraitThumbPath) {
|
||||
await pool.query(
|
||||
`UPDATE artists SET portrait_path = $1, portrait_thumb_path = $2 WHERE id = $3`,
|
||||
@@ -315,16 +325,15 @@ async function replacePaintingImageFromBuffer(paintingId, buffer, mimeType) {
|
||||
|
||||
const fullExt = pickExtFromMime(mimeType);
|
||||
const fullDest = path.join(paintingsDir, safeBase + fullExt);
|
||||
const thumbDest = path.join(thumbsDir, safeBase + '_thumb.jpg');
|
||||
|
||||
unlinkPaintingFiles(row, safeBase);
|
||||
fs.writeFileSync(fullDest, buffer);
|
||||
|
||||
let thumbnailPath = null;
|
||||
let thumbnailPath;
|
||||
try {
|
||||
await generateThumbnailFromFull(fullDest, thumbDest);
|
||||
thumbnailPath = path.join('paintings', 'thumbs', safeBase + '_thumb.jpg').replace(/\\/g, '/');
|
||||
} catch {
|
||||
thumbnailPath = await writePaintingThumb(fullDest, safeBase);
|
||||
} catch (err) {
|
||||
console.warn(`Painting thumb generation failed for painting ${paintingId}:`, err.message);
|
||||
thumbnailPath = path.join('paintings', safeBase + fullExt).replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
@@ -407,20 +416,16 @@ async function replacePaintingImageFromUrl(paintingId, imageUrl, context = {}) {
|
||||
|
||||
const fullExt = pickExt(imageUrl);
|
||||
const fullDest = path.join(paintingsDir, safeBase + fullExt);
|
||||
const thumbDest = path.join(thumbsDir, safeBase + '_thumb.jpg');
|
||||
|
||||
unlinkIfExists(row.image_path ? path.join(IMAGE_DIR, row.image_path) : null);
|
||||
unlinkIfExists(row.thumbnail_path ? path.join(IMAGE_DIR, row.thumbnail_path) : null);
|
||||
unlinkIfExists(fullDest);
|
||||
unlinkIfExists(thumbDest);
|
||||
unlinkPaintingFiles(row, safeBase);
|
||||
|
||||
await downloadImageForFix(imageUrl, fullDest, context);
|
||||
|
||||
let thumbnailPath = null;
|
||||
let thumbnailPath;
|
||||
try {
|
||||
await generateThumbnailFromFull(fullDest, thumbDest);
|
||||
thumbnailPath = path.join('paintings', 'thumbs', safeBase + '_thumb.jpg').replace(/\\/g, '/');
|
||||
} catch {
|
||||
thumbnailPath = await writePaintingThumb(fullDest, safeBase);
|
||||
} catch (err) {
|
||||
console.warn(`Painting thumb generation failed for painting ${paintingId}:`, err.message);
|
||||
thumbnailPath = path.join('paintings', safeBase + fullExt).replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user