mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 22:19:30 +01:00
[MIRROR] Fix github not announcing new prs [MDB IGNORE] (#17216)
* Fix github not announcing new prs * Resets github_webhook_processor.php to upstream version, with our minor modification * Adds the whole pull_request_hooks folder that we also missed from upstream Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com> Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
This commit is contained in:
co-authored by
Kyle Spier-Swenson
GoldenAlpharex
parent
15b114579e
commit
470ea238cb
@@ -43,6 +43,10 @@ $discordWebHooks = array();
|
||||
// Only these repositories will announce in game.
|
||||
// Any repository that players actually care about.
|
||||
$game_announce_whitelist = array(
|
||||
/* SKYRAT EDIT - We want it to announce to us - ORIGINAL:
|
||||
"tgstation",
|
||||
"TerraGov-Marine-Corps",
|
||||
// ORIGINAL END - SKYRAT EDIT: */
|
||||
"Skyrat-tg",
|
||||
);
|
||||
|
||||
@@ -239,7 +243,7 @@ function tag_pr($payload, $opened) {
|
||||
$tags = array();
|
||||
$title = $payload['pull_request']['title'];
|
||||
if($opened) { //you only have one shot on these ones so as to not annoy maintainers
|
||||
$tags = checkchangelog($payload, false);
|
||||
$tags = checkchangelog($payload);
|
||||
|
||||
if(strpos(strtolower($title), 'refactor') !== FALSE)
|
||||
$tags[] = 'Refactor';
|
||||
@@ -271,8 +275,6 @@ function tag_pr($payload, $opened) {
|
||||
check_tag_and_replace($payload, '[dnm]', 'Do Not Merge', $tags);
|
||||
check_tag_and_replace($payload, '[no gbp]', 'GBP: No Update', $tags);
|
||||
|
||||
check_tag_and_replace($payload, '[host]', 'Host Request', $tags);
|
||||
|
||||
return array($tags, $remove);
|
||||
}
|
||||
|
||||
@@ -303,7 +305,7 @@ function check_dismiss_changelog_review($payload){
|
||||
return;
|
||||
|
||||
if(!$no_changelog)
|
||||
checkchangelog($payload, false);
|
||||
checkchangelog($payload);
|
||||
|
||||
$review_message = 'Your changelog for this PR is either malformed or non-existent. Please create one to document your changes.';
|
||||
|
||||
@@ -363,7 +365,7 @@ function handle_pr($payload) {
|
||||
else {
|
||||
$action = 'merged';
|
||||
auto_update($payload);
|
||||
checkchangelog($payload, true);
|
||||
checkchangelog($payload);
|
||||
$validated = TRUE; //pr merged events always get announced.
|
||||
}
|
||||
break;
|
||||
@@ -631,7 +633,7 @@ function has_tree_been_edited($payload, $tree){
|
||||
}
|
||||
|
||||
$no_changelog = false;
|
||||
function checkchangelog($payload, $compile = true) {
|
||||
function checkchangelog($payload) {
|
||||
global $no_changelog;
|
||||
if (!isset($payload['pull_request']) || !isset($payload['pull_request']['body'])) {
|
||||
return;
|
||||
@@ -649,26 +651,16 @@ function checkchangelog($payload, $compile = true) {
|
||||
$body = str_replace("\r\n", "\n", $body);
|
||||
$body = explode("\n", $body);
|
||||
|
||||
$username = $payload['pull_request']['user']['login'];
|
||||
$incltag = false;
|
||||
$changelogbody = array();
|
||||
$currentchangelogblock = array();
|
||||
$foundcltag = false;
|
||||
foreach ($body as $line) {
|
||||
$line = trim($line);
|
||||
if (substr($line,0,4) == ':cl:' || substr($line,0,1) == '??') {
|
||||
$incltag = true;
|
||||
$foundcltag = true;
|
||||
$pos = strpos($line, " ");
|
||||
if ($pos) {
|
||||
$tmp = substr($line, $pos+1);
|
||||
if (trim($tmp) != 'optional name here')
|
||||
$username = $tmp;
|
||||
}
|
||||
continue;
|
||||
} else if (substr($line,0,5) == '/:cl:' || substr($line,0,6) == '/ :cl:' || substr($line,0,5) == ':/cl:' || substr($line,0,5) == '/??' || substr($line,0,6) == '/ ??' ) {
|
||||
$incltag = false;
|
||||
$changelogbody = array_merge($changelogbody, $currentchangelogblock);
|
||||
continue;
|
||||
}
|
||||
if (!$incltag)
|
||||
@@ -684,47 +676,44 @@ function checkchangelog($payload, $compile = true) {
|
||||
$firstword = $line;
|
||||
}
|
||||
|
||||
// Line is empty
|
||||
if (!strlen($firstword)) {
|
||||
if (count($currentchangelogblock) <= 0)
|
||||
continue;
|
||||
$currentchangelogblock[count($currentchangelogblock)-1]['body'] .= "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
//not a prefix line.
|
||||
//so we add it to the last changelog entry as a separate line
|
||||
if (!strlen($firstword) || $firstword[strlen($firstword)-1] != ':') {
|
||||
if (count($currentchangelogblock) <= 0)
|
||||
continue;
|
||||
$currentchangelogblock[count($currentchangelogblock)-1]['body'] .= "\n".$line;
|
||||
continue;
|
||||
}
|
||||
|
||||
$cltype = strtolower(substr($firstword, 0, -1));
|
||||
|
||||
// !!!
|
||||
// !!! If you are changing any of these at the bottom, also edit `tools/pull_request_hooks/changelogConfig.js`.
|
||||
// !!!
|
||||
|
||||
switch ($cltype) {
|
||||
case 'fix':
|
||||
case 'fixes':
|
||||
case 'bugfix':
|
||||
if($item != 'fixed a few things') {
|
||||
$tags[] = 'Fix';
|
||||
$currentchangelogblock[] = array('type' => 'bugfix', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'qol':
|
||||
if($item != 'made something easier to use') {
|
||||
$tags[] = 'Quality of Life';
|
||||
$currentchangelogblock[] = array('type' => 'qol', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'soundadd':
|
||||
if($item != 'added a new sound thingy') {
|
||||
$tags[] = 'Sound';
|
||||
$currentchangelogblock[] = array('type' => 'soundadd', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'sounddel':
|
||||
if($item != 'removed an old sound thingy') {
|
||||
$tags[] = 'Sound';
|
||||
$tags[] = 'Removal';
|
||||
$currentchangelogblock[] = array('type' => 'sounddel', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'add':
|
||||
@@ -732,7 +721,6 @@ function checkchangelog($payload, $compile = true) {
|
||||
case 'rscadd':
|
||||
if($item != 'Added new mechanics or gameplay changes' && $item != 'Added more things') {
|
||||
$tags[] = 'Feature';
|
||||
$currentchangelogblock[] = array('type' => 'rscadd', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'del':
|
||||
@@ -740,95 +728,54 @@ function checkchangelog($payload, $compile = true) {
|
||||
case 'rscdel':
|
||||
if($item != 'Removed old things') {
|
||||
$tags[] = 'Removal';
|
||||
$currentchangelogblock[] = array('type' => 'rscdel', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'imageadd':
|
||||
if($item != 'added some icons and images') {
|
||||
$tags[] = 'Sprites';
|
||||
$currentchangelogblock[] = array('type' => 'imageadd', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'imagedel':
|
||||
if($item != 'deleted some icons and images') {
|
||||
$tags[] = 'Sprites';
|
||||
$tags[] = 'Removal';
|
||||
$currentchangelogblock[] = array('type' => 'imagedel', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'typo':
|
||||
case 'spellcheck':
|
||||
if($item != 'fixed a few typos') {
|
||||
$tags[] = 'Grammar and Formatting';
|
||||
$currentchangelogblock[] = array('type' => 'spellcheck', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'balance':
|
||||
if($item != 'rebalanced something'){
|
||||
$tags[] = 'Balance';
|
||||
$currentchangelogblock[] = array('type' => 'balance', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'code_imp':
|
||||
case 'code':
|
||||
if($item != 'changed some code'){
|
||||
$tags[] = 'Code Improvement';
|
||||
$currentchangelogblock[] = array('type' => 'code_imp', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'refactor':
|
||||
if($item != 'refactored some code'){
|
||||
$tags[] = 'Refactor';
|
||||
$currentchangelogblock[] = array('type' => 'refactor', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'config':
|
||||
if($item != 'changed some config setting'){
|
||||
$tags[] = 'Config Update';
|
||||
$currentchangelogblock[] = array('type' => 'config', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'admin':
|
||||
if($item != 'messed with admin stuff'){
|
||||
$tags[] = 'Administration';
|
||||
$currentchangelogblock[] = array('type' => 'admin', 'body' => $item);
|
||||
}
|
||||
break;
|
||||
case 'server':
|
||||
if($item != 'something server ops should know')
|
||||
$currentchangelogblock[] = array('type' => 'server', 'body' => $item);
|
||||
break;
|
||||
default:
|
||||
//we add it to the last changelog entry as a separate line
|
||||
if (count($currentchangelogblock) > 0)
|
||||
$currentchangelogblock[count($currentchangelogblock)-1]['body'] .= "\n".$line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!count($changelogbody))
|
||||
$no_changelog = true;
|
||||
|
||||
if ($no_changelog || !$compile)
|
||||
return $tags;
|
||||
|
||||
$file = 'author: "'.trim(str_replace(array("\\", '"'), array("\\\\", "\\\""), $username)).'"'."\n";
|
||||
$file .= "delete-after: True\n";
|
||||
$file .= "changes: \n";
|
||||
foreach ($changelogbody as $changelogitem) {
|
||||
$type = $changelogitem['type'];
|
||||
$body = trim(str_replace(array("\\", '"'), array("\\\\", "\\\""), $changelogitem['body']));
|
||||
$file .= ' - '.$type.': "'.$body.'"';
|
||||
$file .= "\n";
|
||||
}
|
||||
$content = array (
|
||||
'branch' => $payload['pull_request']['base']['ref'],
|
||||
'message' => 'Automatic changelog generation for PR #'.$payload['pull_request']['number'].' [ci skip]',
|
||||
'content' => base64_encode($file)
|
||||
);
|
||||
|
||||
$filename = '/html/changelogs/AutoChangeLog-pr-'.$payload['pull_request']['number'].'.yml';
|
||||
echo github_apisend($payload['pull_request']['base']['repo']['url'].'/contents'.$filename, 'PUT', $content);
|
||||
return $tags;
|
||||
}
|
||||
|
||||
function game_server_send($addr, $port, $str) {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { parseChangelog } from "./changelogParser.js";
|
||||
|
||||
const safeYml = (string) =>
|
||||
string.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
||||
|
||||
export function changelogToYml(changelog, login) {
|
||||
const author = changelog.author || login;
|
||||
const ymlLines = [];
|
||||
|
||||
ymlLines.push(`author: "${safeYml(author)}"`);
|
||||
ymlLines.push(`delete-after: True`);
|
||||
ymlLines.push(`changes:`);
|
||||
|
||||
for (const change of changelog.changes) {
|
||||
ymlLines.push(
|
||||
` - ${change.type.changelogKey}: "${safeYml(change.description)}"`
|
||||
);
|
||||
}
|
||||
|
||||
return ymlLines.join("\n");
|
||||
}
|
||||
|
||||
export async function processAutoChangelog({ github, context }) {
|
||||
const changelog = parseChangelog(context.payload.pull_request.body);
|
||||
if (!changelog || changelog.changes.length === 0) {
|
||||
console.log("no changelog found");
|
||||
return;
|
||||
}
|
||||
|
||||
const yml = changelogToYml(
|
||||
changelog,
|
||||
context.payload.pull_request.user.login
|
||||
);
|
||||
|
||||
github.rest.repos.createOrUpdateFileContents({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
path: `html/changelogs/AutoChangeLog-pr-${context.payload.pull_request.number}.yml`,
|
||||
message: `Automatic changelog for PR #${context.payload.pull_request.number} [ci skip]`,
|
||||
content: Buffer.from(yml).toString("base64"),
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { changelogToYml } from "./autoChangelog.js";
|
||||
import { parseChangelog } from "./changelogParser.js";
|
||||
|
||||
assert.equal(
|
||||
changelogToYml(
|
||||
parseChangelog(`
|
||||
My cool PR!
|
||||
:cl: DenverCoder9
|
||||
add: Adds new stuff
|
||||
add: Adds more stuff
|
||||
/:cl:
|
||||
`)
|
||||
),
|
||||
|
||||
`author: "DenverCoder9"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds new stuff"
|
||||
- rscadd: "Adds more stuff"`
|
||||
);
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* A map of changelog phrases to meta-information.
|
||||
*
|
||||
* The first entry in the list is used in the changelog YML file as the key when
|
||||
* used, but other than that all entries are equivalent.
|
||||
*
|
||||
* placeholders - The default messages, if the changelog has this then we pretend it
|
||||
* doesn't exist.
|
||||
*/
|
||||
export const CHANGELOG_ENTRIES = [
|
||||
[
|
||||
["rscadd", "add", "adds"],
|
||||
{
|
||||
placeholders: [
|
||||
"Added new mechanics or gameplay changes",
|
||||
"Added more things",
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["bugfix", "fix", "fixes"],
|
||||
{
|
||||
placeholders: ["fixed a few things"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["rscdel", "del", "dels"],
|
||||
{
|
||||
placeholders: ["Removed old things"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["qol"],
|
||||
{
|
||||
placeholders: ["made something easier to use"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["soundadd"],
|
||||
{
|
||||
placeholders: ["added a new sound thingy"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["sounddel"],
|
||||
{
|
||||
placeholders: ["removed an old sound thingy"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["imageadd"],
|
||||
{
|
||||
placeholders: ["added some icons and images"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["imagedel"],
|
||||
{
|
||||
placeholders: ["deleted some icons and images"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["spellcheck", "typo"],
|
||||
{
|
||||
placeholders: ["fixed a few typos"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["balance"],
|
||||
{
|
||||
placeholders: ["rebalanced something"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["code_imp", "code"],
|
||||
{
|
||||
placeholders: ["changed some code"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["refactor"],
|
||||
{
|
||||
placeholders: ["refactored some code"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["config"],
|
||||
{
|
||||
placeholders: ["changed some config setting"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["admin"],
|
||||
{
|
||||
placeholders: ["messed with admin stuff"],
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
["server"],
|
||||
{
|
||||
placeholders: ["something server ops should know"],
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
// Valid changelog openers
|
||||
export const CHANGELOG_OPEN_TAGS = [":cl:", "??"];
|
||||
|
||||
// Valid changelog closers
|
||||
export const CHANGELOG_CLOSE_TAGS = ["/:cl:", "/ :cl:", ":/cl:", "/??", "/ ??"];
|
||||
|
||||
// Placeholder value for an author
|
||||
export const CHANGELOG_AUTHOR_PLACEHOLDER_NAME = "optional name here";
|
||||
@@ -0,0 +1,80 @@
|
||||
import * as changelogConfig from "./changelogConfig.js";
|
||||
|
||||
const REGEX_CHANGELOG_LINE = /^(\w+): (.+)$/;
|
||||
|
||||
const CHANGELOG_KEYS_TO_ENTRY = {};
|
||||
for (const [types, entry] of changelogConfig.CHANGELOG_ENTRIES) {
|
||||
const entryWithChangelogKey = {
|
||||
...entry,
|
||||
changelogKey: types[0],
|
||||
};
|
||||
|
||||
for (const type of types) {
|
||||
CHANGELOG_KEYS_TO_ENTRY[type] = entryWithChangelogKey;
|
||||
}
|
||||
}
|
||||
|
||||
function parseChangelogBody(lines, openTag) {
|
||||
const [changelogOpening] = lines.splice(0, 1);
|
||||
|
||||
const author =
|
||||
changelogOpening.substring(openTag.length).trim() || undefined;
|
||||
|
||||
const changelog = {
|
||||
author,
|
||||
changes: [],
|
||||
};
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.trim().length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const closeTag of changelogConfig.CHANGELOG_CLOSE_TAGS) {
|
||||
if (line.startsWith(closeTag)) {
|
||||
return changelog;
|
||||
}
|
||||
}
|
||||
|
||||
const match = line.match(REGEX_CHANGELOG_LINE);
|
||||
if (match) {
|
||||
const [_, type, description] = match;
|
||||
|
||||
const entry = CHANGELOG_KEYS_TO_ENTRY[type];
|
||||
|
||||
if (entry.placeholders.includes(description)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
changelog.changes.push({
|
||||
type: entry,
|
||||
description,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const lastChange = changelog.changes[changelog.changes.length - 1];
|
||||
if (lastChange) {
|
||||
lastChange.description += `\n${line}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changelog;
|
||||
}
|
||||
|
||||
export function parseChangelog(text) {
|
||||
const lines = text.split("\n").map((line) => line.trim());
|
||||
|
||||
for (let index = 0; index < lines.length; index++) {
|
||||
const line = lines[index];
|
||||
|
||||
for (const openTag of changelogConfig.CHANGELOG_OPEN_TAGS) {
|
||||
if (line.startsWith(openTag)) {
|
||||
return parseChangelogBody(lines.slice(index), openTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import { parseChangelog } from "./changelogParser.js";
|
||||
|
||||
// Basic test
|
||||
const basicChangelog = parseChangelog(`
|
||||
My cool PR!
|
||||
:cl: DenverCoder9
|
||||
add: Adds new stuff
|
||||
/:cl:
|
||||
`);
|
||||
|
||||
assert.equal(basicChangelog.author, "DenverCoder9");
|
||||
assert.equal(basicChangelog.changes.length, 1);
|
||||
assert.equal(basicChangelog.changes[0].type.changelogKey, "rscadd");
|
||||
assert.equal(basicChangelog.changes[0].description, "Adds new stuff");
|
||||
|
||||
// Multi-line test
|
||||
const multiLineChangelog = parseChangelog(`
|
||||
My cool PR!
|
||||
:cl:
|
||||
add: Adds new stuff
|
||||
to the game
|
||||
/:cl:
|
||||
`);
|
||||
|
||||
assert.equal(multiLineChangelog.author, undefined);
|
||||
assert.equal(multiLineChangelog.changes.length, 1);
|
||||
assert.equal(multiLineChangelog.changes[0].type.changelogKey, "rscadd");
|
||||
assert.equal(
|
||||
multiLineChangelog.changes[0].description,
|
||||
"Adds new stuff\nto the game"
|
||||
);
|
||||
|
||||
// Placeholders
|
||||
const placeholderChangelog = parseChangelog(`
|
||||
My cool PR!
|
||||
:cl:
|
||||
add: Added new mechanics or gameplay changes
|
||||
/:cl:
|
||||
`);
|
||||
|
||||
assert.equal(placeholderChangelog.changes.length, 0);
|
||||
|
||||
// No changelog
|
||||
const noChangelog = parseChangelog(`
|
||||
My cool PR!
|
||||
`);
|
||||
|
||||
assert.equal(noChangelog, undefined);
|
||||
|
||||
// No /:cl:
|
||||
|
||||
const noCloseChangelog = parseChangelog(`
|
||||
My cool PR!
|
||||
:cl:
|
||||
add: Adds new stuff
|
||||
`);
|
||||
|
||||
assert.equal(noCloseChangelog.changes.length, 1);
|
||||
assert.equal(noCloseChangelog.changes[0].type.changelogKey, "rscadd");
|
||||
assert.equal(noCloseChangelog.changes[0].description, "Adds new stuff");
|
||||
|
||||
// :cl: with arbitrary text
|
||||
|
||||
const arbitraryTextChangelog = parseChangelog(`
|
||||
My cool PR!
|
||||
:cl:
|
||||
Adds new stuff
|
||||
/:cl:
|
||||
`);
|
||||
|
||||
assert.equal(arbitraryTextChangelog.changes.length, 0);
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
Reference in New Issue
Block a user