21 feat summary nb fonctions nb warnings top n stacks #39
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: Test CI Integration | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "Dockerfile" | |
| - "action.yml" | |
| - "scripts/ci/**" | |
| - "fixtures/ci-consumer-project/**" | |
| - ".github/workflows/test-ci-integration.yml" | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| # ================================================================= | |
| # Job 1: Test the GitHub Action (composite action, local reference) | |
| # ================================================================= | |
| test-github-action: | |
| name: Test GitHub Action | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Run CoreTrace Stack Analyzer (action) | |
| uses: ./ | |
| id: analysis | |
| with: | |
| sources: test/alloca/oversized-constant.c | |
| fail-on: none | |
| base-dir: ${{ github.workspace }} | |
| sarif-file: action-results.sarif | |
| json-file: action-results.json | |
| upload-sarif: false | |
| - name: Validate SARIF output | |
| run: | | |
| echo "=== Checking SARIF file exists ===" | |
| test -f action-results.sarif || { echo "SARIF file missing!"; exit 1; } | |
| echo "=== Validating JSON structure ===" | |
| python3 -c " | |
| import json, sys | |
| with open('action-results.sarif') as f: | |
| d = json.load(f) | |
| assert d['version'] == '2.1.0', 'Wrong SARIF version' | |
| assert len(d['runs']) > 0, 'No runs in SARIF' | |
| run = d['runs'][0] | |
| assert run['tool']['driver']['name'] == 'coretrace-stack-analyzer', 'Wrong tool name' | |
| # Check that URIs are relative (no leading /) | |
| for result in run.get('results', []): | |
| for loc in result.get('locations', []): | |
| uri = loc['physicalLocation']['artifactLocation']['uri'] | |
| assert not uri.startswith('/'), f'URI is absolute: {uri}' | |
| print(f' OK: {uri}') | |
| print('SARIF validation passed!') | |
| " | |
| - name: Validate JSON output | |
| run: | | |
| test -f action-results.json || { echo "JSON file missing!"; exit 1; } | |
| python3 -c " | |
| import json | |
| with open('action-results.json') as f: | |
| d = json.load(f) | |
| assert 'diagnostics' in d, 'Missing diagnostics key' | |
| assert len(d['diagnostics']) > 0, 'No diagnostics found' | |
| print(f'JSON validation passed! Found {len(d[\"diagnostics\"])} diagnostic(s).') | |
| " | |
| # ================================================================= | |
| # Job 2: Test the Docker image | |
| # ================================================================= | |
| test-docker: | |
| name: Test Docker Image | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Resolve image reference | |
| run: | | |
| owner_lower="$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')" | |
| echo "CORETRACE_IMAGE=ghcr.io/${owner_lower}/coretrace-stack-analyzer:latest" >> "$GITHUB_ENV" | |
| - name: Pull Docker image | |
| run: docker pull "${CORETRACE_IMAGE}" | |
| - name: Run analyzer via Docker (SARIF) | |
| run: | | |
| docker run --rm -v "${{ github.workspace }}:/workspace" \ | |
| "${CORETRACE_IMAGE}" \ | |
| --raw \ | |
| /workspace/test/alloca/oversized-constant.c \ | |
| --format=sarif \ | |
| --base-dir=/workspace \ | |
| > docker-results.sarif | |
| - name: Validate Docker SARIF output | |
| run: | | |
| echo "=== Checking SARIF file ===" | |
| test -s docker-results.sarif || { echo "SARIF file empty!"; exit 1; } | |
| python3 -c " | |
| import json, sys | |
| with open('docker-results.sarif') as f: | |
| d = json.load(f) | |
| assert d['version'] == '2.1.0', 'Wrong SARIF version' | |
| run = d['runs'][0] | |
| assert run['tool']['driver']['name'] == 'coretrace-stack-analyzer' | |
| for result in run.get('results', []): | |
| for loc in result.get('locations', []): | |
| uri = loc['physicalLocation']['artifactLocation']['uri'] | |
| assert not uri.startswith('/'), f'URI is absolute: {uri}' | |
| print(f' OK: {uri}') | |
| print('Docker SARIF validation passed!') | |
| " | |
| - name: Run analyzer via Docker (JSON) | |
| run: | | |
| docker run --rm -v "${{ github.workspace }}:/workspace" \ | |
| "${CORETRACE_IMAGE}" \ | |
| --raw \ | |
| /workspace/test/alloca/oversized-constant.c \ | |
| --format=json \ | |
| > docker-results.json | |
| - name: Validate Docker JSON output | |
| run: | | |
| python3 -c " | |
| import json | |
| with open('docker-results.json') as f: | |
| d = json.load(f) | |
| assert 'diagnostics' in d | |
| assert len(d['diagnostics']) > 0 | |
| print(f'Docker JSON validation passed! Found {len(d[\"diagnostics\"])} diagnostic(s).') | |
| " | |
| - name: Run CI helper script via Docker | |
| run: | | |
| docker run --rm \ | |
| -v "${{ github.workspace }}:/workspace" \ | |
| --entrypoint python3 \ | |
| "${CORETRACE_IMAGE}" \ | |
| /usr/local/bin/run_code_analysis.py \ | |
| /workspace/test/alloca/oversized-constant.c \ | |
| --analyzer /usr/local/bin/stack_usage_analyzer \ | |
| --json-out /workspace/docker-ci-results.json \ | |
| --sarif-out /workspace/docker-ci-results.sarif \ | |
| --base-dir /workspace \ | |
| --fail-on none | |
| - name: Validate CI script output | |
| run: | | |
| test -f docker-ci-results.sarif || { echo "CI SARIF missing!"; exit 1; } | |
| test -f docker-ci-results.json || { echo "CI JSON missing!"; exit 1; } | |
| echo "CI script Docker test passed!" | |
| # ================================================================= | |
| # Job 3: Test analyzer on a minimal consumer project in CI | |
| # ================================================================= | |
| test-consumer-project: | |
| name: Test Consumer Project | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Configure consumer fixture (compile_commands.json) | |
| run: | | |
| cmake -S fixtures/ci-consumer-project -B fixtures/ci-consumer-project/build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_EXPORT_COMPILE_COMMANDS=ON | |
| - name: Run CoreTrace Stack Analyzer (consumer fixture) | |
| uses: ./ | |
| id: consumer-analysis | |
| with: | |
| compile-commands: fixtures/ci-consumer-project/build/compile_commands.json | |
| fail-on: none | |
| base-dir: ${{ github.workspace }} | |
| analysis-profile: fast | |
| resource-model: default | |
| resource-cache-memory-only: "true" | |
| warnings-only: "false" | |
| sarif-file: artifacts/consumer/action-results.sarif | |
| json-file: artifacts/consumer/action-results.json | |
| upload-sarif: false | |
| - name: Validate consumer JSON and SARIF | |
| run: | | |
| python3 - <<'PY' | |
| import json | |
| from pathlib import Path | |
| json_path = Path("artifacts/consumer/action-results.json") | |
| sarif_path = Path("artifacts/consumer/action-results.sarif") | |
| assert json_path.is_file(), f"Missing JSON output: {json_path}" | |
| assert sarif_path.is_file(), f"Missing SARIF output: {sarif_path}" | |
| payload = json.loads(json_path.read_text(encoding="utf-8")) | |
| diagnostics = payload.get("diagnostics", []) | |
| assert diagnostics, "Expected at least one diagnostic in JSON output" | |
| print(f"JSON diagnostics: {len(diagnostics)}") | |
| sarif = json.loads(sarif_path.read_text(encoding="utf-8")) | |
| assert sarif.get("version") == "2.1.0", "Invalid SARIF version" | |
| runs = sarif.get("runs", []) | |
| assert runs, "SARIF has no runs" | |
| results = runs[0].get("results", []) | |
| assert results, "Expected at least one SARIF result" | |
| for result in results: | |
| for loc in result.get("locations", []): | |
| physical = loc.get("physicalLocation", {}) | |
| artifact = physical.get("artifactLocation", {}) | |
| uri = artifact.get("uri", "") | |
| assert not uri.startswith("/"), f"URI must be relative: {uri}" | |
| region = physical.get("region", {}) | |
| col = int(region.get("startColumn", 1)) | |
| assert col >= 1, f"Invalid SARIF startColumn: {col}" | |
| print(f"SARIF results: {len(results)}") | |
| PY | |
| - name: Upload consumer fixture artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ci-consumer-analysis | |
| path: | | |
| artifacts/consumer/action-results.json | |
| artifacts/consumer/action-results.sarif |