The outputs section

In this section you put all the things that you want to generate. This section contains one or more outputs. Each output contain the following data:

  • name a name so you can easily identify it.

  • comment a short description of this output.

  • type selects which type of output will be generated. Examples are gerbers, drill files and pick & place files

  • dir is the directory where this output will be stored.

  • extends used to use another output’s options as base.

  • run_by_default indicates this output will be created when no specific outputs are requested.

  • disable_run_by_default can be used to disable the run_by_default status of other output.

  • output_id text to use for the %I expansion content.

  • options contains one or more options to configure this output.

  • layers a list of layers used for this output. Not all outputs needs this subsection.

Important note about the layers: In the original kiplot (from John Beard) the name of the inner layers was Inner.N where N is the number of the layer, i.e. Inner.1 is the first inner layer. This format is supported for compatibility. Note that this generated a lot of confusion because the default KiCad name for the first inner layer is In1.Cu. People filled issues and submitted pull-requests to fix it, thinking that inner layers weren’t supported. Currently KiCad allows renaming these layers, so this version of kiplot supports the name used in KiCad. Just use the same name you see in the user interface.

The available values for type are:

  • Plot formats:

    • gerber the gerbers for fabrication.

    • ps postscript plot

    • hpgl format for laser printers

    • svg scalable vector graphics

    • pdf portable document format

    • dxf mechanical CAD format

  • Drill formats:

    • excellon data for the drilling machine

    • gerb_drill drilling positions in a gerber file

  • Pick & place

    • position of the components for the pick & place machine

  • Documentation

    • pdf_sch_print schematic in PDF format

    • svg_sch_print schematic in SVG format

    • ps_sch_print schematic in PS format

    • dxf_sch_print schematic in DXF format

    • hpgl_sch_print schematic in HPGL format

    • pdf_pcb_print PDF file containing one or more layer and the page frame

    • svg_pcb_print SVG file containing one or more layer and the page frame

    • pcb_print PDF/SVG/PNG/EPS/PS, similar to pdf_pcb_print and svg_pcb_print, with more flexibility

    • report generates a report about the PDF. Can include images from the above outputs.

    • diff creates PDF files showing schematic or PCB changes.

  • Bill of Materials

    • bom The internal BoM generator.

    • kibom BoM in HTML or CSV format generated by KiBoM

    • ibom Interactive HTML BoM generated by InteractiveHtmlBom

    • kicost BoM in XLSX format with costs generated by KiCost

  • 3D model:

    • step Standard for the Exchange of Product Data for the PCB

    • vrml Virtual Reality Modeling Language for the PCB

    • render_3d PCB render, from the KiCad’s 3D Viewer

    • blender_export PCB export to Blender and high quality 3D render. Including export to: fbx (Kaydara’s Filmbox), ‘obj’ (Wavefront), ‘x3d’ (ISO/IEC standard), gltf (GL format), stl (3D printing) and ‘ply’ (Stanford).

  • Web pages:

    • populate To create step-by-step assembly instructions.

    • kikit_present To create a project presentation web page.

    • navigate_results generates web pages to navigate the generated outputs.

  • Fabrication helpers:

    • panelize creates a PCB panel containing N copies of the PCB.

    • stencil_3d creates a 3D self-registering printable stencil.

    • stencil_for_jig creates steel stencils and 3D register.

  • Others:

    • boardview creates a file useful to repair the board, but without disclosing the full layout.

    • gencad exports the PCB in GENCAD format.

    • compress creates an archive containing generated data.

    • download_datasheets downloads the datasheets for all the components.

    • pcbdraw nice images of the PCB in customized colors.

    • pdfunite joins various PDF files into one.

    • qr_lib generates symbol and footprints for QR codes.

    • sch_variant the schematic after applying all filters and variants, including crossed components.

    • pcb_variant the PCB after applying all filters and variants, including modified 3D models.

    • copy_files used to copy generated files and source material.

    • info creates a report about the tools used during the KiBot run.

    • netlist generates the list of connections for the project (classic and IPC-D-356 formats).

Here is an example of a configuration file to generate the gerbers for the top and bottom layers:

kibot:
  version: 1

preflight:
  run_drc: true

outputs:

  - name: 'gerbers'
    comment: "Gerbers for the board house"
    type: gerber
    dir: gerberdir
    options:
      # generic layer options
      exclude_edge_layer: false
      exclude_pads_from_silkscreen: false
      plot_sheet_reference: false
      plot_footprint_refs: true
      plot_footprint_values: true
      force_plot_invisible_refs_vals: false
      tent_vias: true
      line_width: 0.15

      # gerber options
      use_aux_axis_as_origin: false
      subtract_mask_from_silk: true
      use_protel_extensions: false
      gerber_precision: 4.5
      create_gerber_job_file: true
      use_gerber_x2_attributes: true
      use_gerber_net_attributes: false

    layers:
      - 'F.Cu'
      - 'B.Cu'

Most options are the same you’ll find in the KiCad dialogs.

Outputs are generated in the order they are declared in the YAML file. To create them in an arbitrary order use the --cli-order command line option and they will be created in the order specified in the command line.

Specifying the layers

You have various ways to specify the layers. If you need to specify just one layer you can just use its name:

layers: 'F.Cu'

If you want to specify all the available layers:

layers: 'all'

You can also select the layers you want in KiCad (using File, Plot dialog) and save your PCB. Then you just need to use:

layers: 'selected'

You can also use any of the following grup of layers:

  • copper all the copper layers

  • technical all the technical layers (silk sreen, solder mask, paste, adhesive, etc.)

  • user all the user layers (draw, comments, eco, margin, edge cuts, etc.)

You can also mix the above definitions using a list:

layers:
  - 'copper'
  - 'Dwgs.User'

This will select all the copper layers and the user drawings. Note that the above mentioned options will use file name suffixes and descriptions selected automatically. If you want to use a particular suffix and provide better descriptions you can use the following format:

layers:
  - layer: 'F.Cu'
    suffix: 'F_Cu'
    description: 'Front copper'
  - layer: 'B.Cu'
    suffix: 'B_Cu'
    description: 'Bottom copper'

You can also mix the styles:

layers:
  - 'copper'
  - layer: 'Cmts.User'
    suffix: 'Cmts_User'
    description: 'User comments'
  - 'Dwgs.User'

If you need to use the same list of layers for various outputs you can use YAML anchors. The first time you define the list of layers just assign an anchor, here is an example:

layers: &copper_and_cmts
  - copper
  - 'Cmts.User'

Next time you need this list just use an alias, like this:

layers: *copper_and_cmts

Supported outputs

Notes:

  1. Most relevant options are listed first and in bold. Which ones are more relevant is quite arbitrary, comments are welcome.

  2. Aliases are listed in italics.

Consolidating BoMs

Some times your project is composed by various boards, other times you are producing various products at the same time. In both cases you would want to consolidate the components acquisition in one operation. Of course you can create individual BoMs for each project in CSV format and then consolidate them using a spreadsheet editor. But KiBot offers another option: you create a BoM for your main project and then aggregate the components from the other projects.

Here is a simple example. Suppose you have three projects: merge_1, merge_2 and merge_3. For the merge_1 project you could use the following output:

kibot:
  version: 1

outputs:
  - name: 'bom_csv'
    comment: "Bill of Materials in CSV format"
    type: bom
    dir: BoM
    options:
      use_alt: true

Using the tests/board_samples/kicad_5/merge_1.sch from the git repo and storing the above example in m1.kibot.yaml you could run:

src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_1.sch -d test_merge

And get test_merge/BoM/merge_1-bom.csv:

Row

Description

Part

References

Value

Footprint

Quantity Per PCB

Status

Datasheet

1

Unpolarized capacitor

C

C1

1nF

1

~

2

Unpolarized capacitor

C

C2

10nF

1

~

3

Resistor

R

R1-R3

1k

3

~

Project info:

Schematic:

merge_1

Variant:

default

Revision:

Date:

2021-02-02_12-12-27

KiCad Version:

5.1.9-73d0e3b20d~88~ubuntu21.04.1

Statistics:

Component Groups:

3

Component Count:

5

Fitted Components:

5

Number of PCBs:

1

Total Components:

5

This CSV says you have five components groped in three different types. They are one 1 nF capacitor, one 10 nF capacitor and three 1 k resistors. Now lets generate BoMs for the merge_2 example:

src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_2.sch -d test_merge

We’ll get test_merge/BoM/merge_2-bom.csv:

Row

Description

Part

References

Value

Footprint

Quantity Per PCB

Status

Datasheet

1

Unpolarized capacitor

C

C2

1nF

1

~

2

Unpolarized capacitor

C

C1

10nF

1

~

3

Resistor

R

R2-R4

1000

3

~

4

Resistor

R

R1

10k

1

~

Project info:

Schematic:

merge_2

Variant:

default

Revision:

Date:

2021-01-27_10-19-46

KiCad Version:

5.1.9-73d0e3b20d~88~ubuntu21.04.1

Statistics:

Component Groups:

4

Component Count:

6

Fitted Components:

6

Number of PCBs:

1

Total Components:

6

In this project we have six components from four different types. They are similar to merge_1 but now we also have a 10 k resistor. We don’t need to generate this BoM to consolidate our projects, but is good to know what we have. And now lets generate BoMs for the merge_3 example:

src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_3.sch -d test_merge

We’ll get test_merge/BoM/merge_3-bom.csv:

Row

Description

Part

References

Value

Footprint

Quantity Per PCB

Status

Datasheet

1

Resistor

R

R5

1k

1

~

2

Resistor

R

R1-R4

10k

4

~

Project info:

Schematic:

merge_3

Variant:

default

Revision:

Date:

2021-01-27_10-21-29

KiCad Version:

5.1.9-73d0e3b20d~88~ubuntu21.04.1

Statistics:

Component Groups:

2

Component Count:

5

Fitted Components:

5

Number of PCBs:

1

Total Components:

5

This time we also have five components, but from two different types. They are one 1 k resistor and four 10 k resistors. Now suppose we want to create 10 boards for merge_1, 20 for merge_2 and 30 for merge_3. We could use the following configuration:

kibot:
  version: 1

outputs:
  - name: 'bom_csv'
    comment: "Bill of Materials in CSV format"
    type: bom
    dir: BoM
    options:
      use_alt: true
      number: 10
      aggregate:
        - file: tests/board_samples/kicad_5/merge_2.sch
          number: 20
        - file: tests/board_samples/kicad_5/merge_3.sch
          number: 30

Save it as m2.kibot.yaml and run:

src/kibot -c m2.kibot.yaml -e tests/board_samples/kicad_5/merge_1.sch -d test_merge_consolidate

The test_merge_consolidate/BoM/merge_1-bom.csv file will be generated containing:

Row

Description

Part

References

Value

Footprint

Quantity Per PCB

Build quantity

Status

Datasheet

Source BoM

1

Unpolarized capacitor

C

C1 C2

1nF

2

30

~

merge_1(1) merge_2(1)

2

Unpolarized capacitor

C

C2 C1

10nF

2

30

~

merge_1(1) merge_2(1)

3

Resistor

R

R1-R3 R2-R4 R5

1k

7

120

~

merge_1(3) merge_2(3) merge_3(1)

4

Resistor

R

R1 R1-R4

10k

5

140

~

merge_2(1) merge_3(4)

Project info:

Variant:

default

KiCad Version:

5.1.9-73d0e3b20d~88~ubuntu21.04.1

Global statistics:

Component Groups:

4

Component Count:

16

Fitted Components:

16

Number of PCBs:

60

Total Components:

320

Project info:

merge_1

Schematic:

merge_1

Revision:

Date:

2021-02-02_12-12-27

Company:

Test company

Statistics:

merge_1

Component Groups:

3

Component Count:

5

Fitted Components:

5

Number of PCBs:

10

Total Components:

50

Project info:

merge_2

Schematic:

merge_2

Revision:

Date:

2021-01-27_10-19-46

Statistics:

merge_2

Component Groups:

4

Component Count:

6

Fitted Components:

6

Number of PCBs:

20

Total Components:

120

Project info:

merge_3

Schematic:

merge_3

Revision:

Date:

2021-01-27_10-21-29

Statistics:

merge_3

Component Groups:

2

Component Count:

5

Fitted Components:

5

Number of PCBs:

30

Total Components:

150

You can see that now we have much more stats. They say we have four different types, thirteen for board sets, a total of 60 boards and 250 components. Then we have individual stats for each project. The capacitors are easy to interpret, we have 30 1 nF capacitors merge_1 project has one and merge_2 another. As we have 10 merge_1 and 20 merge_2 boards this is clear. But looking at the 1 k resistors is harder. We have 80, three from merge_1, one from merge_2 and another from merge_3. So we have 103+203+30=120, this is clear, but the BoM says they are R1-R3 R2-R4 R5, which is a little bit confusing. In this simple example is easy to correlate R1-R3 to merge_1, R2-R4 to merge_2 and R5 to merge_1. For bigger projects this gets harder. Lets assign an id to each project, we’ll use ‘A’ for merge_1, ‘B’ for merge_2 and ‘C’ for merge_3:

kibot:
  version: 1

outputs:
  - name: 'bom_csv'
    comment: "Bill of Materials in CSV format"
    type: bom
    dir: BoM
    options:
      use_alt: true
      number: 10
      ref_id: 'A:'
      aggregate:
        - file: tests/board_samples/kicad_5/merge_2.sch
          number: 20
          ref_id: 'B:'
        - file: tests/board_samples/kicad_5/merge_3.sch
          number: 30
          ref_id: 'C:'

Now test_merge_consolidate/BoM/merge_1-bom.csv will have the following information:

Row

Description

Part

References

Value

Footprint

Quantity Per PCB

Build quantity

Status

Datasheet

Source BoM

1

Unpolarized capacitor

C

A:C1 B:C2

1nF

2

30

~

merge_1(1) merge_2(1)

2

Unpolarized capacitor

C

A:C2 B:C1

10nF

2

30

~

merge_1(1) merge_2(1)

3

Resistor

R

A:R1-A:R3 B:R2-B:R4 C:R5

1k

7

120

~

merge_1(3) merge_2(3) merge_3(1)

4

Resistor

R

B:R1 C:R1-C:R4

10k

5

140

~

merge_2(1) merge_3(4)

As you can see now we know A has R1-R3, B R2-R4 and for C R5 is the 1k resistor. If we want to compact the Source BoM column we just need to enable the source_by_id option:

kibot:
  version: 1

outputs:
  - name: 'bom_csv'
    comment: "Bill of Materials in CSV format"
    type: bom
    dir: BoM
    options:
      use_alt: true
      number: 10
      ref_id: 'A:'
      source_by_id: true
      aggregate:
        - file: tests/board_samples/kicad_5/merge_2.sch
          number: 20
          ref_id: 'B:'
        - file: tests/board_samples/kicad_5/merge_3.sch
          number: 30
          ref_id: 'C:'

And we’ll get:

Row

Description

Part

References

Value

Footprint

Quantity Per PCB

Build quantity

Status

Datasheet

Source BoM

1

Unpolarized capacitor

C

A:C1 B:C2

1nF

2

30

~

A:(1) B:(1)

2

Unpolarized capacitor

C

A:C2 B:C1

10nF

2

30

~

A:(1) B:(1)

3

Resistor

R

A:R1-A:R3 B:R2-B:R4 C:R5

1k

7

120

~

A:(3) B:(3) C:(1)

4

Resistor

R

B:R1 C:R1-C:R4

10k

5

140

~

B:(1) C:(4)

Importing outputs from another file

In some cases you may want to reuse configuration files. An example of this are the example files that generate gerbers and drill files for various manufacturers (see).

In this case you can create a section named import containing a list of configuration files. Here is an example:

import:
  - configs/Elecrow.kibot.yaml
  - configs/FusionPCB.kibot.yaml
  - configs/JLCPCB.kibot.yaml
  - configs/P-Ban.kibot.yaml
  - configs/PCBWay.kibot.yaml

This will import all the outputs from the listed files.

Importing other stuff from another file

This is a more complex case of the previous Importing outputs from another file :ref:`import-from-another. In this case you must use the more general syntax:

import:
  - file: FILE_CONTAINING_THE_YAML_DEFINITIONS
    outputs: LIST_OF_OUTPUTS
    preflights: LIST_OF_PREFLIGHTS
    filters: LIST_OF_FILTERS
    variants: LIST_OF_VARIANTS
    global: LIST_OF_GLOBALS
    groups: LIST_OF_GROUPS

This syntax is flexible. If you don’t define which outputs, preflights, filters, variants, global and/or groups all will be imported. So you can just omit them, like this:

import:
  - file: FILE_CONTAINING_THE_YAML_DEFINITIONS

The LIST_OF_items can be a YAML list or just one string. Here is an example:

import:
  - file: FILE_CONTAINING_THE_YAML_DEFINITIONS
    outputs: one_name
    filters: ['name1', 'name2']

This will import the one_name output and the name1 and name2 filters. As variants is omitted, all variants will be imported. The same applies to other things like globals and groups. You can also use the all and none special names, like this:

import:
  - file: FILE_CONTAINING_THE_YAML_DEFINITIONS
    outputs: all
    filters: all
    variants: none
    global: none

This will import all outputs and filters, but not variants or globals. Also note that imported globals has more precedence than the ones defined in the same file. If you want to give more priority to the local values use:

kibot:
  version: 1
  imported_global_has_less_priority: true

import:
...

Another important detail is that global options that are lists gets the values merged. The last set of values found is inserted at the beginning of the list. You can collect filters for all the imported global sections.

Imports are processed recursively: An import section in an imported file is also processed (so importing A.yaml that imports B.yaml effectively imports both).

If an import filename is a relative path, it is resolved relative to the config file that contains the import (so it works regardless of the working directory and, in case of recursive imports, of where top-level config lives).

It’s recommended to always use some file extension in the FILE_CONTAINING_THE_YAML_DEFINITIONS name. If you don’t use any file extension and you use a relative path this name could be confused with an internal template. See Importing internal templates :ref:`import-templates. If you need to use a name without any extension and a relative path, and this name is the same used for a KiBot template use the is_external option:

import:
  - file: Elecrow
    is_external: true

Parametrizable imports

You can create imports that are parametrizable. For this you must use the mechanism explained in the Doing YAML substitution or preprocessing section.

Importing internal templates

KiBot has some internally defined outputs, groups and filters. You can easily use them with the import mechanism. Use the file mechanism and don’t include the extension for the file. When importing an internal template you don’t need to specify its location. Here is an example:

import:
  - file: Elecrow

This will import the definitions for the internal Elecrow configuration. Here is a list of currently defined templates:

They include support for:

  • CheckZoneFill: enables the check_zone_fills preflight and checks the refilled PCB doesn’t changed too much.

    • _diff_cur_pcb_show: Makes a diff between the PCB in memory and the one on disk

    • _diff_cur_pcb_check: Computes the difference between PCB in memory and the one on disk. Aborts if more than 100 pixels changed.

    • Note: The *_KIBOT_CHKZONE_THRESHOLD* parameter can be used to adjust the number of changed pixels that we tolerate. Consult the Definitions during import section to know about parameters.

  • Elecrow: contain fabrication outputs compatible with Elecrow

    • _Elecrow_gerbers: Gerbers

    • _Elecrow_drill: Drill files

    • _Elecrow_compress: Gerbers and drill files compressed in a ZIP

    • _Elecrow: _Elecrow_gerbers+_Elecrow_drill

  • Elecrow_stencil: same as Elecrow, but also generates gerbers for F.Paste and B.Paste layers.

  • FusionPCB: contain fabrication outputs compatible with FusionPCB

    • _FusionPCB_gerbers: Gerbers

    • _FusionPCB_drill: Drill files

    • _FusionPCB_compress: Gerbers and drill files compressed in a ZIP

    • _FusionPCB: _FusionPCB_gerbers+_FusionPCB_drill

  • FusionPCB_stencil: same as FusionPCB, but also generates gerbers for F.Paste and B.Paste layers.

  • JLCPCB: contain fabrication outputs compatible with JLC PCB. Only SMD components. Use the field_lcsc_part global option to specify the LCSC part number field if KiBot fails to detect it.

    • _JLCPCB_gerbers: Gerbers.

    • _JLCPCB_drill: Drill files

    • _JLCPCB_position: Pick and place, applies the _rot_footprint filter. You can change this filter.

    • _JLCPCB_bom: List of LCSC parts, assumes a field named LCSC# contains the LCSC codes. You can change this filter.

    • _JLCPCB_compress: Gerbers, drill, position and BoM files compressed in a ZIP

    • _JLCPCB_fab: _JLCPCB_gerbers+_JLCPCB_drill

    • _JLCPCB_assembly: _JLCPCB_position+_JLCPCB_bom

    • _JLCPCB: _JLCPCB_fab+_JLCPCB_assembly

  • JLCPCB_stencil: same as JLCPCB, but also generates gerbers for F.Paste and B.Paste layers.

  • JLCPCB_with_THT: same as JLCPCB, but also including THT components.

  • JLCPCB_stencil_with_THT: same as JLCPCB_stencil, but also including THT components.

  • MacroFab_XYRS: XYRS position file in MacroFab format

    • _macrofab_xyrs: Position file in XYRS format compatible with MacroFab.

  • PanelDemo_4x4: creates a 4x4 panel of the board, showing some of the panelize options

    • _PanelDemo_4x4: The panel

  • P-Ban: contain fabrication outputs compatible with P-Ban

    • _P-Ban_gerbers: Gerbers. You need to define the layers for more than 8.

    • _P-Ban_drill: Drill files

    • _P-Ban: _P-Ban_gerbers+_P-Ban_drill

  • P-Ban_stencil: same as P-Ban, but also generates gerbers for F.Paste and B.Paste layers.

  • PCB2Blender_2_1

    • _PCB2Blender_layers_2_1: The layers in SVG format. Disabled by default.

    • _PCB2Blender_vrml_2_1: The VRML for the board. Disabled by default.

    • _PCB2Blender_tools_2_1: Pads and bounds information. Disabled by default.

    • _PCB2Blender_2_1: The PCB3D file. Is enabled and creates the other files.

    • _PCB2Blender_elements_2_1: _PCB2Blender_tools_2_1+_PCB2Blender_layers_2_1+_PCB2Blender_vrml_2_1

  • PCB2Blender_2_1_haschtl

    • Imports PCB2Blender_2_1 and disables _PCB2Blender_2_1

    • _PCB2Blender_tools_2_1_haschtl: Pads, bounds and stack-up information. Disabled by default.

    • _PCB2Blender_2_1_haschtl: The PCB3D file. Is enabled and creates the other files.

    • _PCB2Blender_elements_2_1_haschtl: _PCB2Blender_tools_2_1_haschtl+_PCB2Blender_layers_2_1+_PCB2Blender_vrml_2_1

  • PCBWay: contain fabrication outputs compatible with PCBWay

    • _PCBWay_gerbers: Gerbers

    • _PCBWay_drill: Drill files

    • _PCBWay_compress: Gerbers and drill files compressed in a ZIP

    • _PCBWay: _PCBWay_gerbers+_PCBWay_drill

  • PCBWay_stencil: same as PCBWay, but also generates gerbers for F.Paste and B.Paste layers.

Using other output as base for a new one

If you need to define an output that is similar to another, and you want to avoid copying the options from the former, you can extend an output. To achieve it just specify the name of the base output in the extends value. Note that this will use the options of the other output as base, not other data as the comment.

Also note that you can use YAML anchors, but this won’t work if you are importing the base output from other file.

Additionally you must be aware that extending an output doesn’t disable the base output. If you need to disable the original output use disable_run_by_default option.

Grouping outputs

Sometimes you want to generate various outputs together. An example could be the fabrication files, or the documentation for the project.

To explain it we will use an example where you have six outputs. Three are used for fabrication: gerbers, excellon_drill and position. Another three are used for documentation: SVG, PcbDraw and PcbDraw2. The YAML config containing this example can be found here. If you need to generate the fabrication outputs you must run:

kibot gerbers excellon_drill position

One mechanism to group the outputs is to create a compress output that just includes the outputs you want to group. Here is one example:

- name: compress_fab
  comment: "Generates a ZIP file with all the fab outputs"
  type: compress
  run_by_default: false
  options:
    files:
      - from_output: gerbers
      - from_output: excellon_drill
      - from_output: position

The compress_fab output will generate the gerbers, excellon_drill and position outputs. Then it will create a ZIP file containing the files generated by these outputs. The command line invocation for this is:

kibot compress_fab

Using this mechanism you are forced to create a compressed output. To avoid it you can use groups. The groups section is used to create groups of outputs. Here is the example for fabrication files:

groups:
  - name: fab
    outputs:
      - gerbers
      - excellon_drill
      - position

So now you can just run:

kibot fab

The gerbers, excellon_drill and position outputs will be generated without the need to generate an extra file. Groups can be nested, here is an example:

groups:
  - name: fab
    outputs:
      - gerbers
      - excellon_drill
      - position
  - name: plot
    outputs:
      - SVG
      - PcbDraw
      - PcbDraw2
  - name: fab_svg
    outputs:
      - fab
      - SVG

Here the fab_svg group will contain gerbers, excellon_drill, position and SVG.

Groups can be imported from another YAML file.

Avoid naming groups using _ as first character. These names are reserved for KiBot.