You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-26 22:41:17 +02:00
Tools: Include packages that have been updated by Renovate in changelog
This commit is contained in:
@@ -8,6 +8,7 @@ interface LogEntry {
|
||||
message: string;
|
||||
commit: string;
|
||||
author: Author;
|
||||
files: string[];
|
||||
}
|
||||
|
||||
enum Platform {
|
||||
@@ -58,6 +59,10 @@ async function gitLog(sinceTag: string) {
|
||||
const authorEmail = splitted[1];
|
||||
const authorName = splitted[2];
|
||||
const message = splitted[3].trim();
|
||||
let files: string[] = [];
|
||||
|
||||
const filesResult = await execCommand(`git diff-tree --no-commit-id --name-only ${commit} -r`);
|
||||
files = filesResult.split('\n').map(s => s.trim()).filter(s => !!s);
|
||||
|
||||
output.push({
|
||||
commit: commit,
|
||||
@@ -67,6 +72,7 @@ async function gitLog(sinceTag: string) {
|
||||
name: authorName,
|
||||
login: await githubUsername(authorEmail, authorName),
|
||||
},
|
||||
files,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -91,6 +97,102 @@ function platformFromTag(tagName: string): Platform {
|
||||
throw new Error(`Could not determine platform from tag: "${tagName}"`);
|
||||
}
|
||||
|
||||
export const filesApplyToPlatform = (files: string[], platform: string): boolean => {
|
||||
const isMainApp = ['android', 'ios', 'desktop', 'cli', 'server'].includes(platform);
|
||||
const isMobile = ['android', 'ios'].includes(platform);
|
||||
|
||||
for (const file of files) {
|
||||
if (file.startsWith('packages/app-cli') && platform === 'cli') return true;
|
||||
if (file.startsWith('packages/app-clipper') && platform === 'clipper') return true;
|
||||
if (file.startsWith('packages/app-mobile') && isMobile) return true;
|
||||
if (file.startsWith('packages/app-desktop') && platform === 'desktop') return true;
|
||||
if (file.startsWith('packages/fork-htmlparser2') && isMainApp) return true;
|
||||
if (file.startsWith('packages/fork-uslug') && isMainApp) return true;
|
||||
if (file.startsWith('packages/htmlpack') && isMainApp) return true;
|
||||
if (file.startsWith('packages/lib') && isMainApp) return true;
|
||||
if (file.startsWith('packages/pdf-viewer') && platform === 'desktop') return true;
|
||||
if (file.startsWith('packages/react-native-') && isMobile) return true;
|
||||
if (file.startsWith('packages/renderer') && isMainApp) return true;
|
||||
if (file.startsWith('packages/server') && platform === 'server') return true;
|
||||
if (file.startsWith('packages/tools') && isMainApp) return true;
|
||||
if (file.startsWith('packages/turndown') && isMainApp) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export interface RenovateMessage {
|
||||
package: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export const parseRenovateMessage = (message: string): RenovateMessage => {
|
||||
const regexes = [
|
||||
/^Update dependency ([^\s]+) to ([^\s]+)/,
|
||||
/^Update ([^\s]+) monorepo to ([^\s]+)/,
|
||||
];
|
||||
|
||||
for (const regex of regexes) {
|
||||
const m = message.match(regex);
|
||||
|
||||
if (m) {
|
||||
return {
|
||||
package: m[1],
|
||||
version: m[2],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Not a Renovate message: ${message}`);
|
||||
};
|
||||
|
||||
export const summarizeRenovateMessages = (messages: RenovateMessage[]): string => {
|
||||
// Exclude some dev dependencies
|
||||
messages = messages.filter(m => {
|
||||
if ([
|
||||
'yeoman-generator',
|
||||
'madge',
|
||||
'lint-staged',
|
||||
'gettext-extractor',
|
||||
'gettext-extractor',
|
||||
'ts-jest',
|
||||
'ts-node',
|
||||
'typescript',
|
||||
'eslint',
|
||||
'jest',
|
||||
].includes(m.package)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.package.startsWith('@types/')) return false;
|
||||
if (m.package.startsWith('typescript-')) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const temp: Record<string, string> = {};
|
||||
for (const message of messages) {
|
||||
if (!temp[message.package]) {
|
||||
temp[message.package] = message.version;
|
||||
} else {
|
||||
if (message.version > temp[message.package]) {
|
||||
temp[message.package] = message.version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const temp2: string[] = [];
|
||||
for (const [pkg, version] of Object.entries(temp)) {
|
||||
temp2.push(`${pkg} (${version})`);
|
||||
}
|
||||
|
||||
temp2.sort();
|
||||
|
||||
if (temp2.length) return `Updated packages ${temp2.join(', ')}`;
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
function filterLogs(logs: LogEntry[], platform: Platform) {
|
||||
const output: LogEntry[] = [];
|
||||
const revertedLogs = [];
|
||||
@@ -98,6 +200,8 @@ function filterLogs(logs: LogEntry[], platform: Platform) {
|
||||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
// let updatedTranslations = false;
|
||||
|
||||
const renovateMessages: RenovateMessage[] = [];
|
||||
|
||||
for (const log of logs) {
|
||||
|
||||
// Save to an array any commit that has been reverted, and exclude
|
||||
@@ -110,9 +214,18 @@ function filterLogs(logs: LogEntry[], platform: Platform) {
|
||||
|
||||
if (revertedLogs.indexOf(log.message) >= 0) continue;
|
||||
|
||||
let isRenovate = false;
|
||||
let prefix = log.message.trim().toLowerCase().split(':');
|
||||
if (prefix.length <= 1) continue;
|
||||
prefix = prefix[0].split(',').map(s => s.trim());
|
||||
if (prefix.length <= 1) {
|
||||
if (log.author && log.author.name === 'renovate[bot]') {
|
||||
prefix = ['renovate'];
|
||||
isRenovate = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
prefix = prefix[0].split(',').map(s => s.trim());
|
||||
}
|
||||
|
||||
let addIt = false;
|
||||
|
||||
@@ -128,6 +241,11 @@ function filterLogs(logs: LogEntry[], platform: Platform) {
|
||||
if (platform === 'server' && prefix.indexOf('server') >= 0) addIt = true;
|
||||
if (platform === 'cloud' && (prefix.indexOf('cloud') >= 0 || prefix.indexOf('server') >= 0)) addIt = true;
|
||||
|
||||
if (isRenovate && filesApplyToPlatform(log.files, platform)) {
|
||||
renovateMessages.push(parseRenovateMessage(log.message));
|
||||
addIt = false;
|
||||
}
|
||||
|
||||
// Translation updates often comes in format "Translation: Update pt_PT.po"
|
||||
// but that's not useful in a changelog especially since most people
|
||||
// don't know country and language codes. So we catch all these and
|
||||
@@ -148,6 +266,16 @@ function filterLogs(logs: LogEntry[], platform: Platform) {
|
||||
// Actually we don't really need this info - translations are being updated all the time
|
||||
// if (updatedTranslations) output.push({ message: 'Updated translations' });
|
||||
|
||||
const renovateSummary = summarizeRenovateMessages(renovateMessages);
|
||||
if (renovateSummary) {
|
||||
output.push({
|
||||
author: { name: '', email: '', login: '' },
|
||||
commit: '',
|
||||
files: [],
|
||||
message: renovateSummary,
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -281,7 +409,9 @@ function formatCommitMessage(commit: string, msg: string, author: Author, option
|
||||
} else {
|
||||
const commitStrings = [commit.substr(0, 7)];
|
||||
if (authorMd) commitStrings.push(`by ${authorMd}`);
|
||||
output += ` (${commitStrings.join(' ')})`;
|
||||
if (commitStrings.join('').length) {
|
||||
output += ` (${commitStrings.join(' ')})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,8 +509,11 @@ async function main() {
|
||||
console.info(changelogString.join('\n'));
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Fatal error');
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
if (require.main === module) {
|
||||
// eslint-disable-next-line promise/prefer-await-to-then
|
||||
main().catch((error) => {
|
||||
console.error('Fatal error');
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user