diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index e4d5a86e8cc..1d5a48402f7 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -86,30 +86,26 @@ jobs: cat <<"EOF" ${{ toJSON(github.event) }} EOF - + - name: Generate IRC message + if: always() + id: ircmsg + run: | + ${{ github.workspace }}/Meta/mangle_event_for_irc.py <<"EOF" + ["${{ github.actor }}", ${{ github.run_id }}, "${{ job.status }}", + ${{ toJSON(github.event) }} + ] + EOF - name: IRC result notification (direct push) uses: rectalogic/notify-irc@v1 - if: github.repository == 'SerenityOS/serenity' && github.ref == 'refs/heads/master' && github.event_name == 'push' && !cancelled() + if: github.repository == 'SerenityOS/serenity' && github.ref == 'refs/heads/master' && github.event_name == 'push' && !cancelled() && steps.ircmsg.outputs.has_output with: channel: "#serenityos" nickname: serenity-ga - message: |- - ${{ github.actor }} pushed master on ${{ github.event.compare }}: ${{ job.status }} - Subject: ${{ join(github.event.commits[0].message) }} (+ more, maybe) - Details: https://github.com/${{ github.repository }}/actions/runs/${{github.run_id}} - # There might be hundreds of commits in a push: Printing them all to IRC will fail. - # Accessing the last commit is not possible: The python-y '-1' is not understood. - # Counting is not available: The config-file language is not Turing complete. - # We could write a script just to format the IRC message, but this is getting silly. - # https://github.com/SerenityOS/serenity/pull/3980 - + message: ${{ steps.ircmsg.outputs.the_line }} - name: IRC result notification (PR) uses: rectalogic/notify-irc@v1 - if: github.event_name == 'pull_request' && !cancelled() + if: github.repository == 'SerenityOS/serenity' && github.event_name == 'pull_request' && !cancelled() && steps.ircmsg.outputs.has_output with: channel: "#serenityos" nickname: serenity-ga - message: |- - ${{ github.actor }} ${{ github.event.action }} PR #${{ github.event.pull_request.number }}: ${{ job.status }} - Subject: ${{ github.event.pull_request.title }} - Details: ${{ github.event.pull_request._links.html.href }} + message: ${{ steps.ircmsg.outputs.the_line }} diff --git a/Meta/mangle_event_for_irc.py b/Meta/mangle_event_for_irc.py new file mode 100755 index 00000000000..517c6765d21 --- /dev/null +++ b/Meta/mangle_event_for_irc.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +import json +import sys + +# Must be exactly three lines each! +# No trailing newline! (I.e. keep it as backslash-newline-tripleapostrophe.) +TEMPLATE_PUSH = '''\ +{commit}{post_commit} (pushed master: {status}) {compare} https://github.com/SerenityOS/serenity/actions/runs/{run_id}\ +''' +TEMPLATE_PR = '''\ +{title} ({actor} {action}: {status}) {link} https://github.com/SerenityOS/serenity/actions/runs/{run_id}\ +''' + +def compute_lines(wrapper): + actor, run_id, raw_status, event = wrapper + + if raw_status == 'success': + status = 'The build passed.' + elif raw_status == 'failure': + status = 'The build failed.' + else: + status = 'The build {}(?)'.format(raw_status) + + if 'action' not in event: + # This is a push. + if 'commits' not in event or not event['commits']: + show_msg = '??? (No commits in event?!)' + post_commit = '' + else: + commits = event['commits'] + show_commit = commits[-1]['message'] + if 'skip ci' in show_commit or 'ci skip' in show_commit: + print('User requested to skip IRC notification. Okay!') + return False + # First line of the last commit: + show_msg = show_commit.split('\n')[0] + if len(commits) == 1: + post_commit = '' + elif len(commits) == 2: + post_commit = ' (+1 commit)' + else: + post_commit = ' (+{} commits)'.format(len(commits)) + return TEMPLATE_PUSH.format( + actor=actor, + status=status, + run_id=run_id, + commit=show_msg, + post_commit=post_commit, + compare=event.get('compare', '???'), + ) + elif 'pull_request' in event: + # This is a PR. + raw_action = event['action'] + if raw_action == 'opened': + action = 'opened' + elif raw_action == 'reopened': + action = 'reopened' + elif raw_action == 'synchronize': + action = 'updated' + else: + action = '{}(?)'.format(raw_action) + if event['pull_request'].get('draft', True): + print("This is a draft PR, so IRC won't be notified.") + print('Note: No rebuild occurs when the PR is "un-drafted"!') + return False + return TEMPLATE_PR.format( + actor=actor, + action=action, + status=status, + run_id=run_id, + title=event['pull_request'].get('title', '???'), + link=event['pull_request'].get('_links', dict()).get('html', dict()).get('href', '???'), + ) + else: + print('Unrecognized event type?!') + return False + + +def run_on(json_string): + wrapper = json.loads(json_string) + line = compute_lines(wrapper) + has_output = bool(line) + print('::set-output name=has_output::{}'.format(has_output)) + print('> ::set-output name=has_output::{}'.format(has_output)) + if has_output: + print('::set-output name=the_line::{}'.format(line)) + print('> ::set-output name=the_line::{}'.format(line)) + + +def run(): + run_on(sys.stdin.read()) + + +if __name__ == '__main__': + run()