aboutsummaryrefslogtreecommitdiffstats
path: root/.github
diff options
context:
space:
mode:
authornikita kozlovsky <nikitka@users.noreply.github.com>2024-01-17 11:28:46 +0300
committerGitHub <noreply@github.com>2024-01-17 09:28:46 +0100
commitbcf764f1aa71683e3871616abe6f16b47cec42e4 (patch)
tree8268ff8f169c2845aaceb08a49cadfdfcc2e1b29 /.github
parent5173c3f829827c1490ed97f6358176fe6ff67a3e (diff)
downloadydb-bcf764f1aa71683e3871616abe6f16b47cec42e4.tar.gz
ci: add more details to PR comment about build and tests (#1054)
Diffstat (limited to '.github')
-rw-r--r--.github/actions/build_ya/action.yml31
-rw-r--r--.github/actions/test_ya/action.yml17
-rwxr-xr-x.github/scripts/tests/comment-pr.py39
-rwxr-xr-x.github/scripts/tests/generate-summary.py57
-rw-r--r--.github/scripts/tests/gh_status.py44
-rw-r--r--.github/workflows/build_and_test_ya.yml26
6 files changed, 162 insertions, 52 deletions
diff --git a/.github/actions/build_ya/action.yml b/.github/actions/build_ya/action.yml
index b7f09347ad..281701e7ae 100644
--- a/.github/actions/build_ya/action.yml
+++ b/.github/actions/build_ya/action.yml
@@ -28,13 +28,19 @@ runs:
- name: Init
id: init
shell: bash
+ env:
+ build_preset: ${{ inputs.build_preset }}
run: |
echo "SHELLOPTS=xtrace" >> $GITHUB_ENV
export TMP_DIR=$(pwd)/tmp_build
echo "TMP_DIR=$TMP_DIR" >> $GITHUB_ENV
rm -rf $TMP_DIR && mkdir $TMP_DIR
-
+
+ echo "BUILD_PRESET=$build_preset" >> $GITHUB_ENV
+ echo "GITHUB_TOKEN=${{ github.token }}" >> $GITHUB_ENV
+
- name: build
+ id: build
shell: bash
run: |
extra_params=()
@@ -85,12 +91,18 @@ runs:
echo "::debug::get version"
./ya --version
+ echo "Build **{platform_name}-${BUILD_PRESET}** is running..." | .github/scripts/tests/comment-pr.py
+
+ # to be sure
+ set -o pipefail
+
./ya make -k --build "${build_type}" --force-build-depends -D'BUILD_LANGUAGES=CPP PY3 PY2 GO' -T --stat -DCONSISTENT_DEBUG \
--log-file "$TMP_DIR/ya_log.txt" --evlog-file "$TMP_DIR/ya_evlog.jsonl" \
--cache-size 512G --link-threads "${{ inputs.link_threads }}" \
- "${extra_params[@]}" || (
+ "${extra_params[@]}" |& tee $TMP_DIR/ya_make.log || (
RC=$?
echo "::debug::ya make RC=$RC"
+ echo "status=failed" >> $GITHUB_OUTPUT
)
- name: sync logs to s3
@@ -98,9 +110,22 @@ runs:
shell: bash
run: |
echo "::group::s3-sync"
- s3cmd sync --acl-private --no-progress --stats --no-check-md5 "$TMP_DIR/" "$S3_BUCKET_PATH/build_logs/"
+ s3cmd sync --acl-private --exclude="ya_make.log" --no-progress --stats --no-check-md5 "$TMP_DIR/" "$S3_BUCKET_PATH/build_logs/"
+ s3cmd sync --acl-public --no-progress --stats --no-check-md5 "$TMP_DIR/ya_make.log" "$S3_BUCKET_PATH/build_logs/"
echo "::endgroup::"
+ - name: comment-build-status
+ if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
+ shell: bash
+ run: |
+ log_url="$S3_URL_PREFIX/build_logs/ya_make.log"
+
+ if [ "${{ steps.build.outputs.status }}" == "failed" ]; then
+ echo "Build failed. see the [build logs]($log_url)." | .github/scripts/tests/comment-pr.py --fail
+ else
+ echo "Build successful." | .github/scripts/tests/comment-pr.py --ok
+ fi
+
- name: show free space
if: always()
shell: bash
diff --git a/.github/actions/test_ya/action.yml b/.github/actions/test_ya/action.yml
index 250fa7115a..46fa537040 100644
--- a/.github/actions/test_ya/action.yml
+++ b/.github/actions/test_ya/action.yml
@@ -66,6 +66,8 @@ runs:
echo "TESTMO_TOKEN=${{ inputs.testman_token }}" >> $GITHUB_ENV
echo "TESTMO_URL=${{ inputs.testman_url }}" >> $GITHUB_ENV
echo "SUMMARY_LINKS=$(mktemp)" >> $GITHUB_ENV
+ echo "GITHUB_TOKEN=${{ github.token }}" >> $GITHUB_ENV
+ echo "BUILD_PRESET=${{ inputs.build_preset }}" >> $GITHUB_ENV
- name: prepare
shell: bash
@@ -93,7 +95,6 @@ runs:
BRANCH_TAG="$GITHUB_REF_NAME"
ARCH="${{ runner.arch == 'X64' && 'x86-64' || runner.arch == 'ARM64' && 'arm64' || 'unknown' }}"
- BUILD_PRESET="${{ inputs.build_preset }}"
case "$BUILD_PRESET" in
relwithdebinfo)
TESTMO_SOURCE="ya-${ARCH}"
@@ -105,7 +106,7 @@ runs:
TESTMO_SOURCE="ya-${ARCH}-${BUILD_PRESET/release-/}"
;;
*)
- echo "Invalid preset: ${{ inputs.build_preset }}"
+ echo "Invalid preset: $BUILD_PRESET"
exit 1
;;
esac
@@ -170,7 +171,7 @@ runs:
)
# FIXME: copy-paste from build_ya
- case "${{ inputs.build_preset }}" in
+ case "$BUILD_PRESET" in
debug)
params+=(--build "debug")
;;
@@ -196,7 +197,7 @@ runs:
)
;;
*)
- echo "Invalid preset: ${{ inputs.build_preset }}"
+ echo "Invalid preset: $BUILD_PRESET"
exit 1
;;
esac
@@ -213,6 +214,8 @@ runs:
echo "::debug::get version"
./ya --version
+ echo "Tests are running..." | .github/scripts/tests/comment-pr.py
+
if [ ! -z "${{ inputs.bazel_remote_username }}" ]; then
echo "::debug::start tests"
@@ -300,20 +303,16 @@ runs:
- name: write tests summary
shell: bash
if: always()
- env:
- GITHUB_TOKEN: ${{ github.token }}
run: |
mkdir $ARTIFACTS_DIR/summary/
cat $SUMMARY_LINKS | python3 -c 'import sys; print(" | ".join([v for _, v in sorted([l.strip().split(" ", 1) for l in sys.stdin], key=lambda a: (int(a[0]), a))]))' >> $GITHUB_STEP_SUMMARY
- platform_name=$(uname | tr '[:upper:]' '[:lower:]')-$(arch)
-
.github/scripts/tests/generate-summary.py \
--summary-out-path $ARTIFACTS_DIR/summary/ \
--summary-url-prefix $S3_URL_PREFIX/summary/ \
--test-history-url $TEST_HISTORY_URL \
- --build-preset "${platform_name}-${{ inputs.build_preset }}" \
+ --build-preset "$BUILD_PRESET" \
"Tests" ya-test.html "$JUNIT_REPORT_XML"
- name: sync test results to s3
diff --git a/.github/scripts/tests/comment-pr.py b/.github/scripts/tests/comment-pr.py
new file mode 100755
index 0000000000..26af28e27e
--- /dev/null
+++ b/.github/scripts/tests/comment-pr.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+import os
+import json
+import argparse
+from github import Github, Auth as GithubAuth
+from github.PullRequest import PullRequest
+from gh_status import update_pr_comment_text
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--rewrite", dest="rewrite", action="store_true")
+ parser.add_argument("--color", dest="color", default="white")
+ parser.add_argument("--fail", dest="fail", action="store_true")
+ parser.add_argument("--ok", dest="ok", action="store_true")
+ parser.add_argument("text", type=argparse.FileType("r"), nargs="?", default="-")
+
+ args = parser.parse_args()
+ color = args.color
+
+ if args.ok:
+ color = 'green'
+ elif args.fail:
+ color = 'red'
+
+ build_preset = os.environ["BUILD_PRESET"]
+
+ gh = Github(auth=GithubAuth.Token(os.environ["GITHUB_TOKEN"]))
+
+ with open(os.environ["GITHUB_EVENT_PATH"]) as fp:
+ event = json.load(fp)
+
+ pr = gh.create_from_raw_data(PullRequest, event["pull_request"])
+
+ update_pr_comment_text(pr, build_preset, color, args.text.read().rstrip(), args.rewrite)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/.github/scripts/tests/generate-summary.py b/.github/scripts/tests/generate-summary.py
index c46d93c9da..9dc7a5d214 100755
--- a/.github/scripts/tests/generate-summary.py
+++ b/.github/scripts/tests/generate-summary.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import argparse
import dataclasses
+import datetime
import os
import re
import json
@@ -12,6 +13,7 @@ from operator import attrgetter
from typing import List, Optional, Dict
from jinja2 import Environment, FileSystemLoader, StrictUndefined
from junit_utils import get_property_value, iter_xml_files
+from gh_status import update_pr_comment_text
class TestStatus(Enum):
@@ -155,7 +157,7 @@ class TestSummary:
github_srv = os.environ.get("GITHUB_SERVER_URL", "https://github.com")
repo = os.environ.get("GITHUB_REPOSITORY", "ydb-platform/ydb")
- footnote_url = f"{github_srv}/{repo}/tree/main/.github/config"
+ footnote_url = f"{github_srv}/{repo}/tree/main/.github/config/muted_ya.txt"
footnote = "[^1]" if add_footnote else f'<sup>[?]({footnote_url} "All mute rules are defined here")</sup>'
@@ -287,18 +289,20 @@ def gen_summary(summary_url_prefix, summary_out_folder, paths):
return summary
-def get_comment_text(pr: PullRequest, summary: TestSummary, build_preset: str, test_history_url: str):
+def get_comment_text(pr: PullRequest, summary: TestSummary, test_history_url: str):
if summary.is_empty:
return [
- f":red_circle: **{build_preset}**: Test run completed, no test results found for commit {pr.head.sha}. "
+ f"Test run completed, no test results found for commit {pr.head.sha}. "
f"Please check build logs."
]
elif summary.is_failed:
- result = f":red_circle: **{build_preset}**: some tests FAILED"
+ result = f"Some tests failed, follow the links below."
else:
- result = f":green_circle: **{build_preset}**: all tests PASSED"
+ result = f"Tests successful."
- body = [f"{result} for commit {pr.head.sha}."]
+ body = [
+ result
+ ]
if test_history_url:
body.append("")
@@ -309,36 +313,6 @@ def get_comment_text(pr: PullRequest, summary: TestSummary, build_preset: str, t
return body
-def update_pr_comment(run_number: int, pr: PullRequest, summary: TestSummary, build_preset: str, test_history_url: str):
- header = f"<!-- status pr={pr.number}, run={{}} -->"
- header_re = re.compile(header.format(r"(\d+)"))
-
- comment = body = None
-
- for c in pr.get_issue_comments():
- if matches := header_re.match(c.body):
- comment = c
- if int(matches[1]) == run_number:
- body = [c.body, "", "---", ""]
-
- if body is None:
- body = [
- header.format(run_number),
- "> [!NOTE]",
- "> This is an automated comment that will be appended during run.",
- "",
- ]
-
- body.extend(get_comment_text(pr, summary, build_preset, test_history_url))
-
- body = "\n".join(body)
-
- if comment is None:
- pr.create_issue_comment(body)
- else:
- comment.edit(body)
-
-
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--summary-out-path", required=True)
@@ -364,9 +338,16 @@ def main():
with open(os.environ["GITHUB_EVENT_PATH"]) as fp:
event = json.load(fp)
- run_number = int(os.environ.get("GITHUB_RUN_NUMBER"))
pr = gh.create_from_raw_data(PullRequest, event["pull_request"])
- update_pr_comment(run_number, pr, summary, args.build_preset, args.test_history_url)
+
+ text = get_comment_text(pr, summary, args.test_history_url)
+
+ if summary.is_empty | summary.is_failed:
+ color = 'red'
+ else:
+ color = 'green'
+
+ update_pr_comment_text(pr, args.build_preset, color, text='\n'.join(text), rewrite=False)
if __name__ == "__main__":
diff --git a/.github/scripts/tests/gh_status.py b/.github/scripts/tests/gh_status.py
new file mode 100644
index 0000000000..693265aaa8
--- /dev/null
+++ b/.github/scripts/tests/gh_status.py
@@ -0,0 +1,44 @@
+import datetime
+import platform
+from github.PullRequest import PullRequest
+
+
+def get_timestamp():
+ return datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
+
+
+def get_platform_name():
+ return f'{platform.system().lower()}-{platform.machine()}'
+
+
+def update_pr_comment_text(pr: PullRequest, build_preset: str, color: str, text: str, rewrite: bool):
+ platform_name = get_platform_name()
+ header = f"<!-- status pr={pr.number}, preset={platform_name}-{build_preset} -->"
+
+ body = comment = None
+ for c in pr.get_issue_comments():
+ if c.body.startswith(header):
+ print(f"found comment id={c.id}")
+ comment = c
+ if not rewrite:
+ body = [c.body]
+ break
+
+ if body is None:
+ body = [header]
+
+ indicator = f":{color}_circle:"
+ body.append(f"{indicator} `{get_timestamp()}` {text}")
+
+ body = "\n".join(body)
+
+ if '{platform_name}' in body:
+ # input can contain '{platform_name}'
+ body = body.replace('{platform_name}', platform_name)
+
+ if comment is None:
+ print(f"post new comment")
+ pr.create_issue_comment(body)
+ else:
+ print(f"edit comment")
+ comment.edit(body)
diff --git a/.github/workflows/build_and_test_ya.yml b/.github/workflows/build_and_test_ya.yml
index d302d16135..b6421585d6 100644
--- a/.github/workflows/build_and_test_ya.yml
+++ b/.github/workflows/build_and_test_ya.yml
@@ -49,7 +49,9 @@ on:
put_build_results_to_cache:
type: boolean
default: true
-
+defaults:
+ run:
+ shell: bash
jobs:
main:
name: Build and test ${{ inputs.build_preset }}
@@ -63,7 +65,20 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
if: github.event.pull_request.head.sha == ''
-
+
+ - name: comment-build-start
+ if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
+ shell: bash
+ env:
+ BUILD_PRESET: ${{ inputs.build_preset }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ jobs_url="https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs"
+ # tricky: we are searching job with name that contains build_preset
+ check_url=$(curl -s $jobs_url | jq --arg n "$BUILD_PRESET" -r '.jobs[] | select(.name | contains($n)) | .html_url')
+
+ echo "Pre-commit [check]($check_url) for ${{ github.event.pull_request.head.sha }} has started." | .github/scripts/tests/comment-pr.py --rewrite
+
- name: Prepare s3cmd
uses: ./.github/actions/s3cmd
with:
@@ -101,3 +116,10 @@ jobs:
bazel_remote_password: ${{ inputs.put_build_results_to_cache && secrets.REMOTE_CACHE_PASSWORD || '' }}
link_threads: ${{ inputs.link_threads }}
test_threads: ${{ inputs.test_threads }}
+
+ - name: comment-if-cancel
+ if: cancelled() && (github.event_name == 'pull_request' || github.event_name == 'pull_request_target')
+ env:
+ BUILD_PRESET: ${{ inputs.build_preset }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: echo "Check cancelled" | .github/scripts/tests/comment-pr.py --color black