feat: add completeness UI report generation and score extraction #52
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: AIBomGen-cli Integration Test | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| jobs: | |
| integration: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Dummy mode: no input required (fixture not used) | |
| - fixture: none | |
| format: json | |
| hf-mode: dummy | |
| - fixture: none | |
| format: xml | |
| hf-mode: dummy | |
| # Online mode: both fixtures, both formats | |
| - fixture: repo-10 | |
| format: json | |
| hf-mode: online | |
| - fixture: repo-10 | |
| format: xml | |
| hf-mode: online | |
| - fixture: repo-basic | |
| format: json | |
| hf-mode: online | |
| - fixture: repo-basic | |
| format: xml | |
| hf-mode: online | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go 1.25.x | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.25.x' | |
| check-latest: true | |
| cache: true | |
| cache-dependency-path: | | |
| **/go.sum | |
| **/go.work.sum | |
| - name: Cache dist directory | |
| uses: actions/cache@v4 | |
| with: | |
| path: dist | |
| key: ${{ runner.os }}-dist-${{ matrix.fixture }}-${{ matrix.format }}-${{ matrix.hf-mode }}-${{ github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-dist-${{ matrix.fixture }}-${{ matrix.format }}-${{ matrix.hf-mode }}- | |
| - name: Download dependencies | |
| run: go mod download | |
| - name: Run generator | |
| env: | |
| FIXTURE: ${{ matrix.fixture }} | |
| OUTPUT_FORMAT: ${{ matrix.format }} | |
| HF_MODE: ${{ matrix.hf-mode }} | |
| run: | | |
| set -euo pipefail | |
| if [ "${HF_MODE}" = "dummy" ]; then | |
| INPUT_FLAG="" | |
| FIXTURE_DIR="no-input" | |
| else | |
| INPUT_FLAG="--input ./testdata/${FIXTURE}" | |
| FIXTURE_DIR="${FIXTURE}" | |
| fi | |
| TARGET_DIR="dist/integration/${FIXTURE_DIR}/${OUTPUT_FORMAT}/${HF_MODE}" | |
| rm -rf "${TARGET_DIR}" | |
| mkdir -p "${TARGET_DIR}" | |
| FORMAT_FLAG="--format ${OUTPUT_FORMAT}" | |
| go run . generate \ | |
| ${INPUT_FLAG} \ | |
| --output "${TARGET_DIR}/aibom.${OUTPUT_FORMAT}" \ | |
| ${FORMAT_FLAG} \ | |
| --hf-mode "${HF_MODE}" \ | |
| --log-level debug | |
| - name: Validate generated AIBOM files | |
| env: | |
| FIXTURE: ${{ matrix.fixture }} | |
| OUTPUT_FORMAT: ${{ matrix.format }} | |
| HF_MODE: ${{ matrix.hf-mode }} | |
| run: | | |
| set -euo pipefail | |
| if [ "${HF_MODE}" = "dummy" ]; then | |
| FIXTURE_DIR="no-input" | |
| else | |
| FIXTURE_DIR="${FIXTURE}" | |
| fi | |
| TARGET_DIR="dist/integration/${FIXTURE_DIR}/${OUTPUT_FORMAT}/${HF_MODE}" | |
| REPORT_DIR="reports/${FIXTURE_DIR}/${OUTPUT_FORMAT}/${HF_MODE}" | |
| if [ ! -d "${TARGET_DIR}" ]; then | |
| echo "${TARGET_DIR} missing" | |
| exit 1 | |
| fi | |
| mapfile -t bom_files < <(find "${TARGET_DIR}" -maxdepth 1 -type f -name '*_aibom.*') | |
| if [ "${#bom_files[@]}" -eq 0 ]; then | |
| echo "No AIBOM files generated under ${TARGET_DIR}" | |
| exit 1 | |
| fi | |
| rm -rf "${REPORT_DIR}" | |
| mkdir -p "${REPORT_DIR}" | |
| SUMMARY_FILE="${REPORT_DIR}/scores.txt" | |
| : > "${SUMMARY_FILE}" | |
| for file in "${bom_files[@]}"; do | |
| if [ ! -s "$file" ]; then | |
| echo "Generated file $file is empty" | |
| exit 1 | |
| fi | |
| base="$(basename "$file" | sed 's/\.[^.]*$//')" | |
| LOG="${REPORT_DIR}/${base}.log" | |
| go run . validate \ | |
| --input "$file" \ | |
| --format auto \ | |
| --log-level debug \ | |
| --strict \ | |
| --min-score 0.1 2>&1 | tee "$LOG" | |
| # Also run completeness UI to produce a human-friendly summary report | |
| COMPLETENESS_LOG="${REPORT_DIR}/${base}.completeness" | |
| go run . completeness \ | |
| --input "$file" \ | |
| --format auto \ | |
| --log-level standard 2>&1 | tee "$COMPLETENESS_LOG" | |
| # Extract a single score line from the completeness output for short summaries | |
| score_line=$(grep -E 'Model score:|Score: .*%|Score.*%|Completeness: .*%' "$COMPLETENESS_LOG" | head -1 || true) | |
| if [ -z "$score_line" ]; then | |
| score_line="completeness score: unavailable" | |
| fi | |
| summary_entry="$base: $score_line" | |
| echo "$summary_entry" | tee -a "$SUMMARY_FILE" | |
| done | |
| if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then | |
| { | |
| echo "### ${FIXTURE_DIR} | ${OUTPUT_FORMAT} | ${HF_MODE}" | |
| cat "$SUMMARY_FILE" | |
| echo | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| fi | |
| - name: Upload AIBOM artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: aibom-${{ matrix.hf-mode == 'dummy' && 'no-input' || matrix.fixture }}-${{ matrix.format }}-${{ matrix.hf-mode }} | |
| path: dist/integration/${{ matrix.hf-mode == 'dummy' && 'no-input' || matrix.fixture }}/${{ matrix.format }}/${{ matrix.hf-mode }} | |
| if-no-files-found: error | |
| - name: Upload validator reports | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: validator-${{ matrix.hf-mode == 'dummy' && 'no-input' || matrix.fixture }}-${{ matrix.format }}-${{ matrix.hf-mode }} | |
| path: reports/${{ matrix.hf-mode == 'dummy' && 'no-input' || matrix.fixture }}/${{ matrix.format }}/${{ matrix.hf-mode }} | |
| if-no-files-found: error |