microsoft / microsoft/hve-core

Add a shellcheck CI lane and convert shell scripts to PowerShell where cross-platform support is reasonable

Open
#2,579 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

ci feature linting priority-3 scripts
Dominant language
Python
Stars
1.5k
Forks
301
Avg merge
3d 3h
Merged PRs (30d)
92

Description

Problem

Two related gaps in shell script coverage, found while hardening the shared test workflows in #2566.

1. No CI lane runs shellcheck

.github/workflows/codeql-analysis.yml states:

# PowerShell and shell scripts are not CodeQL-supported (covered by PSScriptAnalyzer and shellcheck)

PSScriptAnalyzer does run (psscriptanalyzer job in pr-validation.yml). shellcheck does not. No workflow contains a step that executes it:

  • copilot-setup-steps.yml installs shellcheck and prints shellcheck --version, but never lints anything with it.
  • No other workflow invokes it at all.

So 31 tracked .sh files have no static analysis in CI, and a comment asserts coverage that does not exist. That is worse than an acknowledged gap, because it stops anyone from looking.

This matters now: scripts/ci/install-skill-node-deps.sh was added in #2566 and runs in reusable workflows that hold id-token: write for Codecov OIDC. Its behavior is locked by scripts/tests/security/Test-SharedTestWorkflowHardening.Tests.ps1, but nothing lints the shell itself.

2. Shell scripts limit cross-platform contribution

31 tracked .sh files exist. 14 already have a .ps1 sibling; 17 do not, so a Windows contributor without WSL cannot run them.

17 shell scripts with no PowerShell equivalent
.devcontainer/scripts/on-create.sh
.devcontainer/scripts/post-create.sh
.github/hooks/shared/telemetry/clean-telemetry.sh
.github/hooks/shared/telemetry/generate-telemetry-report.sh
.github/hooks/shared/telemetry/telemetry-collector.sh
.github/skills/experimental/copilot-otel-metrics/examples/azure/deploy.sh
.github/skills/experimental/powerpoint/scripts/embed-audio.sh
.github/skills/experimental/powerpoint/scripts/export-svg.sh
.github/skills/experimental/powerpoint/scripts/generate-themes.sh
.github/skills/experimental/powerpoint/scripts/invoke-pptx-pipeline.sh
.github/skills/experimental/tts-voiceover/scripts/embed-audio.sh
.github/skills/experimental/tts-voiceover/scripts/generate-voiceover.sh
.github/skills/github/gh-code-scanning/scripts/get-code-scanning-alerts.sh
.github/skills/hve-core/vally-tests/scripts/lint-vally-test-safety.sh
scripts/ci/install-skill-node-deps.sh
scripts/tests/fixtures/Security/insecure-download.sh
scripts/tests/fixtures/Security/secure-download.sh

The existing .sh / .ps1 pairs under hve-core-installer and pr-reference show the established convention.

Proposed work

Add a shellcheck lane. A shellcheck job in pr-validation.yml covering tracked .sh files.

Roll it out soft-fail first, or fix findings before enabling it. The current state of those 31 scripts is unknown: nobody has linted them, so the lane could land red across scripts unrelated to whoever adds it. Measure first, then enable enforcing.

Convert where a PowerShell equivalent is reasonable. Not a blanket rewrite:

  • .devcontainer/ scripts are Linux-container lifecycle hooks and should stay shell.
  • scripts/tests/fixtures/Security/*.sh are lint fixtures; converting them would defeat their purpose.
  • Skill scripts invoked by agents and workflow helpers are the useful targets.

Keep .sh alongside any new .ps1 where CI or containers depend on it, matching the existing pairs.

Acceptance criteria

  • A CI lane executes shellcheck against tracked .sh files, and its enforcing/soft-fail state is deliberate and documented.
  • The codeql-analysis.yml comment matches reality, or is corrected.
  • Scripts that can reasonably be cross-platform have a .ps1 equivalent, following the existing pairing convention.
  • Conversions are decided per script with a recorded reason, not applied wholesale.

Notes

Found while remediating a 120-finding accessibility review on fix/docs-a11y-followups (#2566). Filed separately rather than fixed inline: verifying a repo-wide shellcheck lane needs shellcheck available locally, and enabling an unverified gate risks landing CI red on scripts outside that PR's scope.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with .github/workflows/pr-validation.yml and the existing psscriptanalyzer job, then compare shell/PowerShell pairs under hve-core-installer and pr-reference. Check the CodeQL comment and the 31 tracked .sh files before deciding the shellcheck lane’s scope and soft-fail state. Done means CI runs shellcheck, the comment is accurate, and reasonable conversions have paired .ps1 files with per-script decisions recorded.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, powershell, shell, yaml
Domain
ci-cd, devops, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.