diff --git a/.github/workflows/integration-mobile-test-lib-infer-diffusion.yml b/.github/workflows/integration-mobile-test-lib-infer-diffusion.yml index 737f63b690..7063d2223a 100644 --- a/.github/workflows/integration-mobile-test-lib-infer-diffusion.yml +++ b/.github/workflows/integration-mobile-test-lib-infer-diffusion.yml @@ -1293,3 +1293,142 @@ jobs: echo "✅ All Device Farm tests passed!" echo " Your tests: $USER_PASSED passed (out of $USER_TEST_COUNT total)" echo " Device Farm total: $TOTAL | Passed: $PASSED | Failed: $FAILED | Skipped: $SKIPPED" + + - name: Refresh AWS credentials for log download + if: always() && steps.schedule_run.outputs.run_arn + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # 6.0.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }} + aws-region: us-west-2 + role-session-name: device-farm-logs + + - name: Download Device Farm Logs + if: always() && steps.schedule_run.outputs.run_arn + run: | + RUN_ARN="${{ steps.schedule_run.outputs.run_arn }}" + LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" + mkdir -p "$LOG_DIR" + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📥 DOWNLOADING DEVICE FARM LOGS" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "Logs are downloaded so anyone with repo access can view them" + echo "without needing AWS Device Farm credentials." + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" + + RUN_DETAILS=$(aws devicefarm get-run --arn "$RUN_ARN" --output json 2>/dev/null || echo '{}') + RUN_LABEL=$(echo "$RUN_DETAILS" | jq -r '.run.name // "unknown"') + echo "" + echo "========================================" + echo "📦 Run: $RUN_LABEL" + echo "========================================" + + SAFE_RUN=$(echo "$RUN_LABEL" | tr ' /' '__' | tr -cd '[:alnum:]_-') + JOBS=$(aws devicefarm list-jobs --arn "$RUN_ARN" --output json 2>/dev/null || echo '{"jobs":[]}') + + for JOB_ARN in $(echo "$JOBS" | jq -r '.jobs[].arn'); do + DEVICE_NAME=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .device.name // "unknown"') + JOB_RESULT=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .result // "UNKNOWN"') + SAFE_NAME=$(echo "$DEVICE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📱 $DEVICE_NAME ($JOB_RESULT)" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + SUITES=$(aws devicefarm list-suites --arn "$JOB_ARN" --output json 2>/dev/null || echo '{"suites":[]}') + + for SUITE_ARN in $(echo "$SUITES" | jq -r '.suites[].arn'); do + SUITE_NAME=$(echo "$SUITES" | jq -r --arg arn "$SUITE_ARN" '.suites[] | select(.arn == $arn) | .name // "unknown"') + SAFE_SUITE=$(echo "$SUITE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME" + + if echo "$ART_NAME" | grep -qiE "test.spec|testspec"; then + echo "" + echo "::group::📋 [$DEVICE_NAME] $SUITE_NAME — $ART_NAME" + cat "$DEST" 2>/dev/null || true + echo "::endgroup::" + fi + fi + done + + LOG_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type LOG --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$LOG_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME (LOG)" + fi + done + done + + JOB_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$JOB_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + echo "$JOB_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded (job-level): $ART_NAME" + fi + done + done + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📦 All downloaded logs:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + find "$LOG_DIR" -type f -exec ls -lh {} \; 2>/dev/null || echo " (no logs downloaded)" + + - name: Upload Device Farm Logs + if: always() && steps.schedule_run.outputs.run_arn + uses: actions/upload-artifact@v4 + with: + name: devicefarm-logs-diffusion-${{ matrix.platform }} + path: devicefarm-logs/ + retention-days: 30 + if-no-files-found: ignore diff --git a/.github/workflows/integration-mobile-test-ocr-onnx.yml b/.github/workflows/integration-mobile-test-ocr-onnx.yml index c2326a8321..742437fef8 100644 --- a/.github/workflows/integration-mobile-test-ocr-onnx.yml +++ b/.github/workflows/integration-mobile-test-ocr-onnx.yml @@ -1641,6 +1641,156 @@ jobs: retention-days: 90 if-no-files-found: ignore + - name: Refresh AWS credentials for log download + if: always() && (steps.schedule_run.outputs.run_arn_perf || steps.schedule_run.outputs.run_arn_regular) + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # 6.0.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }} + aws-region: us-west-2 + role-session-name: device-farm-logs + + - name: Download Device Farm Logs (all runs) + if: always() && (steps.schedule_run.outputs.run_arn_perf || steps.schedule_run.outputs.run_arn_regular) + run: | + RUN_ARN_PERF="${{ steps.schedule_run.outputs.run_arn_perf }}" + RUN_ARN_REGULAR="${{ steps.schedule_run.outputs.run_arn_regular }}" + LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" + mkdir -p "$LOG_DIR" + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📥 DOWNLOADING DEVICE FARM LOGS (ALL RUNS)" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "Logs are downloaded so anyone with repo access can view them" + echo "without needing AWS Device Farm credentials." + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" + + RUN_ARNS=() + if [ -n "$RUN_ARN_PERF" ]; then + RUN_ARNS+=("$RUN_ARN_PERF") + fi + if [ -n "$RUN_ARN_REGULAR" ]; then + RUN_ARNS+=("$RUN_ARN_REGULAR") + fi + + for RUN_ARN in "${RUN_ARNS[@]}"; do + RUN_DETAILS=$(aws devicefarm get-run --arn "$RUN_ARN" --output json 2>/dev/null || echo '{}') + RUN_LABEL=$(echo "$RUN_DETAILS" | jq -r '.run.name // "unknown"') + echo "" + echo "========================================" + echo "📦 Run: $RUN_LABEL" + echo "========================================" + + SAFE_RUN=$(echo "$RUN_LABEL" | tr ' /' '__' | tr -cd '[:alnum:]_-') + JOBS=$(aws devicefarm list-jobs --arn "$RUN_ARN" --output json 2>/dev/null || echo '{"jobs":[]}') + + for JOB_ARN in $(echo "$JOBS" | jq -r '.jobs[].arn'); do + DEVICE_NAME=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .device.name // "unknown"') + JOB_RESULT=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .result // "UNKNOWN"') + SAFE_NAME=$(echo "$DEVICE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📱 $DEVICE_NAME ($JOB_RESULT)" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + SUITES=$(aws devicefarm list-suites --arn "$JOB_ARN" --output json 2>/dev/null || echo '{"suites":[]}') + + for SUITE_ARN in $(echo "$SUITES" | jq -r '.suites[].arn'); do + SUITE_NAME=$(echo "$SUITES" | jq -r --arg arn "$SUITE_ARN" '.suites[] | select(.arn == $arn) | .name // "unknown"') + SAFE_SUITE=$(echo "$SUITE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME" + + if echo "$ART_NAME" | grep -qiE "test.spec|testspec"; then + echo "" + echo "::group::📋 [$DEVICE_NAME] $SUITE_NAME — $ART_NAME" + cat "$DEST" 2>/dev/null || true + echo "::endgroup::" + fi + fi + done + + LOG_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type LOG --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$LOG_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME (LOG)" + fi + done + done + + JOB_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$JOB_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + echo "$JOB_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded (job-level): $ART_NAME" + fi + done + done + done + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📦 All downloaded logs:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + find "$LOG_DIR" -type f -exec ls -lh {} \; 2>/dev/null || echo " (no logs downloaded)" + + - name: Upload Device Farm Logs + if: always() && (steps.schedule_run.outputs.run_arn_perf || steps.schedule_run.outputs.run_arn_regular) + uses: actions/upload-artifact@v4 + with: + name: devicefarm-logs-ocr-onnx-${{ matrix.platform }} + path: devicefarm-logs/ + retention-days: 30 + if-no-files-found: ignore + combine-reports: name: Combined Performance Report needs: [build-and-test] diff --git a/.github/workflows/integration-mobile-test-qvac-lib-decoder-audio.yml b/.github/workflows/integration-mobile-test-qvac-lib-decoder-audio.yml index 2782aeb639..edfe28c0da 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-decoder-audio.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-decoder-audio.yml @@ -1222,3 +1222,142 @@ jobs: echo " Your tests: $USER_PASSED passed (out of $USER_TEST_COUNT total)" echo " Device Farm total: $TOTAL | Passed: $PASSED | Failed: $FAILED | Skipped: $SKIPPED" + - name: Refresh AWS credentials for log download + if: always() && steps.schedule_run.outputs.run_arn + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # 6.0.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }} + aws-region: us-west-2 + role-session-name: device-farm-logs + + - name: Download Device Farm Logs + if: always() && steps.schedule_run.outputs.run_arn + run: | + RUN_ARN="${{ steps.schedule_run.outputs.run_arn }}" + LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" + mkdir -p "$LOG_DIR" + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📥 DOWNLOADING DEVICE FARM LOGS" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "Logs are downloaded so anyone with repo access can view them" + echo "without needing AWS Device Farm credentials." + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" + + RUN_DETAILS=$(aws devicefarm get-run --arn "$RUN_ARN" --output json 2>/dev/null || echo '{}') + RUN_LABEL=$(echo "$RUN_DETAILS" | jq -r '.run.name // "unknown"') + echo "" + echo "========================================" + echo "📦 Run: $RUN_LABEL" + echo "========================================" + + SAFE_RUN=$(echo "$RUN_LABEL" | tr ' /' '__' | tr -cd '[:alnum:]_-') + JOBS=$(aws devicefarm list-jobs --arn "$RUN_ARN" --output json 2>/dev/null || echo '{"jobs":[]}') + + for JOB_ARN in $(echo "$JOBS" | jq -r '.jobs[].arn'); do + DEVICE_NAME=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .device.name // "unknown"') + JOB_RESULT=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .result // "UNKNOWN"') + SAFE_NAME=$(echo "$DEVICE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📱 $DEVICE_NAME ($JOB_RESULT)" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + SUITES=$(aws devicefarm list-suites --arn "$JOB_ARN" --output json 2>/dev/null || echo '{"suites":[]}') + + for SUITE_ARN in $(echo "$SUITES" | jq -r '.suites[].arn'); do + SUITE_NAME=$(echo "$SUITES" | jq -r --arg arn "$SUITE_ARN" '.suites[] | select(.arn == $arn) | .name // "unknown"') + SAFE_SUITE=$(echo "$SUITE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME" + + if echo "$ART_NAME" | grep -qiE "test.spec|testspec"; then + echo "" + echo "::group::📋 [$DEVICE_NAME] $SUITE_NAME — $ART_NAME" + cat "$DEST" 2>/dev/null || true + echo "::endgroup::" + fi + fi + done + + LOG_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type LOG --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$LOG_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME (LOG)" + fi + done + done + + JOB_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$JOB_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + echo "$JOB_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded (job-level): $ART_NAME" + fi + done + done + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📦 All downloaded logs:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + find "$LOG_DIR" -type f -exec ls -lh {} \; 2>/dev/null || echo " (no logs downloaded)" + + - name: Upload Device Farm Logs + if: always() && steps.schedule_run.outputs.run_arn + uses: actions/upload-artifact@v4 + with: + name: devicefarm-logs-decoder-audio-${{ matrix.platform }} + path: devicefarm-logs/ + retention-days: 30 + if-no-files-found: ignore + diff --git a/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-embed.yml b/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-embed.yml index 4ba1801f97..7b633bd4b9 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-embed.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-embed.yml @@ -1267,3 +1267,142 @@ jobs: echo "✅ All Device Farm tests passed!" echo " Your tests: $USER_PASSED passed (out of $USER_TEST_COUNT total)" echo " Device Farm total: $TOTAL | Passed: $PASSED | Failed: $FAILED | Skipped: $SKIPPED" + + - name: Refresh AWS credentials for log download + if: always() && steps.schedule_run.outputs.run_arn + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # 6.0.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }} + aws-region: us-west-2 + role-session-name: device-farm-logs + + - name: Download Device Farm Logs + if: always() && steps.schedule_run.outputs.run_arn + run: | + RUN_ARN="${{ steps.schedule_run.outputs.run_arn }}" + LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" + mkdir -p "$LOG_DIR" + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📥 DOWNLOADING DEVICE FARM LOGS" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "Logs are downloaded so anyone with repo access can view them" + echo "without needing AWS Device Farm credentials." + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" + + RUN_DETAILS=$(aws devicefarm get-run --arn "$RUN_ARN" --output json 2>/dev/null || echo '{}') + RUN_LABEL=$(echo "$RUN_DETAILS" | jq -r '.run.name // "unknown"') + echo "" + echo "========================================" + echo "📦 Run: $RUN_LABEL" + echo "========================================" + + SAFE_RUN=$(echo "$RUN_LABEL" | tr ' /' '__' | tr -cd '[:alnum:]_-') + JOBS=$(aws devicefarm list-jobs --arn "$RUN_ARN" --output json 2>/dev/null || echo '{"jobs":[]}') + + for JOB_ARN in $(echo "$JOBS" | jq -r '.jobs[].arn'); do + DEVICE_NAME=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .device.name // "unknown"') + JOB_RESULT=$(echo "$JOBS" | jq -r --arg arn "$JOB_ARN" '.jobs[] | select(.arn == $arn) | .result // "UNKNOWN"') + SAFE_NAME=$(echo "$DEVICE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📱 $DEVICE_NAME ($JOB_RESULT)" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + SUITES=$(aws devicefarm list-suites --arn "$JOB_ARN" --output json 2>/dev/null || echo '{"suites":[]}') + + for SUITE_ARN in $(echo "$SUITES" | jq -r '.suites[].arn'); do + SUITE_NAME=$(echo "$SUITES" | jq -r --arg arn "$SUITE_ARN" '.suites[] | select(.arn == $arn) | .name // "unknown"') + SAFE_SUITE=$(echo "$SUITE_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + + ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME" + + if echo "$ART_NAME" | grep -qiE "test.spec|testspec"; then + echo "" + echo "::group::📋 [$DEVICE_NAME] $SUITE_NAME — $ART_NAME" + cat "$DEST" 2>/dev/null || true + echo "::endgroup::" + fi + fi + done + + LOG_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$SUITE_ARN" --type LOG --output json 2>/dev/null || echo '{"artifacts":[]}') + + echo "$LOG_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded: $SUITE_NAME / $ART_NAME (LOG)" + fi + done + done + + JOB_ARTIFACTS=$(aws devicefarm list-artifacts --arn "$JOB_ARN" --type FILE --output json 2>/dev/null || echo '{"artifacts":[]}') + echo "$JOB_ARTIFACTS" | jq -c '.artifacts[]' 2>/dev/null | while read -r ARTIFACT; do + ART_NAME=$(echo "$ARTIFACT" | jq -r '.name // "unknown"') + ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') + ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') + [ -z "$ART_URL" ] && continue + + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') + DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" + + if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then + echo " Downloaded (job-level): $ART_NAME" + fi + done + done + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📦 All downloaded logs:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + find "$LOG_DIR" -type f -exec ls -lh {} \; 2>/dev/null || echo " (no logs downloaded)" + + - name: Upload Device Farm Logs + if: always() && steps.schedule_run.outputs.run_arn + uses: actions/upload-artifact@v4 + with: + name: devicefarm-logs-llamacpp-embed-${{ matrix.platform }} + path: devicefarm-logs/ + retention-days: 30 + if-no-files-found: ignore diff --git a/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-llm.yml b/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-llm.yml index 08ebbd7ef3..3086ba78bb 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-llm.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-infer-llamacpp-llm.yml @@ -1471,6 +1471,7 @@ jobs: RUN_ARN_8="${{ steps.schedule_run.outputs.run_arn_8 }}" RUN_COUNT="${{ steps.schedule_run.outputs.run_count }}" LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" mkdir -p "$LOG_DIR" RUN_ARNS=("$RUN_ARN_1") @@ -1518,6 +1519,12 @@ jobs: ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then @@ -1549,6 +1556,12 @@ jobs: ART_URL=$(echo "$ARTIFACT" | jq -r '.url // empty') ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" if curl -fsSL -o "$DEST" "$ART_URL" 2>/dev/null; then diff --git a/.github/workflows/integration-mobile-test-qvac-lib-infer-nmtcpp.yml b/.github/workflows/integration-mobile-test-qvac-lib-infer-nmtcpp.yml index ea2aa0dddd..fd6e9790f6 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-infer-nmtcpp.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-infer-nmtcpp.yml @@ -1497,6 +1497,7 @@ jobs: RUN_ARN_2="${{ steps.schedule_run.outputs.run_arn_2 }}" RUN_COUNT="${{ steps.schedule_run.outputs.run_count }}" LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" mkdir -p "$LOG_DIR" echo "" @@ -1506,6 +1507,9 @@ jobs: echo "" echo "Logs are downloaded so anyone with repo access can view them" echo "without needing AWS Device Farm credentials." + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi echo "" RUN_ARNS=("$RUN_ARN_1") @@ -1547,6 +1551,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" @@ -1586,6 +1597,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" diff --git a/.github/workflows/integration-mobile-test-qvac-lib-infer-onnx-tts.yml b/.github/workflows/integration-mobile-test-qvac-lib-infer-onnx-tts.yml index e72dcb9504..755102162d 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-infer-onnx-tts.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-infer-onnx-tts.yml @@ -1423,6 +1423,7 @@ jobs: RUN_ARN_2="${{ steps.schedule_run.outputs.run_arn_2 }}" RUN_COUNT="${{ steps.schedule_run.outputs.run_count }}" LOG_DIR="devicefarm-logs/${{ matrix.platform }}-${{ matrix.variant }}" + PLATFORM="${{ matrix.platform }}" mkdir -p "$LOG_DIR" echo "" @@ -1430,6 +1431,10 @@ jobs: echo "📥 DOWNLOADING DEVICE FARM LOGS" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" RUN_ARNS=("$RUN_ARN_1") if [ "$RUN_COUNT" -ge 2 ] && [ -n "$RUN_ARN_2" ]; then @@ -1471,6 +1476,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" @@ -1510,6 +1522,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" diff --git a/.github/workflows/integration-mobile-test-qvac-lib-infer-parakeet.yml b/.github/workflows/integration-mobile-test-qvac-lib-infer-parakeet.yml index e3836aef39..402518efdf 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-infer-parakeet.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-infer-parakeet.yml @@ -1346,6 +1346,7 @@ jobs: RUN_ARN_2="${{ steps.schedule_run.outputs.run_arn_2 }}" RUN_COUNT="${{ steps.schedule_run.outputs.run_count }}" LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" mkdir -p "$LOG_DIR" echo "" @@ -1353,6 +1354,10 @@ jobs: echo "📥 DOWNLOADING DEVICE FARM LOGS" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" RUN_ARNS=("$RUN_ARN_1") if [ "$RUN_COUNT" -ge 2 ] && [ -n "$RUN_ARN_2" ]; then @@ -1394,6 +1399,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" @@ -1433,6 +1445,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}" diff --git a/.github/workflows/integration-mobile-test-qvac-lib-infer-whispercpp.yml b/.github/workflows/integration-mobile-test-qvac-lib-infer-whispercpp.yml index aef17fa639..3565b665e8 100644 --- a/.github/workflows/integration-mobile-test-qvac-lib-infer-whispercpp.yml +++ b/.github/workflows/integration-mobile-test-qvac-lib-infer-whispercpp.yml @@ -1381,6 +1381,7 @@ jobs: RUN_ARN_2="${{ steps.schedule_run.outputs.run_arn_2 }}" RUN_COUNT="${{ steps.schedule_run.outputs.run_count }}" LOG_DIR="devicefarm-logs/${{ matrix.platform }}" + PLATFORM="${{ matrix.platform }}" mkdir -p "$LOG_DIR" echo "" @@ -1388,6 +1389,10 @@ jobs: echo "📥 DOWNLOADING DEVICE FARM LOGS" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" + if [ "$PLATFORM" = "Android" ]; then + echo "ℹ️ Skipping video artifacts on Android to reduce artifact size." + fi + echo "" RUN_ARNS=("$RUN_ARN_1") if [ "$RUN_COUNT" -ge 2 ] && [ -n "$RUN_ARN_2" ]; then @@ -1429,6 +1434,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): $SUITE_NAME / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_${SAFE_SUITE}_${SAFE_ART}.${ART_EXT}" @@ -1468,6 +1480,13 @@ jobs: ART_EXT=$(echo "$ARTIFACT" | jq -r '.extension // "txt"') [ -z "$ART_URL" ] && continue + if [ "$PLATFORM" = "Android" ]; then + if echo "$ART_NAME" | grep -qiE "^video$" || echo "$ART_EXT" | grep -qiE "^mp4$"; then + echo " Skipped (video): job-level / $ART_NAME" + continue + fi + fi + SAFE_ART=$(echo "$ART_NAME" | tr ' /' '__' | tr -cd '[:alnum:]_-') DEST="$LOG_DIR/${SAFE_RUN}_${SAFE_NAME}_job_${SAFE_ART}.${ART_EXT}"