Move auto changelog generation into its own workflow (#70652)

I wanted to move auto labeling into its own workflow, but realized that it and changelog generation were coupled. So I'm detaching that first, and then will work on auto labeling later. Includes general code for a changelog parser so that I can reuse it by that point.

GitHub actions are great for downstreams, as setting up a PHP server for the webhook is not trivial, compared to Existing and getting it for free. They are also much more straightforward to test and update than the webhook. I was able to verify this was working trivially with an empty repository.

Tested and working: Mothblocks/ss13-workflow-testing@0a2de4d
This commit is contained in:
Mothblocks
2022-10-26 20:52:32 -07:00
committed by GitHub
parent e6e7050bb0
commit 8bb8ca9d67
9 changed files with 381 additions and 68 deletions

View File

@@ -240,7 +240,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';
@@ -302,7 +302,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.';
@@ -362,7 +362,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;
@@ -630,7 +630,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;
@@ -648,26 +648,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)
@@ -683,47 +673,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':
@@ -731,7 +718,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':
@@ -739,95 +725,53 @@ 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);
}
function game_server_send($addr, $port, $str) {