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
18 changes: 17 additions & 1 deletion .github/actions/percy-exec/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
description: 'Working directory for the command'
required: false
default: '.'
browser-executable:
description: 'Path to a Chrome/Chromium binary for Percy to use. Defaults to the one found on PATH.'
required: false
default: ''

runs:
using: 'composite'
Expand All @@ -23,7 +27,19 @@
working-directory: ${{ inputs.working-directory }}
env:
PERCY_TOKEN: ${{ inputs.percy-token }}
run: npx percy exec -- ${{ inputs.command }}
PERCY_BROWSER_EXECUTABLE: ${{ inputs.browser-executable }}
run: |
# Percy otherwise downloads its own Chromium from storage.googleapis.com
# on the first snapshot. That download stalls in CI, which blocks the
# synchronous percy_snapshot() calls (so pytest never finishes and writes
# no JUnit) and leaves an empty Percy build with no snapshots. Point Percy
# at the Chrome already installed in the job so it skips the download.
if [ -z "${PERCY_BROWSER_EXECUTABLE:-}" ]; then
PERCY_BROWSER_EXECUTABLE="$(command -v google-chrome || command -v google-chrome-stable || command -v chrome || command -v chromium || command -v chromium-browser || true)"
export PERCY_BROWSER_EXECUTABLE
fi
echo "PERCY_BROWSER_EXECUTABLE=${PERCY_BROWSER_EXECUTABLE:-<unset: Percy will download Chromium>}"
npx percy exec -- ${{ inputs.command }}

Check failure on line 42 in .github/actions/percy-exec/action.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

inputs.command is vulnerable to script injection: values of inputs are provided by whoever triggers the workflow. Change this action to not use user-controlled data directly in a run block, for example by assigning this expression to an environment variable.

See more on https://sonarcloud.io/project/issues?id=plotly_dash&issues=AZ7bxeSZxD2Wm65IOelT&open=AZ7bxeSZxD2Wm65IOelT&pullRequest=3829

- name: Run without Percy (fork PR)
if: inputs.percy-token == ''
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/post-test-status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@
test-report:
name: Consolidated Test Report (Fork PR)
runs-on: ubuntu-latest
# Only run for fork PRs (non-fork PRs are handled in the main workflow)
# Run for fork PRs and Dependabot PRs. Both run with a read-only
# GITHUB_TOKEN in the main workflow, so the check run is created here in the
# base-repo context instead. Other same-repo PRs are handled in the main workflow.
if: |
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_repository.full_name != github.repository
(github.event.workflow_run.head_repository.full_name != github.repository ||
github.event.workflow_run.actor.login == 'dependabot[bot]')

Check failure on line 77 in .github/workflows/post-test-status.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Workflows should not rely on forgeable GitHub context values to trust events

See more on https://sonarcloud.io/project/issues?id=plotly_dash&issues=AZ7baTcOmKBW0hUF3ZIU&open=AZ7baTcOmKBW0hUF3ZIU&pullRequest=3829
permissions:
checks: write
actions: read
Expand Down
40 changes: 38 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,14 @@ jobs:
PERCY_TOKEN: ${{ matrix.python-version == '3.12' && secrets.PERCY_TOKEN || '' }}
PERCY_ENABLE: ${{ matrix.python-version == '3.12' && '1' || '0' }}
PERCY_PARALLEL_TOTAL: -1
# Pin the build identity so every shard joins the same parallel build and
# Percy links it to the PR. Auto-detection otherwise uses the ephemeral
# merge SHA (refs/pull/N/merge), so the build never shows up on the PR.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -654,6 +662,7 @@ jobs:
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev,celery,diskcache]"' \;

- name: Setup Chrome and ChromeDriver
id: setup-chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: stable
Expand All @@ -678,6 +687,7 @@ jobs:
with:
command: pytest --headless --nopercyfinalize --junitxml=test-reports/junit_intg.xml tests/integration --splits 3 --group ${{ matrix.test-group }}
percy-token: ${{ secrets.PERCY_TOKEN }}
browser-executable: ${{ steps.setup-chrome.outputs.chrome-path }}

- name: Upload test results
if: always()
Expand Down Expand Up @@ -713,6 +723,14 @@ jobs:
PERCY_TOKEN: ${{ matrix.python-version == '3.12' && secrets.PERCY_TOKEN || '' }}
PERCY_ENABLE: ${{ matrix.python-version == '3.12' && '1' || '0' }}
PERCY_PARALLEL_TOTAL: -1
# Pin the build identity so every shard joins the same parallel build and
# Percy links it to the PR. Auto-detection otherwise uses the ephemeral
# merge SHA (refs/pull/N/merge), so the build never shows up on the PR.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -747,6 +765,7 @@ jobs:
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev]"' \;

- name: Setup Chrome and ChromeDriver
id: setup-chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: stable
Expand All @@ -773,6 +792,7 @@ jobs:
with:
command: pytest --headless --nopercyfinalize --junitxml=test-reports/junit_html.xml
percy-token: ${{ secrets.PERCY_TOKEN }}
browser-executable: ${{ steps.setup-chrome.outputs.chrome-path }}
working-directory: components/dash-html-components

- name: Upload test results
Expand Down Expand Up @@ -899,6 +919,14 @@ jobs:
PERCY_TOKEN: ${{ matrix.python-version == '3.12' && secrets.PERCY_TOKEN || '' }}
PERCY_ENABLE: ${{ matrix.python-version == '3.12' && '1' || '0' }}
PERCY_PARALLEL_TOTAL: -1
# Pin the build identity so every shard joins the same parallel build and
# Percy links it to the PR. Auto-detection otherwise uses the ephemeral
# merge SHA (refs/pull/N/merge), so the build never shows up on the PR.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -1056,6 +1084,13 @@ jobs:
if: always()
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
# Must match the snapshot jobs so finalize targets the same parallel build
# and the result is attached to the PR head commit, not the merge SHA.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}
steps:
- name: Finalize Main Percy Build
if: |
Expand Down Expand Up @@ -1093,8 +1128,9 @@ jobs:

- name: Publish Test Report
uses: dorny/test-reporter@v1
# Skip for fork PRs - handled by post-test-status.yml workflow_run
if: always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
# Skip for fork PRs and Dependabot PRs - both run with a read-only
# GITHUB_TOKEN, so they're handled by post-test-status.yml workflow_run.
if: always() && (github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'))
with:
name: Test Results Summary
path: 'test-results/**/*.xml'
Expand Down
Loading