diff --git a/.github/sync.yml b/.github/sync.yml deleted file mode 100644 index c354a01..0000000 --- a/.github/sync.yml +++ /dev/null @@ -1,22 +0,0 @@ -group: - repos: | - OE5XRX/HW-Module-DeviceTester - OE5XRX/HW-Module-BusBoard - OE5XRX/HW-Module-PowerBoard - OE5XRX/HW-Module-CM4Carrier - OE5XRX/HW-Module-FMTransceiver - files: - # general files - - .gitignore - - LICENSE - # build files - - .github/workflows/create-debug-docs.yaml - - .github/workflows/create-release-docs.yaml - - .github/workflows/kibot-check.yaml - - doc/_config.yml - - doc/favicon.ico - - doc/Icon.png - - scripts/ - - Gemfile - - production.kibot.yaml - - test.kibot.yaml diff --git a/.github/workflows/create-debug-docs.yaml b/.github/workflows/create-debug-docs.yaml index 980e355..b3108ef 100644 --- a/.github/workflows/create-debug-docs.yaml +++ b/.github/workflows/create-debug-docs.yaml @@ -1,80 +1,11 @@ -name: Create Production Data For Beta Version +name: Create Debug Docs on: workflow_dispatch: push: - branches: - - 'main' - + branches: [main] permissions: contents: write - jobs: - export-ecad: - name: Export ECAD - runs-on: ubuntu-24.04 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Update the PCBs with the BETA and git hash - run: | - export COMMIT=$(git rev-parse --short HEAD) - echo "COMMIT = ${COMMIT}" - sed -i "s/<>/BETA-${COMMIT}/g" *.kicad_* - - - name: Generate Export Files - uses: INTI-CMNB/KiBot@v2_k9 - with: - config: production.kibot.yaml - dir: output - schema: main.kicad_sch - board: main.kicad_pcb - verbose: 0 - - - name: Upload Export Files as Artifacts - uses: actions/upload-artifact@v4 - with: - name: production - path: output - if-no-files-found: error - - - collect-and-provide: - runs-on: ubuntu-24.04 - needs: export-ecad - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.1' - bundler-cache: true - cache-version: 0 - - - name: Setup Pages - id: pages - uses: actions/configure-pages@v5 - with: - generator_config_file: doc - - - name: Build with Jekyll - run: cd doc && bundle exec jekyll build - env: - JEKYLL_ENV: production - - - uses: actions/download-artifact@v5 - with: - name: production - path: doc/_site - - - name: Deploy πŸš€ - uses: JamesIves/github-pages-deploy-action@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - branch: gh-pages - folder: doc/_site - target-folder: ${{ env.DEPLOY_PATH }} - clean: true + build: + uses: OE5XRX/HW-Module-CI/.github/workflows/create-debug-docs.yaml@main + secrets: inherit diff --git a/.github/workflows/create-release-docs.yaml b/.github/workflows/create-release-docs.yaml index ba66cd2..7f81061 100644 --- a/.github/workflows/create-release-docs.yaml +++ b/.github/workflows/create-release-docs.yaml @@ -1,57 +1,9 @@ -name: Create Production Data For Release Version +name: Create Release Docs on: workflow_dispatch: release: types: [published] - jobs: - export-ecad: - name: Export ECAD - runs-on: ubuntu-24.04 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Update the PCBs with the BETA and git hash - run: | - export COMMIT=$(git rev-parse --short HEAD) - echo "COMMIT = ${COMMIT}" - sed -i "s/<>/${GITHUB_REF_NAME}-${COMMIT}/g" *.kicad_* - - - name: Generate Export Files - uses: INTI-CMNB/KiBot@v2_k9 - with: - config: production.kibot.yaml - dir: output - schema: main.kicad_sch - board: main.kicad_pcb - verbose: 0 - - - name: copy doc files to output folder - run: sudo cp doc/* output/ - - - name: Upload Export Files as Artifacts - uses: actions/upload-artifact@v4 - with: - name: production - path: output - if-no-files-found: error - -# - name: Generate Parts on InvenTree Server -# env: -# INVENTREE_API_TOKEN: ${{ secrets.INVENTREE_API_TOKEN }} -# INVENTREE_API_HOST: ${{ secrets.INVENTREE_API_HOST }} -# run: | -# pip install -r scripts/requirements.txt -# python3 scripts/bom-export.py --csv_file output/*-bom.csv --name "${{ github.event.repository.name }}" --version "${{ github.ref_name }}" --pcb_image output/*-3D_top-without.png --assembly_image output/*-3D_top-with.png - - - name: Deploy πŸš€ - uses: JamesIves/github-pages-deploy-action@v4 - with: - token: ${{ secrets.DEPLOY_GH_TOKEN }} - repository-name: OE5XRX/OE5XRX.github.io - branch: main - folder: output - target-folder: docs/remote-station/hardware/${{ github.event.repository.name }} - clean: true + build: + uses: OE5XRX/HW-Module-CI/.github/workflows/create-release-docs.yaml@main + secrets: inherit diff --git a/.github/workflows/kibot-check.yaml b/.github/workflows/kibot-check.yaml index 0710288..2d43302 100644 --- a/.github/workflows/kibot-check.yaml +++ b/.github/workflows/kibot-check.yaml @@ -1,26 +1,11 @@ -name: Kibot check +name: KiBot Check on: workflow_dispatch: pull_request: - branches: - - 'main' + branches: [main] push: - branches: - - 'main' - + branches: [main] jobs: - kibot_check: - name: Check with Kibot - runs-on: ubuntu-24.04 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: check KiCad files - uses: INTI-CMNB/KiBot@v2_k9 - with: - config: test.kibot.yaml - dir: output - schema: main.kicad_sch - verbose: 0 + check: + uses: OE5XRX/HW-Module-CI/.github/workflows/kibot-check.yaml@main + secrets: inherit diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml deleted file mode 100644 index 8586ae1..0000000 --- a/.github/workflows/sync.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Sync Files to other repositories -on: - workflow_dispatch: - push: - branches: - - main - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Run GitHub File Sync - uses: BetaHuhn/repo-file-sync-action@v1 - with: - GH_PAT: ${{ secrets.DEPLOY_GH_TOKEN }} diff --git a/.gitignore b/.gitignore index 6d4d8eb..df7a2de 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ Thumbs.db # Python cache (if scripts are used) __pycache__/ *.pyc + +# Generated by HW-Module-CI at runtime (must never be committed) +doc/_data/project.yml diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 2f7fc6b..0000000 --- a/Gemfile +++ /dev/null @@ -1,8 +0,0 @@ -source 'https://rubygems.org' - -gem "jekyll", "4.4.1" - -group :jekyll_plugins do - gem "just-the-docs", "0.10.1" - gem "jekyll-git-hash" -end diff --git a/README.md b/README.md index 0900c85..8a64323 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,41 @@ # HW-Module-Template -## Description - -This repository is a template for hardware modules using KiCad, designed for clean, maintainable development with CI/CD pipelines generating and publishing production data automatically. - -## Features -* Structured KiCad project (schematic, PCB) -* Clean repository: no production data stored -* GitHub Actions CI/CD pipeline: - * Generates Gerber, BOM, and assembly files - * Uploads artifacts to GitHub Releases -* Open Hardware license ready (CERN-OHL-S) - -## Repository Structure - -``` -HW-Module-Template/ -β”œβ”€β”€ .github/workflows/ # CI/CD pipeline scripts -β”œβ”€β”€ doc/ # Documentation exports -β”œβ”€β”€ symbols/ # Local symbol library (if needed) -β”œβ”€β”€ footprints/ # Local footprint library (if needed) -β”œβ”€β”€ 3d-models/ # STEP/WRL files (optional) -β”œβ”€β”€ main.kicad_pro # KiCad main project file -β”œβ”€β”€ main.kicad_sch # KiCad main schematic file -β”œβ”€β”€ main.kicad_pcb # KiCad main pcb file -β”œβ”€β”€ *.kicad_sch # other KiCad schematic files -β”œβ”€β”€ LICENSE -└── README.md -``` - -## Usage -1. Click β€œUse this template” on GitHub. -2. Clone your repository locally and open in KiCad. -3. fix the missing names in the readme and add documentation in the `doc/index.md` file. -4. Work on your schematic and PCB as usual (create a new project (main-file must be called `main.kicad_*`) or copy a new one into the folder structure). -5. Push your changes. -6. CI/CD will automatically generate production files. -7. If there is a release defined, CI/CD will create a documentation on the main webpage. +GitHub "Use this template" scaffold for new hardware module repositories under OE5XRX. New modules cloned from this template start pre-wired to the shared CI infrastructure at [`OE5XRX/HW-Module-CI`](https://github.com/OE5XRX/HW-Module-CI). -## License +## Quickstart for new modules + +1. Click **"Use this template"** on GitHub to create a new module repo (e.g., `HW-Module-Acme`). +2. Clone the new repo locally. +3. Replace `LICENSE` if your license differs from CERN-OHL-S 2.0. +4. Create your KiCad project at the repo root. The `.kicad_pro`, `.kicad_sch`, and `.kicad_pcb` can be named anything β€” the shared CI auto-detects the basename. Convention: name them after the module (e.g., `Acme.kicad_pro`). +5. Fill in `doc/index.md`: + - Replace `` with the module's display name (e.g., `Acme`). + - Update `nav_order` to position it correctly on the hardware overview page. + - Replace `Some Text` with the module description, voltage tables, etc. + - Output paths already use `{{ site.data.project.name }}` β€” leave those as-is; CI fills in the auto-detected KiCad basename at build time. +6. Commit and push. On the first push to `main`, CI auto-runs: + - `KiBot Check` β€” ERC + DRC preflight + - `Create Debug Docs` β€” publishes preview to the repo's `gh-pages` branch +7. On the first GitHub release: `Create Release Docs` deploys versioned docs to `OE5XRX.github.io` and pushes BOM to InvenTree. + +## What this template provides -This project is licensed under [CERN-OHL-S-2.0](https://choosealicense.com/licenses/cern-ohl-s-2.0/). +- `.github/workflows/` β€” 3 thin wrappers that `uses: HW-Module-CI@main` +- `doc/index.md` β€” Jekyll page scaffold (replace `` + content) +- `3d-models/`, `symbols/`, `footprints/` β€” empty subdirs for optional KiCad libraries +- `LICENSE` β€” CERN-OHL-S 2.0 +- `README.md` β€” this file (overwrite for your module) -## Badges +## What's intentionally NOT in this template + +KiBot configs, Python scripts (BOM export, InvenTree sync, stencil PNG), Jekyll config, Gemfile, doc assets (favicon, logo) β€” all of these live in [`OE5XRX/HW-Module-CI`](https://github.com/OE5XRX/HW-Module-CI) and are pulled in at CI-runtime. Do not copy them here. + +## License -![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/OE5XRX//kibot-check.yaml?branch=main)
-![GitHub Release](https://img.shields.io/github/v/release/OE5XRX/)
-![License: CERN-OHL-S](https://img.shields.io/badge/license-CERN--OHL--S--2.0-blue)
-![KiCad Supported](https://img.shields.io/badge/KiCad-supported-blue)
-![Project Type](https://img.shields.io/badge/type-hardware-red)
+[CERN-OHL-S-2.0](https://choosealicense.com/licenses/cern-ohl-s-2.0/) by default; replace `LICENSE` if your module needs a different license. ## Contact -OE5XRX Amateur Radio Club
-🌐 https://oe5xrx.org
-βœ‰οΈ info@oe5xrx.org
+OE5XRX Amateur Radio Club +🌐 https://oe5xrx.org +βœ‰οΈ info@oe5xrx.org diff --git a/doc/Icon.png b/doc/Icon.png deleted file mode 100644 index f0d52f2..0000000 Binary files a/doc/Icon.png and /dev/null differ diff --git a/doc/_config.yml b/doc/_config.yml deleted file mode 100644 index 56c5d99..0000000 --- a/doc/_config.yml +++ /dev/null @@ -1,16 +0,0 @@ -title: OE5XRX -description: Amateurfunkclub fΓΌr Remote Stationen - -theme: just-the-docs -favicon_ico: /favicon.ico -logo: "/Icon.png" - -mermaid: - version: "11.3.0" - -defaults: - - - scope: - path: "" - values: - layout: "default" diff --git a/doc/favicon.ico b/doc/favicon.ico deleted file mode 100644 index ba65c61..0000000 Binary files a/doc/favicon.ico and /dev/null differ diff --git a/doc/index.md b/doc/index.md index 0375d36..36ea783 100644 --- a/doc/index.md +++ b/doc/index.md @@ -9,8 +9,8 @@ parent: Hardware - - + +
TopBottom
topbottomtopbottom
@@ -18,9 +18,9 @@ Some Text ## Daten -- [Schaltplan](main-schematic.pdf) -- [BOM](main-bom.html) -- [iBOM](main-ibom.html) -- [JLCPCB fabrication & stencil](JLCPCB/main-_JLCPCB_compress.zip) -- [JLCPCB Bom](JLCPCB/main_bom_jlc.csv) -- [JLCPCB Pick&Place](JLCPCB/main_cpl_jlc.csv) +- [Schaltplan]({{ site.data.project.name }}-schematic.pdf) +- [BOM]({{ site.data.project.name }}-bom.html) +- [iBOM]({{ site.data.project.name }}-ibom.html) +- [JLCPCB fabrication & stencil](JLCPCB/{{ site.data.project.name }}-_JLCPCB_compress.zip) +- [JLCPCB Bom](JLCPCB/{{ site.data.project.name }}_bom_jlc.csv) +- [JLCPCB Pick&Place](JLCPCB/{{ site.data.project.name }}_cpl_jlc.csv) diff --git a/production.kibot.yaml b/production.kibot.yaml deleted file mode 100644 index 52e6eaf..0000000 --- a/production.kibot.yaml +++ /dev/null @@ -1,94 +0,0 @@ -kibot: - version: 1 - -globals: - resources_dir: Fabrication - field_lcsc_part: LCSC - -import: - - file: JLCPCB_stencil - -outputs: - - name: ibom - comment: 'Interactive Bill of Materials' - type: ibom - - - name: bom - comment: 'Bill of Materials' - type: bom - options: - csv: - hide_pcb_info: true - hide_stats_info: true - format: CSV - - - name: html_bom - comment: 'HTML BOM' - type: bom - options: - html: - title: 'Bill of Materials' - lcsc_link: 'LCSC' - mouser_link: 'MOUSER' - logo: 'doc/Icon.png' - - - name: SchematicPDF - comment: "Print schematic PDF" - type: pdf_sch_print - options: - color_theme: dracula - background_color: true - - - name: step_file - comment: 'STEP file generation' - type: step - - - name: KiCad_3D_top - comment: "render 3D top" - type: render_3d - options: - view: 'top' - orthographic: true - ray_tracing: true - auto_crop: true - enable_crop_workaround: true - transparent_background: true - - - name: KiCad_3D_bottom - comment: "render 3D bottom" - type: render_3d - options: - view: 'bottom' - orthographic: true - ray_tracing: true - auto_crop: true - enable_crop_workaround: true - transparent_background: true - - - name: KiCad_3D_top_with - comment: "render 3D top with" - type: render_3d - options: - output: '%f-%i%I%v-with.%x' - view: 'top' - orthographic: true - ray_tracing: true - auto_crop: true - enable_crop_workaround: true - transparent_background: true - show_components: 'all' - zoom: -2 - move_y: -1 - - - name: KiCad_3D_top_without - comment: "render 3D top without" - type: render_3d - options: - output: '%f-%i%I%v-without.%x' - view: 'top' - orthographic: true - ray_tracing: true - auto_crop: true - enable_crop_workaround: true - transparent_background: true - show_components: 'none' diff --git a/scripts/bom-export.py b/scripts/bom-export.py deleted file mode 100644 index 0edc34d..0000000 --- a/scripts/bom-export.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/env python3 - -import argparse -import csv -from dataclasses import dataclass, field -from inventree import company -from inventree.api import InvenTreeAPI -from inventree.part import Part, PartCategory, BomItem - -parser = argparse.ArgumentParser(prog="KiCad Bom export to InvenTree") -parser.add_argument("--csv_file", required=True) -parser.add_argument("--name", required=True) -parser.add_argument("--version", required=True) -parser.add_argument("--pcb_image", required=True) -parser.add_argument("--assembly_image", required=True) -args = parser.parse_args() - - -# must define connection settings in environment variables! -# INVENTREE_API_HOST -# INVENTREE_API_USERNAME -# INVENTREE_API_PASSWORD -# OR -# INVENTREE_API_TOKEN -api = InvenTreeAPI() - - -@dataclass(slots=True) -class BuildPart: - reference: str - qty: int - lcsc: list[str] = field(default_factory=list) - mouser: list[str] = field(default_factory=list) - inventree_part: list[Part] = field(default_factory=list) - - def compare_and_fetch(self, supplier_part: company.SupplierPart) -> bool: - if supplier_part.SKU in self.lcsc or supplier_part.SKU in self.mouser: - self.inventree_part.append(Part(api, pk=supplier_part.part)) - return True - return False - - -parts: list[BuildPart] = [] - -with open(args.csv_file, newline="") as csvfile: - reader = csv.DictReader(csvfile) - for row in reader: - parts.append( - BuildPart( - row["References"], - row["Quantity Per PCB"], - row["LCSC"].split(",") if len(row["LCSC"]) > 0 else [], - row["MOUSER"].split(",") if len(row["MOUSER"]) > 0 else [], - ) - ) - -# parts matching -supplier_parts = company.SupplierPart.list(api) - -for part in parts: - for supplier_part in supplier_parts: - if part.compare_and_fetch(supplier_part): - break - -# check all parts if something is missing -for part in parts: - if len(part.lcsc) != 0 or len(part.mouser) != 0: - assert len(part.inventree_part) != 0, f"{part}" - -pcb_cat = PartCategory(api, 54) -pcb_part = Part.create( - api, - { - "category": pcb_cat.pk, - "name": f"{args.name} PCB", - "revision": args.version, - "component": True, - }, -) -response = pcb_part.uploadImage(args.pcb_image) -assert response is not None - -pcb_cat = PartCategory(api, 2) -assembly_part = Part.create( - api, - { - "category": pcb_cat.pk, - "name": f"{args.name} Module", - "revision": args.version, - "component": True, - "assembly": True, - "trackable": True, - }, -) -response = assembly_part.uploadImage(args.assembly_image) -assert response is not None - -bom_item = BomItem.create( - api, - { - "part": assembly_part.pk, - "sub_part": pcb_part.pk, - "reference": "", - "quantity": 1, - }, -) - -for part in parts: - for inventree_part in part.inventree_part: - bom_item = BomItem.create( - api, - { - "part": assembly_part.pk, - "sub_part": inventree_part.pk, - "reference": part.reference, - "quantity": part.qty, - }, - ) diff --git a/scripts/requirements.txt b/scripts/requirements.txt deleted file mode 100644 index 41bda61..0000000 --- a/scripts/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -inventree diff --git a/test.kibot.yaml b/test.kibot.yaml deleted file mode 100644 index 957f454..0000000 --- a/test.kibot.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kibot: - version: 1 - -global: - field_lcsc_part: LCSC - -preflight: - erc: - warnings_as_errors: true - drc: true - update_xml: false - check_zone_fills: true