Skip to content

Commit 253bcb8

Browse files
committed
Generate merged Allure report artifacts
1 parent c036962 commit 253bcb8

File tree

1 file changed

+127
-1
lines changed

1 file changed

+127
-1
lines changed

.github/workflows/qa-android-ui-tests.yml

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,15 +623,139 @@ jobs:
623623
adb -s "${SERIAL}" pull "/sdcard/googletest/test_outputfiles/allure-results" "${OUT_DIR}/${SERIAL}" >/dev/null 2>&1 || true
624624
done
625625
626+
- name: Merge Allure results (add device label)
627+
if: always()
628+
env:
629+
OUT_DIR: ${{ runner.temp }}/allure-results
630+
MERGED_DIR: ${{ runner.temp }}/allure-results-merged
631+
run: |
632+
set -euo pipefail
633+
python3 - <<'PY'
634+
import json
635+
import os
636+
import shutil
637+
import subprocess
638+
from pathlib import Path
639+
640+
out_dir = Path(os.environ["OUT_DIR"])
641+
merged_dir = Path(os.environ["MERGED_DIR"])
642+
merged_dir.mkdir(parents=True, exist_ok=True)
643+
644+
def get_prop(serial: str, prop: str) -> str:
645+
try:
646+
result = subprocess.run(
647+
["adb", "-s", serial, "shell", "getprop", prop],
648+
check=False,
649+
capture_output=True,
650+
text=True,
651+
timeout=5,
652+
)
653+
return result.stdout.strip()
654+
except Exception:
655+
return ""
656+
657+
device_dirs = [p for p in out_dir.iterdir() if p.is_dir()]
658+
device_info = {}
659+
for device_dir in device_dirs:
660+
serial = device_dir.name
661+
model = get_prop(serial, "ro.product.model") or "unknown"
662+
sdk = get_prop(serial, "ro.build.version.release") or get_prop(serial, "ro.build.version.sdk") or "unknown"
663+
device_info[serial] = {"model": model, "sdk": sdk}
664+
665+
def device_label(serial: str) -> str:
666+
meta = device_info.get(serial, {})
667+
model = meta.get("model") or "unknown"
668+
sdk = meta.get("sdk") or "unknown"
669+
return f"{model} - {sdk} ({serial})"
670+
671+
def add_label(data: dict, name: str, value: str) -> dict:
672+
labels = [l for l in data.get("labels", []) if l.get("name") != name]
673+
labels.append({"name": name, "value": value})
674+
data["labels"] = labels
675+
return data
676+
677+
for device_dir in device_dirs:
678+
serial = device_dir.name
679+
src_dir = device_dir / "allure-results"
680+
if not src_dir.is_dir():
681+
src_dir = device_dir
682+
if not src_dir.is_dir():
683+
continue
684+
685+
label = device_label(serial)
686+
for item in src_dir.iterdir():
687+
if item.is_dir():
688+
continue
689+
if item.name in ("executor.json", "environment.properties"):
690+
continue
691+
if item.name.endswith("-result.json"):
692+
try:
693+
data = json.loads(item.read_text(encoding="utf-8"))
694+
except Exception:
695+
continue
696+
data = add_label(data, "device", label)
697+
(merged_dir / item.name).write_text(
698+
json.dumps(data, ensure_ascii=True),
699+
encoding="utf-8",
700+
)
701+
else:
702+
shutil.copy2(item, merged_dir / item.name)
703+
704+
if device_info:
705+
devices = ", ".join(device_label(serial) for serial in sorted(device_info.keys()))
706+
(merged_dir / "environment.properties").write_text(
707+
f"devices={devices}\n", encoding="utf-8"
708+
)
709+
710+
run_id = os.environ.get("GITHUB_RUN_ID", "")
711+
repo = os.environ.get("GITHUB_REPOSITORY", "")
712+
server = os.environ.get("GITHUB_SERVER_URL", "https://github.com")
713+
run_url = f"{server}/{repo}/actions/runs/{run_id}" if repo and run_id else ""
714+
executor = {
715+
"name": "GitHub Actions",
716+
"type": "github",
717+
"url": run_url,
718+
"buildName": os.environ.get("GITHUB_RUN_NUMBER", ""),
719+
"buildUrl": run_url,
720+
"reportName": "Android UI Tests",
721+
}
722+
(merged_dir / "executor.json").write_text(
723+
json.dumps(executor, ensure_ascii=True),
724+
encoding="utf-8",
725+
)
726+
PY
727+
728+
- name: Generate Allure HTML report
729+
if: always()
730+
env:
731+
MERGED_DIR: ${{ runner.temp }}/allure-results-merged
732+
REPORT_DIR: ${{ runner.temp }}/allure-report
733+
run: |
734+
set -euo pipefail
735+
if [[ ! -d "${MERGED_DIR}" ]]; then
736+
echo "No merged Allure results found"
737+
exit 0
738+
fi
739+
740+
ALLURE_VERSION="2.29.0"
741+
ALLURE_TGZ="${RUNNER_TEMP}/allure-${ALLURE_VERSION}.tgz"
742+
curl -fsSL -o "${ALLURE_TGZ}" \
743+
"https://github.com/allure-framework/allure2/releases/download/${ALLURE_VERSION}/allure-${ALLURE_VERSION}.tgz"
744+
tar -xzf "${ALLURE_TGZ}" -C "${RUNNER_TEMP}"
745+
"${RUNNER_TEMP}/allure-${ALLURE_VERSION}/bin/allure" \
746+
generate "${MERGED_DIR}" -o "${REPORT_DIR}" --clean
747+
626748
- name: Upload test artifacts
627749
if: always()
628750
uses: actions/upload-artifact@v4
629751
with:
630752
name: android-ui-test-results
631753
if-no-files-found: warn
754+
retention-days: 90
632755
path: |
633756
tests/testsCore/build/reports/androidTests/connected
634-
${{ runner.temp }}/allure-results
757+
${{ runner.temp }}/allure-results-merged
758+
${{ runner.temp }}/allure-report
635759
636760
- name: Cleanup (remove secrets + build outputs)
637761
if: always()
@@ -640,6 +764,8 @@ jobs:
640764
rm -f "${RUNNER_TEMP}/secrets.json" || true
641765
rm -f "${RUNNER_TEMP}/Wire.apk" "${RUNNER_TEMP}/Wire.old.apk" || true
642766
rm -rf "${RUNNER_TEMP}/allure-results" || true
767+
rm -rf "${RUNNER_TEMP}/allure-results-merged" || true
768+
rm -rf "${RUNNER_TEMP}/allure-report" || true
643769
644770
# Remove build outputs (these can contain BuildConfig secrets) but keep Gradle caches
645771
git clean -ffdx -e .gradle -e .kotlin

0 commit comments

Comments
 (0)