feat: Add native binary analyzer test utilities and implement SM2 signing tests
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled

- Introduced `NativeTestBase` class for ELF, PE, and Mach-O binary parsing helpers and assertions.
- Created `TestCryptoFactory` for SM2 cryptographic provider setup and key generation.
- Implemented `Sm2SigningTests` to validate signing functionality with environment gate checks.
- Developed console export service and store with comprehensive unit tests for export status management.
This commit is contained in:
StellaOps Bot
2025-12-07 13:12:41 +02:00
parent d907729778
commit e53a282fbe
387 changed files with 21941 additions and 1518 deletions

View File

@@ -0,0 +1,128 @@
name: Artifact Signing
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
artifact_path:
description: 'Path to artifact to sign'
required: false
default: ''
env:
COSIGN_VERSION: 'v2.2.0'
jobs:
sign-containers:
name: Sign Container Images
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: read
id-token: write
packages: write
steps:
- uses: actions/checkout@v4
- name: Install cosign
uses: sigstore/cosign-installer@v3
with:
cosign-release: ${{ env.COSIGN_VERSION }}
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Sign images (keyless)
if: ${{ !env.COSIGN_PRIVATE_KEY_B64 }}
env:
COSIGN_EXPERIMENTAL: "1"
run: |
IMAGES=(
"ghcr.io/${{ github.repository }}/concelier"
"ghcr.io/${{ github.repository }}/scanner"
"ghcr.io/${{ github.repository }}/authority"
)
for img in "${IMAGES[@]}"; do
if docker manifest inspect "${img}:${{ github.ref_name }}" > /dev/null 2>&1; then
echo "Signing ${img}:${{ github.ref_name }}..."
cosign sign --yes "${img}:${{ github.ref_name }}"
fi
done
- name: Sign images (with key)
if: ${{ env.COSIGN_PRIVATE_KEY_B64 }}
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY_B64 }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
run: |
echo "$COSIGN_PRIVATE_KEY" | base64 -d > /tmp/cosign.key
IMAGES=(
"ghcr.io/${{ github.repository }}/concelier"
"ghcr.io/${{ github.repository }}/scanner"
"ghcr.io/${{ github.repository }}/authority"
)
for img in "${IMAGES[@]}"; do
if docker manifest inspect "${img}:${{ github.ref_name }}" > /dev/null 2>&1; then
echo "Signing ${img}:${{ github.ref_name }}..."
cosign sign --key /tmp/cosign.key "${img}:${{ github.ref_name }}"
fi
done
rm -f /tmp/cosign.key
sign-sbom:
name: Sign SBOM Artifacts
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- name: Install cosign
uses: sigstore/cosign-installer@v3
with:
cosign-release: ${{ env.COSIGN_VERSION }}
- name: Generate and sign SBOM
run: |
# Generate SBOM using syft
if command -v syft &> /dev/null; then
syft . -o cyclonedx-json > sbom.cdx.json
cosign sign-blob --yes sbom.cdx.json --output-signature sbom.cdx.json.sig
else
echo "syft not installed, skipping SBOM generation"
fi
- name: Upload signed artifacts
uses: actions/upload-artifact@v4
with:
name: signed-sbom
path: |
sbom.cdx.json
sbom.cdx.json.sig
if-no-files-found: ignore
verify-signatures:
name: Verify Existing Signatures
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install cosign
uses: sigstore/cosign-installer@v3
with:
cosign-release: ${{ env.COSIGN_VERSION }}
- name: Verify DSSE envelopes
run: |
find . -name "*.dsse" -o -name "*.dsse.json" | while read f; do
echo "Checking $f..."
# Basic JSON validation
if ! jq empty "$f" 2>/dev/null; then
echo "Warning: Invalid JSON in $f"
fi
done

View File

@@ -0,0 +1,125 @@
name: Manifest Integrity
on:
push:
branches: [main]
paths:
- 'docs/**/*.schema.json'
- 'docs/contracts/**'
- 'docs/schemas/**'
- 'scripts/packs/**'
pull_request:
paths:
- 'docs/**/*.schema.json'
- 'docs/contracts/**'
- 'docs/schemas/**'
- 'scripts/packs/**'
jobs:
validate-schemas:
name: Validate Schema Integrity
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install -g ajv-cli ajv-formats
- name: Validate JSON schemas
run: |
EXIT_CODE=0
for schema in docs/schemas/*.schema.json; do
echo "Validating $schema..."
if ! ajv compile -s "$schema" --spec=draft2020 2>/dev/null; then
echo "Error: $schema is invalid"
EXIT_CODE=1
fi
done
exit $EXIT_CODE
validate-contracts:
name: Validate Contract Documents
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check contract structure
run: |
for contract in docs/contracts/*.md; do
echo "Checking $contract..."
# Verify required sections exist
if ! grep -q "^## " "$contract"; then
echo "Warning: $contract missing section headers"
fi
# Check for decision ID
if grep -q "Decision ID" "$contract" && ! grep -q "DECISION-\|CONTRACT-" "$contract"; then
echo "Warning: $contract missing decision ID format"
fi
done
validate-pack-fixtures:
name: Validate Pack Fixtures
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install jsonschema
- name: Run fixture validation
run: |
if [ -f scripts/packs/run-fixtures-check.sh ]; then
chmod +x scripts/packs/run-fixtures-check.sh
./scripts/packs/run-fixtures-check.sh
fi
checksum-audit:
name: Audit SHA256SUMS Files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate checksums
run: |
find . -name "SHA256SUMS" -type f | while read f; do
dir=$(dirname "$f")
echo "Validating checksums in $dir..."
cd "$dir"
# Check if all referenced files exist
while read hash file; do
if [ ! -f "$file" ]; then
echo "Warning: $file referenced in SHA256SUMS but not found"
fi
done < SHA256SUMS
cd - > /dev/null
done
merkle-consistency:
name: Verify Merkle Roots
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check DSSE Merkle roots
run: |
find . -name "*.dsse.json" -type f | while read f; do
echo "Checking Merkle root in $f..."
# Extract and validate Merkle root if present
if jq -e '.payload' "$f" > /dev/null 2>&1; then
PAYLOAD=$(jq -r '.payload' "$f" | base64 -d 2>/dev/null || echo "")
if echo "$PAYLOAD" | jq -e '._stellaops.merkleRoot' > /dev/null 2>&1; then
MERKLE=$(echo "$PAYLOAD" | jq -r '._stellaops.merkleRoot')
echo " Merkle root: $MERKLE"
fi
fi
done

View File

@@ -0,0 +1,102 @@
name: Notify Smoke Test
on:
push:
branches: [main]
paths:
- 'src/Notify/**'
- 'src/Notifier/**'
pull_request:
paths:
- 'src/Notify/**'
- 'src/Notifier/**'
workflow_dispatch:
env:
DOTNET_VERSION: '10.0.x'
jobs:
unit-tests:
name: Notify Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Restore dependencies
run: dotnet restore src/Notify/
- name: Build
run: dotnet build src/Notify/ --no-restore
- name: Run tests
run: dotnet test src/Notify/ --no-build --verbosity normal
notifier-tests:
name: Notifier Service Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Restore dependencies
run: dotnet restore src/Notifier/
- name: Build
run: dotnet build src/Notifier/ --no-restore
- name: Run tests
run: dotnet test src/Notifier/ --no-build --verbosity normal
smoke-test:
name: Notification Smoke Test
runs-on: ubuntu-latest
needs: [unit-tests, notifier-tests]
services:
mongodb:
image: mongo:7.0
ports:
- 27017:27017
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Build Notifier
run: dotnet build src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/
- name: Start service
run: |
dotnet run --project src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/ &
sleep 10
- name: Health check
run: |
for i in {1..30}; do
if curl -s http://localhost:5000/health > /dev/null; then
echo "Service is healthy"
exit 0
fi
sleep 1
done
echo "Service failed to start"
exit 1
- name: Test notification endpoint
run: |
# Test dry-run notification
curl -X POST http://localhost:5000/api/v1/notifications/test \
-H "Content-Type: application/json" \
-d '{"channel": "log", "message": "Smoke test", "dryRun": true}' \
|| echo "Warning: Notification test endpoint not available"

View File

@@ -0,0 +1,120 @@
name: Release Validation
on:
push:
tags:
- 'v*'
pull_request:
paths:
- 'deploy/**'
- 'scripts/release/**'
workflow_dispatch:
env:
DOTNET_VERSION: '10.0.x'
REGISTRY: ghcr.io
IMAGE_PREFIX: stellaops
jobs:
validate-manifests:
name: Validate Release Manifests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Helm charts
run: |
helm lint deploy/helm/stellaops
helm template stellaops deploy/helm/stellaops --dry-run
- name: Validate Kubernetes manifests
run: |
for f in deploy/k8s/*.yaml; do
kubectl apply --dry-run=client -f "$f" || exit 1
done
- name: Check required images exist
run: |
REQUIRED_IMAGES=(
"concelier"
"scanner"
"authority"
"signer"
"attestor"
"excititor"
"policy"
"scheduler"
"notify"
)
for img in "${REQUIRED_IMAGES[@]}"; do
echo "Checking $img..."
# Validate Dockerfile exists
if [ ! -f "src/${img^}/Dockerfile" ] && [ ! -f "deploy/docker/${img}/Dockerfile" ]; then
echo "Warning: Dockerfile not found for $img"
fi
done
validate-checksums:
name: Validate Artifact Checksums
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify SHA256SUMS files
run: |
find . -name "SHA256SUMS" -type f | while read f; do
dir=$(dirname "$f")
echo "Validating $f..."
cd "$dir"
if ! sha256sum -c SHA256SUMS --quiet 2>/dev/null; then
echo "Warning: Checksum mismatch in $dir"
fi
cd - > /dev/null
done
validate-schemas:
name: Validate Schema Integrity
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install ajv-cli
run: npm install -g ajv-cli ajv-formats
- name: Validate JSON schemas
run: |
for schema in docs/schemas/*.schema.json; do
echo "Validating $schema..."
ajv compile -s "$schema" --spec=draft2020 || echo "Warning: $schema validation issue"
done
release-notes:
name: Generate Release Notes
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
needs: [validate-manifests, validate-checksums, validate-schemas]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate changelog
run: |
PREV_TAG=$(git describe --abbrev=0 --tags HEAD^ 2>/dev/null || echo "")
if [ -n "$PREV_TAG" ]; then
echo "## Changes since $PREV_TAG" > RELEASE_NOTES.md
git log --pretty=format:"- %s (%h)" "$PREV_TAG"..HEAD >> RELEASE_NOTES.md
else
echo "## Initial Release" > RELEASE_NOTES.md
fi
- name: Upload release notes
uses: actions/upload-artifact@v4
with:
name: release-notes
path: RELEASE_NOTES.md

View File

@@ -0,0 +1,133 @@
name: Scanner Analyzers
on:
push:
branches: [main]
paths:
- 'src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.*/**'
- 'src/Scanner/__Tests/StellaOps.Scanner.Analyzers.*/**'
pull_request:
paths:
- 'src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.*/**'
- 'src/Scanner/__Tests/StellaOps.Scanner.Analyzers.*/**'
workflow_dispatch:
env:
DOTNET_VERSION: '10.0.x'
jobs:
discover-analyzers:
name: Discover Analyzers
runs-on: ubuntu-latest
outputs:
analyzers: ${{ steps.find.outputs.analyzers }}
steps:
- uses: actions/checkout@v4
- name: Find analyzer projects
id: find
run: |
ANALYZERS=$(find src/Scanner/__Libraries -name "StellaOps.Scanner.Analyzers.*.csproj" -exec dirname {} \; | xargs -I {} basename {} | sort -u | jq -R -s -c 'split("\n")[:-1]')
echo "analyzers=$ANALYZERS" >> $GITHUB_OUTPUT
build-analyzers:
name: Build Analyzers
runs-on: ubuntu-latest
needs: discover-analyzers
strategy:
fail-fast: false
matrix:
analyzer: ${{ fromJson(needs.discover-analyzers.outputs.analyzers) }}
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Restore
run: dotnet restore src/Scanner/__Libraries/${{ matrix.analyzer }}/
- name: Build
run: dotnet build src/Scanner/__Libraries/${{ matrix.analyzer }}/ --no-restore
test-lang-analyzers:
name: Test Language Analyzers
runs-on: ubuntu-latest
needs: build-analyzers
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Run Bun analyzer tests
run: |
if [ -d "src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests" ]; then
dotnet test src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests/ --verbosity normal
fi
- name: Run Node analyzer tests
run: |
if [ -d "src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests" ]; then
dotnet test src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/ --verbosity normal
fi
fixture-validation:
name: Validate Test Fixtures
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate fixture structure
run: |
find src/Scanner/__Tests -name "expected.json" | while read f; do
echo "Validating $f..."
if ! jq empty "$f" 2>/dev/null; then
echo "Error: Invalid JSON in $f"
exit 1
fi
done
- name: Check fixture completeness
run: |
find src/Scanner/__Tests -type d -name "Fixtures" | while read fixtures_dir; do
echo "Checking $fixtures_dir..."
find "$fixtures_dir" -mindepth 1 -maxdepth 1 -type d | while read test_case; do
if [ ! -f "$test_case/expected.json" ]; then
echo "Warning: $test_case missing expected.json"
fi
done
done
determinism-check:
name: Verify Deterministic Output
runs-on: ubuntu-latest
needs: test-lang-analyzers
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Run determinism tests
run: |
# Run scanner on same input twice, compare outputs
if [ -d "tests/fixtures/determinism" ]; then
dotnet test --filter "Category=Determinism" --verbosity normal
fi