Skip to content

fix: add lint rule to detect bare pip install and fix beval.yml violation - #2548

Open
pratik wayase (PratikWayase) wants to merge 8 commits into
microsoft:mainfrom
PratikWayase:fix/add-lint-rule-to-detect-bare-pip-install
Open

fix: add lint rule to detect bare pip install and fix beval.yml violation#2548
pratik wayase (PratikWayase) wants to merge 8 commits into
microsoft:mainfrom
PratikWayase:fix/add-lint-rule-to-detect-bare-pip-install

Conversation

@PratikWayase

Copy link
Copy Markdown
Contributor

Description

Adds CI enforcement for the repo's uv-first Python convention by introducing a reusable lint workflow that detects bare pip install calls in workflows, scripts, and Python files. Fixes the one known existing violation in beval.yml and updates experimental skill error strings to recommend uv pip install.

Companion to #1313, which adds the corresponding prohibitions to the Python instruction files. Without this enforcement backstop, those rules have no CI validation and regressions can silently appear.

Related Issue(s)

Fixes #2500
Companion to #1313

Type of Change

Select all that apply:

Code & Documentation:

  • Bug fix (non-breaking change fixing an issue)
  • New feature (non-breaking change adding functionality)
  • Breaking change (fix or feature causing existing functionality to change)
  • Documentation update

Infrastructure & Configuration:

  • GitHub Actions workflow
  • Linting configuration (markdown, PowerShell, etc.)
  • Security configuration
  • DevContainer configuration
  • Dependency update

AI Artifacts:

  • Reviewed contribution with hve-builder and addressed all actionable findings
  • Copilot instructions (.github/instructions/*.instructions.md)
  • Copilot prompt (.github/prompts/*.prompt.md)
  • Copilot agent (.github/agents/*.agent.md)
  • Copilot skill (.github/skills/*/SKILL.md)
  • Copilot hook (.github/hooks/*/*.json)
  • Eval spec added/updated for changed AI artifacts (evals/)

Other:

  • Script/automation (.ps1, .sh, .py)
  • Other (please describe):

Testing

All 4 local test scenarios passed successfully:

  1. Clean state: python scripts/lint_pip_install.pySuccess: No bare 'pip install' calls found.
  2. Violation detection: Injected run: pip install malicious-package into a fake workflow → correctly flagged and exited 1.
  3. Exclusion logic: Injected pip install mock-package into evals/fake_eval_test.py → correctly ignored per acceptance criteria.
  4. UV allowance: Injected run: uv pip install fastapi into a fake workflow → correctly passed.

Additionally verified that .venv directories, YAML name: metadata lines, and THIRD-PARTY-NOTICES are properly excluded to prevent false positives.

Checklist

Required Checks

  • Documentation is updated (if applicable)
  • Files follow existing naming conventions
  • Changes are backwards compatible (if applicable)
  • Tests added for new functionality (if applicable)

AI Artifact Contributions

  • Used hve-builder review mode to review contribution
  • Addressed all actionable findings from the hve-builder review
  • Verified contribution follows common standards and type-specific requirements

Required Local Checks

  • Local validation aggregate: npm run validate:local (N/A — no docs/PS/md changed)
  • Documentation validation (if docs changed): npm run validate:docs (N/A)
  • Spell checking: npm run spell-check (N/A — no prose changed)
  • Link validation: npm run lint:md-links (N/A — no URLs added)

Security Considerations

  • This PR does not contain any sensitive or NDA information
  • Any new dependencies have been reviewed for security issues
  • Security-related scripts follow the principle of least privilege

All GitHub Actions in new and modified workflows are SHA-pinned per repo convention:

  • actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
  • actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
  • astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9

The beval.yml install remains pinned to commit SHA d9f46c24f03b0b806d928a8a8ce2fc66d8e470fb to mitigate supply-chain risk.

Additional Notes

Files changed (7 total):

File Change
scripts/lint_pip_install.py New — Lint script with regex detection, .venv/evals/THIRD-PARTY-NOTICES exclusions
.github/workflows/pip-install-lint.yml New — Reusable workflow wrapping the lint script
.github/workflows/pr-validation.yml Modified — Added pip-install-lint job calling the reusable workflow
.github/workflows/beval.yml Modified — Replaced bare pip install with uv pip install --system, added setup-uv step
.github/skills/experimental/powerpoint/scripts/export_slides.py Modified — Error string updated to recommend uv pip install
.github/skills/experimental/powerpoint/scripts/export_svg.py Modified — Error string updated to recommend uv pip install
.github/skills/experimental/powerpoint/scripts/render_pdf_images.py Modified — Error string updated to recommend uv pip install

@PratikWayase
pratik wayase (PratikWayase) requested a review from a team as a code owner July 29, 2026 07:07
Comment thread .github/workflows/pip-install-lint.yml Fixed
Comment thread .github/workflows/beval.yml Fixed
Comment thread .github/workflows/pip-install-lint.yml Fixed
Comment thread .github/workflows/pip-install-lint.yml Fixed
Comment thread .github/workflows/beval.yml Fixed
@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.95%. Comparing base (207ced2) to head (0d22044).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2548      +/-   ##
==========================================
+ Coverage   82.53%   86.95%   +4.42%     
==========================================
  Files         155       93      -62     
  Lines       21123    12430    -8693     
  Branches       13        0      -13     
==========================================
- Hits        17434    10809    -6625     
+ Misses       3687     1621    -2066     
+ Partials        2        0       -2     
Flag Coverage Δ
docusaurus ?
pytest 90.51% <100.00%> (+10.41%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...s/experimental/powerpoint/scripts/export_slides.py 81.94% <ø> (ø)
...ills/experimental/powerpoint/scripts/export_svg.py 74.21% <ø> (ø)
...perimental/powerpoint/scripts/render_pdf_images.py 98.82% <100.00%> (ø)

... and 62 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the contribution. One item not covered by the diff: .github/skills/experimental/powerpoint/SKILL.md has pip install pillow in a dependency note (~line 455). There is no reason for bare pip here — please update to uv pip install pillow. This is exactly the kind of documentation drift the new lint rule is intended to prevent, and it is also an argument for the ignore-comment mechanism suggested on the lint script itself: with broader scan coverage and explicit <!-- pip-install-ok --> markers for genuine bootstrap exceptions, this would have been caught automatically.

Comment thread scripts/lint_pip_install.py Outdated
Comment thread .github/workflows/pip-install-lint.yml Outdated
Comment thread .github/workflows/beval.yml Outdated
echo "${{ github.workspace }}/evals/beval/node_modules/.bin" >> "$GITHUB_PATH"

- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a pre-existing pattern in the repository: astral-sh/setup-uv at this same commit SHA is already used in eval-validation.yml, fuzz-tests.yml, and pytest-tests.yml. This PR adds one more usage of an already-accepted pattern.

The action is pinned to a full commit SHA (c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0), which is the repo's mitigating control for unverified actions. To fully resolve the underlying concern, the repo could replace the action with a manual install step (curl -LsSf https://astral.sh/uv/install.sh | sh) or add astral-sh/setup-uv to a poutine allowlist. Either is a repo-level decision beyond the scope of this PR.

contents: read

jobs:
check-bare-pip-install:
with:
soft-fail: false

pip-install-lint:
Comment thread scripts/linting/Invoke-PipInstallLint.ps1 Outdated
Comment thread scripts/linting/Invoke-PipInstallLint.ps1 Outdated
Comment thread .github/workflows/pip-install-lint.yml
@PratikWayase
pratik wayase (PratikWayase) force-pushed the fix/add-lint-rule-to-detect-bare-pip-install branch from 93cc779 to 71d99d6 Compare August 2, 2026 05:36
Comment thread .github/workflows/beval.yml
Comment thread .github/prompts/data-science/synth-data-generate.prompt.md
Comment thread .github/agents/data-science/gen-jupyter-notebook.agent.md
continue
}

if ($line -match "\bpip3?\s+install\b" -and $line -notmatch "\buv\s+pip3?\s+install\b" -and $line -notmatch "%pip\s+install") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The allowlist checks exempt the entire line when any uv pip install or %pip install substring exists. For example, uv pip install allowed && pip install bypassed passes this required check; I reproduced exit code 0 at the current head. Please evaluate each pip install occurrence independently, or remove approved occurrences before checking for any bare match, and add a regression test for mixed commands on one line.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The scanner misses several maintained repository surfaces: .sh is absent from the extension allowlist, the segment-wide evals exclusion also suppresses scripts/evals, and the default traversal misses hidden .github content outside workflows. I reproduced bare installs in all three surfaces passing with exit code 0. Please enumerate tracked files deterministically, include executable shell formats, narrow the eval exclusion to the intended corpus, and add regression tests for these paths.

Comment on lines +23 to +24
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This job executes a PR-controlled script immediately after checkout, but checkout credentials are persisted by default. Disable credential persistence so modified PR code cannot recover the read token and to follow the repository's workflow credential convention.

Suggested change
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

Comment on lines +8 to +19
$testDir = "$PSScriptRoot/TestLintDir"
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
New-Item -ItemType Directory -Path $testDir | Out-Null
}

AfterAll {
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
}

AfterEach {
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
New-Item -ItemType Directory -Path $testDir | Out-Null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: These fixtures are created inside the repository checkout, so parallel or interrupted test runs can collide or leave workspace state. Please use Pester's $TestDrive for test-owned files.

Suggested change
$testDir = "$PSScriptRoot/TestLintDir"
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
New-Item -ItemType Directory -Path $testDir | Out-Null
}
AfterAll {
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
}
AfterEach {
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
New-Item -ItemType Directory -Path $testDir | Out-Null
$testDir = Join-Path $TestDrive "TestLintDir"
New-Item -ItemType Directory -Path $testDir | Out-Null
}
AfterEach {
if (Test-Path $testDir) { Remove-Item -Recurse -Force $testDir }
New-Item -ItemType Directory -Path $testDir | Out-Null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Current main intentionally deleted this workflow in PR #2552 when beval was retired in favor of Vally agent-conformance suites. Please merge current main, accept this file's deletion, and remove the obsolete beval hunk from this PR. The replacement workflow does not install beval, so this install change does not need to be migrated.

Comment on lines +1 to +4
# Copyright (c) 2026 Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT

Describe "Invoke-PipInstallLint.ps1" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add the standard Pester module requirement and Unit tag so this suite follows the repository's discovery and filtering conventions.

Suggested change
# Copyright (c) 2026 Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
Describe "Invoke-PipInstallLint.ps1" {
#Requires -Modules Pester
# Copyright (c) 2026 Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
Describe "Invoke-PipInstallLint.ps1" -Tag "Unit" {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: add lint rule to detect bare pip install and fix beval.yml violation

5 participants