ci: split checks and fix gitea workflow
CI / Capabilities and shell quality (push) Failing after 12s
CI / Python tests and compilation (push) Failing after 7s
CI / Build and inspect generated packages (push) Skipped
CI / Bash integration and installation guards (push) Skipped
CI / Installed client configuration smoke tests (push) Skipped
CI / Qwen retrieval integration (push) Skipped
CI / PowerShell tests on Ubuntu (push) Failing after 18s
CI / CI configuration security checks (push) Successful in 4s

This commit is contained in:
fraujulian committed 2026-09-24 17:32:31 +02:00
1 parent 0befbbc07c
commit a50575dbec
12 files changed
+146 -288

No files matched your search

+10 -3
View File
@@ -122,6 +122,9 @@ jobs:
bash scripts/tests/test-quick-update.sh --summary bash scripts/tests/test-quick-update.sh --summary
bash scripts/tests/test-managed-install.sh --summary bash scripts/tests/test-managed-install.sh --summary
bash scripts/tests/test-shell-packages.sh --summary bash scripts/tests/test-shell-packages.sh --summary
bash scripts/tests/test-runtime-status.sh --summary
bash scripts/tests/test-install-selections.sh --summary
bash scripts/tests/test-command-summaries.sh --summary
- name: Run doctor and prompt budget checks - name: Run doctor and prompt budget checks
run: | run: |
bash scripts/commands/doctor.sh --summary bash scripts/commands/doctor.sh --summary
@@ -186,9 +189,13 @@ jobs:
- name: Reject unsafe workflow settings - name: Reject unsafe workflow settings
run: | run: |
set -euo pipefail set -euo pipefail
! grep -RInE 'runs-on:[[:space:]]*windows|pull_request_target|permissions:[[:space:]]*write-all|actions/checkout@v|actions/setup-python@v|curl[[:space:]].*\|[[:space:]]*(bash|sh)|wget[[:space:]].*\|[[:space:]]*(bash|sh)' .github/workflows unsafe_patterns='runs-on:[[:space:]]*windows|pull_request_'
test "$(grep -Roh 'runs-on: ubuntu-latest' .github/workflows | wc -l)" -ge 1 unsafe_patterns+='target|permissions:[[:space:]]*write-all|actions/checkout@'
test "$(grep -Roh 'uses: actions/[^@]*@[0-9a-f]\{40\}' .github/workflows | wc -l)" -ge 1 unsafe_patterns+='v|actions/setup-python@'
unsafe_patterns+='v|curl[[:space:]].*\|[[:space:]]*(bash|sh)|wget[[:space:]].*\|[[:space:]]*(bash|sh)'
! grep -RInE "$unsafe_patterns" .gitea/workflows
test "$(grep -Roh 'runs-on: ubuntu-latest' .gitea/workflows | wc -l)" -ge 1
test "$(grep -Roh 'uses: actions/[^@]*@[0-9a-f]\{40\}' .gitea/workflows | wc -l)" -ge 1
- name: Check for tracked secrets - name: Check for tracked secrets
run: | run: |
set -euo pipefail set -euo pipefail
-202
View File
@@ -1,202 +0,0 @@
name: CI
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '23 4 * * 1'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
PYTHONUNBUFFERED: '1'
PIP_DISABLE_PIP_VERSION_CHECK: '1'
jobs:
capabilities:
name: Capabilities and shell quality
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install shell tools
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends shellcheck jq
- name: Check capabilities
run: bash scripts/commands/check-capabilities.sh
- name: Validate Bash syntax
run: git ls-files -z '*.sh' | xargs -0 -r -n1 bash -n
- name: Lint Bash
run: shellcheck --severity=warning $(git ls-files '*.sh')
python:
name: Python tests and compilation
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
- name: Compile Python sources
run: python -m compileall -q scripts shared
- name: Run Python tests
run: |
set -euo pipefail
for file in scripts/tests/test-*.py; do
echo "==> $file"
python "$file"
done
- name: Validate generated configuration
run: python scripts/checks/validate-config.py generated/codex-powershell/config.toml generated/claude-powershell/settings.json
powershell-on-ubuntu:
name: PowerShell tests on Ubuntu
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check PowerShell runtime
shell: bash
run: |
if command -v pwsh >/dev/null 2>&1; then
echo 'POWERSHELL_AVAILABLE=true' >> "$GITHUB_ENV"
exit 0
fi
if sudo apt-get update && sudo apt-get install --yes --no-install-recommends powershell; then
echo 'POWERSHELL_AVAILABLE=true' >> "$GITHUB_ENV"
else
echo 'POWERSHELL_AVAILABLE=false' >> "$GITHUB_ENV"
echo '::warning::PowerShell is unavailable; PowerShell checks skipped for this runner.'
fi
- name: Run PowerShell tests
shell: bash
run: |
if [ "${POWERSHELL_AVAILABLE:-false}" != true ]; then exit 0; fi
pwsh -NoLogo -NoProfile -NonInteractive -File ./scripts/commands/check-capabilities.ps1
for file in scripts/tests/test-*.ps1; do
echo "==> $file"
pwsh -NoLogo -NoProfile -NonInteractive -File "$file" -Summary
done
build:
name: Build and inspect generated packages
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [capabilities, python]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Build packages
env:
REQUIRE_CODEX_SCHEMA: 'false'
run: bash scripts/commands/build.sh --summary
- name: Run build validation
run: bash scripts/tests/test-build-validation.sh --summary
- name: Check generated files are reproducible
run: |
before=$(find generated -type f -print0 | sort -z | xargs -0 sha256sum)
bash scripts/commands/build.sh --summary
after=$(find generated -type f -print0 | sort -z | xargs -0 sha256sum)
test "$before" = "$after"
shell-integration:
name: Bash integration and installation guards
runs-on: ubuntu-latest
timeout-minutes: 25
needs: [build]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Run integration tests
run: |
set -euo pipefail
bash scripts/tests/test-install-guards.sh --summary
bash scripts/tests/test-plugin-selection.sh --summary
bash scripts/tests/test-quick-update.sh --summary
bash scripts/tests/test-managed-install.sh --summary
bash scripts/tests/test-shell-packages.sh --summary
- name: Run doctor and prompt budget checks
run: |
bash scripts/commands/doctor.sh --summary
bash scripts/commands/prompt-budget.sh --summary
- name: Verify dry-run installation safety
run: |
bash scripts/commands/install.sh --summary --dry-run --client both --shell bash
bash scripts/commands/update.sh --summary --dry-run --client both --shell bash
client-smoke:
name: Installed client configuration smoke tests
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [build]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Build packages
run: bash scripts/commands/build.sh --summary
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v22.16.0
with:
node-version: '24'
- name: Install current client CLIs
run: npm install --global @openai/codex @anthropic-ai/claude-code
- name: Validate current Codex and Claude settings
run: |
set -euo pipefail
schema_home=$(mktemp -d)
cp generated/codex-powershell/config.toml "$schema_home/config.toml"
CODEX_HOME="$schema_home" codex --strict-config --help >/dev/null
claude --settings generated/claude-powershell/settings.json --help >/dev/null
retrieval:
name: Qwen retrieval integration
runs-on: ubuntu-latest
timeout-minutes: 30
needs: [python]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
cache: pip
cache-dependency-path: shared/retrieval/requirements.txt
- name: Install retrieval dependencies
run: python -m pip install -r shared/retrieval/requirements.txt
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .cache/huggingface
key: qwen-retrieval-${{ runner.os }}-${{ hashFiles('shared/retrieval/requirements.txt') }}
- name: Run retrieval tests with real models
env:
QWEN_TEST_MODEL_CACHE: ${{ github.workspace }}/.cache/huggingface
HF_HUB_DISABLE_XET: '1'
run: python scripts/tests/test-retrieval-server.py
security:
name: CI configuration security checks
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Reject unsafe workflow settings
run: |
set -euo pipefail
! grep -RInE 'runs-on:[[:space:]]*windows|pull_request_target|permissions:[[:space:]]*write-all|actions/checkout@v|actions/setup-python@v|curl[[:space:]].*\|[[:space:]]*(bash|sh)|wget[[:space:]].*\|[[:space:]]*(bash|sh)' .github/workflows
test "$(grep -Roh 'runs-on: ubuntu-latest' .github/workflows | wc -l)" -ge 1
test "$(grep -Roh 'uses: actions/[^@]*@[0-9a-f]\{40\}' .github/workflows | wc -l)" -ge 1
- name: Check for tracked secrets
run: |
set -euo pipefail
if git ls-files | grep -E '(^|/)(\.env($|\.)|.*\.(pem|key))$'; then
echo 'Potential secret file or private key tracked' >&2
exit 1
fi
if git ls-files -z | xargs -0 -r grep -IlE 'BEGIN (RSA|OPENSSH|EC) PRIVATE KEY'; then
echo 'Potential private key material tracked' >&2
exit 1
fi
+6 -1
View File
@@ -36,6 +36,8 @@ Qwen retrieval uses `shared/retrieval/benchmark.py`; run it through `scripts/lib
## Checks and tests ## Checks and tests
Gitea Actions runs the repository checks from `.gitea/workflows/ci.yml`.
| Script | Purpose | | Script | Purpose |
| --- | --- | | --- | --- |
| `checks/validate-config.py` | Validate generated Codex TOML and Claude JSON. | | `checks/validate-config.py` | Validate generated Codex TOML and Claude JSON. |
@@ -51,7 +53,10 @@ Qwen retrieval uses `shared/retrieval/benchmark.py`; run it through `scripts/lib
| `tests/test-retrieval-server.py` | Validate retrieval indexing, ranking, and optional real-model execution. | | `tests/test-retrieval-server.py` | Validate retrieval indexing, ranking, and optional real-model execution. |
| `tests/test-semantic-retrieval.py` | Validate retrieval installation and removal. | | `tests/test-semantic-retrieval.py` | Validate retrieval installation and removal. |
| `tests/test-session-state.py` | Validate session-state helpers. | | `tests/test-session-state.py` | Validate session-state helpers. |
| `tests/test-shell-packages.ps1`, `tests/test-shell-packages.sh` | Validate generated packages and shell entry points. | | `tests/test-shell-packages.ps1`, `tests/test-shell-packages.sh` | Validate generated package contents and client settings. |
| `tests/test-runtime-status.ps1`, `tests/test-runtime-status.sh` | Validate build summaries and status-line output. |
| `tests/test-install-selections.ps1`, `tests/test-install-selections.sh` | Validate dry-run shell and client selections. |
| `tests/test-command-summaries.ps1`, `tests/test-command-summaries.sh` | Validate doctor, install, and update summary output. |
| `tests/test-telemetry.py` | Validate telemetry output. | | `tests/test-telemetry.py` | Validate telemetry output. |
## Internal helpers ## Internal helpers
+15
View File
@@ -0,0 +1,15 @@
[CmdletBinding()]
param([switch]$Summary)
$ErrorActionPreference = 'Stop'
$root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$doctorSummaryOutput = & (Join-Path $root 'scripts/commands/doctor.ps1') -Summary
if (@($doctorSummaryOutput | Where-Object { $_ -match '^PASS ' }).Count -ne 0) { throw 'Doctor summary mode must not print individual PASS lines.' }
if (@($doctorSummaryOutput | Where-Object { $_ -match '^Doctor: PASS \| \d+ checks$' }).Count -ne 1) { throw "Doctor summary mode must print one 'Doctor: PASS | N checks' line: $($doctorSummaryOutput -join '; ')" }
foreach ($entryPoint in @('install','update')) {
$preview = @(& (Join-Path $root "scripts/commands/$entryPoint.ps1") -Summary -DryRun -Client Both -Shell PowerShell)
if ($preview -match '^(SOURCE|CREATE|UPDATE|UNCHANGED|BACKUP|DRYRUN|PASS) ') { throw "$entryPoint summary leaked per-item output." }
if (@($preview | Where-Object { $_ -match ('^' + $entryPoint + ': PASS') }).Count -ne 1) { throw "$entryPoint summary is missing." }
}
$doctorSummaryOutput | Where-Object { $_ -match '^WARN ' }
if ($Summary) { Write-Output 'Tests: PASS | command summaries' } else { Write-Output 'PASS doctor, install, and update summaries' }
exit 0
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
summary=false
while [ $# -gt 0 ]; do
case "$1" in
--summary) summary=true; shift ;;
*) printf 'Unknown argument: %s\n' "$1" >&2; exit 1 ;;
esac
done
root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
doctor_summary_output=$(bash "$root/scripts/commands/doctor.sh" --summary)
if printf '%s\n' "$doctor_summary_output" | grep -q '^PASS '; then
printf 'Doctor summary mode must not print individual PASS lines.\n' >&2
exit 1
fi
if ! printf '%s\n' "$doctor_summary_output" | grep -Eq '^Doctor: PASS \| [0-9]+ checks$'; then
printf "Doctor summary mode must print one 'Doctor: PASS | N checks' line: %s\n" "$doctor_summary_output" >&2
exit 1
fi
for entry_point in install update; do
preview=$(bash "$root/scripts/commands/$entry_point.sh" --summary --dry-run --client both --shell bash)
if printf '%s\n' "$preview" | grep -Eq '^(SOURCE|CREATE|UPDATE|UNCHANGED|BACKUP|DRYRUN|PASS) '; then
printf '%s summary leaked per-item output.\n' "$entry_point" >&2
exit 1
fi
printf '%s\n' "$preview" | grep -Eiq "^$entry_point: PASS"
done
printf '%s\n' "$doctor_summary_output" | grep '^WARN ' || true
if [ "$summary" = true ]; then printf 'Tests: PASS | command summaries\n'; else printf 'PASS doctor, install, and update summaries\n'; fi
+18
View File
@@ -0,0 +1,18 @@
[CmdletBinding()]
param([switch]$Summary)
$ErrorActionPreference = 'Stop'
$root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
foreach ($shellSelection in @('1','2')) {
foreach ($clientSelection in @('1','2','3')) {
$script:answers = [System.Collections.Generic.Queue[string]]::new()
$script:answers.Enqueue($shellSelection)
$script:answers.Enqueue($clientSelection)
function Read-Host { param($Prompt) $answers.Dequeue() }
$output = & (Join-Path $root 'scripts/commands/install.ps1') -DryRun 6>$null
if ($output -notcontains 'PASS install dry-run') { throw 'Dry-run did not finish.' }
$shell = if ($shellSelection -eq '1') { 'powershell' } else { 'bash' }
if (($output -join "`n") -notmatch "-$shell") { throw 'Incorrect selected package.' }
}
}
if ($Summary) { Write-Output 'Tests: PASS | install selections' } else { Write-Output 'PASS six shell and client selections' }
exit 0
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
summary=false
while [ $# -gt 0 ]; do
case "$1" in
--summary) summary=true; shift ;;
*) printf 'Unknown argument: %s\n' "$1" >&2; exit 1 ;;
esac
done
root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
for shell_selection in 1 2; do
for client_selection in 1 2 3; do
output=$(printf '%s\n%s\n' "$shell_selection" "$client_selection" | bash "$root/scripts/commands/install.sh" --dry-run 2>&1) || { printf '%s\n' "$output" >&2; exit 1; }
printf '%s\n' "$output" | grep -E 'WARN|FAIL|WARNING|ERROR' || true
[[ "$output" == *'PASS install dry-run'* ]]
shell=powershell
[ "$shell_selection" != 2 ] || shell=bash
[[ "$output" == *"-$shell"* ]]
done
done
if [ "$summary" = true ]; then printf 'Tests: PASS | install selections\n'; else printf 'PASS six shell and client selections\n'; fi
+2 -4
View File
@@ -58,13 +58,11 @@ class RetrievalServerTests(unittest.TestCase):
self.assertFalse(huggingface_network_unavailable(OSError('model is missing'))) self.assertFalse(huggingface_network_unavailable(OSError('model is missing')))
def test_ci_disables_xet_for_model_downloads(self): def test_ci_disables_xet_for_model_downloads(self):
for workflow in ('.github/workflows/ci.yml', '.gitea/workflows/ci.yml'): content = (ROOT / '.gitea/workflows/ci.yml').read_text(encoding='utf-8')
content = (ROOT / workflow).read_text(encoding='utf-8')
self.assertIn("HF_HUB_DISABLE_XET: '1'", content) self.assertIn("HF_HUB_DISABLE_XET: '1'", content)
def test_client_smoke_builds_packages(self): def test_client_smoke_builds_packages(self):
for workflow in ('.github/workflows/ci.yml', '.gitea/workflows/ci.yml'): content = (ROOT / '.gitea/workflows/ci.yml').read_text(encoding='utf-8')
content = (ROOT / workflow).read_text(encoding='utf-8')
self.assertIn('name: Build packages\n run: bash scripts/commands/build.sh --summary', content) self.assertIn('name: Build packages\n run: bash scripts/commands/build.sh --summary', content)
def test_runtime_python_uses_adjacent_virtualenv(self): def test_runtime_python_uses_adjacent_virtualenv(self):
+18
View File
@@ -0,0 +1,18 @@
[CmdletBinding()]
param([switch]$Summary)
$ErrorActionPreference = 'Stop'
$root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$powerShellHook = Get-Content -LiteralPath (Join-Path $root 'shared/hooks/flashbang.ps1') -Raw
$bashHook = Get-Content -LiteralPath (Join-Path $root 'shared/hooks/flashbang.sh') -Raw
if ($powerShellHook -notmatch '\$HoldMs\s*=\s*250' -or $powerShellHook -notmatch '\$FadeMs\s*=\s*250' -or ([regex]::Matches($bashHook, 'default=250').Count -lt 2)) { throw 'Flashbang defaults must total 500 milliseconds on PowerShell and Bash.' }
$statusInput = '{"model":{"display_name":"Test Model"},"effort":{"level":"high"},"workspace":{"current_dir":"' + $root.Replace('\','\\') + '","repo":{"name":"TestRepo"}},"context_window":{"context_window_size":200000,"used_percentage":8.5,"total_input_tokens":15500,"total_output_tokens":1200}}'
$branch = & git -C $root branch --show-current
$buildSummaryOutput = & (Join-Path $root 'scripts/commands/build.ps1') -Summary
if (@($buildSummaryOutput | Where-Object { $_ -eq 'Build: PASS | 4 packages' }).Count -ne 1) { throw "build.ps1 -Summary must still print the PASS line: $($buildSummaryOutput -join '; ')" }
$statusOutput = ($statusInput | & (Join-Path $root 'shared/statusline/statusline.ps1')) -join "`n"
$plainStatusOutput = [regex]::Replace($statusOutput, [char]27 + '\[[0-9;]*m', '')
$expectedStatusOutput = "Test Model $([char]0x00B7) Review auto $([char]0x00B7) Effort high $([char]0x00B7) TestRepo @ $branch`nCtx 200k $([char]0x00B7) Used 9% $([char]0x00B7) Tokens 16.7k"
if ($buildSummaryOutput.Count -ne 1) { throw 'Build summary must contain only one success line.' }
if ($plainStatusOutput -ne $expectedStatusOutput) { throw 'PowerShell status line output is incorrect.' }
if ($Summary) { Write-Output 'Tests: PASS | runtime status' } else { Write-Output 'PASS build summary and status lines' }
exit 0
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
summary=false
while [ $# -gt 0 ]; do
case "$1" in
--summary) summary=true; shift ;;
*) printf 'Unknown argument: %s\n' "$1" >&2; exit 1 ;;
esac
done
root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
grep -Eq '\$HoldMs[[:space:]]*=[[:space:]]*250' "$root/shared/hooks/flashbang.ps1"
grep -Eq '\$FadeMs[[:space:]]*=[[:space:]]*250' "$root/shared/hooks/flashbang.ps1"
[ "$(grep -c 'default=250' "$root/shared/hooks/flashbang.sh")" -ge 2 ]
branch=$(git -C "$root" branch --show-current)
build_summary_output=$(bash "$root/scripts/commands/build.sh" --summary)
if ! printf '%s\n' "$build_summary_output" | grep -qx 'Build: PASS | 4 packages'; then
printf 'build.sh --summary must still print the PASS line: %s\n' "$build_summary_output" >&2
exit 1
fi
[ "$build_summary_output" = 'Build: PASS | 4 packages' ]
status_output=$(printf '{"model":{"display_name":"Test Model"},"effort":{"level":"high"},"workspace":{"current_dir":"%s","repo":{"name":"TestRepo"}},"context_window":{"context_window_size":200000,"used_percentage":8.5,"total_input_tokens":15500,"total_output_tokens":1200}}' "$root" | bash "$root/shared/statusline/statusline.sh")
plain_status_output=$(printf '%s' "$status_output" | sed -E $'s/\x1b\\[[0-9;]*m//g')
expected_status_output=$'Test Model \xc2\xb7 Review auto \xc2\xb7 Effort high \xc2\xb7 TestRepo @ '"$branch"$'\nCtx 200k \xc2\xb7 Used 9% \xc2\xb7 Tokens 16.7k'
[ "$plain_status_output" = "$expected_status_output" ]
if [ "$summary" = true ]; then printf 'Tests: PASS | runtime status\n'; else printf 'PASS build summary and status lines\n'; fi
+1 -35
View File
@@ -2,18 +2,6 @@
param([switch]$Summary) param([switch]$Summary)
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
$root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent $root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$powerShellHook = Get-Content -LiteralPath (Join-Path $root 'shared/hooks/flashbang.ps1') -Raw
$bashHook = Get-Content -LiteralPath (Join-Path $root 'shared/hooks/flashbang.sh') -Raw
if ($powerShellHook -notmatch '\$HoldMs\s*=\s*250' -or $powerShellHook -notmatch '\$FadeMs\s*=\s*250' -or ([regex]::Matches($bashHook, 'default=250').Count -lt 2)) { throw 'Flashbang defaults must total 500 milliseconds on PowerShell and Bash.' }
$statusInput = '{"model":{"display_name":"Test Model"},"effort":{"level":"high"},"workspace":{"current_dir":"' + $root.Replace('\','\\') + '","repo":{"name":"TestRepo"}},"context_window":{"context_window_size":200000,"used_percentage":8.5,"total_input_tokens":15500,"total_output_tokens":1200}}'
$branch = & git -C $root branch --show-current
$buildSummaryOutput = & (Join-Path $root 'scripts/commands/build.ps1') -Summary
if (@($buildSummaryOutput | Where-Object { $_ -eq 'Build: PASS | 4 packages' }).Count -ne 1) { throw "build.ps1 -Summary must still print the PASS line: $($buildSummaryOutput -join '; ')" }
$statusOutput = ($statusInput | & (Join-Path $root 'shared/statusline/statusline.ps1')) -join "`n"
$plainStatusOutput = [regex]::Replace($statusOutput, [char]27 + '\[[0-9;]*m', '')
$expectedStatusOutput = "Test Model $([char]0x00B7) Review auto $([char]0x00B7) Effort high $([char]0x00B7) TestRepo @ $branch`nCtx 200k $([char]0x00B7) Used 9% $([char]0x00B7) Tokens 16.7k"
if ($buildSummaryOutput.Count -ne 1) { throw 'Build summary must contain only one success line.' }
if ($plainStatusOutput -ne $expectedStatusOutput) { throw 'PowerShell status line output is incorrect.' }
$sourceAgentCount = @(Get-ChildItem (Join-Path $root 'shared/agents') -Directory).Count $sourceAgentCount = @(Get-ChildItem (Join-Path $root 'shared/agents') -Directory).Count
$sourceSkillCount = @(Get-ChildItem (Join-Path $root 'shared/skills') -Filter 'SKILL.md' -Recurse).Count $sourceSkillCount = @(Get-ChildItem (Join-Path $root 'shared/skills') -Filter 'SKILL.md' -Recurse).Count
$ruleSkillCount = @(Import-Csv -LiteralPath (Join-Path $root 'adapters/rule-skills.tsv') -Delimiter ([char]9)).Count $ruleSkillCount = @(Import-Csv -LiteralPath (Join-Path $root 'adapters/rule-skills.tsv') -Delimiter ([char]9)).Count
@@ -68,27 +56,5 @@ foreach ($shell in @('powershell','bash')) {
} }
} }
} }
foreach ($shellSelection in @('1','2')) { if ($Summary) { Write-Output 'Tests: PASS | generated packages' } else { Write-Output 'PASS four generated client and shell packages' }
foreach ($clientSelection in @('1','2','3')) {
$script:answers = [System.Collections.Generic.Queue[string]]::new()
$script:answers.Enqueue($shellSelection)
$script:answers.Enqueue($clientSelection)
function Read-Host { param($Prompt) $answers.Dequeue() }
$output = & (Join-Path $root 'scripts/commands/install.ps1') -DryRun 6>$null
if ($output -notcontains 'PASS install dry-run') { throw 'Dry-run did not finish.' }
$shell = if ($shellSelection -eq '1') { 'powershell' } else { 'bash' }
if (($output -join "`n") -notmatch "-$shell") { throw 'Incorrect selected package.' }
}
}
$doctorSummaryOutput = & (Join-Path $root 'scripts/commands/doctor.ps1') -Summary
if (@($doctorSummaryOutput | Where-Object { $_ -match '^PASS ' }).Count -ne 0) { throw 'Doctor summary mode must not print individual PASS lines.' }
if (@($doctorSummaryOutput | Where-Object { $_ -match '^Doctor: PASS \| \d+ checks$' }).Count -ne 1) { throw "Doctor summary mode must print one 'Doctor: PASS | N checks' line: $($doctorSummaryOutput -join '; ')" }
foreach ($entryPoint in @('install','update')) {
$preview = @(& (Join-Path $root "scripts/commands/$entryPoint.ps1") -Summary -DryRun -Client Both -Shell PowerShell)
if ($preview -match '^(SOURCE|CREATE|UPDATE|UNCHANGED|BACKUP|DRYRUN|PASS) ') { throw "$entryPoint summary leaked per-item output." }
if (@($preview | Where-Object { $_ -match ('^' + $entryPoint + ': PASS') }).Count -ne 1) { throw "$entryPoint summary is missing." }
}
$doctorSummaryOutput | Where-Object { $_ -match '^WARN ' }
if ($Summary) { Write-Output 'Tests: PASS | shell packages' } else { Write-Output 'PASS four shell packages and six PowerShell selections' }
exit 0 exit 0
+1 -43
View File
@@ -8,20 +8,6 @@ while [ $# -gt 0 ]; do
esac esac
done done
root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd) root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
grep -Eq '\$HoldMs[[:space:]]*=[[:space:]]*250' "$root/shared/hooks/flashbang.ps1"
grep -Eq '\$FadeMs[[:space:]]*=[[:space:]]*250' "$root/shared/hooks/flashbang.ps1"
[ "$(grep -c 'default=250' "$root/shared/hooks/flashbang.sh")" -ge 2 ]
branch=$(git -C "$root" branch --show-current)
build_summary_output=$(bash "$root/scripts/commands/build.sh" --summary)
if ! printf '%s\n' "$build_summary_output" | grep -qx 'Build: PASS | 4 packages'; then
printf 'build.sh --summary must still print the PASS line: %s\n' "$build_summary_output" >&2
exit 1
fi
[ "$build_summary_output" = 'Build: PASS | 4 packages' ]
status_output=$(printf '{"model":{"display_name":"Test Model"},"effort":{"level":"high"},"workspace":{"current_dir":"%s","repo":{"name":"TestRepo"}},"context_window":{"context_window_size":200000,"used_percentage":8.5,"total_input_tokens":15500,"total_output_tokens":1200}}' "$root" | bash "$root/shared/statusline/statusline.sh")
plain_status_output=$(printf '%s' "$status_output" | sed -E $'s/\x1b\\[[0-9;]*m//g')
expected_status_output=$'Test Model \xc2\xb7 Review auto \xc2\xb7 Effort high \xc2\xb7 TestRepo @ '"$branch"$'\nCtx 200k \xc2\xb7 Used 9% \xc2\xb7 Tokens 16.7k'
[ "$plain_status_output" = "$expected_status_output" ]
source_agent_count=$(find "$root/shared/agents" -mindepth 1 -maxdepth 1 -type d | wc -l) source_agent_count=$(find "$root/shared/agents" -mindepth 1 -maxdepth 1 -type d | wc -l)
source_skill_count=$(find "$root/shared/skills" -name SKILL.md | wc -l) source_skill_count=$(find "$root/shared/skills" -name SKILL.md | wc -l)
rule_skill_count=$(($(wc -l < "$root/adapters/rule-skills.tsv") - 1)) rule_skill_count=$(($(wc -l < "$root/adapters/rule-skills.tsv") - 1))
@@ -100,32 +86,4 @@ for shell in powershell bash; do
done done
done done
done done
for shell_selection in 1 2; do if [ "$summary" = true ]; then printf 'Tests: PASS | generated packages\n'; else printf 'PASS four generated client and shell packages\n'; fi
for client_selection in 1 2 3; do
output=$(printf '%s\n%s\n' "$shell_selection" "$client_selection" | bash "$root/scripts/commands/install.sh" --dry-run 2>&1) || { printf '%s\n' "$output" >&2; exit 1; }
printf '%s\n' "$output" | grep -E 'WARN|FAIL|WARNING|ERROR' || true
[[ "$output" == *'PASS install dry-run'* ]]
shell=powershell
[ "$shell_selection" != 2 ] || shell=bash
[[ "$output" == *"-$shell"* ]]
done
done
doctor_summary_output=$(bash "$root/scripts/commands/doctor.sh" --summary)
if printf '%s\n' "$doctor_summary_output" | grep -q '^PASS '; then
printf 'Doctor summary mode must not print individual PASS lines.\n' >&2
exit 1
fi
if ! printf '%s\n' "$doctor_summary_output" | grep -Eq '^Doctor: PASS \| [0-9]+ checks$'; then
printf "Doctor summary mode must print one 'Doctor: PASS | N checks' line: %s\n" "$doctor_summary_output" >&2
exit 1
fi
for entry_point in install update; do
preview=$(bash "$root/scripts/commands/$entry_point.sh" --summary --dry-run --client both --shell bash)
if printf '%s\n' "$preview" | grep -Eq '^(SOURCE|CREATE|UPDATE|UNCHANGED|BACKUP|DRYRUN|PASS) '; then
printf '%s summary leaked per-item output.\n' "$entry_point" >&2
exit 1
fi
printf '%s\n' "$preview" | grep -Eiq "^$entry_point: PASS"
done
printf '%s\n' "$doctor_summary_output" | grep '^WARN ' || true
if [ "$summary" = true ]; then printf 'Tests: PASS | shell packages\n'; else printf 'PASS four shell packages and six Bash selections\n'; fi