diff --git a/.gitea/workflows/kibot.yml b/.gitea/workflows/kibot.yml index b1fd327..60f24f4 100644 --- a/.gitea/workflows/kibot.yml +++ b/.gitea/workflows/kibot.yml @@ -1,30 +1,4 @@ -- name: Download component datasheets - if: steps.config_check.outputs.found == 'true' - continue-on-error: true - run: | - echo "Datasheets will be downloaded by KiBot's download_datasheets output" - echo "They will be saved in Generated/BoM/Datasheets/" - - # Create a README for the datasheets folder if KiBot creates it - if [ -d "${GITHUB_WORKSPACE}/Generated/BoM/Datasheets" ]; then - cat > "${GITHUB_WORKSPACE}/Generated/BoM/Datasheets/README.md" << EOF - # Component Datasheets - - This folder contains downloaded datasheets for components used in the project. - - - Datasheets are downloaded automatically from URLs in the schematic - - Files are named based on the component reference and original filename - - Only unique datasheets are downloaded (duplicates are linked) - - Generated on: $(date) - Project: ${{ steps.find_project.outputs.project_name }} - EOF - - echo "Datasheet folder contents:" - ls -la "${GITHUB_WORKSPACE}/Generated/BoM/Datasheets/" || true - else - echo "Note: Datasheet folder not created yet - will be created by KiBot" - finame: "KiBot PCB Generation" +name: "KiBot PCB Generation" # Controls when the action will run on: @@ -49,12 +23,27 @@ on: board_layers: description: 'Number of PCB layers' required: false - default: '2' + default: '4' type: choice options: - '2' - '4' - '6' + diff_old: + description: 'Old revision for diff (e.g., HEAD~1, commit hash, tag)' + required: false + default: 'HEAD~1' + type: string + diff_new: + description: 'New revision for diff (e.g., HEAD, commit hash, tag)' + required: false + default: 'HEAD' + type: string + enable_interactive_diff: + description: 'Generate interactive HTML diff' + required: false + default: false + type: boolean # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -64,7 +53,7 @@ jobs: steps: - uses: actions/checkout@v3 with: - # So we can run a diff between last 2 changes + # Fetch full history for diff generation fetch-depth: '0' - name: Find KiCad project @@ -105,7 +94,7 @@ jobs: # Use workflow input or default to 4 layers LAYERS="${{ github.event.inputs.board_layers }}" if [ -z "$LAYERS" ]; then - LAYERS="4" # Change this default if needed + LAYERS="4" fi echo "layers=$LAYERS" >> $GITHUB_OUTPUT echo "Using $LAYERS layer configuration" @@ -122,15 +111,158 @@ jobs: echo "No kibot.yaml found in repository root - will use --quick-start mode" fi + - name: Generate schematic diff + id: generate_diff + if: github.event_name == 'push' || github.event_name == 'pull_request' + run: | + PROJECT_DIR="${{ steps.find_project.outputs.project_dir }}" + PROJECT_NAME="${{ steps.find_project.outputs.project_name }}" + + # Create DIFF output directory + mkdir -p "${GITHUB_WORKSPACE}/Generated/DIFF" + cd "$PROJECT_DIR" + + # Get the previous commit hash + if [ "${{ github.event_name }}" = "pull_request" ]; then + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + else + # For push events, compare with previous commit + HEAD_SHA="${{ github.sha }}" + BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "") + fi + + if [ -z "$BASE_SHA" ]; then + echo "No previous commit found for comparison" + echo "has_diff=false" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "Comparing commits: $BASE_SHA...$HEAD_SHA" + + # Find all schematic files + SCH_FILES=$(find . -name "*.kicad_sch" -o -name "*.sch" | head -10) + + if [ -z "$SCH_FILES" ]; then + echo "No schematic files found" + echo "has_diff=false" >> $GITHUB_OUTPUT + exit 0 + fi + + # Generate diff for each schematic + DIFF_GENERATED=false + for SCH_FILE in $SCH_FILES; do + SCH_NAME=$(basename "$SCH_FILE" | sed 's/\.[^.]*$//') + + # Check if file changed between commits + if git diff --name-only "$BASE_SHA" "$HEAD_SHA" | grep -q "$SCH_FILE"; then + echo "Generating diff for $SCH_FILE" + + # Create temp directory for processing + TEMP_DIR=$(mktemp -d) + + # Export old version + git show "$BASE_SHA:$SCH_FILE" > "$TEMP_DIR/${SCH_NAME}_old.kicad_sch" 2>/dev/null || continue + + # Copy current version + cp "$SCH_FILE" "$TEMP_DIR/${SCH_NAME}_new.kicad_sch" + + # Try to use kidiff if available (better visual diff tool for KiCad) + if command -v kidiff &> /dev/null; then + kidiff -o "${GITHUB_WORKSPACE}/Generated/DIFF/${SCH_NAME}_diff.pdf" \ + "$TEMP_DIR/${SCH_NAME}_old.kicad_sch" \ + "$TEMP_DIR/${SCH_NAME}_new.kicad_sch" || true + fi + + # Also generate text diff + git diff "$BASE_SHA" "$HEAD_SHA" -- "$SCH_FILE" > "${GITHUB_WORKSPACE}/Generated/DIFF/${SCH_NAME}_changes.txt" + + # Generate a simple HTML diff for easy viewing + cat > "${GITHUB_WORKSPACE}/Generated/DIFF/${SCH_NAME}_diff.html" << EOF + + +
+
+ EOF
+
+ # Add the diff content with HTML escaping
+ git diff "$BASE_SHA" "$HEAD_SHA" -- "$SCH_FILE" | \
+ sed 's/&/\&/g; s/\</g; s/>/\>/g' | \
+ sed 's/^+[^+].*/&<\/span>/g' | \
+ sed 's/^-[^-].*/&<\/span>/g' >> "${GITHUB_WORKSPACE}/Generated/DIFF/${SCH_NAME}_diff.html"
+
+ echo "" >> "${GITHUB_WORKSPACE}/Generated/DIFF/${SCH_NAME}_diff.html"
+
+ rm -rf "$TEMP_DIR"
+ DIFF_GENERATED=true
+ fi
+ done
+
+ # Generate PCB diff if PCB file changed
+ PCB_FILE="${{ steps.find_project.outputs.pcb_file }}"
+ if git diff --name-only "$BASE_SHA" "$HEAD_SHA" | grep -q "$PCB_FILE"; then
+ echo "Generating PCB diff"
+ PCB_NAME=$(basename "$PCB_FILE" | sed 's/\.[^.]*$//')
+
+ # Generate text diff for PCB
+ git diff "$BASE_SHA" "$HEAD_SHA" -- "$PCB_FILE" > "${GITHUB_WORKSPACE}/Generated/DIFF/${PCB_NAME}_pcb_changes.txt"
+
+ # Summary of changes
+ git diff --stat "$BASE_SHA" "$HEAD_SHA" -- "$PCB_FILE" > "${GITHUB_WORKSPACE}/Generated/DIFF/${PCB_NAME}_pcb_summary.txt"
+
+ DIFF_GENERATED=true
+ fi
+
+ # Create a summary file
+ cat > "${GITHUB_WORKSPACE}/Generated/DIFF/README.md" << EOF
+ # KiCad Project Diff Report
+
+ **Base Commit:** ${BASE_SHA:0:8}
+ **Head Commit:** ${HEAD_SHA:0:8}
+ **Date:** $(date)
+
+ ## Changed Files:
+ $(git diff --name-status "$BASE_SHA" "$HEAD_SHA" -- "*.kicad_sch" "*.sch" "*.kicad_pcb" "*.pcb")
+
+ ## Summary:
+ $(git diff --stat "$BASE_SHA" "$HEAD_SHA" -- "*.kicad_sch" "*.sch" "*.kicad_pcb" "*.pcb")
+
+ ## Commit Messages:
+ $(git log --oneline "$BASE_SHA".."$HEAD_SHA")
+ EOF
+
+ if [ "$DIFF_GENERATED" = true ]; then
+ echo "has_diff=true" >> $GITHUB_OUTPUT
+ else
+ echo "No schematic or PCB changes detected"
+ echo "has_diff=false" >> $GITHUB_OUTPUT
+ fi
+
- name: Run ERC
if: steps.config_check.outputs.found == 'true'
run: |
cd "${{ steps.find_project.outputs.project_dir }}"
+ # Clean up any existing output directories
+ rm -rf Fabrication Generated Output
+
if [ -n "${{ steps.find_project.outputs.sch_file }}" ]; then
echo "Running ERC on schematic files..."
# Use absolute path to config file in repo root
- kibot -c "${GITHUB_WORKSPACE}/kibot.yaml" -s run_erc -v || true
+ # Skip ERC step in preflight to avoid stopping on errors
+ kibot -c "${GITHUB_WORKSPACE}/kibot.yaml" -s run_erc,run_drc -v || true
else
echo "No schematic files found, skipping ERC"
fi
@@ -143,7 +275,8 @@ jobs:
echo "Running DRC on PCB..."
# Use absolute path to config file in repo root
- kibot -c "${GITHUB_WORKSPACE}/kibot.yaml" -s run_drc -v || true
+ # Skip both ERC and DRC in preflight to avoid stopping on errors
+ kibot -c "${GITHUB_WORKSPACE}/kibot.yaml" -s run_erc,run_drc -v || true
continue-on-error: true
- name: Generate outputs with custom config
@@ -155,14 +288,105 @@ jobs:
echo "Project: ${{ steps.find_project.outputs.project_name }}"
echo "Using config: ${GITHUB_WORKSPACE}/kibot.yaml"
- # Run KiBot with the configuration from repo root
+ # First, let's check what's in the current directory
+ echo "Current directory contents:"
+ ls -la
+
+ # Check if Fabrication exists and what it is
+ if [ -e "Fabrication" ]; then
+ echo "Fabrication exists as:"
+ file Fabrication
+ echo "Removing it..."
+ rm -rf Fabrication
+ fi
+
+ # Create a temporary modified config without the global output setting
+ cp "${GITHUB_WORKSPACE}/kibot.yaml" /tmp/kibot_temp.yaml
+
+ # Remove or comment out the global output line if it exists
+ sed -i 's/^ output:.*$/ # output: commented out for workflow/' /tmp/kibot_temp.yaml
+
+ # Update diff revisions if specified
+ if [ -n "${{ github.event.inputs.diff_old }}" ]; then
+ sed -i "s/old: 'HEAD~1'/old: '${{ github.event.inputs.diff_old }}'/" /tmp/kibot_temp.yaml
+ fi
+ if [ -n "${{ github.event.inputs.diff_new }}" ]; then
+ sed -i "s/new: 'HEAD'/new: '${{ github.event.inputs.diff_new }}'/" /tmp/kibot_temp.yaml
+ fi
+
+ # Use a timestamp-based directory to ensure uniqueness
+ OUTPUT_DIR="kibot_output_$(date +%s)"
+
+ # Determine which outputs to run
+ EXTRA_OUTPUTS=""
+ if [ "${{ github.event.inputs.enable_interactive_diff }}" = "true" ]; then
+ EXTRA_OUTPUTS="interactive_diff svg_diff"
+ fi
+
+ # Run KiBot with the modified configuration
# Skip ERC/DRC preflight checks to avoid stopping on errors
- kibot -c "${GITHUB_WORKSPACE}/kibot.yaml" -s run_erc,run_drc -d Fabrication -v
+ # Explicitly run diff and datasheet download outputs
+ echo "Running KiBot with output directory: $OUTPUT_DIR"
+ kibot -c /tmp/kibot_temp.yaml -s run_erc,run_drc -d "$OUTPUT_DIR" -v \
+ sch_diff pcb_diff download_datasheets $EXTRA_OUTPUTS || \
+ kibot -c /tmp/kibot_temp.yaml -s run_erc,run_drc -d "$OUTPUT_DIR" -v
# Move outputs to root Generated folder
mkdir -p "${GITHUB_WORKSPACE}/Generated"
- if [ -d "Fabrication" ]; then
+ if [ -d "$OUTPUT_DIR" ]; then
+ echo "Copying outputs from $OUTPUT_DIR to Generated/"
+ cp -r "$OUTPUT_DIR"/* "${GITHUB_WORKSPACE}/Generated/"
+ rm -rf "$OUTPUT_DIR"
+ elif [ -d "Fabrication" ]; then
+ echo "KiBot used default Fabrication directory, copying from there"
cp -r Fabrication/* "${GITHUB_WORKSPACE}/Generated/"
+ rm -rf Fabrication
+ else
+ echo "Warning: No output directory was created"
+ fi
+
+ - name: Check downloaded datasheets
+ if: steps.config_check.outputs.found == 'true'
+ continue-on-error: true
+ run: |
+ echo "Checking for downloaded datasheets..."
+
+ # KiBot should download datasheets to the configured directory
+ # Check if datasheets were downloaded
+ if [ -d "${GITHUB_WORKSPACE}/Generated/Datasheets" ]; then
+ echo "Datasheets folder found in Generated/"
+
+ # Create README
+ cat > "${GITHUB_WORKSPACE}/Generated/Datasheets/README.md" << EOF
+ # Component Datasheets
+
+ This folder contains downloaded datasheets for all components in the project.
+
+ Organized by component type:
+ - **ICs/** - Integrated circuits (U references)
+ - **Capacitors/** - Capacitors (C references)
+ - **Resistors/** - Resistors (R references)
+ - **Transistors/** - Transistors (Q references)
+ - **Diodes/** - Diodes (D references)
+ - **Connectors/** - Connectors (J, P references)
+ - **Inductors/** - Inductors (L references)
+ - And more...
+
+ Files are named: REFERENCE_VALUE.pdf (e.g., U1_LM7805.pdf)
+
+ Generated on: $(date)
+ Project: ${{ steps.find_project.outputs.project_name }}
+ EOF
+
+ echo "Datasheet folder structure:"
+ find "${GITHUB_WORKSPACE}/Generated/Datasheets" -type f -name "*.pdf" | head -20
+
+ # Count PDFs
+ PDF_COUNT=$(find "${GITHUB_WORKSPACE}/Generated/Datasheets" -type f -name "*.pdf" | wc -l)
+ echo "Total PDFs downloaded: $PDF_COUNT"
+ else
+ echo "No Datasheets folder found - KiBot may not have downloaded any datasheets"
+ echo "Check that components have valid Datasheet URLs in the schematic"
fi
- name: Quick Start fallback