container-shell-safety

Detects unpinned shell steps in caller-supplied-container GitHub Actions jobs.

Updated Jul 4, 2026
One-click install
npx skills add https://github.com/charlesguse/wing-commander --skill container-shell-safety-charlesguse
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: container-shell-safety
Source: https://github.com/charlesguse/wing-commander/tree/main/.claude/skills/container-shell-safety
Command: npx skills add https://github.com/charlesguse/wing-commander --skill container-shell-safety-charlesguse

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires PyYAML, and includes scripts (resource) components.

What problem does it solve? GitHub Actions jobs that run inside a caller-supplied container image resolve the default shell from that image, so a run: step without an explicit shell: bash can fail outright on images where bash is unavailable, breaking workflows on adopter environments. ## Core Features & Use Cases - Defect Enumeration: Scans every workflow under .github/workflows/ and lists each run: step in a container-bound job that has no effective shell: setting at step, job, or workflow level. - Bashism Detection: Flags steps whose bodies match known bash-only constructs such as pipefail, arrays, [[ ]], local, process substitution, and read -d, sorting near-certain defects first. - Use Case: When reviewing a pull request that adds a container: block to a job or edits a run: step inside one, run the script to enumerate every exposed step and decide which ones need shell: bash pinned before merge. ## Quick Start Ask the assistant to review the workflow changes in this pull request for container shell safety and pin shell bash where needed.

Frequently Asked Questions about container-shell-safety

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I find run steps missing shell bash in GitHub Actions workflows?▼

Run the unpinned-container-steps.py script against your workflow files to list every run step in a caller-supplied-container job with no effective shell setting. Findings that match known bash-only constructs are sorted first with the matched construct named.

Why does set -o pipefail fail in a GitHub Actions container job?▼

When a job uses a caller-supplied container image and the step has no shell setting, Actions resolves the shell from that image, which may be sh instead of bash. POSIX sh rejects bash-only constructs like pipefail with errors such as Illegal option -o pipefail on every run.

What bash-only constructs break under sh in GitHub Actions?▼

Constructs that fail under sh include set -o pipefail, array assignments, declare -A, double-bracket conditionals, local, process substitution, read -d, here-strings, substring expansion, case modification, and echo -e. The script checks step bodies against regexes for each of these.

Does this check replace the automated pipefail gate in CI?▼

No, it complements the exact auto-failing gate that only flags set pipefail steps. This script enumerates all unpinned candidates including ones with no bashism yet, leaving the judgment of actual risk to the reviewer since broad auto-failing would false-positive on strings and comments.

How do I fix a step flagged for missing shell bash?▼

Add shell: bash to the step, placed after id or name per the repo convention, or set a job- or workflow-level defaults run shell bash to cover many steps at once. Both forms are recognized as covering a step by the shared shell-pinning logic.