Files
product-template/TEMPLATE.md
T
grabowski 421b4202cc Product repository template
Layout, proplan.toml, README/CHANGELOG, placeholder product image, .gitignore, KiBot/release/docgen workflows and TEMPLATE.md. Source of truth: contrib/product-template in B4L/proplan (cargo test --test product_template checks it as Gitea 1.27 creates a repository from it).
2026-10-13 16:32:25 +07:00

5.8 KiB

B4L product repository template

Every B4L product repository has the same layout, so people and proplan find the product image, the boards, the firmware and the libraries in the same place. This file explains the layout, the rules and proplan.toml. It is copied into every repository created from the template; keep it as the reference.

Create a product repository

In Gitea: New Repository, choose the template B4L/product-template, tick Git Content, give the repository the product's name and a description. Gitea puts the name into README.md, CHANGELOG.md, proplan.toml and the board folder under hardware/ (the files listed in .gitea/template). Then:

  1. Replace assets/product.png with a photo or render of the product (PNG, JPEG or WebP, at most 5 MB).
  2. Create the KiCad project in the board folder (KiCad: File, New Project; the project file is hardware/<name>/<name>.kicad_pro).
  3. Commit and push. The KiBot workflow checks the board on every push.
  4. Tag the first prototype v0.1 when its boards are ordered, and link the tag to the stage on the project's Prototypes tab in proplan.

Layout

Path What goes there
proplan.toml the manifest proplan reads (below)
README.md, CHANGELOG.md what the product is; one changelog section per stage (## v0.2)
assets/product.png the product image
hardware/<board>/ one KiCad project per board
hardware/lib/ symbols, footprints and 3D models shared by the boards
firmware/<target>/ MCU code (STM32CubeIDE or CMake), firmware/lib/ for shared drivers
external/ third-party code as git submodules (e.g. ST's USB-PD middleware)
software/<tool>/ host tools and apps
mech/ FreeCAD sources and STEP exports
sim/ LTspice/ngspice, calculation scripts and notebooks
test/<stage>/ bench results per stage (test/v0.1/)
docs/, docs/datasheets/, docs/tex/ documentation, vendor PDFs, LaTeX sources
.gitea/workflows/ KiBot, release outputs, fabrication document

Rules

  • A board revision is a tag (v0.1, v0.2), never a copied folder (kicad_v1_5/ next to kicad_v1_6/). A real variant built side by side (48 V and 24 V, 2-board and 3-board) is its own folder under hardware/ and its own [[boards]] entry.
  • Generated output (gerbers, BOMs, production zips, PDFs, plots) is built by CI and attached to the release; it is not committed.
  • Vendor datasheets go to docs/datasheets/, not the repository root.
  • Third-party code is a git submodule in external/ and is not edited here.
  • IDE build output and tool caches (Debug/, __pycache__/, .claude/, KiCad backups) stay out; .gitignore covers them.

proplan.toml

proplan reads this file and the image it names, nothing else of the repository's content: at the default branch for the Code tab, and at a stage's tagged commit for the stage's card (so the card shows the product as it was at that tag). Every key is optional.

schema = 1                          # 1; a newer schema is refused

[product]
name = "papir"                      # default: the repository's name
image = "assets/product.png"        # PNG, JPEG or WebP, at most 5 MB; none when left out

[[boards]]                          # one per KiCad project, as many as needed
name = "papir"                      # default: the folder's last part
path = "hardware/papir"             # required

[paths]                             # each default: the folder of the same name
firmware = "firmware"
software = "software"
mech = "mech"
sim = "sim"
test = "test"
docs = "docs"
external = "external"

Paths are relative to the repository root (no leading /, no ..). A board, a path written under [paths] or the image that does not exist is reported on the Code tab ("proplan.toml: missing ..."); a path left out that does not exist is simply not shown. Unknown keys are ignored.

Adopting the layout in an existing repository

An existing repository does not have to move anything: a proplan.toml that names the current folders is enough, and history and open work stay as they are. Moving folders to the template's names can follow later.

papir (KiCad project in papir/, firmware in code/):

[[boards]]
name = "papir"
path = "papir"

[paths]
firmware = "code"
software = "pirnet"
mech = "mech"
docs = "docs"

LVSolarBuck (the current board in kicad48V-R/LVSolarBuck, firmware in code64/):

[product]
image = "housing.png"

[[boards]]
name = "LVSolarBuck"
path = "kicad48V-R/LVSolarBuck"

[paths]
firmware = "code64"
sim = "ltspice"
test = "testing"
docs = "docs"

PowerModule (three board variants):

[product]
image = "images/render-display.png"

[[boards]]
name = "PowerModule"
path = "kicad/PowerModule"

[[boards]]
name = "PowerModule48"
path = "kicad/PowerModule48"

[[boards]]
name = "PowerModule48PD"
path = "kicad/PowerModule48PD"

[paths]
firmware = "code"
software = "tools"
sim = "ltspice"
test = "testing"
docs = "tex"
external = "external"

CI

  • .gitea/workflows/kibot.yml: on a push that touches hardware/, KiBot runs ERC and DRC and builds schematic PDF, gerbers, drill files, pick and place and BOM for every board (hardware/*/*.kicad_pro); the outputs are kept as a workflow artifact.
  • .gitea/workflows/release.yml: on a tag v*, the same outputs are zipped per board and attached to the tag's release (created when missing). The Actions token must be allowed to write releases.
  • .gitea/workflows/docgen.yml: with a docs/input.md (typecad-docgen front matter, as in PowerModule), builds the fabrication document of the first board and pushes it to the docu branch.

All three use the runner label kicad10_auto (as LVSolarBuck). They were adapted from LVSolarBuck and PowerModule and run for the first time when the first board is committed and tagged; check that first run.