Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/scripts/publish-reports.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
# Needs the gh CLI on the runner and GH_TOKEN with contents: write (to create the release/tag and
# upload/delete its assets).
#
# With REPORTS_TAG set (release-test-report.yml), the bundle goes to that version's pre-release
# instead, under its plain name and without the retention cleanup - that release is created by the
# calling workflow and kept until deleted by hand.
#
# Usage: publish-reports.sh <bundle file>
set -euo pipefail

Expand All @@ -17,6 +21,16 @@ retention_days=14

command -v gh >/dev/null || { echo "::error::gh CLI not found on this runner (brew install gh)"; exit 1; }

if [ -n "${REPORTS_TAG:-}" ]; then
name="$(basename "$file")"
gh release upload "$REPORTS_TAG" "$file" --clobber
{
echo "## Reports: $name"
echo "[Download $name]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/$REPORTS_TAG/$name) - attached to the [$REPORTS_TAG]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/tag/$REPORTS_TAG) pre-release"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi

# unit-test.yml and android-test.yml run at the same time, so both may try to create the release on
# the first run - if the create fails, the other job has won the race, as long as it exists now
if ! gh release view "$tag" >/dev/null 2>&1; then
Expand Down
107 changes: 107 additions & 0 deletions .github/scripts/release-report-summary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env bash
# Downloads the report bundles attached to a version's test-report pre-release, totals the JUnit
# results (and unit test line coverage) per suite, and writes them as the release notes and the
# job summary. Used by release-test-report.yml after the test jobs have uploaded their bundles.
#
# Needs the gh CLI on the runner and GH_TOKEN with contents: write.
#
# Usage: release-report-summary.sh <release tag> <version>
set -euo pipefail

tag="$1"
version="$2"
work="$RUNNER_TEMP/release-report"
notes="$work/notes.md"
rm -rf "$work"
mkdir -p "$work/bundles"

gh release download "$tag" --pattern '*.tar.gz' --dir "$work/bundles" || true

run_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
{
echo "# $version release test reports summary"
echo
echo "- Branch: \`$GITHUB_REF_NAME\`"
echo "- Commit: [\`${GITHUB_SHA:0:9}\`]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)"
echo "- Run: [$GITHUB_RUN_ID]($run_url)"
echo "- Date: $(date -u +%Y-%m-%d) (UTC)"
echo
echo "| Suite | Result | Tests | Passed | Failed | Skipped | Report |"
echo "|---|---|---:|---:|---:|---:|---|"
} > "$notes"

failures="$work/failures.md"
: > "$failures"
coverage=""

for suite in "Unit tests:unit-test-reports.tar.gz" \
"Instrumentation tests (API 30, small screen):android-test-reports-api30.tar.gz" \
"Instrumentation tests (API 34, Pixel 6):android-test-reports-api34.tar.gz"; do
label="${suite%%:*}"
bundle="${suite#*:}"
if [ ! -f "$work/bundles/$bundle" ]; then
echo "| $label | ⚠️ no report | | | | | |" >> "$notes"
continue
fi
dir="$work/extract/${bundle%.tar.gz}"
mkdir -p "$dir"
tar -xzf "$work/bundles/$bundle" -C "$dir"

# JUnit XML from both Gradle (test-results) and AGP (androidTest-results): one <testsuite> per
# file with tests/failures/errors/skipped attributes, failing <testcase>s followed by <failure>
# or <error>
xmls=$(find "$dir" -path '*-results/*' -name '*.xml' | sort)
if [ -z "$xmls" ]; then
echo "| $label | ⚠️ no results | | | | | |" >> "$notes"
continue
fi
# shellcheck disable=SC2086
read -r tests failed skipped < <(awk '
function attr(name, m) { return match($0, name "=\"[0-9]+\"") ? substr($0, RSTART + length(name) + 2, RLENGTH - length(name) - 3) + 0 : 0 }
/<testsuite[ >]/ { t += attr("tests"); f += attr("failures") + attr("errors"); s += attr("skipped") }
END { print t + 0, f + 0, s + 0 }' $xmls)
passed=$((tests - failed - skipped))
result="✅ passed"
[ "$failed" -gt 0 ] && result="❌ failed"
url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/$tag/$bundle"
echo "| $label | $result | $tests | $passed | $failed | $skipped | [$bundle]($url) |" >> "$notes"

if [ "$failed" -gt 0 ]; then
echo "**$label**" >> "$failures"
# shellcheck disable=SC2086
awk '
function attr(name, m) { return match($0, name "=\"[^\"]*\"") ? substr($0, RSTART + length(name) + 2, RLENGTH - length(name) - 3) : "" }
/<testcase[ >]/ { tc = attr("classname") "." attr("name") }
/<failure[ >]|<error[ >]/ { if (tc != "") print "- `" tc "`"; tc = "" }' $xmls | sort -u >> "$failures"
echo >> "$failures"
fi

kover="$dir/app/build/reports/kover/report.xml"
if [ -f "$kover" ]; then
line_counter=$(grep -o '<counter type="LINE" missed="[0-9]*" covered="[0-9]*"/>' "$kover" | tail -1)
missed=$(echo "$line_counter" | grep -o 'missed="[0-9]*"' | grep -o '[0-9]*')
covered=$(echo "$line_counter" | grep -o 'covered="[0-9]*"' | grep -o '[0-9]*')
total=$((missed + covered))
if [ "$total" -gt 0 ]; then
coverage="**$(awk "BEGIN { printf \"%.1f\", ($covered/$total)*100 }")%** ($covered/$total lines)"
fi
fi
done

{
if [ -n "$coverage" ]; then
echo
echo "Unit test line coverage: $coverage"
fi
if [ -s "$failures" ]; then
echo
echo "## Failed tests"
echo
cat "$failures"
fi
echo
echo "Each bundle holds the HTML report and JUnit XML; the instrumentation bundles also have the screen recording and per-test screenshots."
} >> "$notes"

gh release edit "$tag" --notes-file "$notes"
cat "$notes" >> "$GITHUB_STEP_SUMMARY"
8 changes: 8 additions & 0 deletions .github/workflows/android-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ on:
branches:
- "aviv-dev-latest"
workflow_dispatch:
# called by release-test-report.yml, which passes the tag of the version's pre-release so the
# bundles are attached there instead of to ci-reports
workflow_call:
inputs:
release-tag:
type: string
default: ""

permissions:
contents: write # attaching the report bundle to the ci-reports pre-release (publish-reports.sh)
Expand Down Expand Up @@ -129,4 +136,5 @@ jobs:
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
REPORTS_TAG: ${{ inputs.release-tag }}
run: bash .github/scripts/publish-reports.sh "artifact-bundle/android-test-reports-api${{ matrix.api-level }}.tar.gz"
41 changes: 0 additions & 41 deletions .github/workflows/build-debug-apk.yml

This file was deleted.

30 changes: 0 additions & 30 deletions .github/workflows/generate-quest-list.yml

This file was deleted.

21 changes: 0 additions & 21 deletions .github/workflows/gradle-wrapper-validation.yml

This file was deleted.

31 changes: 0 additions & 31 deletions .github/workflows/lint.yml.disabled

This file was deleted.

79 changes: 79 additions & 0 deletions .github/workflows/release-test-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Release test report

# Run by hand (Actions > Release test report > Run workflow, picking the branch to release) to get
# the unit + instrumentation test reports for a release build. They're attached to a
# "v<version>-test-reports" pre-release titled "<version> release test reports summary", whose
# notes hold the pass/fail summary. Running again for the same version replaces that pre-release.

on:
workflow_dispatch:
inputs:
version:
description: "Version name (leave empty to use appVersionName from app/build.gradle.kts)"
type: string
default: ""

permissions:
contents: write # creating the pre-release and attaching the report bundles
actions: read
checks: write

concurrency:
group: release-test-report-${{ github.ref }}

jobs:
prepare:
runs-on: [self-hosted, macOS]
outputs:
version: ${{ steps.release.outputs.version }}
tag: ${{ steps.release.outputs.tag }}
steps:
- uses: actions/checkout@v4

- name: Create the pre-release
id: release
env:
GH_TOKEN: ${{ github.token }}
INPUT_VERSION: ${{ inputs.version }}
run: |
version="$INPUT_VERSION"
if [ -z "$version" ]; then
version=$(sed -n 's/^val appVersionName = "\(.*\)"/\1/p' app/build.gradle.kts)
fi
[ -n "$version" ] || { echo "::error::couldn't read appVersionName from app/build.gradle.kts"; exit 1; }
tag="v$version-test-reports"
# a re-run replaces the old reports (and moves the tag to this run's commit) rather than
# mixing bundles from two runs in one release
if gh release view "$tag" >/dev/null 2>&1; then
gh release delete "$tag" --yes --cleanup-tag
fi
gh release create "$tag" --prerelease --target "$GITHUB_SHA" \
--title "$version release test reports summary" \
--notes "Tests are running: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"

unit-test:
needs: prepare
uses: ./.github/workflows/unit-test.yml
with:
release-tag: ${{ needs.prepare.outputs.tag }}

android-test:
needs: prepare
uses: ./.github/workflows/android-test.yml
with:
release-tag: ${{ needs.prepare.outputs.tag }}

summary:
needs: [prepare, unit-test, android-test]
# also (especially) when tests failed - the summary is what shows which ones
if: always() && needs.prepare.result == 'success'
runs-on: [self-hosted, macOS]
steps:
- uses: actions/checkout@v4

- name: Write release notes
env:
GH_TOKEN: ${{ github.token }}
run: bash .github/scripts/release-report-summary.sh "${{ needs.prepare.outputs.tag }}" "${{ needs.prepare.outputs.version }}"
8 changes: 8 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ on:
branches:
- "aviv-dev-latest"
workflow_dispatch:
# called by release-test-report.yml, which passes the tag of the version's pre-release so the
# bundles are attached there instead of to ci-reports
workflow_call:
inputs:
release-tag:
type: string
default: ""

permissions:
contents: write # attaching the report bundle to the ci-reports pre-release (publish-reports.sh)
Expand Down Expand Up @@ -82,4 +89,5 @@ jobs:
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
REPORTS_TAG: ${{ inputs.release-tag }}
run: bash .github/scripts/publish-reports.sh artifact-bundle/unit-test-reports.tar.gz
Loading
Loading