mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-31 19:02:59 +01:00
Updated checkPlugin to work again and added updated workflow files.
This commit is contained in:
parent
cb56ec0c17
commit
59b87e0631
4 changed files with 82 additions and 26 deletions
|
@ -1,5 +1,3 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Usage -- see README.md
|
* Usage -- see README.md
|
||||||
*
|
*
|
||||||
|
@ -22,9 +20,13 @@ const fsp = fs.promises;
|
||||||
import childProcess from 'node:child_process';
|
import childProcess from 'node:child_process';
|
||||||
import log4js from 'log4js';
|
import log4js from 'log4js';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
import semver from "semver";
|
||||||
|
|
||||||
const logger = log4js.getLogger('checkPlugin');
|
const logger = log4js.getLogger('checkPlugin');
|
||||||
|
log4js.configure({
|
||||||
|
appenders: { console: { type: "console" } },
|
||||||
|
categories: { default: { appenders: ["console"], level: "info" } },
|
||||||
|
});
|
||||||
(async () => {
|
(async () => {
|
||||||
// get plugin name & path from user input
|
// get plugin name & path from user input
|
||||||
const pluginName = process.argv[2];
|
const pluginName = process.argv[2];
|
||||||
|
@ -50,6 +52,7 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
}) || '').toString().replace(/\n+$/, '');
|
}) || '').toString().replace(/\n+$/, '');
|
||||||
|
|
||||||
const writePackageJson = async (obj: object) => {
|
const writePackageJson = async (obj: object) => {
|
||||||
|
console.log("writing package.json",obj)
|
||||||
let s = JSON.stringify(obj, null, 2);
|
let s = JSON.stringify(obj, null, 2);
|
||||||
if (s.length && s.slice(s.length - 1) !== '\n') s += '\n';
|
if (s.length && s.slice(s.length - 1) !== '\n') s += '\n';
|
||||||
return await fsp.writeFile(`${pluginPath}/package.json`, s);
|
return await fsp.writeFile(`${pluginPath}/package.json`, s);
|
||||||
|
@ -74,9 +77,20 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
|
|
||||||
const updateDeps = async (parsedPackageJson: any, key: string, wantDeps: {
|
const updateDeps = async (parsedPackageJson: any, key: string, wantDeps: {
|
||||||
[key: string]: string | {ver?: string, overwrite?: boolean}|null
|
[key: string]: string | {ver?: string, overwrite?: boolean}|null
|
||||||
}) => {
|
}|string) => {
|
||||||
const {[key]: deps = {}} = parsedPackageJson;
|
const {[key]: deps = {}} = parsedPackageJson;
|
||||||
let changed = false;
|
let changed = false;
|
||||||
|
|
||||||
|
if (typeof wantDeps === 'string') {
|
||||||
|
if (deps !== wantDeps) {
|
||||||
|
logger.warn(`Dependency mismatch in ${key}: '${wantDeps}' (current: ${deps})`);
|
||||||
|
if (autoFix) {
|
||||||
|
parsedPackageJson[key] = wantDeps;
|
||||||
|
await writePackageJson(parsedPackageJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (const [pkg, verInfo] of Object.entries(wantDeps)) {
|
for (const [pkg, verInfo] of Object.entries(wantDeps)) {
|
||||||
const {ver, overwrite = true} =
|
const {ver, overwrite = true} =
|
||||||
typeof verInfo === 'string' || verInfo == null ? {ver: verInfo} : verInfo;
|
typeof verInfo === 'string' || verInfo == null ? {ver: verInfo} : verInfo;
|
||||||
|
@ -101,7 +115,12 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
|
|
||||||
const prepareRepo = () => {
|
const prepareRepo = () => {
|
||||||
const modified = execSync('git diff-files --name-status');
|
const modified = execSync('git diff-files --name-status');
|
||||||
if (modified !== '') throw new Error(`working directory has modifications:\n${modified}`);
|
if (modified !== '') {
|
||||||
|
logger.warn('working directory has modifications');
|
||||||
|
if (autoFix)
|
||||||
|
execSync('git stash', {stdio: 'inherit'})
|
||||||
|
//throw new Error(`working directory has modifications:\n${modified}`);
|
||||||
|
}
|
||||||
const untracked = execSync('git ls-files -o --exclude-standard');
|
const untracked = execSync('git ls-files -o --exclude-standard');
|
||||||
if (untracked !== '') throw new Error(`working directory has untracked files:\n${untracked}`);
|
if (untracked !== '') throw new Error(`working directory has untracked files:\n${untracked}`);
|
||||||
const indexStatus = execSync('git diff-index --cached --name-status HEAD');
|
const indexStatus = execSync('git diff-index --cached --name-status HEAD');
|
||||||
|
@ -111,7 +130,7 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
br = execSync('git symbolic-ref HEAD');
|
br = execSync('git symbolic-ref HEAD');
|
||||||
if (!br.startsWith('refs/heads/')) throw new Error('detached HEAD');
|
if (!br.startsWith('refs/heads/')) throw new Error('detached HEAD');
|
||||||
br = br.replace(/^refs\/heads\//, '');
|
br = br.replace(/^refs\/heads\//, '');
|
||||||
execSync('git rev-parse --verify -q HEAD^0 || ' +
|
execSync('git rev-parse --verify -q HEAD || ' +
|
||||||
`{ echo "Error: no commits on ${br}" >&2; exit 1; }`);
|
`{ echo "Error: no commits on ${br}" >&2; exit 1; }`);
|
||||||
execSync('git config --get user.name');
|
execSync('git config --get user.name');
|
||||||
execSync('git config --get user.email');
|
execSync('git config --get user.email');
|
||||||
|
@ -159,7 +178,7 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
if (!files.includes('.git')) throw new Error('No .git folder, aborting');
|
if (!files.includes('.git')) throw new Error('No .git folder, aborting');
|
||||||
prepareRepo();
|
prepareRepo();
|
||||||
|
|
||||||
const workflows = ['backend-tests.yml', 'frontend-tests.yml', 'npmpublish.yml', ''];
|
const workflows = ['backend-tests.yml', 'frontend-tests.yml', 'npmpublish.yml', 'test-and-release.yml'];
|
||||||
await Promise.all(workflows.map(async (fn) => {
|
await Promise.all(workflows.map(async (fn) => {
|
||||||
await checkFile(`bin/plugins/lib/${fn}`, `.github/workflows/${fn}`);
|
await checkFile(`bin/plugins/lib/${fn}`, `.github/workflows/${fn}`);
|
||||||
}));
|
}));
|
||||||
|
@ -174,9 +193,9 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
|
|
||||||
await updateDeps(parsedPackageJSON, 'devDependencies', {
|
await updateDeps(parsedPackageJSON, 'devDependencies', {
|
||||||
'eslint': '^8.57.0',
|
'eslint': '^8.57.0',
|
||||||
'eslint-config-etherpad': '^3.0.22',
|
'eslint-config-etherpad': '^4.0.4',
|
||||||
// Changing the TypeScript version can break plugin code, so leave it alone if present.
|
// Changing the TypeScript version can break plugin code, so leave it alone if present.
|
||||||
'typescript': {ver: '^5.4.2', overwrite: false},
|
'typescript': {ver: '^5.4.2', overwrite: true},
|
||||||
// These were moved to eslint-config-etherpad's dependencies so they can be removed:
|
// These were moved to eslint-config-etherpad's dependencies so they can be removed:
|
||||||
'@typescript-eslint/eslint-plugin': null,
|
'@typescript-eslint/eslint-plugin': null,
|
||||||
'@typescript-eslint/parser': null,
|
'@typescript-eslint/parser': null,
|
||||||
|
@ -191,11 +210,24 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
'eslint-plugin-you-dont-need-lodash-underscore': null,
|
'eslint-plugin-you-dont-need-lodash-underscore': null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const currentVersion = semver.parse(parsedPackageJSON.version)!;
|
||||||
|
const newVersion = currentVersion.inc('patch');
|
||||||
|
|
||||||
|
await updateDeps(parsedPackageJSON, 'version', newVersion.version)
|
||||||
|
|
||||||
|
|
||||||
|
await updateDeps(parsedPackageJSON, 'peerDependencies', {
|
||||||
|
// These were moved to eslint-config-etherpad's dependencies so they can be removed:
|
||||||
|
'ep_etherpad-lite': null,
|
||||||
|
});
|
||||||
|
|
||||||
/*await updateDeps(parsedPackageJSON, 'peerDependencies', {
|
/*await updateDeps(parsedPackageJSON, 'peerDependencies', {
|
||||||
// Some plugins require a newer version of Etherpad so don't overwrite if already set.
|
// Some plugins require a newer version of Etherpad so don't overwrite if already set.
|
||||||
'ep_etherpad-lite': {ver: '>=1.8.6', overwrite: false},
|
'ep_etherpad-lite': {ver: '>=1.8.6', overwrite: false},
|
||||||
});*/
|
});*/
|
||||||
|
|
||||||
|
delete parsedPackageJSON.peerDependencies;
|
||||||
|
|
||||||
await updateDeps(parsedPackageJSON, 'engines', {
|
await updateDeps(parsedPackageJSON, 'engines', {
|
||||||
node: '>=18.0.0',
|
node: '>=18.0.0',
|
||||||
});
|
});
|
||||||
|
@ -230,15 +262,22 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
if (checkEntries(parsedPackageJSON.scripts, {
|
if (checkEntries(parsedPackageJSON.scripts, {
|
||||||
'lint': 'eslint .',
|
'lint': 'eslint .',
|
||||||
'lint:fix': 'eslint --fix .',
|
'lint:fix': 'eslint --fix .',
|
||||||
})) await writePackageJson(parsedPackageJSON);
|
}))
|
||||||
|
await writePackageJson(parsedPackageJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!files.includes('package-lock.json')) {
|
if (!files.includes('pnpm-lock.yaml')) {
|
||||||
logger.warn('package-lock.json not found');
|
logger.warn('pnpm-lock.yaml not found');
|
||||||
if (!autoFix) {
|
if (!autoFix) {
|
||||||
logger.warn('Run pnpm install in the plugin folder and commit the package-lock.json file.');
|
logger.warn('Run pnpm install in the plugin folder and commit the package-lock.json file.');
|
||||||
} else {
|
} else {
|
||||||
logger.info('Autofixing missing package-lock.json file');
|
logger.info('Autofixing missing package-lock.json file');
|
||||||
|
try {
|
||||||
|
fs.statfsSync(`${pluginPath}/package-lock.json`)
|
||||||
|
fs.rmSync(`${pluginPath}/package-lock.json`)
|
||||||
|
} catch (e) {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
execSync('pnpm install', {
|
execSync('pnpm install', {
|
||||||
cwd: `${pluginPath}/`,
|
cwd: `${pluginPath}/`,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
|
@ -366,20 +405,20 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
|
|
||||||
// Install dependencies so we can run ESLint. This should also create or update package-lock.json
|
// Install dependencies so we can run ESLint. This should also create or update package-lock.json
|
||||||
// if autoFix is enabled.
|
// if autoFix is enabled.
|
||||||
const npmInstall = `pnpm install${autoFix ? '' : ' --no-package-lock'}`;
|
const npmInstall = `pnpm install`;
|
||||||
execSync(npmInstall, {stdio: 'inherit'});
|
execSync(npmInstall, {stdio: 'inherit'});
|
||||||
// Create the ep_etherpad-lite symlink if necessary. This must be done after running `npm install`
|
// Create the ep_etherpad-lite symlink if necessary. This must be done after running `npm install`
|
||||||
// because that command nukes the symlink.
|
// because that command nukes the symlink.
|
||||||
try {
|
/*try {
|
||||||
const d = await fsp.realpath(path.join(pluginPath, 'node_modules/ep_etherpad-lite'));
|
const d = await fsp.realpath(path.join(pluginPath, 'node_modules/ep_etherpad-lite'));
|
||||||
assert.equal(d, epSrcDir);
|
assert.equal(d, epSrcDir);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
execSync(`${npmInstall} --no-save ep_etherpad-lite@file:${epSrcDir}`, {stdio: 'inherit'});
|
execSync(`${npmInstall} --no-save ep_etherpad-lite@file:${epSrcDir}`, {stdio: 'inherit'});
|
||||||
}
|
}*/
|
||||||
// linting begins
|
// linting begins
|
||||||
try {
|
try {
|
||||||
logger.info('Linting...');
|
logger.info('Linting...');
|
||||||
const lintCmd = autoFix ? 'npx eslint --fix .' : 'npx eslint';
|
const lintCmd = autoFix ? 'pnpm exec eslint --fix .' : 'npx eslint';
|
||||||
execSync(lintCmd, {stdio: 'inherit'});
|
execSync(lintCmd, {stdio: 'inherit'});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// it is gonna throw an error anyway
|
// it is gonna throw an error anyway
|
||||||
|
@ -388,28 +427,40 @@ const logger = log4js.getLogger('checkPlugin');
|
||||||
// linting ends.
|
// linting ends.
|
||||||
|
|
||||||
if (autoFix) {
|
if (autoFix) {
|
||||||
const unchanged = JSON.parse(execSync(
|
/*const unchanged = JSON.parse(execSync(
|
||||||
'untracked=$(git ls-files -o --exclude-standard) || exit 1; ' +
|
'untracked=$(git ls-files -o --exclude-standard) || exit 1; ' +
|
||||||
'git diff-files --quiet && [ -z "$untracked" ] && echo true || echo false'));
|
'git diff-files --quiet && [ -z "$untracked" ] && echo true || echo false'));*/
|
||||||
if (!unchanged) {
|
|
||||||
|
if (true) {
|
||||||
// Display a diff of changes. Git doesn't diff untracked files, so they must be added to the
|
// Display a diff of changes. Git doesn't diff untracked files, so they must be added to the
|
||||||
// index. Use a temporary index file to avoid modifying Git's default index file.
|
// index. Use a temporary index file to avoid modifying Git's default index file.
|
||||||
execSync('git read-tree HEAD; git add -A && git diff-index -p --cached HEAD && echo ""', {
|
execSync('git read-tree HEAD', {
|
||||||
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
|
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
});
|
});
|
||||||
|
execSync('git add -A', {
|
||||||
|
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
execSync('git diff-index -p --cached HEAD', {
|
||||||
|
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
await fsp.unlink(`${pluginPath}/.git/checkPlugin.index`);
|
await fsp.unlink(`${pluginPath}/.git/checkPlugin.index`);
|
||||||
|
|
||||||
const commitCmd = [
|
const commitCmd = [
|
||||||
'git add -A',
|
'git add -A',
|
||||||
'git commit -m "autofixes from Etherpad checkPlugin.js"',
|
'git commit -m "autofixes from Etherpad checkPlugin.js"',
|
||||||
].join(' && ');
|
]
|
||||||
|
|
||||||
if (autoCommit) {
|
if (autoCommit) {
|
||||||
logger.info('Committing changes...');
|
logger.info('Committing changes...');
|
||||||
execSync(commitCmd, {stdio: 'inherit'});
|
execSync(commitCmd[0], {stdio: 'inherit'});
|
||||||
|
execSync(commitCmd[1], {stdio: 'inherit'});
|
||||||
} else {
|
} else {
|
||||||
logger.info('Fixes applied. Check the above git diff then run the following command:');
|
logger.info('Fixes applied. Check the above git diff then run the following command:');
|
||||||
logger.info(`(cd node_modules/${pluginName} && ${commitCmd})`);
|
logger.info(`(cd node_modules/${pluginName} && ${commitCmd.join(' && ')})`);
|
||||||
}
|
}
|
||||||
const pushCmd = 'git push';
|
const pushCmd = 'git push';
|
||||||
if (autoPush) {
|
if (autoPush) {
|
||||||
|
|
|
@ -83,4 +83,10 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Run the backend tests
|
name: Run the backend tests
|
||||||
working-directory: ./etherpad-lite
|
working-directory: ./etherpad-lite
|
||||||
run: pnpm run test
|
run: |
|
||||||
|
res=$(find .. -path "./node_modules/ep_*/static/tests/backend/specs/**" | wc -l)
|
||||||
|
if [ $res -eq 0 ]; then
|
||||||
|
echo "No backend tests found"
|
||||||
|
else
|
||||||
|
pnpm run test
|
||||||
|
fi
|
||||||
|
|
|
@ -8,7 +8,6 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-npm:
|
publish-npm:
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
|
|
|
@ -10,7 +10,7 @@ jobs:
|
||||||
uses: ./.github/workflows/frontend-tests.yml
|
uses: ./.github/workflows/frontend-tests.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
release:
|
release:
|
||||||
if: ${{ github.ref == 'refs/heads/master'|| github.ref == 'refs/heads/main' }}
|
if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }}
|
||||||
needs:
|
needs:
|
||||||
- backend
|
- backend
|
||||||
- frontend
|
- frontend
|
||||||
|
|
Loading…
Reference in a new issue