2024-03-14 20:38:20 +02:00
|
|
|
import * as fs from 'fs-extra';
|
|
|
|
import { execCommand, rootDir } from './tool-utils';
|
2022-11-13 13:37:05 +02:00
|
|
|
const md5File = require('md5-file');
|
2024-03-14 20:38:20 +02:00
|
|
|
import * as glob from 'glob';
|
2018-05-25 14:30:27 +02:00
|
|
|
|
2020-11-06 23:41:12 +02:00
|
|
|
const clipperDir = `${rootDir}/packages/app-clipper`;
|
2020-03-02 20:18:06 +02:00
|
|
|
const tmpSourceDirName = 'Clipper-source';
|
2018-05-25 14:30:27 +02:00
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function copyDir(baseSourceDir: string, sourcePath: string, baseDestDir: string) {
|
2019-09-19 23:51:18 +02:00
|
|
|
await fs.mkdirp(`${baseDestDir}/${sourcePath}`);
|
|
|
|
await fs.copy(`${baseSourceDir}/${sourcePath}`, `${baseDestDir}/${sourcePath}`);
|
2018-05-25 14:30:27 +02:00
|
|
|
}
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function copyToDist(distDir: string) {
|
2018-05-25 14:30:27 +02:00
|
|
|
await copyDir(clipperDir, 'popup/build', distDir);
|
|
|
|
await copyDir(clipperDir, 'content_scripts', distDir);
|
|
|
|
await copyDir(clipperDir, 'icons', distDir);
|
2024-03-14 20:38:20 +02:00
|
|
|
await copyDir(clipperDir, 'util', distDir);
|
|
|
|
await fs.copy(`${clipperDir}/service_worker.mjs`, `${distDir}/service_worker.mjs`);
|
2019-09-19 23:51:18 +02:00
|
|
|
await fs.copy(`${clipperDir}/manifest.json`, `${distDir}/manifest.json`);
|
|
|
|
await fs.remove(`${distDir}/popup/build/manifest.json`);
|
2018-05-25 14:30:27 +02:00
|
|
|
}
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function updateManifestVersionNumber(manifestPath: string) {
|
2018-06-14 20:11:22 +02:00
|
|
|
const manifestText = await fs.readFile(manifestPath, 'utf-8');
|
2020-03-14 01:46:14 +02:00
|
|
|
const manifest = JSON.parse(manifestText);
|
|
|
|
const v = manifest.version.split('.');
|
2018-06-14 20:11:22 +02:00
|
|
|
const buildNumber = Number(v.pop()) + 1;
|
|
|
|
v.push(buildNumber);
|
|
|
|
manifest.version = v.join('.');
|
2019-09-19 23:51:18 +02:00
|
|
|
console.info(`New version: ${manifest.version}`);
|
2018-06-14 20:11:22 +02:00
|
|
|
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 4));
|
2018-06-28 23:16:15 +02:00
|
|
|
return manifest.version;
|
2018-06-14 20:11:22 +02:00
|
|
|
}
|
|
|
|
|
2020-03-11 01:01:05 +02:00
|
|
|
async function createSourceZip() {
|
|
|
|
const tmpSourceDir = `${__dirname}/../${tmpSourceDirName}`;
|
|
|
|
const filename = 'joplin-webclipper-source.zip';
|
|
|
|
const filePath = `${clipperDir}/dist/${filename}`;
|
|
|
|
console.info('Creating source tarball for code validation...');
|
|
|
|
console.info(`Chdir: ${clipperDir}/..`);
|
|
|
|
process.chdir(`${clipperDir}/..`);
|
|
|
|
console.info(await execCommand(`rm -f "${filePath}"`));
|
|
|
|
console.info(await execCommand(`rsync -a --delete --exclude 'node_modules/' --exclude 'build/' --exclude 'dist/' "${clipperDir}/" "${tmpSourceDir}/"`));
|
|
|
|
console.info(await execCommand(`7z a -tzip ${filename} "${tmpSourceDirName}"`));
|
|
|
|
console.info(await execCommand(`mv ${filename} "${clipperDir}/dist/" && rm -rf "${tmpSourceDirName}"`));
|
|
|
|
|
|
|
|
return filePath;
|
|
|
|
}
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function compareFiles(path1: string, path2: string) {
|
2020-03-11 01:01:05 +02:00
|
|
|
return await md5File(path1) === await md5File(path2);
|
|
|
|
}
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function compareDir(dir1: string, dir2: string) {
|
2020-03-11 01:01:05 +02:00
|
|
|
console.info(`Comparing directories ${dir1} to ${dir2}`);
|
|
|
|
|
|
|
|
const globOptions = {
|
|
|
|
ignore: [
|
|
|
|
'**/node_modules/**',
|
|
|
|
'**/.git/**',
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
const filterFiles = (f: string) => {
|
2020-03-11 01:01:05 +02:00
|
|
|
const stat = fs.statSync(f);
|
|
|
|
return !stat.isDirectory();
|
|
|
|
};
|
|
|
|
|
2020-05-21 10:14:33 +02:00
|
|
|
const files1 = glob.sync(`${dir1}/**/*`, globOptions).filter(filterFiles).map(f => f.substr(dir1.length + 1));
|
|
|
|
const files2 = glob.sync(`${dir2}/**/*`, globOptions).filter(filterFiles).map(f => f.substr(dir2.length + 1));
|
2020-03-11 01:01:05 +02:00
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
const missingFiles1: string[] = [];
|
|
|
|
const missingFiles2: string[] = [];
|
|
|
|
const canBeMissing1: string[] = [];
|
|
|
|
const canBeMissing2: string[] = ['manifest.json'];
|
|
|
|
const differentFiles: string[] = [];
|
2020-03-11 01:01:05 +02:00
|
|
|
for (const f of files1) {
|
|
|
|
if (!files2.includes(f)) {
|
|
|
|
if (canBeMissing2.includes(f)) continue;
|
|
|
|
missingFiles2.push(f);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const sameFiles = await compareFiles(`${dir1}/${f}`, `${dir2}/${f}`);
|
|
|
|
if (!sameFiles) differentFiles.push(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const f of files2) {
|
|
|
|
if (!files1.includes(f)) {
|
|
|
|
if (canBeMissing1.includes(f)) continue;
|
|
|
|
missingFiles1.push(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (missingFiles1.length) console.info(`Missing from ${dir1}:`, missingFiles1);
|
|
|
|
if (missingFiles2.length) console.info(`Missing from ${dir2}:`, missingFiles2);
|
|
|
|
if (differentFiles.length) console.info(`Different files: ${differentFiles}`);
|
|
|
|
|
|
|
|
if (!differentFiles.length && !missingFiles1.length && !missingFiles2.length) {
|
|
|
|
console.info('All files are equal');
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function checkSourceZip(sourceZip: string, compiledZip: string) {
|
2020-03-11 01:01:05 +02:00
|
|
|
const tmpDir = `${require('os').tmpdir()}/${Date.now()}`;
|
|
|
|
|
|
|
|
console.info(`Checking source ZIP in ${tmpDir}`);
|
|
|
|
|
|
|
|
const sourceDir = `${tmpDir}/source`;
|
|
|
|
const compiledDir = `${tmpDir}/compiled`;
|
|
|
|
await fs.mkdirp(sourceDir);
|
|
|
|
await fs.mkdirp(compiledDir);
|
|
|
|
|
|
|
|
process.chdir(sourceDir);
|
|
|
|
console.info(await execCommand(`cp "${sourceZip}" .`));
|
|
|
|
console.info(await execCommand(`unzip "${sourceZip}"`));
|
|
|
|
process.chdir(`${sourceDir}/Clipper-source/popup`);
|
2022-06-06 17:13:03 +02:00
|
|
|
console.info(await execCommand('npm install'));
|
2024-03-14 20:38:20 +02:00
|
|
|
console.info(await execCommand('npm run build'));
|
2020-03-11 01:01:05 +02:00
|
|
|
|
|
|
|
process.chdir(compiledDir);
|
|
|
|
console.info(await execCommand(`cp "${compiledZip}" .`));
|
|
|
|
console.info(await execCommand(`unzip "${compiledZip}"`));
|
|
|
|
|
|
|
|
const areEqual = await compareDir(`${sourceDir}/Clipper-source/popup/build`, `${compiledDir}/popup/build`);
|
|
|
|
|
|
|
|
if (areEqual) {
|
|
|
|
await fs.remove(sourceDir);
|
|
|
|
await fs.remove(compiledDir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
async function setReleaseMode(isReleaseMode: boolean) {
|
|
|
|
const joplinEnvPath = `${clipperDir}/util/joplinEnv.mjs`;
|
|
|
|
await fs.writeFile(joplinEnvPath, `// AUTOGENERATED by release-clipper\n\nexport default () => '${isReleaseMode ? 'prod' : 'dev'}';`);
|
|
|
|
}
|
|
|
|
|
2018-05-25 14:30:27 +02:00
|
|
|
async function main() {
|
2020-02-23 23:15:37 +02:00
|
|
|
console.info(await execCommand('git pull'));
|
|
|
|
|
2019-09-19 23:51:18 +02:00
|
|
|
const newVersion = await updateManifestVersionNumber(`${clipperDir}/manifest.json`);
|
2018-05-25 14:30:27 +02:00
|
|
|
|
2018-06-14 20:11:22 +02:00
|
|
|
console.info('Building extension...');
|
2019-09-19 23:51:18 +02:00
|
|
|
process.chdir(`${clipperDir}/popup`);
|
2024-03-14 20:38:20 +02:00
|
|
|
await setReleaseMode(true);
|
2020-03-11 01:01:05 +02:00
|
|
|
console.info(await execCommand(`rm -rf ${clipperDir}/popup/build`));
|
2022-06-06 17:10:21 +02:00
|
|
|
console.info(await execCommand('npm run build'));
|
2018-05-25 14:30:27 +02:00
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
type PlatformDistOptions = {
|
2024-04-05 13:16:49 +02:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
2024-03-14 20:38:20 +02:00
|
|
|
removeManifestKeys(manifest: Record<string, any>): Record<string, any>;
|
|
|
|
outputPath?: string;
|
|
|
|
};
|
|
|
|
const dists: Record<string, PlatformDistOptions> = {
|
2020-03-11 01:01:05 +02:00
|
|
|
chrome: {
|
2018-06-14 20:11:22 +02:00
|
|
|
removeManifestKeys: (manifest) => {
|
2023-06-01 13:02:36 +02:00
|
|
|
manifest = { ...manifest };
|
2024-03-14 20:38:20 +02:00
|
|
|
delete manifest.browser_specific_settings;
|
|
|
|
|
|
|
|
manifest.background = { ...manifest.background };
|
|
|
|
delete manifest.background.scripts;
|
|
|
|
delete manifest.background.persistent;
|
|
|
|
|
2018-06-14 20:11:22 +02:00
|
|
|
return manifest;
|
|
|
|
},
|
|
|
|
},
|
2020-03-11 01:01:05 +02:00
|
|
|
firefox: {
|
2018-06-14 20:11:22 +02:00
|
|
|
removeManifestKeys: (manifest) => {
|
2023-06-01 13:02:36 +02:00
|
|
|
manifest = { ...manifest };
|
2024-03-14 20:38:20 +02:00
|
|
|
|
|
|
|
manifest.background = { ...manifest.background };
|
|
|
|
delete manifest.background.service_worker;
|
|
|
|
|
2018-06-14 20:11:22 +02:00
|
|
|
return manifest;
|
|
|
|
},
|
2019-07-30 09:35:42 +02:00
|
|
|
},
|
2020-03-11 01:01:05 +02:00
|
|
|
};
|
2018-05-25 14:30:27 +02:00
|
|
|
|
2020-03-14 01:46:14 +02:00
|
|
|
for (const distName in dists) {
|
2020-03-11 01:01:05 +02:00
|
|
|
const dist = dists[distName];
|
|
|
|
const distDir = `${clipperDir}/dist/${distName}`;
|
|
|
|
await fs.remove(distDir);
|
|
|
|
await fs.mkdirp(distDir);
|
|
|
|
await copyToDist(distDir);
|
2018-06-14 20:11:22 +02:00
|
|
|
|
2020-03-11 01:01:05 +02:00
|
|
|
const manifestText = await fs.readFile(`${distDir}/manifest.json`, 'utf-8');
|
2018-06-14 20:11:22 +02:00
|
|
|
let manifest = JSON.parse(manifestText);
|
|
|
|
manifest.name = 'Joplin Web Clipper';
|
|
|
|
if (dist.removeManifestKeys) manifest = dist.removeManifestKeys(manifest);
|
2020-03-11 01:01:05 +02:00
|
|
|
await fs.writeFile(`${distDir}/manifest.json`, JSON.stringify(manifest, null, 4));
|
|
|
|
|
|
|
|
process.chdir(distDir);
|
|
|
|
console.info(await execCommand(`rm -f "${distName}.zip"`));
|
|
|
|
console.info(await execCommand(`7z a -tzip ${distName}.zip *`));
|
|
|
|
console.info(await execCommand(`mv ${distName}.zip ..`));
|
2018-06-14 20:11:22 +02:00
|
|
|
|
2020-03-11 01:01:05 +02:00
|
|
|
dists[distName].outputPath = `${clipperDir}/dist/${distName}.zip`;
|
2018-05-25 14:30:27 +02:00
|
|
|
}
|
2018-06-28 23:16:15 +02:00
|
|
|
|
2020-03-11 01:01:05 +02:00
|
|
|
const sourceZip = await createSourceZip();
|
|
|
|
await checkSourceZip(sourceZip, dists.firefox.outputPath);
|
2019-06-13 00:11:24 +02:00
|
|
|
|
2024-03-14 20:38:20 +02:00
|
|
|
await setReleaseMode(false);
|
|
|
|
|
2020-03-11 01:01:05 +02:00
|
|
|
process.chdir(clipperDir);
|
2024-03-14 20:38:20 +02:00
|
|
|
if (!process.argv.includes('--no-publish')) {
|
|
|
|
console.info(await execCommand('git add -A'));
|
|
|
|
console.info(await execCommand(`git commit -m "Clipper release v${newVersion}"`));
|
|
|
|
console.info(await execCommand(`git tag clipper-${newVersion}`));
|
|
|
|
console.info(await execCommand('git push'));
|
|
|
|
console.info(await execCommand('git push --tags'));
|
|
|
|
}
|
2018-05-25 14:30:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
main().catch((error) => {
|
|
|
|
console.error('Fatal error');
|
|
|
|
console.error(error);
|
|
|
|
process.exit(1);
|
2019-07-30 09:35:42 +02:00
|
|
|
});
|