chore: import upstream snapshot with attribution
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
name: Responsive UI Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
# No concurrency group — intentionally omitted.
|
||||
# This workflow runs only via workflow_call (from release.yml's
|
||||
# responsive-test-gate) and workflow_dispatch. The pull_request trigger
|
||||
# was deliberately removed in #2248 to reduce PR CI load on what is a
|
||||
# heavy ~20-minute matrix build (mobile + desktop). A shared concurrency
|
||||
# key here previously caused workflow_call invocations to cancel each
|
||||
# other mid-flight; see #3554 (reverted in #3599) for that history.
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
ui-tests:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
viewport: [mobile, desktop] # Test mobile and desktop on each PR
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14@sha256:ca25035f7e6f74552655a1c5e4a9eb21f85e9d316f1f70371f790ef70095dd58 # v14
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: ldr_test
|
||||
ports:
|
||||
- 5432:5432
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up PDM
|
||||
uses: pdm-project/setup-pdm@973541a5febeafcfdadf8a51211435be6ecfd90f # v4.5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: '24'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: tests/ui_tests/package-lock.json
|
||||
|
||||
- name: Free up disk space
|
||||
run: |
|
||||
# Remove unnecessary large packages to prevent disk space issues during cache save
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /usr/local/lib/android
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf /opt/hostedtoolcache/CodeQL
|
||||
df -h
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
wget \
|
||||
gnupg \
|
||||
ca-certificates \
|
||||
fonts-liberation \
|
||||
libasound2t64 \
|
||||
libatk-bridge2.0-0 \
|
||||
libatk1.0-0 \
|
||||
libcups2 \
|
||||
libdbus-1-3 \
|
||||
libdrm2 \
|
||||
libgbm1 \
|
||||
libgtk-3-0 \
|
||||
libnspr4 \
|
||||
libnss3 \
|
||||
libx11-xcb1 \
|
||||
libxcomposite1 \
|
||||
libxdamage1 \
|
||||
libxrandr2 \
|
||||
xdg-utils \
|
||||
imagemagick
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: pdm install
|
||||
|
||||
- name: Install root frontend dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Vite frontend bundle
|
||||
# Generates src/local_deep_research/web/static/dist/, which the
|
||||
# Flask app loads via vite_helper. Without this the responsive UI
|
||||
# tests run against an unstyled page (no styles.css), which means
|
||||
# any CSS source changes between PRs are invisible to the test
|
||||
# baseline. See follow-up to PR #3985 for context.
|
||||
run: npm run build
|
||||
|
||||
- name: Install Node test dependencies
|
||||
working-directory: tests/ui_tests
|
||||
run: |
|
||||
npm ci
|
||||
# Keep this version in sync with tests/ui_tests/package-lock.json's
|
||||
# puppeteer entry. A mismatch makes npx fetch a second puppeteer
|
||||
# that targets a different Chrome build, corrupting the browser
|
||||
# cache ("folder exists but executable is missing"). Matching the
|
||||
# locked version lets npx reuse the puppeteer just installed above.
|
||||
npx puppeteer@25.1.0 browsers install chrome
|
||||
|
||||
- name: Set up test directories
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/data/encrypted_databases
|
||||
mkdir -p tests/ui_tests/screenshots
|
||||
echo "Created data and screenshots directories for tests"
|
||||
|
||||
- name: Start test server
|
||||
env:
|
||||
CI: true
|
||||
FLASK_ENV: testing
|
||||
TEST_ENV: true
|
||||
SECRET_KEY: test-secret-key-for-ci # Security: CI test credential, not production secret
|
||||
LDR_DISABLE_RATE_LIMITING: true
|
||||
LDR_DATA_DIR: ${{ github.workspace }}/data
|
||||
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/ldr_test # Security: CI test database credentials, not production secrets
|
||||
run: |
|
||||
cd src
|
||||
# Start server and get its PID
|
||||
pdm run python -m local_deep_research.web.app > server.log 2>&1 &
|
||||
SERVER_PID=$!
|
||||
echo "Server PID: $SERVER_PID"
|
||||
# Persist the PID for the "Stop application server" step. That step
|
||||
# runs at the workspace root (no working-directory) while we are in
|
||||
# src/ here, so write an absolute path — otherwise the pidfile never
|
||||
# lines up and cleanup is a silent no-op.
|
||||
echo "$SERVER_PID" > "$GITHUB_WORKSPACE/server.pid"
|
||||
|
||||
# Wait for server to start
|
||||
SERVER_READY=false
|
||||
for i in {1..60}; do
|
||||
# Probe the health endpoint, not bare `/`: `/` 302-redirects to
|
||||
# /auth/login and `curl -f` treats a 302 as success the instant
|
||||
# the socket binds — before DB/app init finishes — so it can pass
|
||||
# while the app is still not ready. /api/v1/health is a true
|
||||
# readiness signal and matches the docker-tests.yml gate.
|
||||
if curl -fsS --connect-timeout 2 --max-time 5 http://127.0.0.1:5000/api/v1/health 2>/dev/null; then
|
||||
echo "Server is ready after $i seconds"
|
||||
SERVER_READY=true
|
||||
break
|
||||
fi
|
||||
# Check if process is still running
|
||||
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
|
||||
echo "Server process died!"
|
||||
echo "Server log:"
|
||||
cat server.log
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting for server... ($i/60)"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Fail fast if the server is alive but never became ready in time.
|
||||
# Without this guard the loop fell through silently on a slow-but-
|
||||
# not-crashed start, so "Register CI test user" and the UI tests ran
|
||||
# against a server that was not yet listening and failed with a
|
||||
# confusing `net::ERR_CONNECTION_REFUSED` in the *test* step instead
|
||||
# of a clear startup failure here. Window was also bumped 30s -> 60s
|
||||
# to match the proven puppeteer-e2e-tests.yml / docker-tests.yml
|
||||
# startup gates (Postgres-backed boot can exceed 30s on a loaded
|
||||
# runner).
|
||||
if [ "$SERVER_READY" != "true" ]; then
|
||||
echo "❌ Server did not become ready within 60 seconds"
|
||||
echo "Server log:"
|
||||
cat server.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Register CI test user
|
||||
working-directory: tests/ui_tests
|
||||
run: node register_ci_user.js http://127.0.0.1:5000
|
||||
|
||||
- name: Run responsive UI tests - ${{ matrix.viewport }}
|
||||
id: run-tests
|
||||
working-directory: tests/ui_tests
|
||||
env:
|
||||
VIEWPORT: ${{ matrix.viewport }}
|
||||
run: |
|
||||
set +e # Don't exit on test failure
|
||||
|
||||
# Run tests and capture output
|
||||
HEADLESS=true node test_responsive_ui_comprehensive.js "$VIEWPORT" 2>&1 | tee test-output.log
|
||||
TEST_EXIT_CODE="${PIPESTATUS[0]}"
|
||||
|
||||
# Extract summary for PR comment
|
||||
echo "### 📱 $VIEWPORT Test Results" > test-summary.md
|
||||
echo "" >> test-summary.md
|
||||
|
||||
# Extract pass/fail counts
|
||||
PASSED=$(grep -oP '\d+(?= passed)' test-output.log | tail -1 || echo "0")
|
||||
FAILED=$(grep -oP '\d+(?= failed)' test-output.log | tail -1 || echo "0")
|
||||
WARNINGS=$(grep -oP '\d+(?= warnings)' test-output.log | tail -1 || echo "0")
|
||||
|
||||
if [ "$FAILED" -eq "0" ]; then
|
||||
echo "✅ **All tests passed!**" >> test-summary.md
|
||||
else
|
||||
echo "❌ **$FAILED critical issues found**" >> test-summary.md
|
||||
fi
|
||||
|
||||
{
|
||||
echo ""
|
||||
echo "- ✅ Passed: $PASSED"
|
||||
echo "- ❌ Failed: $FAILED"
|
||||
echo "- ⚠️ Warnings: $WARNINGS"
|
||||
} >> test-summary.md
|
||||
|
||||
{
|
||||
echo "test_exit_code=$TEST_EXIT_CODE"
|
||||
echo "test_failed=$FAILED"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Only fail if critical failures
|
||||
exit "$TEST_EXIT_CODE"
|
||||
|
||||
- name: Upload viewport test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: ui-test-results-${{ matrix.viewport }}
|
||||
path: |
|
||||
tests/ui_tests/test-output.log
|
||||
tests/ui_tests/test-summary.md
|
||||
tests/ui_tests/screenshots/
|
||||
tests/ui_tests/responsive/
|
||||
src/server.log
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
# NOTE: Earlier screenshot generation/upload steps were removed to fix actionlint warnings
|
||||
# caused by "if: false" disablement. Screenshots are now captured into the artifact above
|
||||
# when they exist. Visual regression workflows can re-enable dedicated screenshot steps later.
|
||||
|
||||
- name: Upload to GitHub Pages (if available)
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
continue-on-error: true
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
VIEWPORT: ${{ matrix.viewport }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPOSITORY: ${{ github.repository }}
|
||||
GH_REPO_OWNER: ${{ github.repository_owner }}
|
||||
GH_REPO_NAME: ${{ github.event.repository.name }}
|
||||
run: |
|
||||
# This requires GitHub Pages to be enabled for the repo
|
||||
# Create a branch for the screenshots
|
||||
BRANCH_NAME="pr-screenshots-$PR_NUMBER-$VIEWPORT"
|
||||
|
||||
# Check if screenshots directory exists
|
||||
if [ ! -d "tests/ui_tests/responsive" ]; then
|
||||
echo "No screenshots directory found, skipping upload"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cd tests/ui_tests/responsive
|
||||
git init
|
||||
git config user.name "GitHub Actions"
|
||||
git config user.email "actions@github.com"
|
||||
|
||||
# Add all screenshots and gallery
|
||||
git add responsive-ui-tests screenshot-gallery.html
|
||||
git commit -m "Screenshots for PR #$PR_NUMBER"
|
||||
|
||||
# Push to a dedicated branch (requires write permissions)
|
||||
git push --force "https://x-access-token:$GH_TOKEN@github.com/$GH_REPOSITORY.git" "HEAD:$BRANCH_NAME" 2>/dev/null || true
|
||||
|
||||
# The URL would be: https://[owner].github.io/[repo]/pr-screenshots-[number]-[viewport]/screenshot-gallery.html
|
||||
echo "Screenshots available at: https://$GH_REPO_OWNER.github.io/$GH_REPO_NAME/$BRANCH_NAME/screenshot-gallery.html" || true
|
||||
|
||||
- name: Stop application server
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f server.pid ]; then
|
||||
kill "$(cat server.pid)" || true
|
||||
rm server.pid
|
||||
fi
|
||||
# `pdm run` stays alive as a wrapper, so the pidfile holds the
|
||||
# wrapper PID and killing it can orphan the actual python server.
|
||||
# Add the same pkill fallback the webkit workflow uses so the
|
||||
# python process (and port 5000) is actually released.
|
||||
pkill -f "python -m local_deep_research.web.app" || true
|
||||
|
||||
post-results:
|
||||
needs: ui-tests
|
||||
runs-on: ubuntu-latest
|
||||
# Workflow has no pull_request trigger; gating on event_name == 'pull_request' kept this job
|
||||
# from ever running. Always run so the combined report is built for workflow_dispatch / release.
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: test-artifacts/
|
||||
|
||||
- name: Generate combined report
|
||||
run: |
|
||||
# Create a combined markdown report with screenshot links
|
||||
{
|
||||
echo "# 📊 Responsive UI Test Report"
|
||||
echo ""
|
||||
echo "## Test Summary"
|
||||
echo ""
|
||||
} > combined-report.md
|
||||
|
||||
# Process each viewport's results
|
||||
for dir in test-artifacts/ui-test-results-*/; do
|
||||
if [ -d "$dir" ]; then
|
||||
viewport=$(basename "$dir" | sed 's/ui-test-results-//')
|
||||
echo "### $viewport" >> combined-report.md
|
||||
|
||||
if [ -f "$dir/test-summary.md" ]; then
|
||||
cat "$dir/test-summary.md" >> combined-report.md
|
||||
fi
|
||||
|
||||
# Count screenshots
|
||||
screenshot_count=$(find "$dir" -name "*.png" 2>/dev/null | wc -l)
|
||||
if [ "$screenshot_count" -gt "0" ]; then
|
||||
{
|
||||
echo ""
|
||||
echo "📸 **$screenshot_count screenshots captured**"
|
||||
} >> combined-report.md
|
||||
fi
|
||||
|
||||
echo "" >> combined-report.md
|
||||
fi
|
||||
done
|
||||
|
||||
{
|
||||
echo "## 📥 Download Options"
|
||||
echo ""
|
||||
echo "- [Download all test artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})"
|
||||
echo "- View artifacts in the 'Artifacts' section below the workflow summary"
|
||||
} >> combined-report.md
|
||||
|
||||
- name: Upload combined report
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: combined-test-report
|
||||
path: combined-report.md
|
||||
retention-days: 30
|
||||
Reference in New Issue
Block a user