diff --git a/.github/actions/ocr-envelope/build-envelope.sh b/.github/actions/ocr-envelope/build-envelope.sh index a25ad05..bbd3183 100755 --- a/.github/actions/ocr-envelope/build-envelope.sh +++ b/.github/actions/ocr-envelope/build-envelope.sh @@ -23,9 +23,28 @@ WARNING_COUNT=0 if [ -f "$OCR_RESULT_FILE" ]; then echo "Reading OCR results from ${OCR_RESULT_FILE}" - # Parse OCR JSON output — the format varies by OCR version - # Common fields: issues, warnings, errors, summary, review_comments - FINDINGS=$(cat "$OCR_RESULT_FILE" | jq '[.issues // (.review_comments // (.results // []))] | flatten' 2>/dev/null || echo '[]') + # Parse OCR JSON output — format varies by command and version + # ocr review: .issues[] or .review_comments[] + # ocr scan: .comments[] with {path, content, start_line, end_line, ...} + RAW_JSON=$(cat "$OCR_RESULT_FILE") + + # Extract comment-like findings from the various OCR output shapes + FINDINGS=$(echo "$RAW_JSON" | jq ' + if .issues then .issues + elif .review_comments then .review_comments + elif .comments then + # Map scan comments to uniform findings format + [.comments[] | { + file: .path, + line: (.start_line // 0), + message: .content, + severity: "warning", + suggestion: (.suggestion_code // "") + }] + elif .results then .results + else [] + end | flatten + ' 2>/dev/null || echo '[]') # Count by severity ERROR_COUNT=$(echo "$FINDINGS" | jq '[.[] | select(.severity == "error" or .severity == "critical" or .severity == "high")] | length' 2>/dev/null || echo 0) @@ -42,15 +61,26 @@ if [ -f "$OCR_RESULT_FILE" ]; then fi # Build summary from OCR report - REVIEW_SUMMARY=$(cat "$OCR_RESULT_FILE" | jq -r '.summary // (.review_summary // "\(.issues | length) issues found")' 2>/dev/null || echo "OCR ${OCR_COMMAND} completed") + COMMENT_COUNT=$(echo "$FINDINGS" | jq 'length' 2>/dev/null || echo 0) + REVIEW_SUMMARY=$(echo "$RAW_JSON" | jq -r ' + if .summary | type == "object" then + "\(.summary.files_reviewed // "?") file(s) reviewed, \(.summary.comments // 0) comment(s)" + elif .summary | type == "string" then .summary + elif .review_summary then .review_summary + else "\(.issues | length) issues found" + end + ' 2>/dev/null || echo "OCR ${OCR_COMMAND} completed") SUMMARY="${ERROR_COUNT} errors, ${WARNING_COUNT} warnings, ${INFO_COUNT:-0} info — ${REVIEW_SUMMARY}" # Build outputs containing the raw OCR data - AGENT_OUTPUTS=$(cat "$OCR_RESULT_FILE" | jq '{ocr_command: $cmd, issue_count: (.issues | length)}' --arg cmd "$OCR_COMMAND" 2>/dev/null || echo '{}') + AGENT_OUTPUTS=$(echo "$RAW_JSON" | jq '{ocr_command: $cmd, comment_count: $count}' \ + --arg cmd "$OCR_COMMAND" \ + --argjson count "$COMMENT_COUNT" \ + 2>/dev/null || echo '{}') export AGENT_OUTPUTS # Only include findings if there are any - if [ "$(echo "$FINDINGS" | jq 'length' 2>/dev/null || echo 0)" -gt 0 ]; then + if [ "$COMMENT_COUNT" -gt 0 ]; then export AGENT_FINDINGS="$FINDINGS" fi diff --git a/.github/workflows/ocr-scan.yml b/.github/workflows/ocr-scan.yml index e8b8145..9e72892 100644 --- a/.github/workflows/ocr-scan.yml +++ b/.github/workflows/ocr-scan.yml @@ -57,34 +57,72 @@ jobs: with: fetch-depth: "0" - - name: "Run OCR Scan" - id: scan + - name: "Install and Configure OCR" + id: setup shell: bash env: OCR_LLM_URL: ${{ secrets.ocr_llm_url }} OCR_LLM_TOKEN: ${{ secrets.ocr_llm_token }} OCR_LLM_MODEL: ${{ secrets.ocr_llm_model || inputs.ocr-llm-model || vars.OCR_LLM_MODEL || 'claude-sonnet-4-20250514' }} OCR_USE_ANTHROPIC: ${{ inputs.ocr-use-anthropic || vars.OCR_LLM_USE_ANTHROPIC || 'true' }} + run: | + # Install OCR CLI globally (puts ocr on PATH) + npm install -g @alibaba-group/open-code-review + + echo "✅ ocr installed: $(ocr --version 2>&1 || true)" + + # Verify scan subcommand exists + if ! ocr scan --help >/dev/null 2>&1; then + echo "❌ 'ocr scan' subcommand not found" + exit 1 + fi + + # Configure LLM provider from workflow secrets + PROVIDER="ci-custom" + ocr config set provider "${PROVIDER}" + ocr config set "custom_providers.${PROVIDER}.url" "${OCR_LLM_URL}" + ocr config set "custom_providers.${PROVIDER}.api_key" "${OCR_LLM_TOKEN}" + ocr config set "custom_providers.${PROVIDER}.model" "${OCR_LLM_MODEL}" + + if [ "${OCR_USE_ANTHROPIC}" = "true" ]; then + ocr config set "custom_providers.${PROVIDER}.protocol" "anthropic" + else + ocr config set "custom_providers.${PROVIDER}.protocol" "openai" + fi + + # Test LLM connectivity + echo "🔌 Testing LLM connection..." + ocr llm test + + - name: "Run OCR Scan" + id: scan + shell: bash + env: + OCR_LLM_MODEL: ${{ secrets.ocr_llm_model || inputs.ocr-llm-model || vars.OCR_LLM_MODEL || 'claude-sonnet-4-20250514' }} SCAN_PATH: ${{ inputs.scan-path || github.event.inputs.scan-path || '.' }} run: | mkdir -p .ocr - # Run full repo scan via npx (guarantees latest OCR CLI version) echo "🔍 Scanning: ${SCAN_PATH}" - npx @open-code-review/cli@latest scan \ + + # Run full repo scan — JSON output goes to stdout with --audience agent + ocr scan \ --path "${SCAN_PATH}" \ --format json \ --audience agent \ - 2>&1 | tee .ocr/scan-output.txt + --model "${OCR_LLM_MODEL}" \ + > .ocr/result.json 2>.ocr/scan-stderr.txt - # Check for result.json output (OCR writes here) - if [ -f ".ocr/result.json" ]; then - echo "OCR results saved to .ocr/result.json" - elif [ -f ".ocr/report.json" ]; then - echo "OCR results saved to .ocr/report.json" + # Show stderr (if any) for debugging + if [ -s .ocr/scan-stderr.txt ]; then + cat .ocr/scan-stderr.txt >&2 + fi + + if [ -s .ocr/result.json ]; then + echo "✅ OCR results saved to .ocr/result.json" else - # Try to extract from stdout - tail -c 100000 .ocr/scan-output.txt | grep -oP '\{.*\}' | head -1 > .ocr/result.json 2>/dev/null || true + echo "⚠️ No JSON output from OCR scan — scan produced no results or failed" + rm -f .ocr/result.json fi - name: "Build Agent Envelope"