diff --git a/.github/workflows/example-report.yml b/.github/workflows/example-report.yml index 816990f..5bf4acc 100644 --- a/.github/workflows/example-report.yml +++ b/.github/workflows/example-report.yml @@ -549,7 +549,7 @@ jobs: run: | project="B25A040A-A980-4602-B90C-D480AB84076D" - run=`curl https://pixel-eagle.vleue.com/$project/runs --json '{"os":"${{ matrix.os }}", "gitref": "${{ needs.get-environment.outputs.gitref }}"}' | jq '.id'` + run=`curl https://pixel-eagle.vleue.com/$project/runs --json '{"os":"${{ matrix.os }}", "gitref": "${{ needs.get-environment.outputs.gitref }}", "branch": "main"}' | jq '.id'` SAVEIFS=$IFS @@ -584,7 +584,7 @@ jobs: cd .. - curl https://pixel-eagle.vleue.com/$project/runs/$run/compare/auto --json '{"os":""}' | jq '{project_id: .project_id, from: .from, to: .to}' > pixeleagle-${{ matrix.os }}.json + curl https://pixel-eagle.vleue.com/$project/runs/$run/compare/auto --json '{"os":"", "branch": "main"}' | jq '{project_id: .project_id, from: .from, to: .to}' > pixeleagle-${{ matrix.os }}.json cat pixeleagle-${{ matrix.os }}.json echo "created run $run" diff --git a/.github/workflows/run-on-pr.yml b/.github/workflows/run-on-pr.yml new file mode 100644 index 0000000..41cda08 --- /dev/null +++ b/.github/workflows/run-on-pr.yml @@ -0,0 +1,234 @@ +name: Example report - Screenshots on PR + +on: + workflow_dispatch: + inputs: + pr: + description: 'PR to run' + required: true + type: string + +concurrency: + group: ${{ github.repository }}-example-report-PR + +env: + PER_PAGE: 20 + +jobs: + get-environment: + name: Get Environment + runs-on: ubuntu-latest + outputs: + pages: ${{ steps.env.outputs.pages }} + gitref: ${{ steps.env.outputs.gitref }} + date: ${{ steps.env.outputs.date }} + steps: + - name: Checkout Bevy main branch + uses: actions/checkout@v4 + with: + repository: 'bevyengine/bevy' + ref: 'pull/${{ inputs.pr }}/head' + - name: Get Environment + id: env + run: | + example_count=`cat Cargo.toml | grep '\[\[example\]\]' | wc -l` + page_count=$((example_count / ${{ env.PER_PAGE }} + 1)) + + echo "gitref=`git rev-parse HEAD`" >> $GITHUB_OUTPUT + echo "date=`date +%Y%m%d%H%M`" >> $GITHUB_OUTPUT + echo "pages=`python -c \"import json; print(json.dumps([i for i in range($page_count)]))\"`" >> $GITHUB_OUTPUT + + take-screenshots: + name: Take Screenshots + needs: get-environment + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-14] + page: ${{ fromJSON(needs.get-environment.outputs.pages) }} + + steps: + + - name: Checkout Bevy main branch + uses: actions/checkout@v4 + with: + repository: 'bevyengine/bevy' + ref: ${{ needs.get-environment.outputs.gitref }} + + - name: Checkout patches + uses: actions/checkout@v4 + with: + path: 'runner-patches' + + - name: Apply patches + shell: pwsh + run: | + Get-ChildItem "runner-patches/patches" -Filter *.patch | + Foreach-Object { + Write-Output "Processing $($_.FullName)" + git apply --ignore-whitespace $($_.FullName) + } + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Install Bevy dependencies + if: runner.os == 'linux' + run: | + sudo apt-get update; + DEBIAN_FRONTEND=noninteractive sudo apt-get install --no-install-recommends -yq \ + libasound2-dev libudev-dev libxkbcommon-x11-0; + + - name: install xvfb, llvmpipe and lavapipe + if: runner.os == 'linux' + run: | + sudo apt-get update -y -qq + sudo add-apt-repository ppa:kisak/turtle -y + sudo apt-get update + sudo apt install -y xvfb libegl1-mesa libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers + + - uses: actions/cache/restore@v4 + id: restore-cache + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }} + restore-keys: ${{ runner.os }}-cargo- + + - name: Take Screenshots (Linux) + id: screenshots-linux + if: runner.os == 'linux' + continue-on-error: true + run: xvfb-run -s "-screen 0 1280x1024x24" cargo run -p example-showcase -- --page ${{ matrix.page }} --per-page ${{ env.PER_PAGE }} run --screenshot-at 400 --frame-duration 0.0125 --stop-at 450 --in-ci --ignore-stress-tests --report-details + + - name: Take Screenshots (Windows) + id: screenshots-windows + if: runner.os == 'windows' + continue-on-error: true + shell: pwsh + run: | + Add-Type -AssemblyName System.Windows.Forms + $screen = [System.Windows.Forms.SystemInformation]::VirtualScreen + [Windows.Forms.Cursor]::Position = "$($screen.Width / 2),$($screen.Height / 2)" + + cargo run -p example-showcase -- --page ${{ matrix.page }} --per-page ${{ env.PER_PAGE }} run --screenshot-at 400 --frame-duration 0.0125 --stop-at 450 --in-ci --ignore-stress-tests --report-details + + - name: Take Screenshots (macOS) + id: screenshots-macos + if: runner.os == 'macos' + continue-on-error: true + run: cargo run -p example-showcase -- --page ${{ matrix.page }} --per-page ${{ env.PER_PAGE }} run --screenshot-at 400 --frame-duration 0.0125 --stop-at 450 --in-ci --ignore-stress-tests --report-details + + - name: Log errors + shell: pwsh + run: | + if (Get-Content no_screenshots) { + perl -p -e 's/(.*) - [.0-9]*\n/\1, /g' no_screenshots > cleaned + $no_screenshots = Get-Content .\cleaned -Raw + echo "::warning title=No Screenshots ${{ runner.os }}/${{ matrix.page }}::$no_screenshots" + } + if (Get-Content failures) { + perl -p -e 's/(.*) - [.0-9]*\n/\1, /g' failures > cleaned + $failures = Get-Content .\cleaned -Raw + echo "::error title=Failed To Run ${{ runner.os }}/${{ matrix.page }}::$failures" + } + + - name: Outputs run results + id: run-results + shell: pwsh + run: | + echo "has_success=$(![String]::IsNullOrWhiteSpace((Get-content successes)))" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + + - name: Upload Screenshots + uses: actions/upload-artifact@v4 + with: + name: screenshots-${{ runner.os }}-${{ matrix.page }} + path: screenshots + + - name: Upload Status + uses: actions/upload-artifact@v4 + with: + name: status-${{ runner.os }}-${{ matrix.page }} + path: | + successes + failures + no_screenshots + + send-to-pixel-eagle: + name: Send screenshots to Pixel Eagle + runs-on: macos-14 + needs: [take-screenshots, get-environment] + strategy: + fail-fast: false + matrix: + include: + - os: Linux + - os: macOS + - os: Windows + steps: + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + pattern: screenshots-${{ matrix.os }}-* + + - name: Move examples to the correct folder + id: gather-examples + continue-on-error: true + run: | + mkdir screenshots-${{ matrix.os }} + for screenshotfolder in screenshots-${{ matrix.os }}-* + do + echo $screenshotfolder + rsync --verbose --archive $screenshotfolder/* screenshots-${{ matrix.os }}/ + rm -rf $screenshotfolder + done + + - name: Send to Pixel Eagle + if: steps.gather-examples.outcome == 'success' + run: | + project="B25A040A-A980-4602-B90C-D480AB84076D" + + run=`curl https://pixel-eagle.vleue.com/$project/runs --json '{"os":"${{ matrix.os }}", "gitref": "${{ needs.get-environment.outputs.gitref }}", "branch": "PR-${{ inputs.pr }}"}' | jq '.id'` + + SAVEIFS=$IFS + + cd screenshots-${{ matrix.os }} + + IFS=$'\n' + + # Build a json array of screenshots and their hashes + hashes='['; + for screenshot in $(find . -type f -name "*.png"); + do + name=${screenshot:2} + echo $name + hash=`shasum -a 256 $screenshot | awk '{print $1}'` + hashes="$hashes [\"$name\",\"$hash\"]," + done + hashes=`echo $hashes | rev | cut -c 2- | rev` + hashes="$hashes]" + + IFS=$SAVEIFS + + # Upload screenshots with unknown hashes + curl https://pixel-eagle.vleue.com/$project/runs/$run/hashes --json "$hashes" | jq '.[]|[.name] | @tsv' | + while IFS=$'\t' read -r name; do + name=`echo $name | tr -d '"'` + echo "Uploading $name" + curl https://pixel-eagle.vleue.com/$project/runs/$run/screenshots -F "data=@./$name" -F "screenshot=$name" + echo + done + + IFS=$SAVEIFS + + cd .. + + curl https://pixel-eagle.vleue.com/$project/runs/$run/compare/auto --json '{"os":"", "branch": "main"}' | jq '{project_id: .project_id, from: .from, to: .to}' > pixeleagle-${{ matrix.os }}.json + cat pixeleagle-${{ matrix.os }}.json + + echo "created run $run"