This is an automated email from the ASF dual-hosted git repository.
ndimiduk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/yetus.git
The following commit(s) were added to refs/heads/main by this push:
new 2a831e7e YETUS-1260. Add GitHub Actions Job Summary support (#362)
2a831e7e is described below
commit 2a831e7e6a2f6a2f41bc1944a06d89afc65ca510
Author: Nick Dimiduk <[email protected]>
AuthorDate: Mon Feb 9 13:39:08 2026 +0100
YETUS-1260. Add GitHub Actions Job Summary support (#362)
* YETUS-1260. Add GitHub Actions Job Summary support
* add docker support
---
.../precommit/robots/githubactions.html.md | 19 +++
precommit/src/main/shell/core.d/docker.sh | 6 +-
precommit/src/main/shell/robots.d/githubactions.sh | 153 +++++++++++++++++-
.../src/test/shell/githubactions_finalreport.bats | 175 +++++++++++++++++++++
4 files changed, 351 insertions(+), 2 deletions(-)
diff --git
a/asf-site-src/source/documentation/in-progress/precommit/robots/githubactions.html.md
b/asf-site-src/source/documentation/in-progress/precommit/robots/githubactions.html.md
index 698cbb55..346f6dce 100644
---
a/asf-site-src/source/documentation/in-progress/precommit/robots/githubactions.html.md
+++
b/asf-site-src/source/documentation/in-progress/precommit/robots/githubactions.html.md
@@ -24,6 +24,8 @@ GitHub Action support is available in two different ways.
There are some settin
* Annotations will be used to mark problems in the files for those plug-ins
that support this feature and
if `--linecomments` has `github` as a configured bug system (the default).
* Statuses will be added if the GitHub Token gives permission.
+* Job Summary will be written with a Markdown-formatted report of the test
results, visible directly on the
+workflow run page without downloading artifacts.
## Workflow Action
@@ -108,6 +110,23 @@ TRIGGER: ${GITHUB_ACTIONS}=True
GitHub Actions support has only been tested on the ubuntu-latest image. It
automatically configures `--patch-dir` to be `${GITHUB_WORKSAPCE}/yetus` if not
previously set.
+## Job Summary
+
+When running under GitHub Actions, Apache Yetus automatically writes a summary
of the test results to the
+[Job
Summary](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/).
This provides
+immediate visibility of pass/fail status and details directly on the workflow
run page, without needing to
+download artifacts or parse log files.
+
+The Job Summary includes:
+
+* Overall pass/fail status with vote counts
+* Vote table showing each subsystem's result, runtime, and comments
+* Failed tests section (if any tests failed)
+* Links to log files (if artifact URLs are available)
+
+This feature requires no configuration and is automatically enabled when the
`GITHUB_STEP_SUMMARY` environment
+variable is present (which GitHub Actions sets automatically).
+
See also:
* Apache Yetus' [workflow action
source](https://github.com/apache/yetus-test-patch-action) for lower level
details on the workflow action implementation.
diff --git a/precommit/src/main/shell/core.d/docker.sh
b/precommit/src/main/shell/core.d/docker.sh
index fa518e94..3a5581c7 100755
--- a/precommit/src/main/shell/core.d/docker.sh
+++ b/precommit/src/main/shell/core.d/docker.sh
@@ -939,9 +939,13 @@ function docker_handler
determine_user
- # need to call this explicitly
+ # need to call these explicitly (not in plugin lists)
console_docker_support
+ if declare -f githubactions_docker_support >/dev/null; then
+ githubactions_docker_support
+ fi
+
for plugin in ${PROJECT_NAME} ${BUILDTOOL} "${BUGSYSTEMS[@]}"
"${TESTTYPES[@]}" "${TESTFORMATS[@]}"; do
if declare -f "${plugin}_docker_support" >/dev/null; then
"${plugin}_docker_support"
diff --git a/precommit/src/main/shell/robots.d/githubactions.sh
b/precommit/src/main/shell/robots.d/githubactions.sh
index 461cb362..d614e07b 100755
--- a/precommit/src/main/shell/robots.d/githubactions.sh
+++ b/precommit/src/main/shell/robots.d/githubactions.sh
@@ -85,7 +85,158 @@ function githubactions_set_plugin_defaults
GITHUB_REPO="${GITHUB_REPOSITORY}"
}
+## @description Docker support for GitHub Actions
+## @audience private
+## @stability evolving
+## @replaceable no
+function githubactions_docker_support
+{
+ if [[ -z "${GITHUB_STEP_SUMMARY}" ]]; then
+ return 0
+ fi
+
+ if [[ ! -f "${GITHUB_STEP_SUMMARY}" ]]; then
+ return 0
+ fi
+
+ DOCKER_EXTRAARGS+=("-v"
"${GITHUB_STEP_SUMMARY}:${DOCKER_WORK_DIR}/step_summary.md")
+ GITHUB_STEP_SUMMARY="${DOCKER_WORK_DIR}/step_summary.md"
+ add_docker_env GITHUB_STEP_SUMMARY
+}
+
function githubactions_cleanup_and_exit
{
echo "::endgroup::"
-}
\ No newline at end of file
+}
+
+## @description Write a summary report to GitHub Actions Job Summary
+## @audience private
+## @stability evolving
+## @replaceable no
+function githubactions_finalreport
+{
+ declare -i i=0
+ declare ourstring
+ declare vote
+ declare subs
+ declare ela
+ declare calctime
+ declare logfile
+ declare comment
+ declare url
+ declare emoji
+ declare loglink
+
+ if [[ -z "${GITHUB_STEP_SUMMARY}" ]]; then
+ return 0
+ fi
+
+ if [[ ! -w "${GITHUB_STEP_SUMMARY}" ]]; then
+ yetus_error "WARNING: GITHUB_STEP_SUMMARY (${GITHUB_STEP_SUMMARY}) is not
writable"
+ return 0
+ fi
+
+ big_console_header "Writing GitHub Actions Job Summary"
+
+ url=$(get_artifact_url)
+
+ {
+ if [[ ${RESULT} == 0 ]]; then
+ printf '## :confetti_ball: +1 overall\n\n'
+ else
+ printf '## :broken_heart: -1 overall\n\n'
+ fi
+
+ i=0
+ until [[ ${i} -ge ${#TP_HEADER[@]} ]]; do
+ printf '%s\n\n' "${TP_HEADER[i]}"
+ ((i=i+1))
+ done
+
+ printf '| Vote | Subsystem | Runtime | Logfile | Comment |\n'
+ printf '|:----:|----------:|--------:|:-------:|:--------|\n'
+
+ i=0
+ until [[ ${i} -ge ${#TP_VOTE_TABLE[@]} ]]; do
+ ourstring=$(echo "${TP_VOTE_TABLE[i]}" | tr -s ' ')
+ vote=$(echo "${ourstring}" | cut -f2 -d\| | tr -d ' ')
+ subs=$(echo "${ourstring}" | cut -f3 -d\|)
+ ela=$(echo "${ourstring}" | cut -f4 -d\|)
+ calctime=$(clock_display "${ela}")
+ logfile=$(echo "${ourstring}" | cut -f5 -d\| | tr -d ' ')
+ comment=$(echo "${ourstring}" | cut -f6 -d\|)
+
+ if [[ "${vote}" = "H" ]]; then
+ printf '| | | | | _%s_ |\n' "${comment}"
+ ((i=i+1))
+ continue
+ fi
+
+ # Honor GITHUB_USE_EMOJI_VOTE setting
+ if [[ ${GITHUB_USE_EMOJI_VOTE} == true ]]; then
+ case ${vote} in
+ 1|"+1")
+ emoji="+1 :green_heart:"
+ ;;
+ -1)
+ emoji="-1 :x:"
+ ;;
+ 0)
+ emoji="+0 :ok:"
+ ;;
+ -0)
+ emoji="-0 :warning:"
+ ;;
+ *)
+ emoji=${vote}
+ ;;
+ esac
+ else
+ emoji="${vote}"
+ fi
+
+ # Format logfile as link if URL is available
+ if [[ -n "${logfile}" ]]; then
+ if [[ -n "${url}" ]]; then
+ loglink=$(echo "${logfile}" | "${SED}" -e "s,@@BASE@@,${url},g")
+ loglink="[${logfile/@@BASE@@\//}](${loglink})"
+ else
+ loglink="${logfile/@@BASE@@\//}"
+ fi
+ else
+ loglink=""
+ fi
+
+ printf '| %s | %s | %s | %s | %s |\n' \
+ "${emoji}" \
+ "${subs}" \
+ "${calctime}" \
+ "${loglink}" \
+ "${comment}"
+
+ ((i=i+1))
+ done
+
+ if [[ ${#TP_TEST_TABLE[@]} -gt 0 ]]; then
+ printf '\n### Failed Tests\n\n'
+ printf '| Reason | Tests |\n'
+ printf '|-------:|:------|\n'
+ i=0
+ until [[ ${i} -ge ${#TP_TEST_TABLE[@]} ]]; do
+ echo "${TP_TEST_TABLE[i]}"
+ ((i=i+1))
+ done
+ fi
+
+ printf '\n### Subsystem Report\n\n'
+ printf '| Subsystem | Report/Notes |\n'
+ printf '|----------:|:-------------|\n'
+
+ i=0
+ until [[ ${i} -ge ${#TP_FOOTER_TABLE[@]} ]]; do
+ comment=$(echo "${TP_FOOTER_TABLE[i]}" | "${SED}" -e
"s,@@BASE@@,${url},g")
+ printf '%s\n' "${comment}"
+ ((i=i+1))
+ done
+ } >> "${GITHUB_STEP_SUMMARY}"
+}
diff --git a/precommit/src/test/shell/githubactions_finalreport.bats
b/precommit/src/test/shell/githubactions_finalreport.bats
new file mode 100644
index 00000000..cd4e003d
--- /dev/null
+++ b/precommit/src/test/shell/githubactions_finalreport.bats
@@ -0,0 +1,175 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+load functions_test_helper
+
+setup_gha() {
+ # Source the githubactions robot
+ # shellcheck disable=SC1090
+ . "${BATS_TEST_DIRNAME}/../../main/shell/robots.d/githubactions.sh"
+
+ # Mock required functions
+ big_console_header() { :; }
+ clock_display() { echo "$1s"; }
+ get_artifact_url() { echo ""; }
+ yetus_error() { echo "$*" >&2; }
+ SED="sed"
+
+ # Set up step summary file
+ GITHUB_STEP_SUMMARY="${TMP}/step_summary.md"
+ touch "${GITHUB_STEP_SUMMARY}"
+ export GITHUB_STEP_SUMMARY
+
+ # Initialize arrays and settings
+ TP_VOTE_TABLE=()
+ TP_TEST_TABLE=()
+ TP_HEADER=()
+ TP_FOOTER_TABLE=()
+ VERSION="0.0.0-test"
+ GITHUB_USE_EMOJI_VOTE=false
+}
+
+@test "githubactions_finalreport (no GITHUB_STEP_SUMMARY)" {
+ setup_gha
+ unset GITHUB_STEP_SUMMARY
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+}
+
+@test "githubactions_finalreport (GITHUB_STEP_SUMMARY not writable)" {
+ setup_gha
+ GITHUB_STEP_SUMMARY="/nonexistent/path/summary.md"
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+}
+
+@test "githubactions_finalreport (success result)" {
+ setup_gha
+ RESULT=0
+ TP_VOTE_TABLE=("|+1| compile |60||passed|")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ grep -q ":confetti_ball:" "${GITHUB_STEP_SUMMARY}"
+ grep -q "+1 overall" "${GITHUB_STEP_SUMMARY}"
+ grep -q "compile" "${GITHUB_STEP_SUMMARY}"
+}
+
+@test "githubactions_finalreport (failure result)" {
+ setup_gha
+ RESULT=1
+ TP_VOTE_TABLE=("|-1| unit |120||tests failed|")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ grep -q ":broken_heart:" "${GITHUB_STEP_SUMMARY}"
+ grep -q -- "-1 overall" "${GITHUB_STEP_SUMMARY}"
+ grep -q "unit" "${GITHUB_STEP_SUMMARY}"
+}
+
+@test "githubactions_finalreport (with headers)" {
+ setup_gha
+ RESULT=0
+ TP_HEADER=("Build completed successfully")
+ TP_VOTE_TABLE=("|+1| compile |60||passed|")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ grep -q "Build completed successfully" "${GITHUB_STEP_SUMMARY}"
+}
+
+@test "githubactions_finalreport (with failed tests)" {
+ setup_gha
+ RESULT=1
+ TP_VOTE_TABLE=("|-1| unit |120||tests failed|")
+ TP_TEST_TABLE=("| Failed tests | org.example.TestFoo |")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ grep -q "Failed Tests" "${GITHUB_STEP_SUMMARY}"
+ grep -q "TestFoo" "${GITHUB_STEP_SUMMARY}"
+}
+
+@test "githubactions_finalreport (vote table header row)" {
+ setup_gha
+ RESULT=0
+ TP_VOTE_TABLE=("|H||||Prechecks|")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ grep -q "_Prechecks_" "${GITHUB_STEP_SUMMARY}"
+}
+
+@test "githubactions_finalreport (emoji vote enabled)" {
+ setup_gha
+ RESULT=0
+ GITHUB_USE_EMOJI_VOTE=true
+ TP_VOTE_TABLE=("|+1| compile |60||passed|")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ grep -q ":green_heart:" "${GITHUB_STEP_SUMMARY}"
+}
+
+@test "githubactions_finalreport (emoji vote disabled)" {
+ setup_gha
+ RESULT=0
+ GITHUB_USE_EMOJI_VOTE=false
+ TP_VOTE_TABLE=("|+1| compile |60||passed|")
+ run githubactions_finalreport
+ [ "${status}" -eq 0 ]
+ # Should have +1 but not the emoji
+ grep -q "+1" "${GITHUB_STEP_SUMMARY}"
+ ! grep -q ":green_heart:" "${GITHUB_STEP_SUMMARY}"
+}
+
+setup_docker_support() {
+ # Source the githubactions robot
+ # shellcheck disable=SC1090
+ . "${BATS_TEST_DIRNAME}/../../main/shell/robots.d/githubactions.sh"
+
+ # Mock add_docker_env
+ DOCKER_EXTRAENVS=()
+ add_docker_env() {
+ for k in "$@"; do
+ DOCKER_EXTRAENVS+=("${k}")
+ done
+ }
+
+ DOCKER_EXTRAARGS=()
+ DOCKER_WORK_DIR="/workdir"
+}
+
+@test "githubactions_docker_support (no GITHUB_STEP_SUMMARY)" {
+ setup_docker_support
+ unset GITHUB_STEP_SUMMARY
+ run githubactions_docker_support
+ [ "${status}" -eq 0 ]
+ [ "${#DOCKER_EXTRAARGS[@]}" -eq 0 ]
+}
+
+@test "githubactions_docker_support (GITHUB_STEP_SUMMARY file missing)" {
+ setup_docker_support
+ GITHUB_STEP_SUMMARY="/nonexistent/path/summary.md"
+ run githubactions_docker_support
+ [ "${status}" -eq 0 ]
+ [ "${#DOCKER_EXTRAARGS[@]}" -eq 0 ]
+}
+
+@test "githubactions_docker_support (mounts summary file)" {
+ setup_docker_support
+ GITHUB_STEP_SUMMARY="${TMP}/step_summary.md"
+ touch "${GITHUB_STEP_SUMMARY}"
+ githubactions_docker_support
+ [[ "${DOCKER_EXTRAARGS[*]}" == *"-v"* ]]
+ [[ "${DOCKER_EXTRAARGS[*]}" ==
*"${TMP}/step_summary.md:/workdir/step_summary.md"* ]]
+ [ "${GITHUB_STEP_SUMMARY}" = "/workdir/step_summary.md" ]
+ [[ "${DOCKER_EXTRAENVS[*]}" == *"GITHUB_STEP_SUMMARY"* ]]
+}