Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
94 changes: 94 additions & 0 deletions .github/workflows/_selftest-uv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# TEMPORARY β€” validation harness for the pip->uv migration (PR #60).
# Delete this file (plus the root pyproject.toml and selftest_pkg/) before
# merging to dev. It is not a reusable workflow and has no downstream consumers.
#
# It drives the REAL reusable workflows via local `uses:` against the in-repo
# dummy package (root pyproject.toml + selftest_pkg/), so the actual build /
# install / coverage / audit / type-check plumbing runs under uv on real
# runners β€” not just isolated uv commands.
#
# Why the fix under test matters: actions/setup-python gives a bare interpreter
# with no active virtualenv, and `uv pip install` refuses a non-venv install
# unless UV_SYSTEM_PYTHON=1 / --system is set. Every uv workflow now declares
# that env at workflow level; these jobs prove it works end to end.
#
# Triggered on push to this branch only, with pr_comment:false everywhere, so
# nothing is posted to PR #60.
name: "[selftest] uv migration"

on:
push:
branches: [migrate-to-uv]
workflow_dispatch:

# Must cover the union of permissions the called reusable workflows declare,
# or GitHub rejects the call at compile time (startup failure) β€” even though
# the features needing them are disabled here (pr_comment/deploy_pages/sarif).
permissions:
contents: write # coverage.yml job declares contents: write (deploy_pages)
pull-requests: write # PR-comment jobs
security-events: write # pip-audit.yml SARIF upload

jobs:
# Build sdist+wheel under `uv build`, install the wheel with extras under
# `uv pip install`, run pytest β€” across every supported Python.
build-tests:
uses: ./.github/workflows/build-tests.yml
with:
python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
install_extras: test
test_path: selftest_pkg/tests
pr_comment: false

# Editable install with extras under `uv pip install -e .[dev]` + pytest-cov.
coverage:
uses: ./.github/workflows/coverage.yml
with:
test_extras: dev
test_path: selftest_pkg/tests
coverage_source: selftest_pkg
pr_comment: false

# Editable install under uv, then mypy against the dummy package.
type-check:
uses: ./.github/workflows/type-check.yml
with:
test_extras: dev
mypy_args: selftest_pkg
pr_comment: false

# `uv pip install ".[test]"` then `uv pip freeze` -> pip-licenses.
license-check:
uses: ./.github/workflows/license-check.yml
with:
install_extras: "[test]"
warn_only: true
pr_comment: false

# `uv pip install ".[test]"` then pip-audit over the resolved deps.
pip-audit:
uses: ./.github/workflows/pip-audit.yml
with:
install_extras: "[test]"
warn_only: true
pr_comment: false

# Static guard: every workflow that runs `uv pip` MUST also declare
# UV_SYSTEM_PYTHON, or it will fail at runtime on the setup-python interpreter.
env-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Assert uv workflows declare UV_SYSTEM_PYTHON
run: |
set -euo pipefail
missing=0
for f in .github/workflows/*.yml; do
[ "$(basename "$f")" = "_selftest-uv.yml" ] && continue
if grep -qE 'uv pip (install|freeze)' "$f" && ! grep -q 'UV_SYSTEM_PYTHON' "$f"; then
echo "::error file=$f::uses 'uv pip' but does not declare UV_SYSTEM_PYTHON"
missing=1
fi
done
[ "$missing" -eq 0 ] && echo "All uv workflows declare UV_SYSTEM_PYTHON."
exit "$missing"
Comment on lines +76 to +94

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

Extend the guard to enforce UV_PRERELEASE too.

Lines 88-89 only assert UV_SYSTEM_PYTHON, so a future uv pip workflow can drop UV_PRERELEASE and still pass this harness even though that is the regression this PR is fixing.

Proposed fix
       - name: Assert uv workflows declare UV_SYSTEM_PYTHON
         run: |
           set -euo pipefail
           missing=0
           for f in .github/workflows/*.yml; do
             [ "$(basename "$f")" = "_selftest-uv.yml" ] && continue
-            if grep -qE 'uv pip (install|freeze)' "$f" && ! grep -q 'UV_SYSTEM_PYTHON' "$f"; then
-              echo "::error file=$f::uses 'uv pip' but does not declare UV_SYSTEM_PYTHON"
-              missing=1
+            if grep -qE 'uv pip (install|freeze)' "$f"; then
+              if ! grep -q 'UV_SYSTEM_PYTHON' "$f"; then
+                echo "::error file=$f::uses 'uv pip' but does not declare UV_SYSTEM_PYTHON"
+                missing=1
+              fi
+              if ! grep -q 'UV_PRERELEASE' "$f"; then
+                echo "::error file=$f::uses 'uv pip' but does not declare UV_PRERELEASE"
+                missing=1
+              fi
             fi
           done
           [ "$missing" -eq 0 ] && echo "All uv workflows declare UV_SYSTEM_PYTHON."
           exit "$missing"
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Static guard: every workflow that runs `uv pip` MUST also declare
# UV_SYSTEM_PYTHON, or it will fail at runtime on the setup-python interpreter.
env-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Assert uv workflows declare UV_SYSTEM_PYTHON
run: |
set -euo pipefail
missing=0
for f in .github/workflows/*.yml; do
[ "$(basename "$f")" = "_selftest-uv.yml" ] && continue
if grep -qE 'uv pip (install|freeze)' "$f" && ! grep -q 'UV_SYSTEM_PYTHON' "$f"; then
echo "::error file=$f::uses 'uv pip' but does not declare UV_SYSTEM_PYTHON"
missing=1
fi
done
[ "$missing" -eq 0 ] && echo "All uv workflows declare UV_SYSTEM_PYTHON."
exit "$missing"
# Static guard: every workflow that runs `uv pip` MUST also declare
# UV_SYSTEM_PYTHON, or it will fail at runtime on the setup-python interpreter.
env-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Assert uv workflows declare UV_SYSTEM_PYTHON
run: |
set -euo pipefail
missing=0
for f in .github/workflows/*.yml; do
[ "$(basename "$f")" = "_selftest-uv.yml" ] && continue
if grep -qE 'uv pip (install|freeze)' "$f"; then
if ! grep -q 'UV_SYSTEM_PYTHON' "$f"; then
echo "::error file=$f::uses 'uv pip' but does not declare UV_SYSTEM_PYTHON"
missing=1
fi
if ! grep -q 'UV_PRERELEASE' "$f"; then
echo "::error file=$f::uses 'uv pip' but does not declare UV_PRERELEASE"
missing=1
fi
fi
done
[ "$missing" -eq 0 ] && echo "All uv workflows declare UV_SYSTEM_PYTHON."
exit "$missing"
🧰 Tools
πŸͺ› zizmor (1.26.1)

[warning] 81-81: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/_selftest-uv.yml around lines 76 - 94, Extend the selftest
guard in env-coverage to check both UV_SYSTEM_PYTHON and UV_PRERELEASE for any
workflow that uses uv pip. Update the shell loop in _selftest-uv.yml so the
existing grep-based assertion around uv pip install/freeze also fails when
UV_PRERELEASE is missing, and emit an error that names the workflow file and
both required env vars.

29 changes: 20 additions & 9 deletions .github/workflows/build-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ on:
description: >
Post a 'πŸ”¨ Build Tests' section in the OVOS PR Checks comment.
Only runs on pull_request events.
# uv installs into the setup-python interpreter (no venv on the runner)
env:
UV_SYSTEM_PYTHON: "1"
# The OVOS ecosystem ships pre-1.0 alphas and relies on prerelease floor-pins
# (pkg>=X.Ya1). pip honoured those transitively; uv's default mode does not when
# a package also has stable releases (e.g. ovos-PHAL's ovos-phal-plugin-ipgeo
# >=0.1.9a1, which has a coexisting stable 0.1.7). Allow prereleases so the
# floor-pins resolve as they did under pip β€” version caps still bound them.
UV_PRERELEASE: "allow"

jobs:
build_tests:
strategy:
Expand All @@ -63,6 +73,9 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install uv
run: pip install uv

- name: Checkout gh-automations scripts
uses: actions/checkout@v6
with:
Expand All @@ -76,20 +89,18 @@ jobs:
sudo apt-get install -yq python3-dev libssl-dev ${{ inputs.system_deps }}

- name: Install Build Tools
run: |
python -m pip install --upgrade pip
python -m pip install build wheel
run: uv pip install build wheel

- name: Pre-install pip requirements
if: ${{ inputs.pre_install_pip != '' }}
run: |
# shellcheck disable=SC2086
python -m pip install ${{ inputs.pre_install_pip }}
uv pip install ${{ inputs.pre_install_pip }}
Comment on lines 101 to +105

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ”’ Security & Privacy | 🟠 Major | ⚑ Quick win

Treat pre_install_pip as argv, not shell.

Line 98 expands a reusable-workflow input directly inside run:. If any caller forwards untrusted text here, it becomes arbitrary shell on the runner.

Proposed fix
       - name: Pre-install pip requirements
         if: ${{ inputs.pre_install_pip != '' }}
+        env:
+          PRE_INSTALL_PIP: ${{ inputs.pre_install_pip }}
         run: |
-          # shellcheck disable=SC2086
-          uv pip install ${{ inputs.pre_install_pip }}
+          python - <<'PY'
+          import os, shlex, subprocess
+          reqs = shlex.split(os.environ["PRE_INSTALL_PIP"])
+          subprocess.check_call(["uv", "pip", "install", *reqs])
+          PY
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Pre-install pip requirements
if: ${{ inputs.pre_install_pip != '' }}
run: |
# shellcheck disable=SC2086
python -m pip install ${{ inputs.pre_install_pip }}
uv pip install ${{ inputs.pre_install_pip }}
- name: Pre-install pip requirements
if: ${{ inputs.pre_install_pip != '' }}
env:
PRE_INSTALL_PIP: ${{ inputs.pre_install_pip }}
run: |
python - <<'PY'
import os, shlex, subprocess
reqs = shlex.split(os.environ["PRE_INSTALL_PIP"])
subprocess.check_call(["uv", "pip", "install", *reqs])
PY
🧰 Tools
πŸͺ› zizmor (1.26.1)

[error] 98-98: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-tests.yml around lines 94 - 98, The Pre-install pip
requirements step in the build-tests workflow is expanding pre_install_pip
directly inside a run shell command, which allows shell injection. Update that
step to treat inputs.pre_install_pip as argv rather than shell text by passing
it through a safe action or by assigning it to an environment variable and
invoking uv pip install without unquoted interpolation. Keep the change
localized to the workflow step named Pre-install pip requirements and preserve
the existing conditional behavior.

Source: Linters/SAST tools


- name: Build Distribution Packages
id: build
run: |
python -m build
uv build

- name: Install Built Package
id: install
Expand All @@ -98,19 +109,19 @@ jobs:
EXTRAS="${{ inputs.install_extras }}"
if [ -n "$WHEEL" ]; then
if [ -n "$EXTRAS" ]; then
pip install "${WHEEL}[${EXTRAS}]"
uv pip install "${WHEEL}[${EXTRAS}]"
else
pip install "$WHEEL"
uv pip install "$WHEEL"
fi
else
pip install dist/*.tar.gz 2>/dev/null || { echo "No dist files found"; exit 1; }
uv pip install dist/*.tar.gz 2>/dev/null || { echo "No dist files found"; exit 1; }
fi

- name: Run Tests
id: tests
if: ${{ inputs.test_path != '' }}
run: |
python -m pip install pytest
uv pip install pytest
python -m pytest ${{ inputs.test_path }} -v

- name: Save result
Expand Down
17 changes: 12 additions & 5 deletions .github/workflows/coverage-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ on:
default: "gh-pages"
description: "Branch to push the HTML coverage report to."

# uv installs into the setup-python interpreter (no venv on the runner)
env:
UV_SYSTEM_PYTHON: "1"
UV_PRERELEASE: "allow" # OVOS ships pre-1.0 alphas; resolve prerelease floor-pins like pip did

jobs:
coverage_pages:
runs-on: ${{ inputs.runner }}
Expand All @@ -55,6 +60,9 @@ jobs:
with:
python-version: ${{ inputs.python_version }}

- name: Install uv
run: pip install uv

- name: Install System Dependencies
if: ${{ inputs.system_deps != '' }}
run: |
Expand All @@ -63,17 +71,16 @@ jobs:

- name: Install Dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest pytest-cov coverage[toml] ovoscope
if python -m pip install -e ".[dev]" 2>/dev/null; then
uv pip install pytest pytest-cov coverage[toml] ovoscope
if uv pip install -e ".[dev]" 2>/dev/null; then
echo "Installed package with [dev] extras"
elif python -m pip install -e . 2>/dev/null; then
elif uv pip install -e . 2>/dev/null; then
echo "Installed package (no [dev] extras)"
else
echo "No installable package found at repo root β€” continuing without install"
fi
if [ -n "${{ inputs.install_extras }}" ]; then
python -m pip install ${{ inputs.install_extras }}
uv pip install ${{ inputs.install_extras }}
Comment on lines 89 to +90

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ”’ Security & Privacy | 🟠 Major | ⚑ Quick win

Avoid shell-expanding install_extras.

Line 83 treats the workflow input as shell source instead of arguments. In a reusable workflow, that makes install_extras a command-injection surface.

Proposed fix
-          if [ -n "${{ inputs.install_extras }}" ]; then
-            uv pip install ${{ inputs.install_extras }}
+          if [ -n "${{ inputs.install_extras }}" ]; then
+            INSTALL_EXTRAS="${{ inputs.install_extras }}" python - <<'PY'
+            import os, shlex, subprocess
+            extras = shlex.split(os.environ["INSTALL_EXTRAS"])
+            subprocess.check_call(["uv", "pip", "install", *extras])
+            PY
           fi
🧰 Tools
πŸͺ› zizmor (1.26.1)

[error] 82-82: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 82-82: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/coverage-pages.yml around lines 82 - 83, The
coverage-pages workflow currently passes install_extras directly into a shell
command, creating a command-injection risk in the reusable workflow. Update the
install step in the workflow so the input is treated as data/arguments rather
than shell source, using the existing install_extras handling around the uv pip
install invocation and keeping the logic in the same job step.

Source: Linters/SAST tools

fi

- name: Run Tests with Coverage
Expand Down
22 changes: 14 additions & 8 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ on:
default: 14
description: "Days to retain the coverage XML artifact"

# uv installs into the setup-python interpreter (no venv on the runner)
env:
UV_SYSTEM_PYTHON: "1"
UV_PRERELEASE: "allow" # OVOS ships pre-1.0 alphas; resolve prerelease floor-pins like pip did

jobs:
coverage:
runs-on: ${{ inputs.runner }}
Expand All @@ -107,38 +112,39 @@ jobs:
with:
python-version: ${{ inputs.python_version }}

- name: Install uv
run: pip install uv

- name: Install System Dependencies
if: ${{ inputs.system_deps != '' }}
run: |
sudo apt-get update -q
sudo apt-get install -yq ${{ inputs.system_deps }}

- name: Install Dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest pytest-cov coverage[toml]
run: uv pip install pytest pytest-cov coverage[toml]

- name: Pre-install pip requirements
if: ${{ inputs.pre_install_pip != '' }}
run: |
# shellcheck disable=SC2086
python -m pip install ${{ inputs.pre_install_pip }}
uv pip install ${{ inputs.pre_install_pip }}

- name: Install Package
run: |
PRIMARY="${{ inputs.test_extras }}"
FALLBACK="${{ inputs.test_extras_fallback }}"
if [ -n "$PRIMARY" ] && python -m pip install -e ".[$PRIMARY]" 2>/dev/null; then
if [ -n "$PRIMARY" ] && uv pip install -e ".[$PRIMARY]" 2>/dev/null; then
echo "Installed package with [$PRIMARY] extras"
elif [ -n "$FALLBACK" ] && python -m pip install -e ".[$FALLBACK]" 2>/dev/null; then
elif [ -n "$FALLBACK" ] && uv pip install -e ".[$FALLBACK]" 2>/dev/null; then
echo "Installed package with [$FALLBACK] extras"
elif python -m pip install -e . 2>/dev/null; then
elif uv pip install -e . 2>/dev/null; then
echo "Installed package (no test extras found)"
else
echo "No installable package found at repo root β€” continuing without install"
fi
if [ -n "${{ inputs.install_extras }}" ]; then
python -m pip install ${{ inputs.install_extras }}
uv pip install ${{ inputs.install_extras }}
fi

- name: Run Tests with Coverage
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/docs-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ jobs:
2>&1 | tee /tmp/markdownlint-output.txt || true
fi
markdownlint-cli2 "**/*.md" 2>&1
continue-on-error: true

- name: Format docs check section for PR comment
if: ${{ inputs.pr_comment && github.event_name == 'pull_request' }}
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/downstream-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ on:
default: "dev"
description: "Deprecated β€” ignored. Report is now uploaded as an artifact instead of committed."

# uv installs into the setup-python interpreter (no venv on the runner)
env:
UV_SYSTEM_PYTHON: "1"
UV_PRERELEASE: "allow" # OVOS ships pre-1.0 alphas; resolve prerelease floor-pins like pip did

jobs:
check_downstream:
runs-on: ${{ inputs.runner }}
Expand All @@ -55,6 +60,8 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python_version }}
- name: Install uv
run: pip install uv
- name: Install System Dependencies
run: |
sudo apt-get update -q
Expand All @@ -71,12 +78,11 @@ jobs:
${{ inputs.system_deps }}
- name: Install OVOS ecosystem and pipdeptree
run: |
python -m pip install build wheel pipdeptree
curl -fsSL -o constraints.txt "${{ inputs.constraints_url }}"
# Install the full OVOS ecosystem so pipdeptree can find all reverse deps
pip install -r constraints.txt || true
uv pip install -r constraints.txt || true
# Re-install the target package pinned to the constraints version
pip install -c constraints.txt "${{ inputs.package_name }}" || true
uv pip install -c constraints.txt "${{ inputs.package_name }}" || true
Comment on lines 86 to +92

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟑 Minor | ⚑ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

script="$(fd -p check_downstream.py action . | head -n1)"
echo "check_downstream.py: ${script:-not found}"

if [ -n "${script:-}" ]; then
  ast-grep outline "$script" --view expanded || true
  echo
  echo "Searching for pipdeptree/process usage..."
  rg -n -C2 'pipdeptree|subprocess\.(run|check_call|check_output)|shutil\.which' "$script"
fi

Repository: OpenVoiceOS/gh-automations

Length of output: 1909


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository references to pipdeptree:"
rg -n --hidden --glob '!**/.git/**' 'pipdeptree' .

echo
echo "Workflow section around the install step:"
sed -n '60,100p' .github/workflows/downstream-check.yml

Repository: OpenVoiceOS/gh-automations

Length of output: 3687


Keep pipdeptree available for the downstream report
scripts/check_downstream.py still runs python -m pipdeptree, so this step needs an explicit install for it or another guarantee that constraints.txt provides it.

🧰 Tools
πŸͺ› zizmor (1.26.1)

[error] 81-81: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 85-85: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/downstream-check.yml around lines 79 - 85, The downstream
install step is missing an explicit guarantee that pipdeptree is available
before scripts/check_downstream.py runs python -m pipdeptree. Update the install
logic in the workflow step that installs the OVOS ecosystem and the target
package so pipdeptree is installed explicitly or otherwise ensured via
constraints.txt, and keep the existing downstream report flow working without
depending on an implicit transitive install.

- name: Generate downstream report
run: |
python action/github/scripts/check_downstream.py \
Expand Down
23 changes: 15 additions & 8 deletions .github/workflows/intent-case-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ on:
Minimum overall pass rate (0.0-1.0). Fails the shard when the
observed rate is below this value.

# uv installs into the setup-python interpreter (no venv on the runner)
env:
UV_SYSTEM_PYTHON: "1"
UV_PRERELEASE: "allow" # OVOS ships pre-1.0 alphas; resolve prerelease floor-pins like pip did

jobs:
intent_case_tests:
runs-on: ${{ inputs.runner }}
Expand Down Expand Up @@ -134,6 +139,9 @@ jobs:
with:
python-version: ${{ inputs.python_version }}

- name: Install uv
run: pip install uv

- name: Install System Dependencies
if: ${{ inputs.system_deps != '' || inputs.require_padatious }}
run: |
Expand All @@ -152,10 +160,10 @@ jobs:
install_plugin() {
local name="$1" pypi="$2" gh="$3"
if [ "$PRE_RELEASE" == "true" ]; then
pip install --force-reinstall "git+https://github.com/${gh}@dev" || {
uv pip install --force-reinstall "git+https://github.com/${gh}@dev" || {
echo "::error::Failed to install $name from GitHub dev"; exit 1; }
else
pip install "$pypi" || {
uv pip install "$pypi" || {
echo "::error::Failed to install $name from PyPI"; exit 1; }
fi
}
Expand All @@ -178,18 +186,17 @@ jobs:

- name: Install Package with Test Extras
run: |
python -m pip install --upgrade pip
python -m pip install pytest pytest-json-report
uv pip install pytest pytest-json-report
if [ "${{ inputs.pre_release }}" == "true" ]; then
pip install --force-reinstall "git+https://github.com/TigreGotico/ovoscope@dev"
uv pip install --force-reinstall "git+https://github.com/TigreGotico/ovoscope@dev"
else
pip install ovoscope
uv pip install ovoscope
fi
EXTRAS="${{ inputs.install_extras }}"
if [ -n "$EXTRAS" ]; then
pip install ".[$EXTRAS]"
uv pip install ".[$EXTRAS]"
else
pip install .
uv pip install .
Comment on lines 194 to +206

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ”’ Security & Privacy | 🟠 Major | ⚑ Quick win

Avoid inline expansion of install_extras.

Line 195 embeds a caller-provided string directly into the shell script. In a reusable workflow that is enough for $(...)/backticks to execute on the runner. Pass the input via env: and read $INSTALL_EXTRAS in the script instead.

Suggested fix
       - name: Install Package with Test Extras
+        env:
+          INSTALL_EXTRAS: ${{ inputs.install_extras }}
         run: |
           uv pip install pytest pytest-json-report
           if [ "${{ inputs.pre_release }}" == "true" ]; then
             uv pip install --force-reinstall "git+https://github.com/TigreGotico/ovoscope@dev"
           else
             uv pip install ovoscope
           fi
-          EXTRAS="${{ inputs.install_extras }}"
+          EXTRAS="${INSTALL_EXTRAS}"
           if [ -n "$EXTRAS" ]; then
             uv pip install ".[$EXTRAS]"
           else
             uv pip install .
           fi
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Install Package with Test Extras
run: |
python -m pip install --upgrade pip
python -m pip install pytest pytest-json-report
uv pip install pytest pytest-json-report
if [ "${{ inputs.pre_release }}" == "true" ]; then
pip install --force-reinstall "git+https://github.com/TigreGotico/ovoscope@dev"
uv pip install --force-reinstall "git+https://github.com/TigreGotico/ovoscope@dev"
else
pip install ovoscope
uv pip install ovoscope
fi
EXTRAS="${{ inputs.install_extras }}"
if [ -n "$EXTRAS" ]; then
pip install ".[$EXTRAS]"
uv pip install ".[$EXTRAS]"
else
pip install .
uv pip install .
- name: Install Package with Test Extras
env:
INSTALL_EXTRAS: ${{ inputs.install_extras }}
run: |
uv pip install pytest pytest-json-report
if [ "${{ inputs.pre_release }}" == "true" ]; then
uv pip install --force-reinstall "git+https://github.com/TigreGotico/ovoscope@dev"
else
uv pip install ovoscope
fi
EXTRAS="${INSTALL_EXTRAS}"
if [ -n "$EXTRAS" ]; then
uv pip install ".[$EXTRAS]"
else
uv pip install .
🧰 Tools
πŸͺ› zizmor (1.26.1)

[error] 195-195: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/intent-case-tests.yml around lines 187 - 199, The Install
Package with Test Extras step is interpolating the caller-provided
install_extras input directly into the shell script, which can allow shell
expansion during workflow execution. Update that step to pass install_extras
through env: and read it as a shell variable inside the script, then use that
variable in the uv pip install .[...] branch. Refer to the Install Package with
Test Extras block and the EXTRAS handling in intent-case-tests.yml.

Source: Linters/SAST tools

fi
python -c "import ovoscope; print('ovoscope path:', ovoscope.__file__)"

Expand Down
Loading