-
Notifications
You must be signed in to change notification settings - Fork 7.7k
ci(tests): Move hardware tests to GitLab #11890
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
👋 Hello lucasssvaz, we appreciate your contribution to this project! 📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project. Click to see more instructions ...
Review and merge process you can expect ...
|
echo "Ensuring GitLab sync has completed before triggering pipeline..." | ||
# Use push time determined in get-artifacts job | ||
push_time="${{ needs.get-artifacts.outputs.push_time }}" |
Check failure
Code scanning / CodeQL
Code injection Critical test
${ needs.get-artifacts.outputs.push_time }
workflow_run
Potential code injection in
${ needs.get-artifacts.outputs.push_time }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To resolve the potential code injection, we should set the push_time
value as an environment variable in the workflow step, using the workflow expression syntax. Then, within the shell script, reference $push_time
(or $PUSH_TIME
) using shell variable expansion, not expression interpolation. This ensures the shell receives the value directly, with no further parsing or evaluation of expression content by the shell.
Specifically, in the step at line 262 (run:
), instead of:
push_time="${{ needs.get-artifacts.outputs.push_time }}"
we should:
- Add an
env:
block to this step, settingPUSH_TIME: ${{ needs.get-artifacts.outputs.push_time }}
. - In the shell script, replace occurrences of
${{ needs.get-artifacts.outputs.push_time }}
orpush_time="..."
withpush_time="$PUSH_TIME"
or just use$PUSH_TIME
directly.
No other behavior will be changed, but this ensures there is no workflow expression interpolation inside the shell script.
-
Copy modified lines R262-R263 -
Copy modified line R271
@@ -259,6 +259,8 @@ | ||
|
||
- name: Wait for GitLab sync | ||
if: ${{ steps.check-tests.outputs.enabled == 'true' }} | ||
env: | ||
PUSH_TIME: ${{ needs.get-artifacts.outputs.push_time }} | ||
run: | | ||
# A webhook to sync the repository is sent to GitLab when a commit is pushed to GitHub | ||
# We wait for 10 minutes after the push to GitHub to be safe | ||
@@ -266,7 +268,7 @@ | ||
echo "Ensuring GitLab sync has completed before triggering pipeline..." | ||
|
||
# Use push time determined in get-artifacts job | ||
push_time="${{ needs.get-artifacts.outputs.push_time }}" | ||
push_time="$PUSH_TIME" | ||
|
||
if [ -n "$push_time" ]; then | ||
echo "Push time: $push_time" |
- name: Trigger GitLab Pipeline and Download Artifacts | ||
if: ${{ steps.check-tests.outputs.enabled == 'true' }} | ||
uses: digital-blueprint/[email protected] |
Check warning
Code scanning / CodeQL
Unpinned tag for a non-immutable Action in workflow Medium test
Uses Step: gitlab-trigger
run: | | ||
echo "Build, Hardware and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ env.original_run_id }}" | ||
echo "Wokwi tests: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}" | ||
echo "Build and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ steps.get-info.outputs.original_run_id }}" |
Check failure
Code scanning / CodeQL
Cache Poisoning via low-privileged code injection High test
${ steps.get-info.outputs.original_run_id }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To address the vulnerability, we should ensure that the value assigned to original_run_id
comes only from trusted GitHub metadata (e.g., from ${{ github.event.workflow_run.id }}
), and not from artifacts which can be influenced by untrusted jobs. The fix consists of:
- In the
get-artifacts
job, remove the extraction ofrun_id.txt
from./artifacts/parent-artifacts/run_id.txt
and instead explicitly setoriginal_run_id
using the trusted GitHub-provided context:${{ github.event.workflow_run.id }}
. - Adjust all lines depending on
original_run_id
inget-info
step accordingly. - Update the output assignment to only use this trusted value.
This way, any code injection risk from artifact contents is eliminated, and only official workflow run IDs are used for subsequent privileged steps.
-
Copy modified lines R42-R43 -
Copy modified line R62
@@ -39,7 +39,8 @@ | ||
original_sha=$(cat ./artifacts/parent-artifacts/sha.txt) | ||
original_ref=$(cat ./artifacts/parent-artifacts/ref.txt) | ||
original_conclusion=$(cat ./artifacts/parent-artifacts/conclusion.txt) | ||
original_run_id=$(cat ./artifacts/parent-artifacts/run_id.txt) | ||
# Use trusted run ID from GitHub context | ||
original_run_id="${{ github.event.workflow_run.id }}" | ||
|
||
# Sanitize the values to avoid security issues | ||
|
||
@@ -58,8 +59,7 @@ | ||
# Conclusion: Allow alphabetical characters and underscores | ||
original_conclusion=$(echo "$original_conclusion" | tr -cd '[:alpha:]_') | ||
|
||
# Run ID: Allow numeric characters | ||
original_run_id=$(echo "$original_run_id" | tr -cd '[:digit:]') | ||
# Run ID: Already trusted by assignment, no need to sanitize | ||
|
||
echo "original_event=$original_event" >> $GITHUB_OUTPUT | ||
echo "original_action=$original_action" >> $GITHUB_OUTPUT |
run: | | ||
echo "Build, Hardware and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ env.original_run_id }}" | ||
echo "Wokwi tests: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}" | ||
echo "Build and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ steps.get-info.outputs.original_run_id }}" |
Check warning
Code scanning / CodeQL
Code injection Medium test
${ steps.get-info.outputs.original_run_id }
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To fix the issue, we should avoid direct interpolation of potentially untrusted output variables via ${{ ... }}
in the shell command under run:
. Instead, we should pass the potentially untrusted value as an environment variable, and then reference it in the shell script using native shell syntax (e.g., $ORIGINAL_RUN_ID
). Specifically, in the "Print links to other runs" step, we will:
- Add an
env:
block, passingORIGINAL_RUN_ID: ${{ steps.get-info.outputs.original_run_id }}
. - Change the script in the step to use
$ORIGINAL_RUN_ID
(not expression interpolation) in the echo statement. - Ensure no functional changes, just make the value's usage safe.
- No new imports, methods, or definitions are required beyond this.
-
Copy modified lines R79-R80 -
Copy modified line R82
@@ -76,8 +76,10 @@ | ||
echo "original_run_id = $original_run_id" | ||
|
||
- name: Print links to other runs | ||
env: | ||
ORIGINAL_RUN_ID: ${{ steps.get-info.outputs.original_run_id }} | ||
run: | | ||
echo "Build and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ steps.get-info.outputs.original_run_id }}" | ||
echo "Build and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/$ORIGINAL_RUN_ID" | ||
echo "Hardware and Wokwi tests: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}" | ||
|
||
unit-test-results: |
with: | ||
script: | | ||
const ref = process.env.original_ref; | ||
const ref = '${{ needs.get-artifacts.outputs.original_ref }}'; |
Check failure
Code scanning / CodeQL
Code injection Critical test
${ needs.get-artifacts.outputs.original_ref }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
General fix:
To prevent code injection, values originating from untrusted sources (including artifact files) must not be injected via GitHub Actions expression syntax ("${{...}}") inside scripts. Instead, pass such values as environment variables via the env
block, and within the script
, access them using the shell or (process.env
for JavaScript).
Detailed fix:
- In the
actions/github-script
step that currently definesconst ref = '${{ needs.get-artifacts.outputs.original_ref }}';
, move the interpolation of${{ needs.get-artifacts.outputs.original_ref }}
into the environment (env
) block as a variable, e.g.,REF: ${{ needs.get-artifacts.outputs.original_ref }}
. - In the
script
, reference this asconst ref = process.env.REF;
. Remove the direct interpolation via${{...}}
in the JavaScript source. - No changes to business logic or functional side effects.
Files/lines to change:
- File:
.github/workflows/tests_results.yml
- In the
actions/github-script
step underunit-test-results
, add a newenv:
block (or add to it if already present), passingREF: ${{ needs.get-artifacts.outputs.original_ref }}
. - Edit the
script:
to setconst ref = process.env.REF;
, replacing the existing assignment.
- In the
Imports/definitions needed:
- No new imports are needed. Only use standard JavaScript in the script field.
-
Copy modified lines R142-R145 -
Copy modified line R148 -
Copy modified line R151
@@ -139,12 +139,16 @@ | ||
- name: Clean up caches | ||
if: always() | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | ||
env: | ||
REF: ${{ needs.get-artifacts.outputs.original_ref }} | ||
ORIGINAL_EVENT: ${{ needs.get-artifacts.outputs.original_event }} | ||
ORIGINAL_ACTION: ${{ needs.get-artifacts.outputs.original_action }} | ||
with: | ||
script: | | ||
const ref = '${{ needs.get-artifacts.outputs.original_ref }}'; | ||
const ref = process.env.REF; | ||
const key_prefix = 'test-' + ref + '-'; | ||
|
||
if ('${{ needs.get-artifacts.outputs.original_event }}' == 'pull_request' && '${{ needs.get-artifacts.outputs.original_action }}' != 'closed') { | ||
if (process.env.ORIGINAL_EVENT == 'pull_request' && process.env.ORIGINAL_ACTION != 'closed') { | ||
console.log('Skipping cache cleanup for open PR'); | ||
return; | ||
} |
const key_prefix = 'test-' + ref + '-'; | ||
if (process.env.original_event == 'pull_request' && process.env.original_action != 'closed') { | ||
if ('${{ needs.get-artifacts.outputs.original_event }}' == 'pull_request' && '${{ needs.get-artifacts.outputs.original_action }}' != 'closed') { |
Check failure
Code scanning / CodeQL
Code injection Critical test
${ needs.get-artifacts.outputs.original_event }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To fix this problem, update the workflow so that original_event
, original_action
, and original_ref
(and any other required output values) are passed to the github-script
step via environment variables, not via direct expression interpolation in JavaScript code.
That is:
- Replace all usages like
${{ needs.get-artifacts.outputs.original_event }}
in the script body withprocess.env.ORIGINAL_EVENT
. - Set respective
env:
properties for thegithub-script
step. - Update all JavaScript logic inside the script to use the environment variables.
- No change to behavior; merely changing how values reach the script.
In .github/workflows/tests_results.yml
, update the step "Clean up caches"
(lines 140-170) to:
- Add
env:
for environment variables (ORIGINAL_EVENT
,ORIGINAL_ACTION
,ORIGINAL_REF
). - In the
script
, replace all references like'${{ needs.get-artifacts.outputs.original_event }}'
withprocess.env.ORIGINAL_EVENT
, and similarly for the others.
No packages to install; all changes are within the workflow YAML.
-
Copy modified lines R142-R145 -
Copy modified line R148 -
Copy modified line R151
@@ -139,12 +139,16 @@ | ||
- name: Clean up caches | ||
if: always() | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | ||
env: | ||
ORIGINAL_EVENT: ${{ needs.get-artifacts.outputs.original_event }} | ||
ORIGINAL_ACTION: ${{ needs.get-artifacts.outputs.original_action }} | ||
ORIGINAL_REF: ${{ needs.get-artifacts.outputs.original_ref }} | ||
with: | ||
script: | | ||
const ref = '${{ needs.get-artifacts.outputs.original_ref }}'; | ||
const ref = process.env.ORIGINAL_REF; | ||
const key_prefix = 'test-' + ref + '-'; | ||
|
||
if ('${{ needs.get-artifacts.outputs.original_event }}' == 'pull_request' && '${{ needs.get-artifacts.outputs.original_action }}' != 'closed') { | ||
if (process.env.ORIGINAL_EVENT === 'pull_request' && process.env.ORIGINAL_ACTION !== 'closed') { | ||
console.log('Skipping cache cleanup for open PR'); | ||
return; | ||
} |
const key_prefix = 'test-' + ref + '-'; | ||
if (process.env.original_event == 'pull_request' && process.env.original_action != 'closed') { | ||
if ('${{ needs.get-artifacts.outputs.original_event }}' == 'pull_request' && '${{ needs.get-artifacts.outputs.original_action }}' != 'closed') { |
Check failure
Code scanning / CodeQL
Code injection Critical test
${ needs.get-artifacts.outputs.original_action }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To fix the issue, we should never interpolate untrusted variables directly into the script:
section of a github-script
step via ${{ ... }}
syntax. Instead, we should set the untrusted value as an environment variable in the workflow step (env:
block), and then read it using process.env
in the script—this avoids interpolation and instead relies on out-of-band environment setup, which mitigates code injection risks.
Specifically:
- In the
unit-test-results
job, in theClean up caches
step (lines 139–170), set all required "original" variables as environment variables in theenv:
section. - In the
script:
block, replace direct expressions like${{ needs.get-artifacts.outputs.original_action }}
etc. with their safe environment equivalents (e.g.,process.env.ORIGINAL_ACTION
). - This change is within the shown workflow step, so no other parts of the file need editing.
-
Copy modified lines R142-R145 -
Copy modified line R148 -
Copy modified line R151
@@ -139,12 +139,16 @@ | ||
- name: Clean up caches | ||
if: always() | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | ||
env: | ||
ORIGINAL_REF: ${{ needs.get-artifacts.outputs.original_ref }} | ||
ORIGINAL_EVENT: ${{ needs.get-artifacts.outputs.original_event }} | ||
ORIGINAL_ACTION: ${{ needs.get-artifacts.outputs.original_action }} | ||
with: | ||
script: | | ||
const ref = '${{ needs.get-artifacts.outputs.original_ref }}'; | ||
const ref = process.env.ORIGINAL_REF; | ||
const key_prefix = 'test-' + ref + '-'; | ||
|
||
if ('${{ needs.get-artifacts.outputs.original_event }}' == 'pull_request' && '${{ needs.get-artifacts.outputs.original_action }}' != 'closed') { | ||
if (process.env.ORIGINAL_EVENT == 'pull_request' && process.env.ORIGINAL_ACTION != 'closed') { | ||
console.log('Skipping cache cleanup for open PR'); | ||
return; | ||
} |
const owner = '${{ github.repository_owner }}'; | ||
const repo = '${{ github.repository }}'.split('/')[1]; | ||
const sha = process.env.original_sha; | ||
const sha = '${{ needs.get-artifacts.outputs.original_sha }}'; |
Check failure
Code scanning / CodeQL
Code injection Critical test
${ needs.get-artifacts.outputs.original_sha }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
General fix:
Do not pass user-controlled or potentially untrusted data directly into workflow expressions used in run:
or script:
contexts. Instead, use environment variables to pass such data, and reference them using the underlying shell or language's environment variable access method.
Detailed steps:
- In the
Report conclusion
step (lines 171-191), change the reference tooriginal_sha
from using the dangerous${{ needs.get-artifacts.outputs.original_sha }}
directly in the script to injecting it as an environment variable. - Add an
env
block to the step, settingSHA: ${{ needs.get-artifacts.outputs.original_sha }}
. - In the
script:
block, replaceconst sha = '${{ needs.get-artifacts.outputs.original_sha }}';
withconst sha = process.env.SHA;
- (Optional but recommended) Remove any other interpolated outputs in the script in favour of the same approach if they're user-controlled.
Lines/regions to change:
- In
.github/workflows/tests_results.yml
, edit the step beginning with- name: Report conclusion
at lines 171-191.
Requirements:
- No new imports needed, as
process.env
is natively available in JavaScript. - Scripting syntax must be updated.
-
Copy modified lines R173-R174 -
Copy modified line R179
@@ -170,11 +170,13 @@ | ||
- name: Report conclusion | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | ||
if: always() | ||
env: | ||
SHA: ${{ needs.get-artifacts.outputs.original_sha }} | ||
with: | ||
script: | | ||
const owner = '${{ github.repository_owner }}'; | ||
const repo = '${{ github.repository }}'.split('/')[1]; | ||
const sha = '${{ needs.get-artifacts.outputs.original_sha }}'; | ||
const sha = process.env.SHA; | ||
core.debug(`owner: ${owner}`); | ||
core.debug(`repo: ${repo}`); | ||
core.debug(`sha: ${sha}`); |
core.debug(`sha: ${sha}`); | ||
const { context: name, state } = (await github.rest.repos.createCommitStatus({ | ||
context: `Runtime Tests / Report results (${process.env.original_event} -> workflow_run -> workflow_run)`, | ||
context: `Runtime Tests / Report results (${{ needs.get-artifacts.outputs.original_event }} -> workflow_run -> workflow_run)`, |
Check failure
Code scanning / CodeQL
Code injection Critical test
${ needs.get-artifacts.outputs.original_event }
workflow_run
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To fix this problem, replace direct ${{ ... }}
interpolation of untrusted inputs (specifically, the value of ${{ needs.get-artifacts.outputs.original_event }}
on line 182) with usage of environment variables. Pass the sanitized workflow output as an environment variable to the step, and then reference that environment variable inside the script via process.env
(JavaScript) rather than via expression interpolation. Specifically:
- In the "Report conclusion" step (lines 170-191), add an
env:
block that setsORIGINAL_EVENT: ${{ needs.get-artifacts.outputs.original_event }}
. - In the
script:
block, reference this value asprocess.env.ORIGINAL_EVENT
rather than using${{ ... }}
. - Refactor line 182 to use this environment variable when creating the
context
string. - Make similar adjustments for other workflow outputs if necessary and if they are user-controlled, but focus on
ORIGINAL_EVENT
as flagged by the alert.
No new dependencies or changes outside this region are required.
-
Copy modified lines R173-R174 -
Copy modified line R183 -
Copy modified line R185
@@ -170,6 +170,8 @@ | ||
- name: Report conclusion | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | ||
if: always() | ||
env: | ||
ORIGINAL_EVENT: ${{ needs.get-artifacts.outputs.original_event }} | ||
with: | ||
script: | | ||
const owner = '${{ github.repository_owner }}'; | ||
@@ -178,8 +180,9 @@ | ||
core.debug(`owner: ${owner}`); | ||
core.debug(`repo: ${repo}`); | ||
core.debug(`sha: ${sha}`); | ||
const event = process.env.ORIGINAL_EVENT; | ||
const { context: name, state } = (await github.rest.repos.createCommitStatus({ | ||
context: `Runtime Tests / Report results (${{ needs.get-artifacts.outputs.original_event }} -> workflow_run -> workflow_run)`, | ||
context: `Runtime Tests / Report results (${event} -> workflow_run -> workflow_run)`, | ||
owner: owner, | ||
repo: repo, | ||
sha: sha, |
# Ensure we run from repo root so relative paths work consistently | ||
try: | ||
os.chdir(REPO_ROOT) | ||
except Exception: |
Check notice
Code scanning / CodeQL
Insufficient Logging Low
try: | ||
fixed = txt.replace("'", '"') | ||
return [str(x).strip() for x in json.loads(fixed)] | ||
except Exception: |
Check notice
Code scanning / CodeQL
Insufficient Logging Low
Test Results 76 files 76 suites 14m 50s ⏱️ Results for commit 318070e. |
Description of Change
Reworked test workflows to be able to move hardware tests to internal GitLab.
Test Scenarios
Tested in fork + internal GitLab
Related links
Test results:
https://github.com/lucasssvaz/arduino-esp32/blob/gh-pages/runtime-test-results/RUNTIME_TEST_RESULTS.md