-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ci] improve experience with optional GitHub workflows (#3740)
* improve experience with optional GitHub workflows * Update README.md * Update r_artifacts.yml * Update optional_checks.yml * continue * Update triggering_comments.yml * Update README.md * Update r_artifacts.yml * Update r_artifacts.yml * Update r_artifacts.yml * Update r_valgrind.yml * Update r_artifacts.yml * Update r_valgrind.yml * Update r_valgrind.yml * Update r_valgrind.yml * add docstrings to fix lint * better formatting for multi-line commands
- Loading branch information
1 parent
577b2f9
commit f997a06
Showing
10 changed files
with
404 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#!/bin/bash | ||
# | ||
# [description] | ||
# Update comment appending a given body to the specified original comment. | ||
# | ||
# [usage] | ||
# append_comment.sh <COMMENT_ID> <BODY> | ||
# | ||
# COMMENT_ID: ID of comment that should be modified. | ||
# | ||
# BODY: Text that will be appended to the original comment body. | ||
|
||
set -e | ||
|
||
if [ -z "$GITHUB_ACTIONS" ]; then | ||
echo "Must be run inside GitHub Actions CI" | ||
exit -1 | ||
fi | ||
|
||
if [ $# -ne 2 ]; then | ||
echo "Usage: $0 <COMMENT_ID> <BODY>" | ||
exit -1 | ||
fi | ||
|
||
comment_id=$1 | ||
body=$2 | ||
|
||
old_comment_body=$( | ||
curl -sL \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
"${GITHUB_API_URL}/repos/microsoft/LightGBM/issues/comments/$comment_id" | \ | ||
jq '.body' | ||
) | ||
body=${body/failure/failure ❌} | ||
body=${body/error/failure ❌} | ||
body=${body/cancelled/failure ❌} | ||
body=${body/timed_out/failure ❌} | ||
body=${body/success/success ✔️} | ||
data=$( | ||
jq -n \ | ||
--argjson body "${old_comment_body%?}\r\n\r\n$body\"" \ | ||
'{"body":$body}' | ||
) | ||
curl -sL \ | ||
-X PATCH \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
-d "$data" \ | ||
"${GITHUB_API_URL}/repos/microsoft/LightGBM/issues/comments/$comment_id" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# coding: utf-8 | ||
"""Get the most recent status of workflow for the current PR.""" | ||
import json | ||
from os import environ | ||
from sys import argv, exit | ||
from time import sleep | ||
try: | ||
from urllib import request | ||
except ImportError: | ||
import urllib2 as request | ||
|
||
|
||
def get_runs(workflow_name): | ||
"""Get all triggering workflow comments in the current PR. | ||
Parameters | ||
---------- | ||
workflow_name : string | ||
Name of the workflow. | ||
Returns | ||
------- | ||
pr_runs : list | ||
List of comment objects sorted by the time of creation in decreasing order. | ||
""" | ||
pr_runs = [] | ||
if environ.get("GITHUB_EVENT_NAME", "") == "pull_request": | ||
pr_number = int(environ.get("GITHUB_REF").split('/')[-2]) | ||
req = request.Request(url="{}/repos/microsoft/LightGBM/issues/{}/comments".format(environ.get("GITHUB_API_URL"), | ||
pr_number), | ||
headers={"Accept": "application/vnd.github.v3+json"}) | ||
url = request.urlopen(req) | ||
data = json.loads(url.read().decode('utf-8')) | ||
url.close() | ||
pr_runs = [i for i in data | ||
if i['author_association'].lower() in {'owner', 'member', 'collaborator'} | ||
and i['body'].startswith('/gha run') | ||
and 'Workflow **{}** has been triggered!'.format(workflow_name) in i['body']] | ||
return pr_runs[::-1] | ||
|
||
|
||
def get_status(runs): | ||
"""Get the most recent status of workflow for the current PR. | ||
Parameters | ||
---------- | ||
runs : list | ||
List of comment objects sorted by the time of creation in decreasing order. | ||
Returns | ||
------- | ||
status : string | ||
The most recent status of workflow. | ||
Can be 'success', 'failure' or 'in-progress'. | ||
""" | ||
status = 'success' | ||
for run in runs: | ||
body = run['body'] | ||
if "Status: " in body: | ||
if "Status: skipped" in body: | ||
continue | ||
if "Status: failure" in body: | ||
status = 'failure' | ||
break | ||
if "Status: success" in body: | ||
status = 'success' | ||
break | ||
else: | ||
status = 'in-progress' | ||
break | ||
return status | ||
|
||
|
||
if __name__ == "__main__": | ||
workflow_name = argv[1] | ||
while True: | ||
status = get_status(get_runs(workflow_name)) | ||
if status != 'in-progress': | ||
break | ||
sleep(60) | ||
if status == 'failure': | ||
exit(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/bin/bash | ||
# | ||
# [description] | ||
# Rerun specified workflow for given pull request. | ||
# | ||
# [usage] | ||
# rerun_workflow.sh <WORKFLOW_ID> <PR_NUMBER> <PR_BRANCH> | ||
# | ||
# WORKFLOW_ID: Identifier (config name of ID) of a workflow to be rerun. | ||
# | ||
# PR_NUMBER: Number of pull request for which workflow should be rerun. | ||
# | ||
# PR_BRANCH: Name of pull request's branch. | ||
|
||
set -e | ||
|
||
if [ -z "$GITHUB_ACTIONS" ]; then | ||
echo "Must be run inside GitHub Actions CI" | ||
exit -1 | ||
fi | ||
|
||
if [ $# -ne 3 ]; then | ||
echo "Usage: $0 <WORKFLOW_ID> <PR_NUMBER> <PR_BRANCH>" | ||
exit -1 | ||
fi | ||
|
||
workflow_id=$1 | ||
pr_number=$2 | ||
pr_branch=$3 | ||
|
||
runs=$( | ||
curl -sL \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
"${GITHUB_API_URL}/repos/microsoft/LightGBM/actions/workflows/${workflow_id}/runs?event=pull_request&branch=${pr_branch}" | \ | ||
jq '.workflow_runs' | ||
) | ||
runs=$(echo $runs | jq --arg pr_number "$pr_number" --arg pr_branch "$pr_branch" 'map(select(.event == "pull_request" and ((.pull_requests | length) != 0 and (.pull_requests[0].number | tostring) == $pr_number or .head_branch == $pr_branch)))') | ||
runs=$(echo $runs | jq 'sort_by(.run_number) | reverse') | ||
|
||
if [[ $(echo $runs | jq 'length') -gt 0 ]]; then | ||
curl -sL \ | ||
-X POST \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
"${GITHUB_API_URL}/repos/microsoft/LightGBM/actions/runs/$(echo $runs | jq '.[0].id')/rerun" | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#!/bin/bash | ||
# | ||
# [description] | ||
# Set a status with a given name to the specified commit. | ||
# | ||
# [usage] | ||
# set_commit_status.sh <NAME> <STATUS> <SHA> | ||
# | ||
# NAME: Name of status. | ||
# Status with existing name overwrites a previous one. | ||
# | ||
# STATUS: Status to be set. | ||
# Can be "error", "failure", "pending" or "success". | ||
# | ||
# SHA: SHA of a commit to set a status on. | ||
|
||
set -e | ||
|
||
if [ -z "$GITHUB_ACTIONS" ]; then | ||
echo "Must be run inside GitHub Actions CI" | ||
exit -1 | ||
fi | ||
|
||
if [ $# -ne 3 ]; then | ||
echo "Usage: $0 <NAME> <STATUS> <SHA>" | ||
exit -1 | ||
fi | ||
|
||
name=$1 | ||
|
||
status=$2 | ||
status=${status/error/failure} | ||
status=${status/cancelled/failure} | ||
status=${status/timed_out/failure} | ||
status=${status/in_progress/pending} | ||
status=${status/queued/pending} | ||
|
||
sha=$3 | ||
|
||
data=$( | ||
jq -n \ | ||
--arg state $status \ | ||
--arg url "${GITHUB_SERVER_URL}/microsoft/LightGBM/actions/runs/${GITHUB_RUN_ID}" \ | ||
--arg name "$name" \ | ||
'{"state":$state,"target_url":$url,"context":$name}' | ||
) | ||
|
||
curl -sL \ | ||
-X POST \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
-d "$data" \ | ||
"${GITHUB_API_URL}/repos/microsoft/LightGBM/statuses/$sha" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#!/bin/bash | ||
# | ||
# [description] | ||
# Trigger manual workflow run by a dispatch event. | ||
# | ||
# [usage] | ||
# trigger_dispatch_run.sh <PR_URL> <COMMENT_ID> <DISPATCH_NAME> | ||
# | ||
# PR_URL: URL of pull request from which dispatch is triggering. | ||
# | ||
# COMMENT_ID: ID of comment that is triggering a dispatch. | ||
# | ||
# DISPATCH_NAME: Name of a dispatch to be triggered. | ||
|
||
set -e | ||
|
||
if [ -z "$GITHUB_ACTIONS" ]; then | ||
echo "Must be run inside GitHub Actions CI" | ||
exit -1 | ||
fi | ||
|
||
if [ $# -ne 3 ]; then | ||
echo "Usage: $0 <PR_URL> <COMMENT_ID> <DISPATCH_NAME>" | ||
exit -1 | ||
fi | ||
|
||
pr_url=$1 | ||
comment_id=$2 | ||
dispatch_name=$3 | ||
|
||
pr=$( | ||
curl -sL \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
"$pr_url" | ||
) | ||
data=$( | ||
jq -n \ | ||
--arg event_type "$dispatch_name" \ | ||
--arg pr_number "$(echo $pr | jq '.number')" \ | ||
--arg pr_sha "$(echo $pr | jq '.head.sha')" \ | ||
--arg pr_branch "$(echo $pr | jq '.head.ref')" \ | ||
--arg comment_number "$comment_id" \ | ||
'{"event_type":$event_type,"client_payload":{"pr_number":$pr_number,"pr_sha":$pr_sha,"pr_branch":$pr_branch,"comment_number":$comment_number}}' | ||
) | ||
curl -sL \ | ||
-X POST \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $SECRETS_WORKFLOW" \ | ||
-d "$data" \ | ||
"${GITHUB_API_URL}/repos/microsoft/LightGBM/dispatches" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Optional checks | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
all-successful: | ||
timeout-minutes: 120 | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/[email protected] | ||
with: | ||
fetch-depth: 5 | ||
submodules: false | ||
- name: Check that all tests succeeded | ||
run: | | ||
workflows=("R valgrind tests") | ||
for i in "${workflows[@]}"; do | ||
python "$GITHUB_WORKSPACE/.ci/get_workflow_status.py" "$i" \ | ||
|| { echo "The last reported status from workflow \"$i\" is failure. Commit fixes and rerun the workflow."; \ | ||
exit -1; } | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,39 @@ | ||
name: R artifact builds | ||
|
||
on: | ||
pull_request_review_comment: | ||
types: [created] | ||
repository_dispatch: | ||
types: [gha_run_build_r_artifacts] | ||
|
||
jobs: | ||
cran-package: | ||
name: cran-package | ||
if: github.event.comment.body == '/gha build r-artifacts' && contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association) | ||
timeout-minutes: 60 | ||
runs-on: ubuntu-latest | ||
container: rocker/r-base | ||
env: | ||
SECRETS_WORKFLOW: ${{ secrets.WORKFLOW }} | ||
steps: | ||
- name: Install Git before checkout | ||
- name: Install essential software before checkout | ||
shell: bash | ||
run: | | ||
apt-get update | ||
apt-get install --no-install-recommends -y git | ||
apt-get install --no-install-recommends -y \ | ||
curl \ | ||
git \ | ||
jq | ||
- name: Checkout repository | ||
uses: actions/[email protected] | ||
with: | ||
fetch-depth: 5 | ||
submodules: true | ||
repository: microsoft/LightGBM | ||
ref: "refs/pull/${{ github.event.client_payload.pr_number }}/merge" | ||
- name: Send init status | ||
if: ${{ always() }} | ||
run: | | ||
$GITHUB_WORKSPACE/.ci/append_comment.sh \ | ||
"${{ github.event.client_payload.comment_number }}" \ | ||
"Workflow **${{ github.workflow }}** has been triggered! 🚀\r\n${GITHUB_SERVER_URL}/microsoft/LightGBM/actions/runs/${GITHUB_RUN_ID}" | ||
- name: Build package | ||
shell: bash | ||
id: build_package | ||
|
@@ -37,3 +49,9 @@ jobs: | |
with: | ||
name: ${{ steps.build_package.outputs.artifact_name }} | ||
path: ${{ steps.build_package.outputs.artifact_path }} | ||
- name: Send final status | ||
if: ${{ always() }} | ||
run: | | ||
$GITHUB_WORKSPACE/.ci/append_comment.sh \ | ||
"${{ github.event.client_payload.comment_number }}" \ | ||
"Status: ${{ job.status }}." |
Oops, something went wrong.