[spark-compete] enhance: Theme toggle button never announces its state to screen readers #403
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Install hardening | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| jobs: | |
| install-hardening: | |
| name: install-hardening | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd | |
| - name: Validate installer syntax | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| bash -n install.sh | |
| pwsh -NoProfile -Command '$tokens = $null; $errors = $null; [System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path "./install.ps1"), [ref] $tokens, [ref] $errors) | Out-Null; if ($errors.Count) { $errors | ForEach-Object { Write-Error $_ }; exit 1 }' | |
| - name: Validate checksums and manifests | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| python3 - <<'PY' | |
| import hashlib | |
| import json | |
| import pathlib | |
| import sys | |
| root = pathlib.Path(".") | |
| expected = {} | |
| checksums_text = root / "install/checksums.txt" | |
| if b"\r" in checksums_text.read_bytes(): | |
| sys.exit("install/checksums.txt must use LF line endings so shasum -c works on macOS") | |
| for line in checksums_text.read_text(encoding="utf-8").splitlines(): | |
| line = line.strip() | |
| if not line: | |
| continue | |
| digest, relpath = line.split(maxsplit=1) | |
| expected[relpath] = digest | |
| for relpath, digest in expected.items(): | |
| actual = hashlib.sha256((root / relpath).read_bytes()).hexdigest() | |
| if actual != digest: | |
| sys.exit(f"{relpath} checksum mismatch: {actual} != {digest}") | |
| checksums = json.loads((root / "install/checksums.json").read_text(encoding="utf-8")) | |
| commands = json.loads((root / "install/commands.json").read_text(encoding="utf-8")) | |
| manifest = json.loads((root / "install/release-manifest.json").read_text(encoding="utf-8")) | |
| json_hashes = {entry["path"]: entry["sha256"] for entry in checksums["files"]} | |
| command_hashes = commands["checksums"]["sha256"] | |
| if json_hashes != expected: | |
| sys.exit("checksums.json does not match checksums.txt") | |
| if command_hashes != expected: | |
| sys.exit("commands.json checksums do not match checksums.txt") | |
| manifest_ref = manifest["sparkCli"].get("ref", manifest["sparkCli"]["commit"]) | |
| if commands["source"]["ref"] != manifest_ref: | |
| sys.exit("commands.json source ref does not match release manifest") | |
| if commands["source"].get("commit") and commands["source"]["commit"] != manifest["sparkCli"]["commit"]: | |
| sys.exit("commands.json source commit does not match release manifest") | |
| if not all(len(value) == 64 for value in manifest["runtimes"]["uv"]["assets"].values()): | |
| sys.exit("release manifest uv asset hashes must be sha256 digests") | |
| for relpath, digest in expected.items(): | |
| for haystack in [ | |
| (root / "install/checksums.json").read_text(encoding="utf-8"), | |
| (root / "install/commands.json").read_text(encoding="utf-8"), | |
| (root / "install/attestations.md").read_text(encoding="utf-8"), | |
| ]: | |
| if digest not in haystack: | |
| sys.exit(f"{digest} missing from published verification metadata") | |
| PY | |
| shasum -a 256 -c install/checksums.txt | |
| node scripts/check-security-release-surface.mjs | |
| - name: Validate trust boundary | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| spark_ref="$(python3 -c 'import json; s=json.load(open("install/release-manifest.json"))["sparkCli"]; print(s.get("ref", s["commit"]))')" | |
| grep -q "SPARK_ALLOW_DEV_SOURCE" install.sh | |
| grep -q "AllowDevSource" install.ps1 | |
| grep -q "Refusing non-canonical Spark CLI source" install.sh | |
| grep -q "Refusing non-canonical Spark CLI source" install.ps1 | |
| grep -q "Refusing custom git ref without --allow-dev-source" install.sh | |
| grep -q "Refusing custom git ref without -AllowDevSource" install.ps1 | |
| grep -q "Strict-Transport-Security" nginx.conf | |
| grep -q "location = /install" nginx.conf | |
| grep -q "location = /install/commands.json" nginx.conf | |
| grep -q "location = /commands.json" nginx.conf | |
| grep -q "location = /docs" nginx.conf | |
| grep -q "location = /install/attestations.md" nginx.conf | |
| grep -q "location = /install/signatures.md" nginx.conf | |
| grep -q "location = /install/release-manifest.json" nginx.conf | |
| grep -q "location = /SECURITY.md" nginx.conf | |
| grep -q "location = /.well-known/security.txt" nginx.conf | |
| grep -q "location = /llms.txt" nginx.conf | |
| grep -q "location = /llms-full.txt" nginx.conf | |
| grep -q "location = /.well-known/llms.txt" nginx.conf | |
| grep -q "X-Llms-Txt" nginx.conf | |
| grep -q "location = /docs/install-safety/" nginx.conf | |
| grep -q "location = /docs/suites/" nginx.conf | |
| grep -q "location = /docs/self-improvement/" nginx.conf | |
| grep -q "location = /docs/lifecycle/" nginx.conf | |
| grep -q "location = /docs/install-safety.md" nginx.conf | |
| grep -q "location = /docs/suites.md" nginx.conf | |
| grep -q "location = /docs/self-improvement.md" nginx.conf | |
| grep -q "location = /docs/lifecycle.md" nginx.conf | |
| grep -q "location \\^~ /docs/pages/" nginx.conf | |
| grep -q "Install Spark without guessing" docs/install-safety/index.html | |
| grep -q "The starter kit in normal words" docs/suites/index.html | |
| grep -q "Turn Spark on, check it, and stop it safely" docs/lifecycle/index.html | |
| grep -q "Make agents better with scored loops" docs/self-improvement/index.html | |
| grep -q "Spark Suites" docs/suites.md | |
| grep -q "Spark Self-Improvement" docs/self-improvement.md | |
| grep -q "Spark Agent Full Context" llms-full.txt | |
| grep -q "Canonical: https://agent.sparkswarm.ai/.well-known/security.txt" .well-known/security.txt | |
| grep -q "Contact: mailto:" .well-known/security.txt | |
| grep -q "gh attestation verify" install/commands.json | |
| grep -q "cosign verify-blob" install/commands.json | |
| grep -q "cosign verify-blob" install/signatures.md | |
| grep -q "release-manifest.json" index.html | |
| grep -q "$spark_ref" install.sh | |
| grep -q "$spark_ref" install.ps1 | |
| grep -q "uv archive checksum mismatch" install.sh | |
| grep -q "uv archive checksum mismatch" install.ps1 | |
| ! grep -q "astral.sh/uv/install.sh | sh" install.sh | |
| ! grep -q "Invoke-Expression" install.ps1 | |
| grep -q "actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26" .github/workflows/install-hardening.yml | |
| grep -q 'try_files $uri $uri/ =404;' nginx.conf | |
| ! grep -q 'try_files $uri $uri/ /index.html;' nginx.conf | |
| ! grep -q "add_header Cache-Control" nginx.conf | |
| ! git grep -n -I -E '301a16435504eaf2|9d32b1d17df505|docs\.sparkswarm\.ai|sparkswarm\.ai/docs/insight' -- . ':!.github/workflows/install-hardening.yml' | |
| - name: Validate command docs | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| node scripts/check-docs-readiness.mjs | |
| node scripts/check-command-docs.mjs | |
| git clone --depth 1 https://github.com/vibeforge1111/spark-cli "$RUNNER_TEMP/spark-cli" | |
| SPARK_CLI_PATH="$RUNNER_TEMP/spark-cli" node scripts/smoke-command-docs-cli.mjs | |
| - name: Build container | |
| shell: bash | |
| run: docker build -t spark-agent-site-hardening . | |
| - name: Attest release manifest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 | |
| with: | |
| subject-path: install/release-manifest.json | |
| - name: Attest installer provenance | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 | |
| with: | |
| subject-checksums: install/checksums.txt | |
| installer-smoke: | |
| name: installer-smoke (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd | |
| - name: Bash installer dry-run | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| bash -n install.sh | |
| SPARK_PREFIX="$RUNNER_TEMP/spark-installer-dry-run" bash install.sh --dry-run | |
| - name: PowerShell installer dry-run | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $tokens = $null | |
| $errors = $null | |
| [System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path "./install.ps1"), [ref] $tokens, [ref] $errors) | Out-Null | |
| if ($errors.Count) { | |
| $errors | ForEach-Object { Write-Error $_ } | |
| exit 1 | |
| } | |
| powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -Prefix "$env:RUNNER_TEMP\spark-installer-dry-run" -DryRun |