create-qa-architect 5.0.1 → 5.0.7
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/RELEASE_CHECKLIST.md +2 -4
- package/.github/workflows/daily-deploy-check.yml +136 -0
- package/.github/workflows/dependabot-auto-merge.yml +32 -0
- package/.github/workflows/nightly-gitleaks-verification.yml +1 -1
- package/.github/workflows/release.yml +12 -10
- package/.github/workflows/weekly-audit.yml +173 -0
- package/LICENSE +3 -3
- package/README.md +11 -17
- package/config/defaults.js +22 -1
- package/config/quality-config.schema.json +1 -1
- package/create-saas-monetization.js +65 -27
- package/docs/ARCHITECTURE.md +16 -13
- package/docs/DEPLOYMENT.md +1 -2
- package/docs/PREFLIGHT_REPORT.md +100 -0
- package/docs/TESTING.md +4 -6
- package/lib/billing-dashboard.html +6 -12
- package/lib/config-validator.js +8 -2
- package/lib/dependency-monitoring-premium.js +21 -19
- package/lib/github-api.js +249 -0
- package/lib/interactive/questions.js +4 -0
- package/lib/license-validator.js +1 -1
- package/lib/licensing.js +16 -18
- package/lib/package-utils.js +9 -8
- package/lib/project-maturity.js +1 -1
- package/lib/template-loader.js +2 -0
- package/lib/ui-helpers.js +2 -1
- package/lib/validation/base-validator.js +5 -1
- package/lib/validation/cache-manager.js +1 -0
- package/lib/validation/config-security.js +9 -4
- package/lib/validation/validation-factory.js +1 -1
- package/lib/validation/workflow-validation.js +27 -22
- package/lib/yaml-utils.js +15 -10
- package/package.json +17 -14
- package/scripts/check-docs.sh +63 -0
- package/scripts/smart-test-strategy.sh +98 -0
- package/scripts/test-e2e-package.sh +283 -0
- package/scripts/validate-command-patterns.js +112 -0
- package/setup.js +38 -9
- package/templates/QUALITY_TROUBLESHOOTING.md +32 -33
- package/templates/scripts/smart-test-strategy.sh +1 -1
|
@@ -27,14 +27,12 @@ Use this checklist before any version bump or npm publication.
|
|
|
27
27
|
|
|
28
28
|
### Security Audit Compliance
|
|
29
29
|
|
|
30
|
-
- [ ] `
|
|
30
|
+
- [ ] `npm audit` shows no high/critical vulnerabilities
|
|
31
|
+
- [ ] `gitleaks detect --source . --redact` passes (no secrets)
|
|
31
32
|
- [ ] **CRITICAL**: Gitleaks checksums are real SHA256 values, not placeholders
|
|
32
33
|
- [ ] `lib/validation/config-security.js` GITLEAKS_CHECKSUMS contains verified hashes
|
|
33
34
|
- [ ] No "PLACEHOLDER_CHECKSUM" strings exist in security validation code
|
|
34
35
|
- [ ] Gitleaks pinned version in code matches documented security version
|
|
35
|
-
- [ ] No new security vulnerabilities introduced since audit
|
|
36
|
-
- [ ] All security fixes from audit still in place
|
|
37
|
-
- [ ] Security audit document references current version (or base version for pre-releases like `4.0.1-rc.1`)
|
|
38
36
|
|
|
39
37
|
### Real Binary Verification
|
|
40
38
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Daily Deploy Check Workflow
|
|
2
|
+
# Copy this to .github/workflows/daily-deploy-check.yml in each project
|
|
3
|
+
#
|
|
4
|
+
# Required secrets:
|
|
5
|
+
# AUDIT_WEBHOOK_SECRET - shared secret for authenticating with vibebuildlab API
|
|
6
|
+
#
|
|
7
|
+
# Required variables (set in repo settings):
|
|
8
|
+
# PRODUCTION_URL - the production URL to check (e.g., https://saas.vibebuildlab.com)
|
|
9
|
+
#
|
|
10
|
+
# This workflow:
|
|
11
|
+
# 1. Runs daily at 6am UTC
|
|
12
|
+
# 2. Checks if production URL responds and SSL is valid
|
|
13
|
+
# 3. Reports deploy stage status to vibebuildlab dashboard
|
|
14
|
+
|
|
15
|
+
name: Daily Deploy Check
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
schedule:
|
|
19
|
+
# Every day at 6am UTC
|
|
20
|
+
- cron: '0 6 * * *'
|
|
21
|
+
workflow_dispatch: # Manual trigger
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
VIBEBUILDLAB_API: https://dash.vibebuildlab.com/api/audit-results
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
deploy-check:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
timeout-minutes: 5
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- name: Check URL responds
|
|
33
|
+
id: url_check
|
|
34
|
+
run: |
|
|
35
|
+
URL="${{ vars.PRODUCTION_URL }}"
|
|
36
|
+
|
|
37
|
+
if [ -z "$URL" ]; then
|
|
38
|
+
echo "::error::PRODUCTION_URL variable not set"
|
|
39
|
+
echo "responds=false" >> $GITHUB_OUTPUT
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$URL" --max-time 30 || echo "000")
|
|
44
|
+
|
|
45
|
+
echo "status_code=$STATUS" >> $GITHUB_OUTPUT
|
|
46
|
+
|
|
47
|
+
if [ "$STATUS" = "200" ] || [ "$STATUS" = "301" ] || [ "$STATUS" = "302" ]; then
|
|
48
|
+
echo "responds=true" >> $GITHUB_OUTPUT
|
|
49
|
+
else
|
|
50
|
+
echo "responds=false" >> $GITHUB_OUTPUT
|
|
51
|
+
fi
|
|
52
|
+
continue-on-error: true
|
|
53
|
+
|
|
54
|
+
- name: Check SSL certificate
|
|
55
|
+
id: ssl_check
|
|
56
|
+
run: |
|
|
57
|
+
URL="${{ vars.PRODUCTION_URL }}"
|
|
58
|
+
|
|
59
|
+
if [ -z "$URL" ]; then
|
|
60
|
+
echo "valid=false" >> $GITHUB_OUTPUT
|
|
61
|
+
exit 0
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Extract domain from URL
|
|
65
|
+
DOMAIN=$(echo "$URL" | sed -E 's|https?://([^/]+).*|\1|')
|
|
66
|
+
|
|
67
|
+
# Check SSL expiry
|
|
68
|
+
EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2 || echo "")
|
|
69
|
+
|
|
70
|
+
if [ -n "$EXPIRY" ]; then
|
|
71
|
+
echo "valid=true" >> $GITHUB_OUTPUT
|
|
72
|
+
echo "expiry=$EXPIRY" >> $GITHUB_OUTPUT
|
|
73
|
+
|
|
74
|
+
# Check if expiring within 7 days
|
|
75
|
+
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || date -j -f "%b %d %H:%M:%S %Y %Z" "$EXPIRY" +%s 2>/dev/null || echo "0")
|
|
76
|
+
NOW_EPOCH=$(date +%s)
|
|
77
|
+
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
|
|
78
|
+
|
|
79
|
+
echo "days_left=$DAYS_LEFT" >> $GITHUB_OUTPUT
|
|
80
|
+
|
|
81
|
+
if [ "$DAYS_LEFT" -lt 7 ]; then
|
|
82
|
+
echo "::warning::SSL certificate expires in $DAYS_LEFT days!"
|
|
83
|
+
fi
|
|
84
|
+
else
|
|
85
|
+
echo "valid=false" >> $GITHUB_OUTPUT
|
|
86
|
+
fi
|
|
87
|
+
continue-on-error: true
|
|
88
|
+
|
|
89
|
+
- name: Determine deploy status
|
|
90
|
+
id: result
|
|
91
|
+
run: |
|
|
92
|
+
if [ "${{ steps.url_check.outputs.responds }}" = "true" ]; then
|
|
93
|
+
echo "deploy=pass" >> $GITHUB_OUTPUT
|
|
94
|
+
else
|
|
95
|
+
echo "deploy=fail" >> $GITHUB_OUTPUT
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
- name: Report to vibebuildlab
|
|
99
|
+
if: always()
|
|
100
|
+
run: |
|
|
101
|
+
# Get project slug from repo name
|
|
102
|
+
PROJECT_SLUG="${{ github.event.repository.name }}"
|
|
103
|
+
|
|
104
|
+
curl -X POST "$VIBEBUILDLAB_API" \
|
|
105
|
+
-H "Content-Type: application/json" \
|
|
106
|
+
-H "Authorization: Bearer ${{ secrets.AUDIT_WEBHOOK_SECRET }}" \
|
|
107
|
+
-d "{
|
|
108
|
+
\"project\": \"${PROJECT_SLUG}\",
|
|
109
|
+
\"stages\": {
|
|
110
|
+
\"deploy\": \"${{ steps.result.outputs.deploy }}\"
|
|
111
|
+
},
|
|
112
|
+
\"details\": {
|
|
113
|
+
\"url_responds\": ${{ steps.url_check.outputs.responds }},
|
|
114
|
+
\"ssl_valid\": ${{ steps.ssl_check.outputs.valid || false }},
|
|
115
|
+
\"status_code\": ${{ steps.url_check.outputs.status_code || 0 }}
|
|
116
|
+
},
|
|
117
|
+
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
|
|
118
|
+
}"
|
|
119
|
+
continue-on-error: true
|
|
120
|
+
|
|
121
|
+
- name: Summary
|
|
122
|
+
if: always()
|
|
123
|
+
run: |
|
|
124
|
+
echo "## Deploy Check Results" >> $GITHUB_STEP_SUMMARY
|
|
125
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
126
|
+
echo "**URL:** ${{ vars.PRODUCTION_URL }}" >> $GITHUB_STEP_SUMMARY
|
|
127
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
128
|
+
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
|
|
129
|
+
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
|
|
130
|
+
echo "| URL Responds | ${{ steps.url_check.outputs.responds == 'true' && '✅' || '❌' }} (HTTP ${{ steps.url_check.outputs.status_code }}) |" >> $GITHUB_STEP_SUMMARY
|
|
131
|
+
echo "| SSL Valid | ${{ steps.ssl_check.outputs.valid == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
132
|
+
if [ -n "${{ steps.ssl_check.outputs.expiry }}" ]; then
|
|
133
|
+
echo "| SSL Expiry | ${{ steps.ssl_check.outputs.expiry }} (${{ steps.ssl_check.outputs.days_left }} days) |" >> $GITHUB_STEP_SUMMARY
|
|
134
|
+
fi
|
|
135
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
136
|
+
echo "**Deploy Stage:** ${{ steps.result.outputs.deploy }}" >> $GITHUB_STEP_SUMMARY
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Dependabot Auto-Merge
|
|
2
|
+
|
|
3
|
+
on: pull_request
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: write
|
|
7
|
+
pull-requests: write
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
dependabot:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
if: github.actor == 'dependabot[bot]'
|
|
13
|
+
steps:
|
|
14
|
+
- name: Dependabot metadata
|
|
15
|
+
id: metadata
|
|
16
|
+
uses: dependabot/fetch-metadata@v2
|
|
17
|
+
with:
|
|
18
|
+
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
|
19
|
+
|
|
20
|
+
- name: Enable auto-merge for patch and minor updates
|
|
21
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor'
|
|
22
|
+
run: gh pr merge --auto --squash "$PR_URL"
|
|
23
|
+
env:
|
|
24
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
25
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
+
|
|
27
|
+
- name: Approve PR
|
|
28
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor'
|
|
29
|
+
run: gh pr review --approve "$PR_URL"
|
|
30
|
+
env:
|
|
31
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
32
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
run: |
|
|
43
43
|
echo "🔐 Running REAL gitleaks download and verification test..."
|
|
44
44
|
echo "Platform: $(uname -s)-$(uname -m)"
|
|
45
|
-
echo "Expected checksum:
|
|
45
|
+
echo "Expected checksum: 5fd1b3b0073269484d40078662e921d07427340ab9e6ed526ccd215a565b3298"
|
|
46
46
|
|
|
47
47
|
# Create a test script that downloads and verifies gitleaks
|
|
48
48
|
cat > test-real-download.js << 'EOF'
|
|
@@ -4,6 +4,10 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
tags: ['v*']
|
|
6
6
|
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write # Required for OIDC trusted publishing to npm
|
|
9
|
+
contents: write # Required for creating GitHub releases
|
|
10
|
+
|
|
7
11
|
jobs:
|
|
8
12
|
release:
|
|
9
13
|
runs-on: ubuntu-latest
|
|
@@ -14,27 +18,25 @@ jobs:
|
|
|
14
18
|
- name: Setup Node.js
|
|
15
19
|
uses: actions/setup-node@v4
|
|
16
20
|
with:
|
|
17
|
-
node-version: '
|
|
21
|
+
node-version: '22'
|
|
18
22
|
registry-url: 'https://registry.npmjs.org'
|
|
19
23
|
|
|
24
|
+
- name: Upgrade npm for OIDC trusted publishing
|
|
25
|
+
run: npm install -g npm@latest
|
|
26
|
+
|
|
20
27
|
- name: Install dependencies
|
|
21
28
|
run: npm ci
|
|
22
29
|
|
|
23
30
|
- name: Run pre-release checks
|
|
24
31
|
run: npm run prerelease
|
|
25
32
|
|
|
26
|
-
- name: Publish to npm
|
|
27
|
-
run: npm publish
|
|
28
|
-
env:
|
|
29
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
33
|
+
- name: Publish to npm with provenance
|
|
34
|
+
run: npm publish --provenance
|
|
30
35
|
|
|
31
36
|
- name: Create GitHub Release
|
|
32
|
-
uses:
|
|
33
|
-
env:
|
|
34
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
37
|
+
uses: softprops/action-gh-release@v2
|
|
35
38
|
with:
|
|
36
|
-
|
|
37
|
-
release_name: Release ${{ github.ref_name }}
|
|
39
|
+
name: Release ${{ github.ref_name }}
|
|
38
40
|
body: |
|
|
39
41
|
## Changes in ${{ github.ref_name }}
|
|
40
42
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Weekly Audit Workflow
|
|
2
|
+
# Copy this to .github/workflows/weekly-audit.yml in each project
|
|
3
|
+
#
|
|
4
|
+
# Required secrets:
|
|
5
|
+
# AUDIT_WEBHOOK_SECRET - shared secret for authenticating with vibebuildlab API
|
|
6
|
+
#
|
|
7
|
+
# This workflow:
|
|
8
|
+
# 1. Runs weekly (Sunday 2am UTC) and on manual trigger
|
|
9
|
+
# 2. Checks build, tests, lint, typecheck, security
|
|
10
|
+
# 3. Reports results to vibebuildlab dashboard
|
|
11
|
+
|
|
12
|
+
name: Weekly Audit
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
schedule:
|
|
16
|
+
# Every Sunday at 2am UTC
|
|
17
|
+
- cron: '0 2 * * 0'
|
|
18
|
+
workflow_dispatch: # Manual trigger
|
|
19
|
+
|
|
20
|
+
env:
|
|
21
|
+
VIBEBUILDLAB_API: https://dash.vibebuildlab.com/api/audit-results
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
audit:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 15
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Setup Node.js
|
|
33
|
+
uses: actions/setup-node@v4
|
|
34
|
+
with:
|
|
35
|
+
node-version: '20'
|
|
36
|
+
cache: 'npm'
|
|
37
|
+
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: npm ci
|
|
40
|
+
|
|
41
|
+
- name: Run build
|
|
42
|
+
id: build
|
|
43
|
+
run: |
|
|
44
|
+
if npm run build; then
|
|
45
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
46
|
+
else
|
|
47
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
48
|
+
fi
|
|
49
|
+
continue-on-error: true
|
|
50
|
+
|
|
51
|
+
- name: Run tests
|
|
52
|
+
id: tests
|
|
53
|
+
run: |
|
|
54
|
+
# Run tests and capture output
|
|
55
|
+
TEST_OUTPUT=$(npm test 2>&1) || true
|
|
56
|
+
echo "$TEST_OUTPUT"
|
|
57
|
+
|
|
58
|
+
# Parse results
|
|
59
|
+
PASSED=$(echo "$TEST_OUTPUT" | grep -oE '[0-9]+ passed' | tail -1 | awk '{print $1}' || echo "0")
|
|
60
|
+
FAILED=$(echo "$TEST_OUTPUT" | grep -oE '[0-9]+ failed' | tail -1 | awk '{print $1}' || echo "0")
|
|
61
|
+
|
|
62
|
+
echo "passed=${PASSED:-0}" >> $GITHUB_OUTPUT
|
|
63
|
+
echo "failed=${FAILED:-0}" >> $GITHUB_OUTPUT
|
|
64
|
+
|
|
65
|
+
if [ "${FAILED:-0}" = "0" ] && [ "${PASSED:-0}" != "0" ]; then
|
|
66
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
67
|
+
else
|
|
68
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
69
|
+
fi
|
|
70
|
+
continue-on-error: true
|
|
71
|
+
|
|
72
|
+
- name: Run lint
|
|
73
|
+
id: lint
|
|
74
|
+
run: |
|
|
75
|
+
LINT_OUTPUT=$(npm run lint 2>&1) || true
|
|
76
|
+
ERRORS=$(echo "$LINT_OUTPUT" | grep -cE '^\s+[0-9]+:[0-9]+\s+error' || echo "0")
|
|
77
|
+
echo "errors=${ERRORS:-0}" >> $GITHUB_OUTPUT
|
|
78
|
+
|
|
79
|
+
if [ "${ERRORS:-0}" = "0" ]; then
|
|
80
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
81
|
+
else
|
|
82
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
83
|
+
fi
|
|
84
|
+
continue-on-error: true
|
|
85
|
+
|
|
86
|
+
- name: Run typecheck
|
|
87
|
+
id: typecheck
|
|
88
|
+
run: |
|
|
89
|
+
if npm run typecheck 2>/dev/null || npx tsc --noEmit 2>/dev/null; then
|
|
90
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
91
|
+
echo "errors=0" >> $GITHUB_OUTPUT
|
|
92
|
+
else
|
|
93
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
94
|
+
echo "errors=1" >> $GITHUB_OUTPUT
|
|
95
|
+
fi
|
|
96
|
+
continue-on-error: true
|
|
97
|
+
|
|
98
|
+
- name: Security audit
|
|
99
|
+
id: security
|
|
100
|
+
run: |
|
|
101
|
+
AUDIT_OUTPUT=$(npm audit 2>&1) || true
|
|
102
|
+
|
|
103
|
+
if echo "$AUDIT_OUTPUT" | grep -qiE '[0-9]+ (high|critical)'; then
|
|
104
|
+
echo "vulnerabilities=1" >> $GITHUB_OUTPUT
|
|
105
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
106
|
+
else
|
|
107
|
+
echo "vulnerabilities=0" >> $GITHUB_OUTPUT
|
|
108
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
109
|
+
fi
|
|
110
|
+
continue-on-error: true
|
|
111
|
+
|
|
112
|
+
- name: Determine audit result
|
|
113
|
+
id: result
|
|
114
|
+
run: |
|
|
115
|
+
# execute stage: build must pass
|
|
116
|
+
if [ "${{ steps.build.outputs.success }}" = "true" ]; then
|
|
117
|
+
echo "execute=pass" >> $GITHUB_OUTPUT
|
|
118
|
+
else
|
|
119
|
+
echo "execute=fail" >> $GITHUB_OUTPUT
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# audit stage: tests + lint + typecheck + security
|
|
123
|
+
if [ "${{ steps.tests.outputs.success }}" = "true" ] && \
|
|
124
|
+
[ "${{ steps.lint.outputs.success }}" = "true" ] && \
|
|
125
|
+
[ "${{ steps.typecheck.outputs.success }}" = "true" ] && \
|
|
126
|
+
[ "${{ steps.security.outputs.success }}" = "true" ]; then
|
|
127
|
+
echo "audit=pass" >> $GITHUB_OUTPUT
|
|
128
|
+
else
|
|
129
|
+
echo "audit=fail" >> $GITHUB_OUTPUT
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
- name: Report to vibebuildlab
|
|
133
|
+
if: always()
|
|
134
|
+
run: |
|
|
135
|
+
# Get project slug from package.json name or repo name
|
|
136
|
+
PROJECT_SLUG=$(node -e "console.log(require('./package.json').name)" 2>/dev/null || echo "${{ github.event.repository.name }}")
|
|
137
|
+
|
|
138
|
+
curl -X POST "$VIBEBUILDLAB_API" \
|
|
139
|
+
-H "Content-Type: application/json" \
|
|
140
|
+
-H "Authorization: Bearer ${{ secrets.AUDIT_WEBHOOK_SECRET }}" \
|
|
141
|
+
-d "{
|
|
142
|
+
\"project\": \"${PROJECT_SLUG}\",
|
|
143
|
+
\"stages\": {
|
|
144
|
+
\"execute\": \"${{ steps.result.outputs.execute }}\",
|
|
145
|
+
\"audit\": \"${{ steps.result.outputs.audit }}\"
|
|
146
|
+
},
|
|
147
|
+
\"details\": {
|
|
148
|
+
\"tests_passed\": ${{ steps.tests.outputs.passed || 0 }},
|
|
149
|
+
\"tests_failed\": ${{ steps.tests.outputs.failed || 0 }},
|
|
150
|
+
\"lint_errors\": ${{ steps.lint.outputs.errors || 0 }},
|
|
151
|
+
\"type_errors\": ${{ steps.typecheck.outputs.errors || 0 }},
|
|
152
|
+
\"vulnerabilities\": ${{ steps.security.outputs.vulnerabilities || 0 }},
|
|
153
|
+
\"build_success\": ${{ steps.build.outputs.success }}
|
|
154
|
+
},
|
|
155
|
+
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
|
|
156
|
+
}"
|
|
157
|
+
continue-on-error: true
|
|
158
|
+
|
|
159
|
+
- name: Summary
|
|
160
|
+
if: always()
|
|
161
|
+
run: |
|
|
162
|
+
echo "## Audit Results" >> $GITHUB_STEP_SUMMARY
|
|
163
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
164
|
+
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
|
|
165
|
+
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
|
|
166
|
+
echo "| Build | ${{ steps.build.outputs.success == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
167
|
+
echo "| Tests | ${{ steps.tests.outputs.success == 'true' && '✅' || '❌' }} (${{ steps.tests.outputs.passed }} passed, ${{ steps.tests.outputs.failed }} failed) |" >> $GITHUB_STEP_SUMMARY
|
|
168
|
+
echo "| Lint | ${{ steps.lint.outputs.success == 'true' && '✅' || '❌' }} (${{ steps.lint.outputs.errors }} errors) |" >> $GITHUB_STEP_SUMMARY
|
|
169
|
+
echo "| TypeScript | ${{ steps.typecheck.outputs.success == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
170
|
+
echo "| Security | ${{ steps.security.outputs.success == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
171
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
172
|
+
echo "**Execute Stage:** ${{ steps.result.outputs.execute }}" >> $GITHUB_STEP_SUMMARY
|
|
173
|
+
echo "**Audit Stage:** ${{ steps.result.outputs.audit }}" >> $GITHUB_STEP_SUMMARY
|
package/LICENSE
CHANGED
|
@@ -17,17 +17,17 @@ TERMS OF USE:
|
|
|
17
17
|
- Standard pre-commit hooks
|
|
18
18
|
|
|
19
19
|
2. PAID TIERS
|
|
20
|
-
- Pro: $
|
|
20
|
+
- Pro: $19/month or $190/year
|
|
21
21
|
- Security scanning (Gitleaks + ESLint security)
|
|
22
22
|
- Smart Test Strategy
|
|
23
23
|
- Multi-language support
|
|
24
24
|
- Unlimited repos
|
|
25
|
-
- Team:
|
|
25
|
+
- Team: Contact us (coming soon)
|
|
26
26
|
- All Pro features
|
|
27
27
|
- RBAC and team policies
|
|
28
28
|
- Slack alerts
|
|
29
29
|
- Multi-repo dashboard
|
|
30
|
-
- Enterprise:
|
|
30
|
+
- Enterprise: Contact us (coming soon)
|
|
31
31
|
- All Team features
|
|
32
32
|
- SSO/SAML integration
|
|
33
33
|
- Custom policies
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Quality automation CLI for JavaScript/TypeScript and Python 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
|
-
**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
|
|
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
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -41,14 +41,14 @@ npx create-qa-architect@latest
|
|
|
41
41
|
|
|
42
42
|
## Pricing
|
|
43
43
|
|
|
44
|
-
| Tier | Price
|
|
45
|
-
| -------------- |
|
|
46
|
-
| **Free** | $0
|
|
47
|
-
| **Pro** | $
|
|
48
|
-
| **Team** |
|
|
49
|
-
| **Enterprise** |
|
|
44
|
+
| Tier | Price | What You Get |
|
|
45
|
+
| -------------- | ----------------- | -------------------------------------------------------------------------------------------------- |
|
|
46
|
+
| **Free** | $0 | CLI tool, basic linting/formatting, npm audit (capped: 1 private repo, 50 runs/mo) |
|
|
47
|
+
| **Pro** | $19/mo or $190/yr | **Security scanning (Gitleaks + ESLint security)**, Smart Test Strategy, multi-language, unlimited |
|
|
48
|
+
| **Team** | Contact us | + RBAC, Slack alerts, multi-repo dashboard, team audit log _(coming soon)_ |
|
|
49
|
+
| **Enterprise** | Contact us | + SSO/SAML, custom policies, compliance pack, dedicated TAM _(coming soon)_ |
|
|
50
50
|
|
|
51
|
-
> **Pro included in [
|
|
51
|
+
> **Pro included in [VBL Starter Kit](https://vibebuildlab.com/starter-kit)** — Team/Enterprise are standalone purchases.
|
|
52
52
|
|
|
53
53
|
### Security Features by Tier
|
|
54
54
|
|
|
@@ -60,7 +60,7 @@ npx create-qa-architect@latest
|
|
|
60
60
|
|
|
61
61
|
### License
|
|
62
62
|
|
|
63
|
-
**
|
|
63
|
+
**Commercial License (freemium)** — free tier covers the basic CLI; Pro/Team/Enterprise features require a paid subscription. See [LICENSE](LICENSE).
|
|
64
64
|
|
|
65
65
|
## Tech Stack
|
|
66
66
|
|
|
@@ -188,13 +188,7 @@ npm run validate:pre-push # Pre-push validation
|
|
|
188
188
|
|
|
189
189
|
## Roadmap
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
- [x] Progressive quality (maturity detection)
|
|
193
|
-
- [x] Python toolchain support
|
|
194
|
-
- [x] Smart test strategy (Pro)
|
|
195
|
-
- [x] Monorepo support (Nx, Turborepo, Lerna, Rush, npm/pnpm/yarn workspaces)
|
|
196
|
-
- [ ] Rust and Go support
|
|
197
|
-
- [ ] VS Code extension
|
|
191
|
+
See [ROADMAP.md](ROADMAP.md) for planned features and strategic direction.
|
|
198
192
|
|
|
199
193
|
## Contributing
|
|
200
194
|
|
|
@@ -214,7 +208,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
|
214
208
|
|
|
215
209
|
## License
|
|
216
210
|
|
|
217
|
-
|
|
211
|
+
Commercial freemium license — the base CLI is free to use; Pro/Team/Enterprise features require a paid subscription. See [LICENSE](LICENSE) for details.
|
|
218
212
|
|
|
219
213
|
## Legal
|
|
220
214
|
|
package/config/defaults.js
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
const STYLELINT_EXTENSIONS = ['css', 'scss', 'sass', 'less', 'pcss']
|
|
5
5
|
const DEFAULT_STYLELINT_TARGET = `**/*.{${STYLELINT_EXTENSIONS.join(',')}}`
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {Object} DefaultsOptions
|
|
9
|
+
* @property {string[]=} stylelintTargets
|
|
10
|
+
* @property {boolean=} typescript
|
|
11
|
+
* @property {boolean=} python
|
|
12
|
+
*/
|
|
13
|
+
|
|
7
14
|
const baseScripts = {
|
|
8
15
|
format: 'prettier --write .',
|
|
9
16
|
'format:check': 'prettier --check .',
|
|
@@ -41,7 +48,12 @@ const stylelintBraceGroup = stylelintTargets => {
|
|
|
41
48
|
return `{${targets.join(',')}}`
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
/**
|
|
52
|
+
* @param {DefaultsOptions} [options]
|
|
53
|
+
* @returns {Record<string, string>}
|
|
54
|
+
*/
|
|
55
|
+
const baseLintScripts = (options = {}) => {
|
|
56
|
+
const { stylelintTargets } = options
|
|
45
57
|
const stylelintTarget = stylelintBraceGroup(stylelintTargets)
|
|
46
58
|
return {
|
|
47
59
|
lint: `eslint . && stylelint "${stylelintTarget}" --allow-empty-input`,
|
|
@@ -96,6 +108,9 @@ const TS_LINT_STAGED_PATTERN = '**/*.{js,jsx,ts,tsx,mjs,cjs,html}'
|
|
|
96
108
|
|
|
97
109
|
const clone = value => JSON.parse(JSON.stringify(value))
|
|
98
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @param {DefaultsOptions} [options]
|
|
113
|
+
*/
|
|
99
114
|
function getDefaultScripts({ stylelintTargets } = {}) {
|
|
100
115
|
return {
|
|
101
116
|
...clone(baseScripts),
|
|
@@ -103,6 +118,9 @@ function getDefaultScripts({ stylelintTargets } = {}) {
|
|
|
103
118
|
}
|
|
104
119
|
}
|
|
105
120
|
|
|
121
|
+
/**
|
|
122
|
+
* @param {DefaultsOptions} [options]
|
|
123
|
+
*/
|
|
106
124
|
function getDefaultDevDependencies({ typescript } = {}) {
|
|
107
125
|
const devDeps = { ...clone(baseDevDependencies) }
|
|
108
126
|
if (typescript) {
|
|
@@ -111,6 +129,9 @@ function getDefaultDevDependencies({ typescript } = {}) {
|
|
|
111
129
|
return devDeps
|
|
112
130
|
}
|
|
113
131
|
|
|
132
|
+
/**
|
|
133
|
+
* @param {DefaultsOptions} [options]
|
|
134
|
+
*/
|
|
114
135
|
function getDefaultLintStaged({ typescript, stylelintTargets, python } = {}) {
|
|
115
136
|
const pattern = typescript ? TS_LINT_STAGED_PATTERN : JS_LINT_STAGED_PATTERN
|
|
116
137
|
return clone(baseLintStaged(pattern, stylelintTargets, python))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://github.com/
|
|
3
|
+
"$id": "https://github.com/vibebuildlab/qa-architect/blob/main/config/quality-config.schema.json",
|
|
4
4
|
"title": "Quality Automation Configuration",
|
|
5
5
|
"description": "Configuration for create-qa-architect progressive quality checks",
|
|
6
6
|
"type": "object",
|