create-qa-architect 5.3.1 → 5.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/quality.yml +11 -11
- package/.github/workflows/shell-ci.yml.example +82 -0
- package/.github/workflows/shell-quality.yml.example +148 -0
- package/README.md +120 -12
- package/config/shell-ci.yml +82 -0
- package/config/shell-quality.yml +148 -0
- package/docs/CI-COST-ANALYSIS.md +323 -0
- package/eslint.config.cjs +2 -0
- package/lib/commands/analyze-ci.js +616 -0
- package/lib/commands/deps.js +70 -22
- package/lib/commands/index.js +4 -0
- package/lib/config-validator.js +28 -45
- package/lib/error-reporter.js +1 -1
- package/lib/github-api.js +34 -4
- package/lib/license-signing.js +15 -0
- package/lib/licensing.js +116 -22
- package/lib/package-utils.js +9 -9
- package/lib/project-maturity.js +58 -6
- package/lib/smart-strategy-generator.js +20 -3
- package/lib/telemetry.js +1 -1
- package/lib/ui-helpers.js +1 -1
- package/lib/validation/config-security.js +22 -18
- package/lib/validation/index.js +68 -97
- package/package.json +3 -3
- package/scripts/validate-claude-md.js +80 -0
- package/setup.js +607 -51
|
@@ -12,8 +12,10 @@ name: Quality Checks
|
|
|
12
12
|
on:
|
|
13
13
|
push:
|
|
14
14
|
branches: [main, master, develop]
|
|
15
|
+
# PATH_FILTERS_PLACEHOLDER
|
|
15
16
|
pull_request:
|
|
16
17
|
branches: [main, master, develop]
|
|
18
|
+
# SECURITY_SCHEDULE_PLACEHOLDER
|
|
17
19
|
|
|
18
20
|
jobs:
|
|
19
21
|
# Step 1: Detect project maturity level and package manager
|
|
@@ -148,6 +150,7 @@ jobs:
|
|
|
148
150
|
security:
|
|
149
151
|
runs-on: ubuntu-latest
|
|
150
152
|
needs: detect-maturity
|
|
153
|
+
# SECURITY_CONDITION_PLACEHOLDER
|
|
151
154
|
if: needs.detect-maturity.outputs.has-deps == 'true'
|
|
152
155
|
|
|
153
156
|
steps:
|
|
@@ -236,14 +239,11 @@ jobs:
|
|
|
236
239
|
esac
|
|
237
240
|
|
|
238
241
|
- name: Check for hardcoded secrets
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
# Use
|
|
242
|
-
#
|
|
243
|
-
|
|
244
|
-
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
|
|
245
|
-
with:
|
|
246
|
-
args: --redact --verbose
|
|
242
|
+
run: |
|
|
243
|
+
echo "🔍 Running gitleaks secret scanning..."
|
|
244
|
+
# Use setup.js security scan which manages gitleaks binary internally
|
|
245
|
+
# This avoids the commercial license requirement of the gitleaks-action
|
|
246
|
+
node setup.js --security-config
|
|
247
247
|
|
|
248
248
|
- name: Security pattern detection
|
|
249
249
|
uses: semgrep/semgrep-action@713efdd345f3035192eaa63f56867b88e63e4e5d # v1
|
|
@@ -266,9 +266,9 @@ jobs:
|
|
|
266
266
|
runs-on: ubuntu-latest
|
|
267
267
|
needs: detect-maturity
|
|
268
268
|
if: fromJSON(needs.detect-maturity.outputs.test-count) > 0
|
|
269
|
+
# TESTS_CONDITION_PLACEHOLDER
|
|
270
|
+
# MATRIX_PLACEHOLDER
|
|
269
271
|
strategy:
|
|
270
|
-
matrix:
|
|
271
|
-
node-version: [20, 22]
|
|
272
272
|
fail-fast: false
|
|
273
273
|
|
|
274
274
|
steps:
|
|
@@ -320,7 +320,7 @@ jobs:
|
|
|
320
320
|
if: runner.os == 'Linux'
|
|
321
321
|
run: |
|
|
322
322
|
echo "🔐 Running real gitleaks binary verification test..."
|
|
323
|
-
RUN_REAL_BINARY_TEST=1 node tests/gitleaks-real-binary-test.js
|
|
323
|
+
QAA_DEVELOPER=true RUN_REAL_BINARY_TEST=1 node tests/gitleaks-real-binary-test.js
|
|
324
324
|
|
|
325
325
|
# Step 6: Documentation - run for production-ready projects
|
|
326
326
|
documentation:
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: Shell Script CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
shellcheck:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Run ShellCheck
|
|
18
|
+
uses: ludeeus/action-shellcheck@master
|
|
19
|
+
with:
|
|
20
|
+
scandir: '.'
|
|
21
|
+
severity: warning
|
|
22
|
+
format: gcc
|
|
23
|
+
env:
|
|
24
|
+
SHELLCHECK_OPTS: -x -s bash
|
|
25
|
+
|
|
26
|
+
syntax-check:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout code
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: Bash syntax validation
|
|
34
|
+
run: |
|
|
35
|
+
echo "Validating bash syntax for all .sh files..."
|
|
36
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
37
|
+
echo "Checking: $script"
|
|
38
|
+
bash -n "$script" || exit 1
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
permissions-check:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- name: Checkout code
|
|
46
|
+
uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- name: Check script permissions
|
|
49
|
+
run: |
|
|
50
|
+
echo "Checking that shell scripts are executable..."
|
|
51
|
+
non_executable=$(find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" ! -perm -u+x)
|
|
52
|
+
if [ -n "$non_executable" ]; then
|
|
53
|
+
echo "⚠️ Warning: The following scripts are not executable:"
|
|
54
|
+
echo "$non_executable"
|
|
55
|
+
echo ""
|
|
56
|
+
echo "To fix, run: chmod +x <script-name>"
|
|
57
|
+
else
|
|
58
|
+
echo "✅ All shell scripts are executable"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
bats-tests:
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
if: hashFiles('**/*.bats') != ''
|
|
64
|
+
|
|
65
|
+
steps:
|
|
66
|
+
- name: Checkout code
|
|
67
|
+
uses: actions/checkout@v4
|
|
68
|
+
|
|
69
|
+
- name: Setup BATS
|
|
70
|
+
run: |
|
|
71
|
+
sudo apt-get update
|
|
72
|
+
sudo apt-get install -y bats
|
|
73
|
+
|
|
74
|
+
- name: Run BATS tests
|
|
75
|
+
run: |
|
|
76
|
+
if [ -d "tests" ] && [ -n "$(find tests -name '*.bats' 2>/dev/null)" ]; then
|
|
77
|
+
bats tests/*.bats
|
|
78
|
+
elif [ -n "$(find . -maxdepth 1 -name '*.bats' 2>/dev/null)" ]; then
|
|
79
|
+
bats *.bats
|
|
80
|
+
else
|
|
81
|
+
echo "No BATS test files found"
|
|
82
|
+
fi
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
name: Shell Script Quality Checks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
documentation:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Check README exists
|
|
18
|
+
run: |
|
|
19
|
+
if [ ! -f "README.md" ]; then
|
|
20
|
+
echo "❌ README.md is missing"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
echo "✅ README.md exists"
|
|
24
|
+
|
|
25
|
+
- name: Validate README content
|
|
26
|
+
run: |
|
|
27
|
+
readme_lines=$(wc -l < README.md)
|
|
28
|
+
if [ "$readme_lines" -lt 10 ]; then
|
|
29
|
+
echo "⚠️ README.md is very short (< 10 lines)"
|
|
30
|
+
echo " Consider adding: description, usage examples, installation"
|
|
31
|
+
else
|
|
32
|
+
echo "✅ README.md has adequate content ($readme_lines lines)"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
- name: Check for usage documentation
|
|
36
|
+
run: |
|
|
37
|
+
if grep -q -i "usage\|example\|how to" README.md; then
|
|
38
|
+
echo "✅ README includes usage documentation"
|
|
39
|
+
else
|
|
40
|
+
echo "⚠️ README should include usage examples"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
script-analysis:
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- name: Checkout code
|
|
48
|
+
uses: actions/checkout@v4
|
|
49
|
+
|
|
50
|
+
- name: Count shell scripts
|
|
51
|
+
id: count
|
|
52
|
+
run: |
|
|
53
|
+
script_count=$(find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | wc -l)
|
|
54
|
+
echo "count=$script_count" >> $GITHUB_OUTPUT
|
|
55
|
+
echo "Found $script_count shell script(s)"
|
|
56
|
+
|
|
57
|
+
- name: Analyze script complexity
|
|
58
|
+
if: steps.count.outputs.count > 0
|
|
59
|
+
run: |
|
|
60
|
+
echo "Analyzing shell script complexity..."
|
|
61
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
62
|
+
lines=$(wc -l < "$script")
|
|
63
|
+
functions=$(grep -c "^[[:space:]]*function\|^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*()[[:space:]]*{" "$script" || echo 0)
|
|
64
|
+
echo " $script: $lines lines, $functions functions"
|
|
65
|
+
|
|
66
|
+
if [ "$lines" -gt 500 ]; then
|
|
67
|
+
echo " ⚠️ Large script (>500 lines) - consider splitting"
|
|
68
|
+
fi
|
|
69
|
+
done
|
|
70
|
+
|
|
71
|
+
best-practices:
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
|
|
74
|
+
steps:
|
|
75
|
+
- name: Checkout code
|
|
76
|
+
uses: actions/checkout@v4
|
|
77
|
+
|
|
78
|
+
- name: Check for shebang
|
|
79
|
+
run: |
|
|
80
|
+
echo "Checking for proper shebang in shell scripts..."
|
|
81
|
+
missing_shebang=0
|
|
82
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
83
|
+
if ! head -n 1 "$script" | grep -q "^#!/"; then
|
|
84
|
+
echo "⚠️ Missing shebang: $script"
|
|
85
|
+
missing_shebang=$((missing_shebang + 1))
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
if [ "$missing_shebang" -eq 0 ]; then
|
|
90
|
+
echo "✅ All scripts have proper shebang"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
- name: Check for set -e or set -euo pipefail
|
|
94
|
+
run: |
|
|
95
|
+
echo "Checking for error handling (set -e / set -euo pipefail)..."
|
|
96
|
+
missing_set_e=0
|
|
97
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
98
|
+
if ! grep -q "set -e\|set -euo pipefail" "$script"; then
|
|
99
|
+
echo "⚠️ Missing error handling: $script"
|
|
100
|
+
echo " Recommendation: Add 'set -euo pipefail' after shebang"
|
|
101
|
+
missing_set_e=$((missing_set_e + 1))
|
|
102
|
+
fi
|
|
103
|
+
done
|
|
104
|
+
|
|
105
|
+
if [ "$missing_set_e" -eq 0 ]; then
|
|
106
|
+
echo "✅ All scripts use error handling"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
security:
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
|
|
112
|
+
steps:
|
|
113
|
+
- name: Checkout code
|
|
114
|
+
uses: actions/checkout@v4
|
|
115
|
+
|
|
116
|
+
- name: Check for hardcoded secrets
|
|
117
|
+
run: |
|
|
118
|
+
echo "Scanning for potential hardcoded secrets..."
|
|
119
|
+
found_issues=0
|
|
120
|
+
|
|
121
|
+
# Check for common secret patterns
|
|
122
|
+
if grep -r -i "password\s*=\|api_key\s*=\|secret\s*=" --include="*.sh" .; then
|
|
123
|
+
echo "⚠️ Found potential hardcoded secrets"
|
|
124
|
+
echo " Use environment variables instead: \${VARIABLE_NAME}"
|
|
125
|
+
found_issues=1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Check for AWS keys
|
|
129
|
+
if grep -r "AKIA[0-9A-Z]{16}" --include="*.sh" .; then
|
|
130
|
+
echo "❌ Found AWS access key pattern"
|
|
131
|
+
found_issues=1
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
if [ "$found_issues" -eq 0 ]; then
|
|
135
|
+
echo "✅ No obvious hardcoded secrets found"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
- name: Check for unsafe practices
|
|
139
|
+
run: |
|
|
140
|
+
echo "Checking for unsafe shell practices..."
|
|
141
|
+
|
|
142
|
+
# Check for eval usage
|
|
143
|
+
if grep -r "eval " --include="*.sh" . | grep -v "^#"; then
|
|
144
|
+
echo "⚠️ Found 'eval' usage - potential security risk"
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Check for unquoted variables
|
|
148
|
+
echo " (ShellCheck will provide detailed analysis)"
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# QA Architect
|
|
2
2
|
|
|
3
|
-
Quality automation CLI for JavaScript/TypeScript and
|
|
3
|
+
Quality automation CLI for JavaScript/TypeScript, Python, and shell script projects. One command adds ESLint, Prettier, Husky, lint-staged, and GitHub Actions. Pro tiers add security scanning (Gitleaks), Smart Test Strategy, and multi-language support.
|
|
4
4
|
|
|
5
5
|
**This repo = the free CLI.** For the Pro dashboard with repo analytics, CI integration, and automation workflows, see [QA Architect Pro](https://vibebuildlab.com/qa-architect) (included in VBL Starter Kit).
|
|
6
6
|
|
|
@@ -21,6 +21,7 @@ Quality automation CLI for JavaScript/TypeScript and Python projects. One comman
|
|
|
21
21
|
- **GitHub Actions** - Automated quality checks in CI/CD
|
|
22
22
|
- **TypeScript Smart** - Auto-detects and configures TypeScript projects
|
|
23
23
|
- **Python Support** - Complete Python toolchain with Black, Ruff, isort, mypy, pytest
|
|
24
|
+
- **Shell Script Support** - ShellCheck linting, syntax validation, permissions checks, best practices
|
|
24
25
|
- **Security Automation** - npm audit (Free), Gitleaks + ESLint security (Pro)
|
|
25
26
|
- **Progressive Quality** - Adaptive checks based on project maturity
|
|
26
27
|
- **Smart Test Strategy** - Risk-based pre-push validation (Pro feature)
|
|
@@ -95,22 +96,93 @@ npx create-qa-architect@latest
|
|
|
95
96
|
| Documentation check | ✅ | ✅ |
|
|
96
97
|
| Env vars audit | ❌ | ✅ |
|
|
97
98
|
|
|
99
|
+
### CI/CD Optimization by Tier
|
|
100
|
+
|
|
101
|
+
| Feature | Free | Pro+ |
|
|
102
|
+
| ---------------------------- | ---- | ---- |
|
|
103
|
+
| GitHub Actions cost analyzer | ❌ | ✅ |
|
|
104
|
+
|
|
105
|
+
## Workflow Tiers (GitHub Actions Cost Optimization)
|
|
106
|
+
|
|
107
|
+
qa-architect now defaults to **minimal CI** to avoid unexpected GitHub Actions bills. Choose the tier that matches your needs:
|
|
108
|
+
|
|
109
|
+
### Minimal (Default) - $0-5/month
|
|
110
|
+
|
|
111
|
+
**Best for:** Solo developers, side projects, open source
|
|
112
|
+
|
|
113
|
+
- Single Node version (22) testing
|
|
114
|
+
- Security scans run weekly (not on every commit)
|
|
115
|
+
- Path filters skip CI for docs/README changes
|
|
116
|
+
- **Runtime:** ~5-10 min/commit
|
|
117
|
+
- **Est. cost:** ~$0-5/mo for typical projects (2-5 commits/day)
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx create-qa-architect@latest
|
|
121
|
+
# or explicitly:
|
|
122
|
+
npx create-qa-architect@latest --workflow-minimal
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Standard - $5-20/month
|
|
126
|
+
|
|
127
|
+
**Best for:** Small teams, client projects, production apps
|
|
128
|
+
|
|
129
|
+
- Matrix testing (Node 20 + 22) **only on main branch**
|
|
130
|
+
- Security scans run weekly
|
|
131
|
+
- Path filters enabled
|
|
132
|
+
- **Runtime:** ~15-20 min/commit
|
|
133
|
+
- **Est. cost:** ~$5-20/mo for typical projects
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx create-qa-architect@latest --workflow-standard
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Comprehensive - $100-350/month
|
|
140
|
+
|
|
141
|
+
**Best for:** Enterprise teams, high-compliance projects, large teams
|
|
142
|
+
|
|
143
|
+
- Matrix testing (Node 20 + 22) on **every commit**
|
|
144
|
+
- Security scans inline (every commit)
|
|
145
|
+
- No path filters (runs on all changes)
|
|
146
|
+
- **Runtime:** ~50-100 min/commit
|
|
147
|
+
- **Est. cost:** ~$100-350/mo for typical projects
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx create-qa-architect@latest --workflow-comprehensive
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Switching Between Tiers
|
|
154
|
+
|
|
155
|
+
Already using qa-architect? Convert to minimal to reduce costs:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
npx create-qa-architect@latest --update --workflow-minimal
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Analyzing Your Costs (Pro Feature)
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npx create-qa-architect@latest --analyze-ci
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Shows estimated GitHub Actions usage and provides optimization recommendations.
|
|
168
|
+
|
|
98
169
|
### License
|
|
99
170
|
|
|
100
171
|
**Commercial License (freemium)** — free tier covers the basic CLI; Pro/Team/Enterprise features require a paid subscription. See [LICENSE](LICENSE).
|
|
101
172
|
|
|
102
173
|
## Tech Stack
|
|
103
174
|
|
|
104
|
-
| Component
|
|
105
|
-
|
|
|
106
|
-
| **Runtime**
|
|
107
|
-
| **Linting**
|
|
108
|
-
| **Formatting**
|
|
109
|
-
| **CSS Linting**
|
|
110
|
-
| **Git Hooks**
|
|
111
|
-
| **Python**
|
|
112
|
-
| **
|
|
113
|
-
| **
|
|
175
|
+
| Component | Technology |
|
|
176
|
+
| ----------------- | -------------------------------------------------- |
|
|
177
|
+
| **Runtime** | Node.js 20+ |
|
|
178
|
+
| **Linting** | ESLint 9 (flat config) |
|
|
179
|
+
| **Formatting** | Prettier 3 |
|
|
180
|
+
| **CSS Linting** | Stylelint 16 |
|
|
181
|
+
| **Git Hooks** | Husky 9 + lint-staged 15 |
|
|
182
|
+
| **Python** | Black, Ruff, mypy, pytest |
|
|
183
|
+
| **Shell Scripts** | ShellCheck, syntax validation, permissions checks |
|
|
184
|
+
| **Performance** | Lighthouse CI |
|
|
185
|
+
| **Security** | npm audit (Free), Gitleaks + ESLint security (Pro) |
|
|
114
186
|
|
|
115
187
|
## Getting Started
|
|
116
188
|
|
|
@@ -155,7 +227,7 @@ npx create-qa-architect@latest --deps
|
|
|
155
227
|
```bash
|
|
156
228
|
npx create-qa-architect@latest --prelaunch
|
|
157
229
|
npm install
|
|
158
|
-
npm run validate:
|
|
230
|
+
npm run validate:all
|
|
159
231
|
```
|
|
160
232
|
|
|
161
233
|
## Usage Examples
|
|
@@ -193,6 +265,42 @@ npx create-qa-architect@latest --validate-docs
|
|
|
193
265
|
npx create-qa-architect@latest --comprehensive
|
|
194
266
|
```
|
|
195
267
|
|
|
268
|
+
### GitHub Actions Cost Analysis (Pro)
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# Analyze GitHub Actions usage and costs
|
|
272
|
+
npx create-qa-architect@latest --analyze-ci
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Output:**
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
📊 GitHub Actions Usage Analysis
|
|
279
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
280
|
+
Repository: my-project
|
|
281
|
+
|
|
282
|
+
Estimated usage: 4,800 min/month
|
|
283
|
+
Commit frequency: ~2.0 commits/day
|
|
284
|
+
Workflows detected: 2
|
|
285
|
+
|
|
286
|
+
Workflow breakdown:
|
|
287
|
+
├─ ci.yml:
|
|
288
|
+
• ~50 min/run
|
|
289
|
+
• ~60 runs/month = 3000 min/month
|
|
290
|
+
├─ test.yml:
|
|
291
|
+
• ~30 min/run
|
|
292
|
+
• ~60 runs/month = 1800 min/month
|
|
293
|
+
|
|
294
|
+
💰 Cost Analysis
|
|
295
|
+
Free tier (2,000 min): ⚠️ EXCEEDED by 2,800 min
|
|
296
|
+
Overage cost: $22.40/month
|
|
297
|
+
|
|
298
|
+
Alternative options:
|
|
299
|
+
Team plan ($4/user/month): Still exceeds (1,800 min overage)
|
|
300
|
+
Total cost: $18.40/month
|
|
301
|
+
Self-hosted runners: $0/min (but VPS costs ~$5-20/month)
|
|
302
|
+
```
|
|
303
|
+
|
|
196
304
|
### Custom Templates
|
|
197
305
|
|
|
198
306
|
```bash
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: Shell Script CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
shellcheck:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Run ShellCheck
|
|
18
|
+
uses: ludeeus/action-shellcheck@master
|
|
19
|
+
with:
|
|
20
|
+
scandir: '.'
|
|
21
|
+
severity: warning
|
|
22
|
+
format: gcc
|
|
23
|
+
env:
|
|
24
|
+
SHELLCHECK_OPTS: -x -s bash
|
|
25
|
+
|
|
26
|
+
syntax-check:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout code
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: Bash syntax validation
|
|
34
|
+
run: |
|
|
35
|
+
echo "Validating bash syntax for all .sh files..."
|
|
36
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
37
|
+
echo "Checking: $script"
|
|
38
|
+
bash -n "$script" || exit 1
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
permissions-check:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- name: Checkout code
|
|
46
|
+
uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- name: Check script permissions
|
|
49
|
+
run: |
|
|
50
|
+
echo "Checking that shell scripts are executable..."
|
|
51
|
+
non_executable=$(find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" ! -perm -u+x)
|
|
52
|
+
if [ -n "$non_executable" ]; then
|
|
53
|
+
echo "⚠️ Warning: The following scripts are not executable:"
|
|
54
|
+
echo "$non_executable"
|
|
55
|
+
echo ""
|
|
56
|
+
echo "To fix, run: chmod +x <script-name>"
|
|
57
|
+
else
|
|
58
|
+
echo "✅ All shell scripts are executable"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
bats-tests:
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
if: hashFiles('**/*.bats') != ''
|
|
64
|
+
|
|
65
|
+
steps:
|
|
66
|
+
- name: Checkout code
|
|
67
|
+
uses: actions/checkout@v4
|
|
68
|
+
|
|
69
|
+
- name: Setup BATS
|
|
70
|
+
run: |
|
|
71
|
+
sudo apt-get update
|
|
72
|
+
sudo apt-get install -y bats
|
|
73
|
+
|
|
74
|
+
- name: Run BATS tests
|
|
75
|
+
run: |
|
|
76
|
+
if [ -d "tests" ] && [ -n "$(find tests -name '*.bats' 2>/dev/null)" ]; then
|
|
77
|
+
bats tests/*.bats
|
|
78
|
+
elif [ -n "$(find . -maxdepth 1 -name '*.bats' 2>/dev/null)" ]; then
|
|
79
|
+
bats *.bats
|
|
80
|
+
else
|
|
81
|
+
echo "No BATS test files found"
|
|
82
|
+
fi
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
name: Shell Script Quality Checks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
documentation:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Check README exists
|
|
18
|
+
run: |
|
|
19
|
+
if [ ! -f "README.md" ]; then
|
|
20
|
+
echo "❌ README.md is missing"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
echo "✅ README.md exists"
|
|
24
|
+
|
|
25
|
+
- name: Validate README content
|
|
26
|
+
run: |
|
|
27
|
+
readme_lines=$(wc -l < README.md)
|
|
28
|
+
if [ "$readme_lines" -lt 10 ]; then
|
|
29
|
+
echo "⚠️ README.md is very short (< 10 lines)"
|
|
30
|
+
echo " Consider adding: description, usage examples, installation"
|
|
31
|
+
else
|
|
32
|
+
echo "✅ README.md has adequate content ($readme_lines lines)"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
- name: Check for usage documentation
|
|
36
|
+
run: |
|
|
37
|
+
if grep -q -i "usage\|example\|how to" README.md; then
|
|
38
|
+
echo "✅ README includes usage documentation"
|
|
39
|
+
else
|
|
40
|
+
echo "⚠️ README should include usage examples"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
script-analysis:
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- name: Checkout code
|
|
48
|
+
uses: actions/checkout@v4
|
|
49
|
+
|
|
50
|
+
- name: Count shell scripts
|
|
51
|
+
id: count
|
|
52
|
+
run: |
|
|
53
|
+
script_count=$(find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | wc -l)
|
|
54
|
+
echo "count=$script_count" >> $GITHUB_OUTPUT
|
|
55
|
+
echo "Found $script_count shell script(s)"
|
|
56
|
+
|
|
57
|
+
- name: Analyze script complexity
|
|
58
|
+
if: steps.count.outputs.count > 0
|
|
59
|
+
run: |
|
|
60
|
+
echo "Analyzing shell script complexity..."
|
|
61
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
62
|
+
lines=$(wc -l < "$script")
|
|
63
|
+
functions=$(grep -c "^[[:space:]]*function\|^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*()[[:space:]]*{" "$script" || echo 0)
|
|
64
|
+
echo " $script: $lines lines, $functions functions"
|
|
65
|
+
|
|
66
|
+
if [ "$lines" -gt 500 ]; then
|
|
67
|
+
echo " ⚠️ Large script (>500 lines) - consider splitting"
|
|
68
|
+
fi
|
|
69
|
+
done
|
|
70
|
+
|
|
71
|
+
best-practices:
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
|
|
74
|
+
steps:
|
|
75
|
+
- name: Checkout code
|
|
76
|
+
uses: actions/checkout@v4
|
|
77
|
+
|
|
78
|
+
- name: Check for shebang
|
|
79
|
+
run: |
|
|
80
|
+
echo "Checking for proper shebang in shell scripts..."
|
|
81
|
+
missing_shebang=0
|
|
82
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
83
|
+
if ! head -n 1 "$script" | grep -q "^#!/"; then
|
|
84
|
+
echo "⚠️ Missing shebang: $script"
|
|
85
|
+
missing_shebang=$((missing_shebang + 1))
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
if [ "$missing_shebang" -eq 0 ]; then
|
|
90
|
+
echo "✅ All scripts have proper shebang"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
- name: Check for set -e or set -euo pipefail
|
|
94
|
+
run: |
|
|
95
|
+
echo "Checking for error handling (set -e / set -euo pipefail)..."
|
|
96
|
+
missing_set_e=0
|
|
97
|
+
find . -type f -name "*.sh" ! -path "*/node_modules/*" ! -path "*/.git/*" | while read -r script; do
|
|
98
|
+
if ! grep -q "set -e\|set -euo pipefail" "$script"; then
|
|
99
|
+
echo "⚠️ Missing error handling: $script"
|
|
100
|
+
echo " Recommendation: Add 'set -euo pipefail' after shebang"
|
|
101
|
+
missing_set_e=$((missing_set_e + 1))
|
|
102
|
+
fi
|
|
103
|
+
done
|
|
104
|
+
|
|
105
|
+
if [ "$missing_set_e" -eq 0 ]; then
|
|
106
|
+
echo "✅ All scripts use error handling"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
security:
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
|
|
112
|
+
steps:
|
|
113
|
+
- name: Checkout code
|
|
114
|
+
uses: actions/checkout@v4
|
|
115
|
+
|
|
116
|
+
- name: Check for hardcoded secrets
|
|
117
|
+
run: |
|
|
118
|
+
echo "Scanning for potential hardcoded secrets..."
|
|
119
|
+
found_issues=0
|
|
120
|
+
|
|
121
|
+
# Check for common secret patterns
|
|
122
|
+
if grep -r -i "password\s*=\|api_key\s*=\|secret\s*=" --include="*.sh" .; then
|
|
123
|
+
echo "⚠️ Found potential hardcoded secrets"
|
|
124
|
+
echo " Use environment variables instead: \${VARIABLE_NAME}"
|
|
125
|
+
found_issues=1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Check for AWS keys
|
|
129
|
+
if grep -r "AKIA[0-9A-Z]{16}" --include="*.sh" .; then
|
|
130
|
+
echo "❌ Found AWS access key pattern"
|
|
131
|
+
found_issues=1
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
if [ "$found_issues" -eq 0 ]; then
|
|
135
|
+
echo "✅ No obvious hardcoded secrets found"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
- name: Check for unsafe practices
|
|
139
|
+
run: |
|
|
140
|
+
echo "Checking for unsafe shell practices..."
|
|
141
|
+
|
|
142
|
+
# Check for eval usage
|
|
143
|
+
if grep -r "eval " --include="*.sh" . | grep -v "^#"; then
|
|
144
|
+
echo "⚠️ Found 'eval' usage - potential security risk"
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Check for unquoted variables
|
|
148
|
+
echo " (ShellCheck will provide detailed analysis)"
|