ci: Talk to Shaka Bot (#5565)

Now maintainers can send commands to Shaka Bot via PR comments.

Initially, Shaka Bot understands the following commands from anyone:
 - `@shaka-bot help`: Show this help message

And the following commands from maintainers only:
 - `@shaka-bot test`: Start lab tests on all devices
- `@shaka-bot test ce`: Start lab tests on CE devices only (no desktop
browsers)
This commit is contained in:
Joey Parrish
2023-08-31 10:15:17 -07:00
committed by GitHub
parent 6bd01db24a
commit 27e991d11e
5 changed files with 246 additions and 0 deletions
@@ -0,0 +1,27 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# The help command implementation.
# Assumes that lib.sh has been loaded and all required variables are set.
# Using single quotes to avoid executing the things in backticks, which are
# really markdown.
(
echo 'I honor the following commands from anyone:'
echo ' - `@shaka-bot help`: Show this help message'
echo ''
echo 'I honor the following commands from maintainers only:'
echo ' - `@shaka-bot test`: Start lab tests on all devices'
echo ' - `@shaka-bot test ce`: Start lab tests on CE devices only (no desktop browsers)'
) | reply_from_pipe
@@ -0,0 +1,56 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# The test command implementation.
# Assumes that lib.sh has been loaded and all required variables are set.
if ! check_permissions; then
reply "Only maintainers may start lab tests."
exit 0
fi
# These are passed to the lab testing workflow.
WORKFLOW_ARGS=( "pr=$PR_NUMBER" )
case "${SHAKA_BOT_ARGUMENTS[0]}" in
# CE devices only.
ce) WORKFLOW_ARGS+=( "browser_filter=Tizen Chromecast ChromeAndroid" ) ;;
# No command argument, no extra workflow arguments.
"") ;;
*)
reply "Unrecognized test argument: ${SHAKA_BOT_ARGUMENTS[0]}"
exit 1
;;
esac
if start_workflow selenium-lab-tests.yaml "${WORKFLOW_ARGS[@]}"; then
(
echo "Lab tests started with arguments:"
for arg in "${WORKFLOW_ARGS[@]}"; do
echo " - \`$arg\`"
done
) | reply_from_pipe
else
(
echo "I failed to start the lab test workflow."
echo ""
echo "Please check GitHub Actions logs for details."
) | reply_from_pipe
# Fail this workflow to make it easier to find the right run
# and its logs.
exit 1
fi
@@ -0,0 +1,83 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Utilities for handling @shaka-bot commands.
# Ignore case in all string comparisons.
shopt -s nocasematch
function check_required_variable() {
local VAR_NAME="$1"
# The ! syntax here is Bash variable indirection.
if [[ -z "${!VAR_NAME}" ]]; then
echo "Missing environment variable: $VAR_NAME"
exit 1
fi
}
# Leaving a comment requires a token with "repo" scope.
function reply() {
echo "@$COMMENTER: $@" | \
gh issue comment "$PR_NUMBER" -R "$THIS_REPO" -F -
}
# Leaving a comment requires a token with "repo" scope.
function reply_from_pipe() {
(echo -n "@$COMMENTER: "; cat /dev/stdin) | \
gh issue comment "$PR_NUMBER" -R "$THIS_REPO" -F -
}
# Checking permissions requires a token with "repo" and "org:read" scopes, and
# write access.
function check_permissions() {
# Check permissions: this API call fails if the commenter has no special
# permissions on the repo.
gh api "/repos/$THIS_REPO/collaborators/$COMMENTER"
}
# Starting a workflow requires a token with "repo" scope and write access.
# $1 is the workflow filename. Subsequent arguments are key=value pairs to be
# passed as input to the workflow_dispatch event.
function start_workflow() {
local WORKFLOW="$1"
shift
# The gh command wants -f before each key-value pair. The caller shouldn't
# have to know that, so we rebuild the argument array with -f here.
local GH_ARGS=()
for arg in "$@"; do
GH_ARGS+=( "-f" "$arg" )
done
gh workflow run "$WORKFLOW" -R "$THIS_REPO" "${GH_ARGS[@]}"
}
# Outputs to global variables SHAKA_BOT_COMMAND and SHAKA_BOT_ARGUMENTS (array).
function parse_command() {
# Tokenize the comment by whitespace.
local TOKENS=( $COMMENT_BODY )
local INDEX
for (( INDEX=0; INDEX < ${#TOKENS[@]}; INDEX++ )); do
if [[ "${TOKENS[i]}" == "@shaka-bot" ]]; then
SHAKA_BOT_COMMAND="${TOKENS[i+1]}"
# A slice of all tokens starting with index i+2.
SHAKA_BOT_ARGUMENTS=( "${TOKENS[@]:i+2}" )
return 0
fi
done
return 1
}
+51
View File
@@ -0,0 +1,51 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Handle @shaka-bot commands commented on PRs.
# Run everything from the folder in which this script lives.
cd "$(dirname "$0")"
# Load utils.
. lib.sh
# Check required environment variables passed from the workflow.
# If running this manually while testing changes, supply these.
check_required_variable GH_TOKEN # With repo & org:read scope, write access
check_required_variable THIS_REPO # like shaka-project/shaka-player
check_required_variable COMMENTER # like joeyparrish
check_required_variable PR_NUMBER # like 1234
check_required_variable COMMENT_BODY # like "@shaka-bot howdy"
if [[ "$COMMENTER" == "shaka-bot" ]]; then
# Exclude comments by shaka-bot, who will sometimes use its own name.
exit 0
fi
# Parse the command. Outputs to globals SHAKA_BOT_COMMAND and
# SHAKA_BOT_ARGUMENTS (array).
parse_command
if [[ "$SHAKA_BOT_COMMAND" == "" ]]; then
# No command found.
exit 0
fi
echo "PR $PR_NUMBER, detected command $SHAKA_BOT_COMMAND"
case "$SHAKA_BOT_COMMAND" in
help) . command-help.sh ;;
test) . command-test.sh ;;
*) echo "Unknown command!" ;;
esac
+29
View File
@@ -0,0 +1,29 @@
name: Talk to Shaka Bot (PRs)
# Runs when comments are created or edited. Jobs below will be filtered to
# only run on PRs, not regular issues.
on:
issue_comment:
types: [created, edited]
jobs:
handle_command:
# Only runs on PRs that contain '@shaka-bot' comments, but not comments
# made by shaka-bot itself, who will sometimes use its own name.
# Note that contains() is not case sensitive.
if: github.event.issue.pull_request && contains(github.event.comment.body, '@shaka-bot') && github.event.comment.user.login != 'shaka-bot'
runs-on: [ubuntu-latest]
env:
# This token must have "repo" scope, "org:read" scope, and write access.
GH_TOKEN: ${{ secrets.SHAKA_BOT_TOKEN }}
THIS_REPO: ${{ github.repository }}
COMMENTER: ${{ github.event.comment.user.login }}
PR_NUMBER: ${{ github.event.issue.number }}
COMMENT_BODY: ${{ github.event.comment.body }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Handle command
shell: bash
run: .github/workflows/shaka-bot-commands/main.sh