Implemented cachebuster for Admin-X Settings and Koenig-Lexical files

fixes https://github.com/TryGhost/DevOps/issues/86

- this will now hash the files and append a cachebuster, so we never
  serve stale files again
This commit is contained in:
Daniel Lockyer 2023-10-05 11:59:00 +02:00 committed by Daniel Lockyer
parent bf9bf9f210
commit 3e42d4b1be
3 changed files with 35 additions and 7 deletions

View File

@ -224,12 +224,12 @@ export const importSettings = async () => {
}
const baseUrl = (config.cdnUrl ? `${config.cdnUrl}assets/` : ghostPaths().assetRootWithHost);
const url = new URL(`${baseUrl}admin-x-settings/admin-x-settings.js`);
const url = new URL(`${baseUrl}admin-x-settings/${config.adminXSettingsFilename}?v=${config.adminXSettingsHash}`);
if (url.protocol === 'http:') {
window['@tryghost/admin-x-settings'] = await import(`http://${url.host}${url.pathname}`);
window['@tryghost/admin-x-settings'] = await import(`http://${url.host}${url.pathname}${url.search}`);
} else {
window['@tryghost/admin-x-settings'] = await import(`https://${url.host}${url.pathname}`);
window['@tryghost/admin-x-settings'] = await import(`https://${url.host}${url.pathname}${url.search}`);
}
return window['@tryghost/admin-x-settings'];

View File

@ -10,12 +10,12 @@ export default async function fetchKoenigLexical() {
// Else, if we pass a CDN URL, use that
// Else, use the asset root from the ghostPaths util
const baseUrl = (config.editorUrl || (config.cdnUrl ? `${config.cdnUrl}assets/koenig-lexical/` : `${ghostPaths().assetRootWithHost}koenig-lexical/`));
const url = new URL(`${baseUrl}koenig-lexical.umd.js`);
const url = new URL(`${baseUrl}${config.editorFilename}?v=${config.editorHash}`);
if (url.protocol === 'http:') {
await import(`http://${url.host}${url.pathname}`);
await import(`http://${url.host}${url.pathname}${url.search}`);
} else {
await import(`https://${url.host}${url.pathname}`);
await import(`https://${url.host}${url.pathname}${url.search}`);
}
return window['@tryghost/koenig-lexical'];

View File

@ -1,18 +1,47 @@
/* eslint-disable */
'use strict';
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const adminXSettingsPath = '../../apps/admin-x-settings/dist';
function generateHash(filePath) {
const fileName = path.basename(filePath);
const fileContents = fs.readFileSync(filePath, 'utf8');
const hash = crypto.createHash('sha256').update(fileContents).digest('hex').slice(0, 10);
return hash;
}
module.exports = {
name: 'asset-delivery',
env: null,
packageConfig: {},
config(env) {
// only set this.env on the first call otherwise when `postBuild()` is
// called this.env will always be 'test' due to multiple `config()` calls
if (!this.env) {
this.env = env;
const koenigLexicalPath = require.resolve('@tryghost/koenig-lexical');
this.packageConfig['editorFilename'] = path.basename(koenigLexicalPath);
this.packageConfig['editorHash'] = process.env.EDITOR_URL ? 'development' : generateHash(koenigLexicalPath);
// TODO: ideally take this from the package, but that's broken thanks to .cjs file ext
const defaultAdminXSettingFilename = 'admin-x-settings.js';
this.packageConfig['adminXSettingsFilename'] = defaultAdminXSettingFilename;
this.packageConfig['adminXSettingsHash'] = (this.env === 'production') ? generateHash(path.join(adminXSettingsPath, defaultAdminXSettingFilename)) : 'development';
if (true) {
console.log('Admin-X Settings:', this.packageConfig['adminXSettingsFilename'], this.packageConfig['adminXSettingsHash']);
console.log('Koenig-Lexical:', this.packageConfig['editorFilename'], this.packageConfig['editorHash']);
}
return this.packageConfig;
}
},
@ -47,7 +76,6 @@ module.exports = {
});
// copy the @tryghost/admin-x-settings assets
const adminXSettingsPath = '../../apps/admin-x-settings/dist';
const assetsAdminXPath = `${assetsOut}/assets/admin-x-settings`;
if (fs.existsSync(adminXSettingsPath)) {