How do you version your KiCad projects?

I’m really interested in learning about the different ways that people in the KiCad community version their hardware projects.

For example, in the software world, there are some widely adopted standards such as Semantic Versioning that assign a well-defined meaning to the MAJOR.MINOR.PATCH versioning scheme.

I’ve seen many KiCad projects use versions that look like semver (e.g. v1.0), but I’ve found that the meaning of the MAJOR, MINOR, and PATCH version components can have very different meanings depending on who the project authors are.

Alternatively, some projects use a simple revision scheme (Rev A, Rev B, Rev C, etc). Others use a simple version scheme (v1, v2, v3). Others use a combination of version and revision (V1 Rev A, V1 Rev B, V2 Rev A, etc). I’ve even seen some projects that rely solely on a git hash as the revision identifier.

If you have a versioning scheme that you’ve been using successfully, I’d love to hear about it. Specifically, I’m interested in understanding the meaning behind the version identifiers, and the logic that dictates when you increment the version. For example, if you use a semver versioning scheme like v1.2, what does the 1 vs. the 2 mean to you? What would cause the version to increment from v1.2 to v2.0 vs. v1.3? If the terms “version” and “revision” mean different things to you, how are they used differently in your workflow?

In particular, I’d really like to hear from folks who:

  1. Use Git for version control of KiCad files and release their design & manufacturing files (gerbers, PDFs, etc) through a structured release mechanism like GitHub Releases.
  2. Use KiCad together with a traditional product lifecycle management (PLM) system (Arena, Aligni, etc) that requires “part numbers” and “revisions” be assigned to all documents like the schematic, PCB layout, BOM, etc.
  3. Use KiCad for designing products with multiple iteration cycles, where multiple versions of the design need to be managed simultaneously (e.g. V1 is in mass production, while V2 is in the EVT phase).

Some context about where this question is coming from:

I’ve spent a lot of time designing hardware in [big company] where the PLM system’s Part Number + Revision is the source of truth. Every schematic is assigned a “drawing number” (part number) with an incrementing “drawing revision”, and each new revision of the schematic drawing is checked into the master PLM system. The PCB layout is also assigned a totally separate “drawing number” (part number) + drawing revision that does not match the ones in the schematic (changes can be made to either independently).

However, in most KiCad projects I’ve seen in the wild, the schematic & PCB layout (and sometimes docs & firmware) are all checked into a single git repo and releases of the entire repo are assigned a single version number like v1.2.

I’m trying to reconcile my oldschool “big company” PLM-based worldview with a more modern software-like approach to project versioning (like semver), and I’m wondering if anybody has found an elegant way to bridge the two worlds together.

5 Likes

As an example, this article describes how the folks at Brainbow use a version of semver for KiCad projects:

1 Like

I use semantic versioning with git with following conventions:

  • MAJOR is incremented once an external interface changes, so connectors are moved, have a changed pinout, mounting holes are changed, microcontroller has different pinout so software needs to be adjusted, etc. so basically it reflects if any other aspect then electrical board design is affected.
  • MINOR is changed for every pure electrical changes for new, clean releases. this can be everything from changing a few passive values up to adding a whole new function to the board.
  • PATCH is only used for actual patches. so if you have an existing layout where some resistors need to be changed, if you have to reconnect some pads with a wire and so on.

main schematic and board layout have always the same version number, subsheets can differ:

  • if the subsheet is a module used in multiple projects then the module has its own git repository and therefor also a own version number based on the same principles as above. it is intended to always have the latest version of a module on a new board design.
  • if the subsheet exists only for this specific project I usually don’t take too much care of the version of the subsheet as the main sheet already reflects the version changes. but in principle you can also apply the semantic versioning if you change the subsheets.

I used “v” for “version” but my boss told “revision” is used in the PCB world, so I switched to that although I didn’t see any real good reason for it.

The difference between software and PCBs is that there are unusally only few versions ever of a board, for natural reasons – they are products which don’t evolve over time frequently. There are of course exceptions, but I think prototypes + 1…10 versions or something like that is quite normal. Software can be developed differently and there can be forks and simultaneous versions and concecutive versions for tens of years, continuous releases, nightly releases (like KiCad) etc.

We didn’t bother ourselves much with version numbers. Sometimes I just changed a minor number, sometimes a major if there was a larger change. It could have been randomized. :slight_smile: In the end it was just to show the order of the versions, and to differentiate for manufacturing etc. But it was a very small company, so I can’t recommend this for others.

1 Like

I am using rev_1, rev_2 for prototypes and rev_A, rev_B for manufacturing PCBs. Currently the last revision of any PCB we manufacture is C.
In PCB world there is no need for so many revisions as each revision costs. Starting production costs at least a few hundred dollars (much more then ‘starting a production’ of new software version).
The manufacturers charge you for the software of the assembly machines and for each time they prepare them for the assembly of your PCBs (placing rolls with elements in a manner consistent with the documentation of your PCB).

I use Major.Minor.Patch versioning also.

But, the Major is for the PCB version. If the PCB version has not been changed, the Major version will not be changed.

Minor is for component changing, if there is component has been changed or modified(including fiited, not fitted, substtitue and so on), the Minor version will be changed.

And for some small modification(correct some small mistakes in description), the Patch version will be changed.

The schematic version will be the same as the BOM version also.

Here is my numbering/versioning scheme: https://docs.google.com/document/d/1XeZhEkoAvaRxvdhkERgBn7fWumktTpZoiKBsEUGfBH4/edit#heading=h.agw8vsci6zxu

I use letter-number revisioning, so an assembly would have a revision like B02. The letter indicates any change to the PCB, and the number indicates any changes to the bill of materials that can use the same PCB. So, B01 and B02 can use the same PCB, but as soon as I have to change a footprint, it becomes C01.

I only update the revision when publishing it. For personal projects, this may mean placing an order for PCBs or components. For work projects, this usually means issuing a change notice so that the manufacturing team can source the new revision. So, “work in progress” Git commits don’t increment the revision.

For personal stuff i use an integer and increment it. Semver is specifically for things with APIs and i find its broad general adoption baffling, i’ve been in or heard so many arguments over what exactly “minor” and “patch” mean for a given application and imo it’s just a sign that this is not the system for this application. Overcomplicated. I love the simplicity of just using an integer. At work, we usually use a major.minor (no patch) scheme, but sometimes will use a different scheme if a client prefers it, and usually that’s just good ol’ incrementing integer.

I make no distinction between prototype and non-prototype because usually the final “prototype” becomes the non-prototype after it passes all checks and nobody has any further issues to report with it.

2 Likes

Thank you to everyone who commented so far! It’s really interesting to see the different ways that people are approaching this. I’ll reply with some questions once I’ve digested and thought through some of these ideas a bit more.

  • MAJOR is incremented once an external interface changes, so connectors are moved, have a changed pinout, mounting holes are changed, microcontroller has different pinout so software needs to be adjusted, etc. so basically it reflects if any other aspect then electrical board design is affected.
  • MINOR is changed for every pure electrical changes for new, clean releases. this can be everything from changing a few passive values up to adding a whole new function to the board.

@Tojan this definition is interesting because your criteria for MAJOR version changes aligns pretty well with the concept of Form, Fit, and Function (F3). In a more traditional part number-based system, the decision whether to increment the revision of an existing part number or pull a new part number is commonly based on whether the change affects the form, fit, or function of the part (which is effectively the “external interface” you describe). If a change affects the FFF, a new part number is created. If the change doesn’t affect the FFF, the change can be implemented by incrementing the revision. It feels like you could make the following logical mapping pretty cleanly into a PLM:

  • MAJOR → Part Number
  • MINOR → Revision

I’ll have to think through this a bit more, but I like the general approach here!

  • PATCH is only used for actual patches. so if you have an existing layout where some resistors need to be changed, if you have to reconnect some pads with a wire and so on.

When you say “actual patches” do you mean physical rework/bodges to existing boards? Just want to make sure I understand the workflow you’re describing. Let’s say you manufacture v1.2.0 PCB and then you add a blue wire bodge to fix an issue. Do you add the new wire to the KiCad schematic (but no change to PCB layout) and create a new release v1.2.1? Would you also create a v1.3.0 release the next time you manufacture the board with the same fix actually implemented in the PCB design?

@eelik I think this may be a historical thing from when PCB design was done on hand-taped artwork documents where changes were recorded with a “drawing rev” (e.g. “REV B”):

(Photo from PCB WIZARDS.COM which has some awesome old school photos)

In my personal experience at previous employers, changes to an existing schematic/layout document have always been recorded as a change to the “revision”. I’ve usually seen the term “version” used to represent major milestone changes to a product (usually accompanied by a new part number), where each version can have multiple incremental revision changes.


@Piotr “prototype” meaning non-production (e.g. R&D stage), and “manufacturing” meaning production? So for example, a single PCB design may go through the change sequence rev_1, rev_2, rev_3, rev_A, where “rev_A” is the first production release?


@craftyjon I like the simplicity of this scheme. How do you handle releasing minor changes that don’t actually change the PCB or the BOM? For example, if you fixed a documentation typo in the schematic and had to release it to manufacturing, how do you differentiate between the two revisions in this scheme?


If you don’t mind, could you describe this workflow in a bit more detail? Do you generate a C01.zip release that contains the gerbers, PDFs, etc for the manufacturing team? Are you folks using any tools to facilitate the exchange between engineering and manufacturing (e.g. PLM or something else?)


@alexisvl On one hand, I totally get this sentiment. There is a general trend of trying to shoehorn hardware development into tooling made for SW development, and semver doesn’t feel like a perfect fit (especially when you have to track additional things like manufacturing deviations and rework instructions).

On the other hand, the semver solves the problem of changes to dependencies by using a well defined contract between the producers and consumers of a piece of software. I think you can make an argument that the PCB can be thought of as a dependency (for the mechanical engineer, SW team, factory test team, etc), and that having a well defined contract that makes the nature of a change explicit is valuable. In general, I like the idea that an external consumer of a PCB can just look at the version identifier for a new version and know whether it’s compatible or not.


I think this distinction is helpful in larger orgs where having a clear distinction between prototype vs. production is needed because engineering owns prototype development, but operations owns the sustaining of production designs (logically and from a budget perspective as well).

2 Likes

Eight years ago, I wrote a version system for making my own PCB’s using EAGLE.
However, since then I have yet to make a PCB.

If you’ve made more than one revision to one particular PCB, please cut my version
system to pieces and tell me why it sucks, or what it lacks and how you would revise
it in making your own “experimental” PCB’s.

At that time, I was planning to make my PCB’s with EAGLE, but today I am only considering Kicad 6.

My PCB Numbering scheme
Aug 20, 2014

My PCBs will be experimental in nature.   But I will eventually get
a "done" version that I will wish to reproduce in quantity.

My PCB numbering scheme will help me achieve two goals:

	1 Seven years from now, when I pick up a PCB that I made I
          will be able to see what good it is, if any, whether to
          keep it, or if it is obsolete.
	
	2 The numeral on my PCB will correspond to ***exactly one***
          or more EAGLE schematic and board files.   By looking at 
          the PCB, I will know which EAGLE file(s) to use in order
          to reproduce it.

Software goes through major and minor releases like so...
	alpha - first verson
	beta  - released for testing
	rc    - release candidate (most bugs removed but not all)
        final - a released version, w/ major & minor numerals

My PCB numbering scheme will be similar to this.

Suffixes:
a <--> alpha release
  (corresponds to)
b <--> beta release "better than alpha"
c <--> release and get ready to test
d <--> "dog" version, which stands for PAWS - "populated and works"
       Or the "d" suffix could simply mean "done", i.e., I tried it
       and it works fine.

   Version no.
       X.YY
       where X is the major version no. and YY is the minor version no.
       For example, 12V Battery monitor v0.58d
       For example, Power-on LED v0.1a

Minor versions will represent successive hardware improvements,
e.g., 0.1 - first version, 0.2 - second version, etc.

Let me be perfectly clear:   When the PCB changes, but the schematic
does NOT change, only the minor version no. will change.   Examples
would be adding test points to the PCB, rerouting traces, changing
the size of the PCB but NOT any of the components or the technology,
changing design rules, trace widths.

If the PCB is simple, and I get it done right the first time, as veri-
fied by testing, then the version number will go immediately from 
X.YYa to X.yyd.

Major versions will increment when the BOM has changed OR the
schematic has changed, or both.   In other words, components were
changed or added, either to improve functionality or to make it 
work with newer or better ICs or both, or to integrate new parts/
functions.

Let me be perfectly clear:   When the BOM or the schematic changes,
and ONLY then, will the major version no. change. Examples would be
adding a different version of an IC, converting from THT to SMT,
adding a component, or deleting a component.

Examples 

However, adding an offboard component, such as a toggle switch in
orer to power off a particular section when not in use, ***will
not*** require a major version increment.

major version increment:    0.9  ----> 1.0
minor version increment:    1.1  ----> 1.2 or 0.6 ----> 0.7

If I thought that I'd need to make more minor revisions, I'd go
with two digits to the right of the decimal point, i.e., 0.01, 0.02,
0.03, 0.04, 0.05, 0.06, 0.07, ..., 0.10, 0.11, 0.12, 0.13, ...,
0.96, 0.97, 0.98, 0.99, etc.
I doubt the extra digit is necessary, but I could be wrong.
So for now, I will go with a single digit to the right of the decimal
point, plus a suffix.   But I reserve the option to change my mind
later.

Hence, I envision my first experimental prototype boards will be 
labeled like so:
	12V Battery Monitor 0.1a
	12V Battery Monitor 0.1b
	12V Battery Monitor 0.1c
	12V Battery Monitor 0.1d

This scheme allows a jump from, say
	12V Battery Monitor 0.1c
to either 12V Battery Monitor 0.1d or
to        12V Battery Monitor 1.1a or
to  	  12V Battery Monitor 0.2a

This scheme allows me three experimental versions with suffixes a,b,c 
before getting a PCB that is "done".    Will this be sufficient?   If not,
I will simply bump up the minor  version number.   I will try to ensure the
PCB version to be reproduced will be the one with the suffix "d" for done.

Aug. 21, 2017

The first version of a PCB might be labeled, for example,
		12V Battery Monitor.

This is the zero'th version.   C programmers start counting with zero.
Anybody else starts counting with one.   So the  zero'th version will 
bear no numbering scheme whatsoever.   Thus, if I get the PCB working
on the very first try, it will remain unmarked by revision numerals.

I simply use a date string in ISO_8601 format. Some people use git for for versioning, but I prefer to use the simpler use of occasionally making backups in zip files, and I also prepend a date in ISO_8601 format to those backups.

At the start of a project I do not pay much attention to this date string, but when I generate gerber files for production then I make sure the date string both on the PCB and in the zip backup files are the same, and I also backup the gerber files wich were sent to the PCB fab.

1 Like

A documentation typo would typically be released as an ECO that didn’t increment the revision if the impact of the typo was not relevant for manufacturing. For example, if a schematic note was wrong, or if a typo appeared on an assembly drawing that didn’t materially impact the assembly.

On the other hand, if a typo did or could impact the assembly materially, it would be a revision bump.

We generate outputs that include the revision in the filename as well as internal part number and description (we don’t have all the outputs in a single zip file, but rather several different sets of outputs as we have different internal part numbers for schematic, PCB (bare board, gets gerbers and fab drawing), and PCA (completed assembly; gets BOM and assembly drawing). Yes, this workflow basically requires a PLM tool. I’ve used a number of different PLM tools to implement things like this.

The way we handle this is that “breaking API changes” to a PCA require a whole new internal part number. Ideally you can take any revision of a given part number and slot it in to the same spot in a bigger system.

We also don’t distinguish between prototype and non-prototyping in the revision scheme. The lifecycle status of a part (meaning is it a prototype or production or obsolete, etc) is tracked by the PLM system and can be looked up, but isn’t a part of the identifying numbers printed on a board.

I just put the date and perhaps time on the file name. I try use version number too, if it is “final” and used in manufacturing.

it is exactly as you described. we have to track our differrent board versions verry accurate as we only produce very small series of boards. therefore each board which was produced already but gets changed in any way gets the PATCH number increased and this change is only represented in the schematic not in the layout. if this change then gets cleanly implemented in the layout for the next produced series the MINOR number gets incremented.

Just in case, pointing out that git supports submodules, which allows you to splice repos. It’s described in the docs.

1 Like

Thanks for pointing this out. I’m currently using git submodules to manage shared KiCad libraries across multiple projects (although I know that people have mixed feelings about using submodules in general). Makes sense that you could use it one level up to bring individual HW & SW repos together into a single repo.

In the case where you do have a single combined repo with HW/FW/docs/etc (either as a flat repo or using git submodules), these individual components will most likely have their own unique version numbers. I don’t think it would make much sense to create releases of this repo under a single version like v1.2 (i.e. what would the MAJOR and MINOR versions mean in the combined case?)

However, I ran across a good example of a combined repo where the releases on GitHub use a date-based version number (e.g. 2022.07.6). In this case, the version number is just an incremental date that doesn’t carry any additional meaning, and the release just contains the latest versions of the HW/FW/docs/etc. This release scheme seems more tailored towards the FW release process, and I’m not exactly sure how you would track back each HW version (v1, v2, etc) to a specific git ref in the repo.

I’m sure you could write automation to generate and store the information somwhere.