Unverified Commit 26db8cba authored by Lucas Saavedra Vaz's avatar Lucas Saavedra Vaz Committed by GitHub

ci(tests): Avoid the use of pull_request_target where possible (#9899)

parent 0ef29868
# This file is used to run the runtime tests for the Arduino core for ESP32.
# The tests are run on the hardware, Wokwi and QEMU emulators.
# The QEMU tests are disabled for now as they are redundant with most of the Wokwi tests.
# As the Wokwi tests require access to secrets, they are run in a separate workflow.
# We need to ensure that the artifacts from previous tests in the chain are propagated for publishing the results.
# This is the current trigger sequence for the tests:
# tests.yml -> tests_wokwi.yml -> tests_results.yml
# ⌙> tests_build.yml
# ⌙> tests_hw.yml
# ⌙> tests_qemu.yml
name: Runtime Tests
on:
workflow_dispatch:
pull_request_target:
pull_request:
types: [opened, reopened, closed, synchronize, labeled, unlabeled]
paths:
- '.github/workflows/tests*'
- '.github/scripts/*.sh'
- '!.github/scripts/check-cmakelists.sh'
- '!.github/scripts/find_*'
- '!.github/scripts/on-*.sh'
- '!.github/scripts/set_push_chunks.sh'
- '!.github/scripts/update-version.sh'
- '!.github/scripts/upload_py_tools.sh'
- 'tests/**'
- 'cores/**'
- 'libraries/**'
......@@ -19,14 +38,19 @@ concurrency:
group: tests-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
# To avoid giving elevated permissions to the entire workflow, specify default permissions at the top level
# and then override them for specific jobs.
permissions: { contents: read }
jobs:
push-event-file:
name: Push event file
runs-on: ubuntu-latest
steps:
- name: Upload
uses: actions/upload-artifact@v4
with:
name: event_file
path: ${{ github.event_path }}
gen-matrix:
name: Generate matrix
if: github.event.action != 'closed'
runs-on: ubuntu-latest
outputs:
build-types: ${{ steps.set-matrix.outputs.build-types }}
......@@ -59,9 +83,8 @@ jobs:
call-build-tests:
name: Build
uses: espressif/arduino-esp32/.github/workflows/build_tests.yml@master
uses: ./.github/workflows/tests_build.yml
needs: gen-matrix
if: github.event.action != 'closed'
strategy:
matrix:
type: ${{ fromJson(needs.gen-matrix.outputs.build-types) }}
......@@ -72,11 +95,11 @@ jobs:
call-hardware-tests:
name: Hardware
uses: espressif/arduino-esp32/.github/workflows/hw.yml@master
uses: ./.github/workflows/tests_hw.yml
needs: [gen-matrix, call-build-tests]
if: |
github.repository == 'espressif/arduino-esp32' &&
(github.event_name != 'pull_request_target' ||
(github.event_name != 'pull_request' ||
contains(github.event.pull_request.labels.*.name, 'hil_test'))
strategy:
fail-fast: false
......@@ -87,26 +110,10 @@ jobs:
type: ${{ matrix.type }}
chip: ${{ matrix.chip }}
call-wokwi-tests:
name: Wokwi
uses: espressif/arduino-esp32/.github/workflows/wokwi.yml@master
needs: [gen-matrix, call-build-tests]
if: github.event.action != 'closed'
strategy:
fail-fast: false
matrix:
type: ${{ fromJson(needs.gen-matrix.outputs.wokwi-types) }}
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2']
secrets:
WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }}
with:
type: ${{ matrix.type }}
chip: ${{ matrix.chip }}
# This job is disabled for now
call-qemu-tests:
name: QEMU
uses: espressif/arduino-esp32/.github/workflows/qemu.yml@master
uses: ./.github/workflows/tests_qemu.yml
needs: [gen-matrix, call-build-tests]
if: false
strategy:
......@@ -118,78 +125,4 @@ jobs:
type: ${{ matrix.type }}
chip: ${{ matrix.chip }}
unit-test-results:
name: Unit Test Results
needs: [call-hardware-tests, call-wokwi-tests, call-qemu-tests]
if: always() && github.event_name == 'pull_request_target'
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
steps:
- name: Download and Extract HW Artifacts
uses: actions/download-artifact@v4
continue-on-error: true
with:
merge-multiple: true
pattern: tests-results-hw-*
path: ./results/hw
- name: Download and Extract Wokwi Artifacts
uses: actions/download-artifact@v4
continue-on-error: true
with:
merge-multiple: true
pattern: tests-results-wokwi-*
path: ./results/wokwi
- name: Download and Extract QEMU Artifacts
uses: actions/download-artifact@v4
continue-on-error: true
with:
merge-multiple: true
pattern: tests-results-qemu-*
path: ./results/qemu
- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
with:
commit: ${{ github.event.pull_request.head.sha || github.sha }}
files: ./results/**/*.xml
clean:
name: Clean objects
needs: unit-test-results
if: always()
permissions:
actions: write
runs-on: ubuntu-latest
steps:
- name: Clean up caches
uses: actions/github-script@v7
with:
script: |
const ref = '${{ github.event.pull_request.number || github.ref }}';
const key_prefix = 'tests-' + ref + '-';
if ('${{ github.event_name }}' == 'pull_request_target' && '${{ github.event.action }}' != 'closed') {
console.log('Skipping cache cleanup for open PR');
return;
}
await github.paginate(github.rest.actions.getActionsCacheList, {
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100,
key: key_prefix
}).then(caches => {
if (caches) {
for (const cache of caches) {
console.log(`Deleting cache: ${cache.key}`);
github.rest.actions.deleteActionsCacheById({
owner: context.repo.owner,
repo: context.repo.repo,
cache_id: cache.id
});
}
}
});
# Wokwi tests are run after this workflow as it needs access to secrets
......@@ -20,8 +20,8 @@ jobs:
id: ${{ github.event.pull_request.number || github.ref }}-${{ github.event.pull_request.head.sha || github.sha }}-${{ inputs.chip }}-${{ inputs.type }}
steps:
- name: Check if already built
if: ${{ github.event.pull_request.number != null }}
id: cache-build-binaries
if: github.event.pull_request.number != null
uses: actions/cache/restore@v4
with:
key: tests-${{ env.id }}-bin
......@@ -46,21 +46,6 @@ jobs:
- name: Checkout user repository
if: ${{ steps.check-build.outputs.enabled == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
sparse-checkout-cone-mode: false
sparse-checkout: |
/*
!.github
# To avoid giving unknown scripts elevated permissions, download them from the master branch
- name: Get CI scripts from master
if: ${{ steps.check-build.outputs.enabled == 'true' }}
run: |
mkdir -p .github
cd .github
curl https://codeload.github.com/${{ github.repository }}/tar.gz/master | tar -xz --strip=2 arduino-esp32-master/.github
- name: Get libs cache
uses: actions/cache@v4
......@@ -83,7 +68,7 @@ jobs:
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} binaries as cache
uses: actions/cache/save@v4
if: ${{ steps.check-build.outputs.enabled == 'true' }}
if: steps.check-build.outputs.enabled == 'true' && github.event.pull_request.number != null
with:
key: tests-${{ env.id }}-bin
path: |
......
......@@ -22,9 +22,9 @@ jobs:
image: python:3.10.1-bullseye
options: --privileged
steps:
- name: Check if already built
if: ${{ github.event.pull_request.number != null }}
- name: Check if already passed
id: cache-results
if: github.event.pull_request.number != null
uses: actions/cache/restore@v4
with:
key: tests-${{ env.id }}-results-hw
......@@ -48,21 +48,6 @@ jobs:
- name: Checkout user repository
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
sparse-checkout-cone-mode: false
sparse-checkout: |
/*
!.github
# To avoid giving unknown scripts elevated permissions, download them from the master branch
- name: Get CI scripts from master
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
run: |
mkdir -p .github
cd .github
curl https://codeload.github.com/${{ github.repository }}/tar.gz/master | tar -xz --strip=2 arduino-esp32-master/.github
# setup-python currently only works on ubuntu images
# - uses: actions/setup-python@v5
......@@ -95,7 +80,7 @@ jobs:
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} hardware results as cache
uses: actions/cache/save@v4
if: ${{ always() && steps.check-tests.outputs.enabled == 'true' }}
if: steps.check-tests.outputs.enabled == 'true' && github.event.pull_request.number != null
with:
key: tests-${{ env.id }}-results-hw
path: |
......
......@@ -18,9 +18,9 @@ jobs:
QEMU_INSTALL_PATH: "$HOME"
runs-on: ubuntu-latest
steps:
- name: Check if already run
if: ${{ github.event.pull_request.number != null }}
- name: Check if already passed
id: get-cache-results
if: github.event.pull_request.number != null
uses: actions/cache/restore@v4
with:
key: tests-${{ env.id }}-results-qemu
......@@ -97,7 +97,7 @@ jobs:
with:
path: |
~/qemu
key: qemu-${{ steps.get-qemu-version.outputs.release }}-${{ hashFiles('.github/workflows/qemu.yml') }}
key: qemu-${{ steps.get-qemu-version.outputs.release }}-${{ hashFiles('.github/workflows/tests_qemu.yml') }}
- name: Download QEMU
if: ${{ steps.cache-qemu.outputs.cache-hit != 'true' && steps.check-tests.outputs.enabled == 'true' }}
......@@ -125,7 +125,7 @@ jobs:
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} QEMU results as cache
uses: actions/cache/save@v4
if: ${{ always() && steps.check-tests.outputs.enabled == 'true' }}
if: steps.check-tests.outputs.enabled == 'true' && github.event.pull_request.number != null
with:
key: tests-${{ env.id }}-results-qemu
path: |
......
name: Publish and clean test results
on:
workflow_run:
workflows: ["Wokwi tests"]
types:
- completed
# No permissions by default
permissions: { contents: read }
jobs:
unit-test-results:
name: Unit Test Results
if: |
github.event.workflow_run.conclusion == 'success' ||
github.event.workflow_run.conclusion == 'failure' ||
github.event.workflow_run.conclusion == 'timed_out'
runs-on: ubuntu-latest
permissions:
actions: write
statuses: write
checks: write
pull-requests: write
steps:
- name: Download and Extract Artifacts
uses: dawidd6/action-download-artifact@v6
with:
run_id: ${{ github.event.workflow_run.id }}
path: ./artifacts
- name: Get original info
run: |
original_event=$(cat ./artifacts/parent-artifacts/event.txt)
original_action=$(cat ./artifacts/parent-artifacts/action.txt)
original_sha=$(cat ./artifacts/parent-artifacts/sha.txt)
original_ref=$(cat ./artifacts/parent-artifacts/ref.txt)
echo "original_event=$original_event" >> $GITHUB_ENV
echo "original_action=$original_action" >> $GITHUB_ENV
echo "original_sha=$original_sha" >> $GITHUB_ENV
echo "original_ref=$original_ref" >> $GITHUB_ENV
echo "original_event = $original_event"
echo "original_action = $original_action"
echo "original_sha = $original_sha"
echo "original_ref = $original_ref"
- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
with:
commit: ${{ env.original_sha }}
event_file: ./artifacts/parent-artifacts/event_file/event.json
event_name: ${{ env.original_event }}
files: ./artifacts/**/*.xml
action_fail: true
- name: Clean up caches
uses: actions/github-script@v7
with:
script: |
const ref = '${{ env.original_ref }}';
const key_prefix = 'tests-' + ref + '-';
if ('${{ env.original_event }}' == 'pull_request' && '${{ env.original_action }}' != 'closed') {
console.log('Skipping cache cleanup for open PR');
return;
}
await github.paginate(github.rest.actions.getActionsCacheList, {
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100,
key: key_prefix
}).then(caches => {
if (caches) {
for (const cache of caches) {
console.log(`Deleting cache: ${cache.key}`);
github.rest.actions.deleteActionsCacheById({
owner: context.repo.owner,
repo: context.repo.repo,
cache_id: cache.id
});
}
}
});
- name: Report conclusion
uses: actions/github-script@v7
if: always()
with:
script: |
const owner = '${{ github.repository_owner }}';
const repo = '${{ github.repository }}'.split('/')[1];
const sha = '${{ env.original_sha }}';
core.debug(`owner: ${owner}`);
core.debug(`repo: ${repo}`);
core.debug(`sha: ${sha}`);
const { context: name, state } = (await github.rest.repos.createCommitStatus({
context: 'Runtime Tests / Report results (${{ env.original_event }} -> workflow_run -> workflow_run)',
owner: owner,
repo: repo,
sha: sha,
state: '${{ job.status }}',
description: '${{ job.status }}' ? 'Runtime tests successful' : 'Runtime tests failed',
target_url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
})).data;
core.info(`${name} is ${state}`);
This diff is collapsed.
name: Wokwi tests
on:
workflow_call:
inputs:
chip:
type: string
description: 'Chip to run tests for'
required: true
type:
type: string
description: 'Type of tests to run'
required: true
secrets:
WOKWI_CLI_TOKEN:
description: 'Wokwi CLI API token'
required: true
env:
WOKWI_TIMEOUT: 600000 # Milliseconds
jobs:
wokwi-test:
name: Wokwi ${{ inputs.chip }} ${{ inputs.type }} tests
env:
id: ${{ github.event.pull_request.number || github.ref }}-${{ github.event.pull_request.head.sha || github.sha }}-${{ inputs.chip }}-${{ inputs.type }}
runs-on: ubuntu-latest
steps:
- name: Check if already run
if: ${{ github.event.pull_request.number != null }}
id: get-cache-results
uses: actions/cache/restore@v4
with:
key: tests-${{ env.id }}-results-wokwi
path: |
tests/**/*.xml
tests/**/result_*.json
- name: Evaluate if tests should be run
id: check-tests
run: |
cache_exists=${{ steps.get-cache-results.outputs.cache-hit == 'true' }}
enabled=true
if [[ $cache_exists == 'true' ]]; then
echo "Already ran, skipping"
enabled=false
fi
echo "enabled=$enabled" >> $GITHUB_OUTPUT
- name: Checkout user repository
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
sparse-checkout-cone-mode: false
sparse-checkout: |
/*
!.github
# To avoid giving unknown scripts elevated permissions, download them from the master branch
- name: Get CI scripts from master
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
run: |
mkdir -p .github
cd .github
curl https://codeload.github.com/${{ github.repository }}/tar.gz/master | tar -xz --strip=2 arduino-esp32-master/.github
- uses: actions/setup-python@v5
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with:
cache-dependency-path: tests/requirements.txt
cache: 'pip'
python-version: '3.x'
- name: Install dependencies
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
run: |
pip install -U pip
pip install -r tests/requirements.txt --extra-index-url https://dl.espressif.com/pypi
- name: Install Wokwi CLI
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
run: curl -L https://wokwi.com/ci/install.sh | sh
- name: Wokwi CI Server
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: wokwi/wokwi-ci-server-action@v1
- name: Get binaries
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/download-artifact@v4
with:
name: tests-bin-${{ inputs.chip }}-${{ inputs.type }}
path: |
~/.arduino/tests
- name: Run Tests
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
env:
WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }}
run: |
bash .github/scripts/tests_run.sh -c -type ${{ inputs.type }} -t ${{inputs.chip}} -i 0 -m 1 -W ${{env.WOKWI_TIMEOUT}}
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} Wokwi results as cache
uses: actions/cache/save@v4
if: ${{ always() && steps.check-tests.outputs.enabled == 'true' }}
with:
key: tests-${{ env.id }}-results-wokwi
path: |
tests/**/*.xml
tests/**/result_*.json
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} Wokwi results as artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: tests-results-wokwi-${{ inputs.chip }}-${{ inputs.type }}
overwrite: true
path: |
tests/**/*.xml
tests/**/result_*.json
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment