diff --git a/kibot.yaml b/kibot.yaml index dc13e53..9050833 100644 --- a/kibot.yaml +++ b/kibot.yaml @@ -1,297 +1,544 @@ -- 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" +# KiBot configuration for 2/4/6 layer boards +# Works with Gitea CI/CD pipeline -# Controls when the action will run -on: - push: - paths: - - '**/*.kicad_sch' - - '**/*.kicad_pcb' - - '**/*.kicad_pro' - - 'kibot.yaml' - - '.gitea/workflows/*.yml' - pull_request: - paths: - - '**/*.kicad_sch' - - '**/*.kicad_pcb' - - '**/*.kicad_pro' - - 'kibot.yaml' - - '.gitea/workflows/*.yml' - repository_dispatch: - types: [run_qs] - workflow_dispatch: - inputs: - board_layers: - description: 'Number of PCB layers' - required: false - default: '2' - type: choice - options: - - '2' - - '4' - - '6' +kibot: + version: 1 -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - generate: - runs-on: kicad-kibot-runner +global: + # Filters for ERC/DRC warnings + filters: + - number: 1007 + - number: 1015 + - number: 58 + - number: 61 + + # Default output directory - will be overridden by command line + # output: 'Fabrication' # Commented out to use command line option + + # Variant for assembly if needed + variant: '' + + # Date format for filenames + date_format: '%Y-%m-%d_%H-%M-%S' - steps: - - uses: actions/checkout@v3 - with: - # So we can run a diff between last 2 changes - fetch-depth: '0' +preflight: + run_erc: true + run_drc: true + check_zone_fills: true + ignore_unconnected: false + update_xml: true + erc: + warnings_as_errors: false + # Continue even if ERC fails + dont_stop: true + drc: + warnings_as_errors: false + # Continue even if DRC fails + dont_stop: true - - name: Find KiCad project - id: find_project - run: | - # Find all .kicad_pcb files in the repository - PCB_FILES=$(find . -name "*.kicad_pcb" -type f | grep -v -E '/(backups?|backup|old|archive|deprecated)/' | head -5) - - if [ -z "$PCB_FILES" ]; then - echo "Error: No KiCad PCB files found" - exit 1 - fi - - # Use the first PCB file found - PCB_FILE=$(echo "$PCB_FILES" | head -1) - PROJECT_DIR=$(dirname "$PCB_FILE") - PROJECT_NAME=$(basename "$PCB_FILE" .kicad_pcb) - - echo "Found KiCad project: $PROJECT_NAME" - echo "Project directory: $PROJECT_DIR" - echo "PCB file: $PCB_FILE" - - # Find schematic file - SCH_FILE=$(find "$PROJECT_DIR" -name "*.kicad_sch" -o -name "*.sch" | head -1) - - echo "pcb_file=$PCB_FILE" >> $GITHUB_OUTPUT - echo "project_dir=$PROJECT_DIR" >> $GITHUB_OUTPUT - echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT - echo "sch_file=$SCH_FILE" >> $GITHUB_OUTPUT - - # List all found projects for debugging - echo "All PCB files found:" - echo "$PCB_FILES" +outputs: + # Schematic outputs + - name: 'print_sch' + comment: "Schematic PDF" + type: pdf_sch_print + dir: Schematic + options: + output: '%f-schematic.%x' - - name: Set layer count - id: layers - run: | - # 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 - fi - echo "layers=$LAYERS" >> $GITHUB_OUTPUT - echo "Using $LAYERS layer configuration" + - name: 'print_sch_svg' + comment: "Schematic SVG" + type: svg_sch_print + dir: Schematic + options: + output: '%f-schematic.%x' - - name: Check for KiBot config - id: config_check - run: | - # Check if kibot.yaml exists in repository root - if [ -f "kibot.yaml" ]; then - echo "found=true" >> $GITHUB_OUTPUT - echo "Using kibot.yaml configuration from repository root" - else - echo "found=false" >> $GITHUB_OUTPUT - echo "No kibot.yaml found in repository root - will use --quick-start mode" - fi + # PCB 2D renders + - name: 'pcb_top' + comment: "PCB render top" + type: pcbdraw + dir: PCB/2D_render + options: + output: '%f-top.%x' + format: svg + show_components: all + dpi: 300 - - name: Run ERC - if: steps.config_check.outputs.found == 'true' - run: | - cd "${{ steps.find_project.outputs.project_dir }}" - - 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 - else - echo "No schematic files found, skipping ERC" - fi - continue-on-error: true + - name: 'pcb_bottom' + comment: "PCB render bottom" + type: pcbdraw + dir: PCB/2D_render + options: + output: '%f-bottom.%x' + format: svg + bottom: true + show_components: all + dpi: 300 - - name: Run DRC - if: steps.config_check.outputs.found == 'true' - run: | - cd "${{ steps.find_project.outputs.project_dir }}" - - 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 - continue-on-error: true + # PCB PDF documentation + - name: 'print_pcb' + comment: "PCB PDF" + type: pdf_pcb_print + dir: PCB/PDF + options: + output: '%f-pcb.%x' + plot_sheet_reference: true + monochrome: false + pages: + - layers: + - F.Cu + - F.Paste + - F.Silkscreen + - Edge.Cuts + sheet: 'Front copper' + - layers: + - B.Cu + - B.Paste + - B.Silkscreen + - Edge.Cuts + mirror: true + sheet: 'Bottom copper' + - layers: + - In1.Cu + - Edge.Cuts + sheet: 'Inner layer 1' + skip_if_no_layer: true + - layers: + - In2.Cu + - Edge.Cuts + sheet: 'Inner layer 2' + skip_if_no_layer: true + - layers: + - In3.Cu + - Edge.Cuts + sheet: 'Inner layer 3' + skip_if_no_layer: true + - layers: + - In4.Cu + - Edge.Cuts + sheet: 'Inner layer 4' + skip_if_no_layer: true - - name: Generate outputs with custom config - if: steps.config_check.outputs.found == 'true' - run: | - cd "${{ steps.find_project.outputs.project_dir }}" - - echo "Generating outputs for ${{ steps.layers.outputs.layers }} layer board" - echo "Project: ${{ steps.find_project.outputs.project_name }}" - echo "Using config: ${GITHUB_WORKSPACE}/kibot.yaml" - - # Run KiBot with the configuration from repo root - # Skip ERC/DRC preflight checks to avoid stopping on errors - kibot -c "${GITHUB_WORKSPACE}/kibot.yaml" -s run_erc,run_drc -d Fabrication -v - - # Move outputs to root Generated folder - mkdir -p "${GITHUB_WORKSPACE}/Generated" - if [ -d "Fabrication" ]; then - cp -r Fabrication/* "${GITHUB_WORKSPACE}/Generated/" - fi + # Gerber files - automatically handles 2/4/6 layers + - name: 'gerbers' + comment: "Gerber files" + type: gerber + dir: Gerbers + options: + output: '%f%i.%x' + exclude_edge_layer: true + exclude_pads_from_silkscreen: true + plot_sheet_reference: false + plot_footprint_refs: true + plot_footprint_values: false + force_plot_invisible_refs_vals: false + tent_vias: true + use_protel_extensions: false + create_gerber_job_file: true + disable_aperture_macros: true + gerber_precision: 4.6 + use_gerber_x2_attributes: false + use_gerber_net_attributes: false + line_width: 0.1 + subtract_mask_from_silk: true + layers: + # Copper layers - automatically included if present + - F.Cu + - B.Cu + - In1.Cu + - In2.Cu + - In3.Cu + - In4.Cu + # Technical layers + - F.Paste + - B.Paste + - F.Silkscreen + - B.Silkscreen + - F.Mask + - B.Mask + - Edge.Cuts + - User.Comments + - F.Fab + - B.Fab - - name: Quick Start fallback - if: steps.config_check.outputs.found == 'false' - run: | - cd "${{ steps.find_project.outputs.project_dir }}" - echo "Running KiBot in quick-start mode" - kibot --quick-start - - # Move outputs to root Generated folder - mkdir -p "${GITHUB_WORKSPACE}/Generated" - if [ -d "Generated" ]; then - cp -r Generated/* "${GITHUB_WORKSPACE}/Generated/" - fi + # Excellon drill files + - name: 'drill' + comment: "Drill files" + type: excellon + dir: Gerbers + options: + output: '%f%i.%x' + metric_units: true + minimal_header: false + mirror_y_axis: false + report: + filename: '%f-drill_report.txt' + pth_and_npth_single_file: false - - name: Add board information to outputs - run: | - echo "Board configuration: ${{ steps.layers.outputs.layers }} layers" > Generated/board_info.txt - echo "Project: ${{ steps.find_project.outputs.project_name }}" >> Generated/board_info.txt - echo "Project path: ${{ steps.find_project.outputs.project_dir }}" >> Generated/board_info.txt - echo "Generated on: $(date)" >> Generated/board_info.txt - echo "Commit: ${{ github.sha }}" >> Generated/board_info.txt + # Drill map + - name: 'drill_map' + comment: "Drill map" + type: gerb_drill + dir: Gerbers + options: + output: '%f-drill_map.%x' - - name: Fix file permissions - run: | - chmod -R a+rw Generated || true + # Pick and place files + - name: 'position' + comment: "Pick and place file" + type: position + dir: Assembly + options: + output: '%f-position-%i.%x' # Added %i to differentiate front/back files + format: CSV + units: millimeters + separate_files_for_front_and_back: true + only_smd: false - - name: Retrieve results - All outputs - uses: actions/upload-artifact@v3 - with: - name: Automatic_outputs - path: Generated + # Interactive BOM + - name: 'ibom' + comment: "Interactive BOM" + type: ibom + dir: Assembly + options: + output: '%f-ibom.%x' + dark_mode: false + hide_pads: false + show_fabrication: false + hide_silkscreen: false + highlight_pin1: true + no_redraw_on_drag: false + board_rotation: 0 + check_extra_fields: false + include_tracks: false + include_nets: false - - name: Retrieve results - Gerbers - if: steps.config_check.outputs.found == 'true' - uses: actions/upload-artifact@v3 - with: - name: Gerbers-${{ steps.layers.outputs.layers }}layer - path: Generated/Gerbers + # Generic BOM in CSV format + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM/Generic + options: + output: '%f_bom.%x' + format: CSV + separator: ',' + ref_separator: ',' + group_fields: ['Value', 'Footprint', 'Tolerance', 'Voltage'] + columns: + - field: 'References' + name: 'Reference' + - field: 'Value' + name: 'Value' + - field: 'Quantity Per PCB' + name: 'Qty' + - field: 'Footprint' + name: 'Package' + - field: 'Description' + name: 'Description' + - field: 'Manufacturer' + name: 'Manufacturer' + - field: 'MPN' + name: 'Part Number' + - field: 'LCSC' + name: 'LCSC Part' + - field: 'Digikey' + name: 'Digikey Part' + - field: 'Mouser' + name: 'Mouser Part' - - name: Retrieve results - Assembly - if: steps.config_check.outputs.found == 'true' - uses: actions/upload-artifact@v3 - with: - name: Assembly-${{ steps.layers.outputs.layers }}layer - path: Generated/Assembly + # Generic BOM in HTML format + - name: 'bom_html' + comment: "Bill of Materials in HTML format" + type: bom + dir: BoM/Generic + options: + output: '%f_bom.%x' + format: HTML + html: + style: 'modern-blue' # Style for HTML output + datasheet_as_link: 'Datasheet' # Column name for datasheet links + generate_dnf: true + logo: false + title: 'Bill of Materials - %f' + group_fields: ['Value', 'Footprint', 'Tolerance', 'Voltage'] + columns: + - field: 'References' + name: 'Reference' + - field: 'Value' + name: 'Value' + - field: 'Quantity Per PCB' + name: 'Qty' + - field: 'Footprint' + name: 'Package' + - field: 'Description' + name: 'Description' + - field: 'Manufacturer' + name: 'Manufacturer' + - field: 'MPN' + name: 'Part Number' + - field: 'LCSC' + name: 'LCSC Part' + - field: 'Digikey' + name: 'Digikey Part' + - field: 'Mouser' + name: 'Mouser Part' - - name: Retrieve results - BOM - if: steps.config_check.outputs.found == 'true' - uses: actions/upload-artifact@v3 - with: - name: BOM-${{ steps.layers.outputs.layers }}layer - path: Generated/BoM + # Generic BOM in XLSX format + - name: 'bom_xlsx' + comment: "Bill of Materials in Excel format" + type: bom + dir: BoM/Generic + options: + output: '%f_bom.%x' + format: XLSX + xlsx: + datasheet_as_link: 'Datasheet' # Column name for datasheet links + generate_dnf: true + logo: false + title: 'Bill of Materials' + max_col_width: 50 + highlight_empty: true + group_fields: ['Value', 'Footprint', 'Tolerance', 'Voltage'] + columns: + - field: 'References' + name: 'Reference' + - field: 'Value' + name: 'Value' + - field: 'Quantity Per PCB' + name: 'Qty' + - field: 'Footprint' + name: 'Package' + - field: 'Description' + name: 'Description' + - field: 'Manufacturer' + name: 'Manufacturer' + - field: 'MPN' + name: 'Part Number' + - field: 'LCSC' + name: 'LCSC Part' + - field: 'Digikey' + name: 'Digikey Part' + - field: 'Mouser' + name: 'Mouser Part' + - field: 'Datasheet' + name: 'Datasheet' - - name: Retrieve results - 3D Model - if: steps.config_check.outputs.found == 'true' - uses: actions/upload-artifact@v3 - with: - name: 3D-Model - path: Generated/3D + # Download datasheets + - name: 'download_datasheets' + comment: "Download component datasheets" + type: download_datasheets + dir: BoM/Datasheets + run_by_default: true + options: + # Don't specify output - let KiBot handle the downloaded files + # output: '%f_datasheets.csv' # Removed - this was causing the issue + field: 'Datasheet' # Field containing datasheet URLs + dnf_filter: '_none' # Don't filter DNF parts + download: true # Actually download the files (not just list them) + link_repeated: true # Create links for repeated datasheets + repeated: false # Don't download the same datasheet twice - - name: Retrieve results - Fabrication Package - if: steps.config_check.outputs.found == 'true' - uses: actions/upload-artifact@v3 - with: - name: Fabrication-Package-${{ steps.layers.outputs.layers }}layer - path: Generated/*.zip + # 3D model + - name: 'step' + comment: "3D STEP model" + type: step + dir: 3D + options: + output: '%f-3D.%x' + metric_units: true + origin: grid + no_virtual: true - - name: Retrieve results - JLCPCB Package - if: steps.config_check.outputs.found == 'true' - uses: actions/upload-artifact@v3 - with: - name: JLCPCB-${{ steps.layers.outputs.layers }}layer - path: Generated/*_JLCPCB_compress.zip + # Board characteristics report + - name: 'report' + comment: "Board report" + type: report + dir: . + options: + output: '%f-report.%x' + do_convert: true - - name: Retrieve results - Diff Report - if: steps.generate_diff.outputs.has_diff == 'true' - uses: actions/upload-artifact@v3 - with: - name: Schematic-PCB-Diff - path: Generated/DIFF + # Schematic diff + - name: 'sch_diff' + comment: "Schematic diff PDF" + type: diff + dir: DIFF + run_by_default: true + options: + output: '%f-schematic-diff.%x' + format: 'pdf' # Output format: pdf, svg, ps, or png + pcb: false # This is for schematic + old: 'HEAD~1' # Old version to compare (previous commit) + new: 'HEAD' # New version (current) + cache_dir: '.cache' + add_link_id: true # Add link IDs to the generated diff + only_different: true # Only include pages that changed + threshold: 0 # Difference threshold (0 = any difference) + fuzz: 5 # Fuzzy matching tolerance in pixels + diff_mode: 'red_green' # How to show differences + old_color: '#FF0000' # Color for old/removed items + new_color: '#00FF00' # Color for new/added items + + # PCB diff + - name: 'pcb_diff' + comment: "PCB diff PDF" + type: diff + dir: DIFF + run_by_default: true + options: + output: '%f-pcb-diff.%x' + format: 'pdf' # Output format + pcb: true # This is for PCB + old: 'HEAD~1' # Old version to compare + new: 'HEAD' # New version + cache_dir: '.cache' + add_link_id: false # Not used for PCB + only_different: true # Only include layers that changed + threshold: 0 # Difference threshold + fuzz: 5 # Fuzzy matching tolerance + diff_mode: 'red_green' # Visual diff mode + old_color: '#FF0000' # Color for removed items + new_color: '#00FF00' # Color for added items + layers: # Which PCB layers to include in diff + - 'F.Cu' + - 'B.Cu' + - 'In1.Cu' + - 'In2.Cu' + - 'In3.Cu' + - 'In4.Cu' + - 'F.Silkscreen' + - 'B.Silkscreen' + - 'F.Mask' + - 'B.Mask' + - 'Edge.Cuts' + - 'F.Courtyard' + - 'B.Courtyard' + - 'F.Fab' + - 'B.Fab' - # Deploy to documentation branch - deploy: - runs-on: kicad-kibot-runner - needs: generate + # Interactive diff using KiRi (HTML output) + - name: 'interactive_diff' + comment: "Interactive HTML diff" + type: diff + dir: DIFF + run_by_default: false # Optional - can be slow + options: + output: '%f-interactive-diff.%x' + format: 'html' # HTML format for interactive viewing + pcb: true + old: 'HEAD~1' + new: 'HEAD' + cache_dir: '.cache' + only_different: true + diff_mode: 'stats' # Show statistics in HTML + + # SVG diff for web viewing + - name: 'svg_diff' + comment: "SVG diff for web" + type: diff + dir: DIFF + run_by_default: false + options: + output: '%f-diff.%x' + format: 'svg' # SVG format for web embedding + pcb: true + old: 'HEAD~1' + new: 'HEAD' + cache_dir: '.cache' + only_different: true + diff_mode: 'red_green' + old_color: '#FF0000' + new_color: '#00FF00' + zones: 'fill' # How to handle zones: fill, outline, or none - steps: - - uses: actions/checkout@v4 + # JLCPCB fabrication package + - name: 'jlcpcb_gerbers' + comment: "Gerbers for JLCPCB" + type: gerber + dir: JLCPCB + options: + output: '%f%i.%x' + exclude_edge_layer: false + exclude_pads_from_silkscreen: true + plot_sheet_reference: false + plot_footprint_refs: true + plot_footprint_values: false + force_plot_invisible_refs_vals: false + tent_vias: true + use_protel_extensions: true # JLCPCB prefers Protel extensions + create_gerber_job_file: false # JLCPCB doesn't need this + disable_aperture_macros: true + gerber_precision: 4.6 + use_gerber_x2_attributes: false + use_gerber_net_attributes: false + line_width: 0.1 + subtract_mask_from_silk: true + layers: + - F.Cu + - B.Cu + - In1.Cu + - In2.Cu + - In3.Cu + - In4.Cu + - F.Paste + - B.Paste + - F.Silkscreen + - B.Silkscreen + - F.Mask + - B.Mask + - Edge.Cuts - - name: Retrieve results - uses: actions/download-artifact@v3 - with: - name: Automatic_outputs - path: Generated + # JLCPCB drill files + - name: 'jlcpcb_drill' + comment: "Drill files for JLCPCB" + type: excellon + dir: JLCPCB + options: + output: '%f%i.%x' + metric_units: true + minimal_header: false + mirror_y_axis: false + pth_and_npth_single_file: false # JLCPCB prefers separate files + + # JLCPCB ZIP file + - name: 'jlcpcb_zip' + comment: "JLCPCB fabrication ZIP" + type: compress + dir: . + options: + output: '%f_JLCPCB_compress.%x' + format: ZIP + files: + - source: JLCPCB/* + dest: / - - name: Disable Jekyll - # Jekyll will filter the KiRi folders - run: | - touch Generated/.nojekyll + # Fabrication package (ZIP) + - name: 'fabrication' + comment: "Fabrication package" + type: compress + dir: . + options: + output: '%f-fabrication.%x' + format: ZIP + files: + - source: Gerbers/* + dest: / + - source: PCB/PDF/* + dest: /Documentation + - source: Assembly/* + dest: /Assembly + - source: 3D/* + dest: /3D - - name: Push to docu branch - env: - GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - run: | - # Set up git identity - git config --global user.email "${{ gitea.actor }}@noreply.localhost" - git config --global user.name "${{ gitea.actor }}" - - # Get the repository URL and add authentication - REPO_URL=$(git config --get remote.origin.url) - AUTHED_URL=${REPO_URL/https:\/\//https:\/\/${GITEA_TOKEN}@} - - # Clone the docu branch into a separate folder - git clone --depth 1 --branch docu "$AUTHED_URL" docu-branch || \ - git clone --depth 1 "$AUTHED_URL" docu-branch - - cd docu-branch - git checkout -B docu - - # Clean old contents and copy new files - rm -rf ./* - cp -r ../Generated/* ./ - - # Commit and push if there are changes - git add . - if ! git diff --cached --quiet; then - git commit -m "chore: update deployed documentation" - git push --force "$AUTHED_URL" docu - else - echo "No changes to deploy" - fi \ No newline at end of file +# Variants for different layer counts (optional) +variants: + - name: 2layer + comment: "2 layer board variant" + type: kibom + + - name: 4layer + comment: "4 layer board variant" + type: kibom + + - name: 6layer + comment: "6 layer board variant" + type: kibom \ No newline at end of file