kicad-bot 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. kicad_bot-0.1.4/.claude/settings.local.json +51 -0
  2. kicad_bot-0.1.4/.github/dependabot.yml +18 -0
  3. kicad_bot-0.1.4/.github/workflows/ci.yml +74 -0
  4. kicad_bot-0.1.4/.github/workflows/codeql.yml +32 -0
  5. kicad_bot-0.1.4/.github/workflows/release-please.yml +68 -0
  6. kicad_bot-0.1.4/.github/workflows/release.yml +60 -0
  7. kicad_bot-0.1.4/.github/workflows/self-test.yml +52 -0
  8. kicad_bot-0.1.4/.gitignore +35 -0
  9. kicad_bot-0.1.4/.release-please-manifest.json +3 -0
  10. kicad_bot-0.1.4/CHANGELOG.md +44 -0
  11. kicad_bot-0.1.4/CONTRIBUTING.md +72 -0
  12. kicad_bot-0.1.4/LICENSE +202 -0
  13. kicad_bot-0.1.4/PKG-INFO +163 -0
  14. kicad_bot-0.1.4/README.md +136 -0
  15. kicad_bot-0.1.4/action.yml +202 -0
  16. kicad_bot-0.1.4/docs/architecture.md +102 -0
  17. kicad_bot-0.1.4/docs/capabilities.md +55 -0
  18. kicad_bot-0.1.4/docs/config-schema.md +90 -0
  19. kicad_bot-0.1.4/docs/kicad-bot.schema.json +106 -0
  20. kicad_bot-0.1.4/docs/publishing.md +108 -0
  21. kicad_bot-0.1.4/docs/secrets.md +60 -0
  22. kicad_bot-0.1.4/docs/troubleshooting.md +73 -0
  23. kicad_bot-0.1.4/docs/usage.md +116 -0
  24. kicad_bot-0.1.4/examples/drc-violation/README.md +41 -0
  25. kicad_bot-0.1.4/examples/drc-violation/drc-violation.kicad_pcb +124 -0
  26. kicad_bot-0.1.4/examples/drc-violation/drc-violation.kicad_pro +31 -0
  27. kicad_bot-0.1.4/examples/drc-violation/drc-violation.kicad_sch +14 -0
  28. kicad_bot-0.1.4/examples/drc-violation/kicad-bot.json +9 -0
  29. kicad_bot-0.1.4/examples/minimal/README.md +49 -0
  30. kicad_bot-0.1.4/examples/minimal/kicad-bot.json +9 -0
  31. kicad_bot-0.1.4/examples/minimal/minimal.kicad_pcb +106 -0
  32. kicad_bot-0.1.4/examples/minimal/minimal.kicad_pro +31 -0
  33. kicad_bot-0.1.4/examples/minimal/minimal.kicad_sch +14 -0
  34. kicad_bot-0.1.4/pyproject.toml +67 -0
  35. kicad_bot-0.1.4/release-please-config.json +32 -0
  36. kicad_bot-0.1.4/scripts/install-kibot-stack.sh +52 -0
  37. kicad_bot-0.1.4/src/kicad_bot/__init__.py +17 -0
  38. kicad_bot-0.1.4/src/kicad_bot/bom.py +22 -0
  39. kicad_bot-0.1.4/src/kicad_bot/cli.py +281 -0
  40. kicad_bot-0.1.4/src/kicad_bot/diff.py +22 -0
  41. kicad_bot-0.1.4/src/kicad_bot/fab.py +22 -0
  42. kicad_bot-0.1.4/src/kicad_bot/metrics.py +124 -0
  43. kicad_bot-0.1.4/src/kicad_bot/pr_comment.py +144 -0
  44. kicad_bot-0.1.4/src/kicad_bot/quickstart.py +22 -0
  45. kicad_bot-0.1.4/src/kicad_bot/report.py +148 -0
  46. kicad_bot-0.1.4/src/kicad_bot/verify.py +291 -0
  47. kicad_bot-0.1.4/tests/conftest.py +50 -0
  48. kicad_bot-0.1.4/tests/fixtures/drc_sample.json +27 -0
  49. kicad_bot-0.1.4/tests/fixtures/erc_sample.json +30 -0
  50. kicad_bot-0.1.4/tests/integration/__init__.py +0 -0
  51. kicad_bot-0.1.4/tests/integration/test_install_kibot_stack.py +89 -0
  52. kicad_bot-0.1.4/tests/integration/test_verify_e2e.py +101 -0
  53. kicad_bot-0.1.4/tests/unit/__init__.py +0 -0
  54. kicad_bot-0.1.4/tests/unit/test_cli.py +67 -0
  55. kicad_bot-0.1.4/tests/unit/test_install_kibot_stack.py +52 -0
  56. kicad_bot-0.1.4/tests/unit/test_metrics.py +48 -0
  57. kicad_bot-0.1.4/tests/unit/test_pr_comment.py +36 -0
  58. kicad_bot-0.1.4/tests/unit/test_report.py +43 -0
  59. kicad_bot-0.1.4/tests/unit/test_verify_parse.py +66 -0
@@ -0,0 +1,51 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git -C \"c:\\\\Users\\\\Gabriel\\\\Desktop\\\\kicad-bot-action\" status)",
5
+ "Read(//c/Users/Gabriel/Desktop/**)",
6
+ "Read(//c/Users/Gabriel/.claude/projects/c--Users-Gabriel-Desktop-kicad-bot-action/memory//**)",
7
+ "Bash(git init *)",
8
+ "Bash(git branch *)",
9
+ "Bash(py --version)",
10
+ "Bash(gh auth *)",
11
+ "Bash(gh repo *)",
12
+ "Bash(echo \"exit: $?\")",
13
+ "Bash(gh --version)",
14
+ "Bash(echo \"exit=$?\")",
15
+ "PowerShell(gh auth status 2>&1; \"exit=$LASTEXITCODE\")",
16
+ "PowerShell($o = gh auth status 2>&1 | Out-String; Write-Output $o; Write-Output \"EXIT=$LASTEXITCODE\")",
17
+ "Bash(rm -rf /c/Users/Gabriel/Desktop/_ref; echo cleaned)",
18
+ "Bash(curl -fsSL https://www.apache.org/licenses/LICENSE-2.0.txt -o LICENSE)",
19
+ "PowerShell(if \\(Test-Path LICENSE\\) { \\(Get-Item LICENSE\\).Length; Get-Content LICENSE -TotalCount 2 } else { \"no license file\" })",
20
+ "PowerShell(Write-Output \\(\"files: \" + \\(\\(Get-ChildItem -Force -Name\\) -join \", \"\\)\\))",
21
+ "PowerShell(\"hello-test-123\")",
22
+ "PowerShell([Console]::Out.WriteLine\\(\"DIRECT_CONSOLE_PROBE_99\"\\); Get-Location | Select-Object -ExpandProperty Path)",
23
+ "Bash(python -m venv .venv)",
24
+ "Bash(./.venv/Scripts/python.exe -m pip install -q --upgrade pip)",
25
+ "Bash(./.venv/Scripts/python.exe -m pip install -q -e \".[dev]\")",
26
+ "Bash(./.venv/Scripts/python.exe -m pytest)",
27
+ "Bash(python -c \"print\\('SIMPLE_STDOUT_TEST_OK'\\)\")",
28
+ "Read(//c/c/Users/Gabriel/Desktop/_ref/cortex-memory-budget/**)",
29
+ "Read(//c/c/Users/Gabriel/Desktop/_ref/cortex-memory-budget/src/cortex_memory_budget/**)",
30
+ "Bash(./.venv/Scripts/python.exe -m kicad_bot.verify --help)",
31
+ "Bash(echo \"HELP_RC=$?\")",
32
+ "Bash(./.venv/Scripts/python.exe -m ruff check .)",
33
+ "Bash(./.venv/Scripts/python.exe -m ruff format --check .)",
34
+ "Bash(./.venv/Scripts/python.exe -m mypy)",
35
+ "Bash(./.venv/Scripts/python.exe -m pytest -q)",
36
+ "Bash(rm -f tests/test_verify_parse.py tests/test_cli.py tests/test_metrics.py tests/test_report.py tests/test_pr_comment.py)",
37
+ "Bash(rm -rf tests/__pycache__)",
38
+ "Read(//c/c/Users/Gabriel/Desktop/kicad-bot-action/**)",
39
+ "Bash(./.venv/Scripts/python.exe -m pytest -v)",
40
+ "Bash(./.venv/Scripts/python.exe -m pytest tests/unit -q)",
41
+ "Bash(gh pr *)",
42
+ "WebFetch(domain:patch-diff.githubusercontent.com)",
43
+ "WebFetch(domain:raw.githubusercontent.com)",
44
+ "WebSearch",
45
+ "Bash(python -c \"import yaml,sys; [yaml.safe_load\\(open\\(f\\)\\) for f in ['.github/workflows/release.yml','.github/workflows/release-please.yml']]; print\\('YAML OK'\\)\")"
46
+ ],
47
+ "additionalDirectories": [
48
+ "C:\\Users\\Gabriel\\Desktop\\_ref"
49
+ ]
50
+ }
51
+ }
@@ -0,0 +1,18 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 5
8
+ groups:
9
+ dev-tools:
10
+ patterns:
11
+ - "ruff"
12
+ - "mypy"
13
+ - "pytest*"
14
+ - package-ecosystem: "github-actions"
15
+ directory: "/"
16
+ schedule:
17
+ interval: "weekly"
18
+ open-pull-requests-limit: 5
@@ -0,0 +1,74 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ lint:
17
+ name: Lint & type-check
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
21
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
22
+ with:
23
+ python-version: "3.12"
24
+ cache: "pip"
25
+ cache-dependency-path: pyproject.toml
26
+ - name: Install
27
+ run: python -m pip install -e ".[dev]"
28
+ - name: Ruff lint
29
+ run: python -m ruff check .
30
+ - name: Ruff format check
31
+ run: python -m ruff format --check .
32
+ - name: Mypy (strict)
33
+ run: python -m mypy
34
+
35
+ unit:
36
+ name: Unit tests (py${{ matrix.python-version }})
37
+ runs-on: ubuntu-latest
38
+ strategy:
39
+ fail-fast: false
40
+ matrix:
41
+ python-version: ["3.11", "3.12", "3.13"]
42
+ steps:
43
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
44
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
45
+ with:
46
+ python-version: ${{ matrix.python-version }}
47
+ cache: "pip"
48
+ cache-dependency-path: pyproject.toml
49
+ - name: Install
50
+ run: python -m pip install -e ".[dev]"
51
+ - name: Unit tests
52
+ run: python -m pytest tests/unit --cov=kicad_bot --cov-report=term-missing
53
+
54
+ integration:
55
+ name: Integration tests (real kicad-cli)
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
59
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
60
+ with:
61
+ python-version: "3.12"
62
+ cache: "pip"
63
+ cache-dependency-path: pyproject.toml
64
+ - name: Install kicad-cli
65
+ run: |
66
+ set -euo pipefail
67
+ sudo add-apt-repository --yes ppa:kicad/kicad-9.0-releases
68
+ sudo apt-get update
69
+ sudo apt-get install --yes --no-install-recommends kicad-cli || sudo apt-get install --yes --no-install-recommends kicad
70
+ kicad-cli version
71
+ - name: Install package
72
+ run: python -m pip install -e ".[dev]"
73
+ - name: Integration tests
74
+ run: python -m pytest tests/integration -v
@@ -0,0 +1,32 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: "27 4 * * 1"
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ analyze:
16
+ name: Analyze (Python)
17
+ runs-on: ubuntu-latest
18
+ permissions:
19
+ security-events: write
20
+ packages: read
21
+ steps:
22
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
23
+ - name: Initialize CodeQL
24
+ uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
25
+ with:
26
+ languages: python
27
+ - name: Autobuild
28
+ uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
29
+ - name: Analyze
30
+ uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
31
+ with:
32
+ category: "/language:python"
@@ -0,0 +1,68 @@
1
+ name: release-please
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ release-please:
17
+ name: Release Please
18
+ runs-on: ubuntu-latest
19
+ permissions:
20
+ contents: write
21
+ pull-requests: write
22
+ outputs:
23
+ pr: ${{ steps.release.outputs.pr }}
24
+ release_created: ${{ steps.release.outputs.release_created }}
25
+ tag_name: ${{ steps.release.outputs.tag_name }}
26
+ steps:
27
+ - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
28
+ id: release
29
+ with:
30
+ # A PAT (or GitHub App token) is required so that the release PR and
31
+ # its branch trigger other workflows. Events created with the default
32
+ # GITHUB_TOKEN do not start new workflow runs, which is why CI does not
33
+ # run on the release-please branch. Falls back to GITHUB_TOKEN when the
34
+ # secret is absent so the workflow still opens the PR.
35
+ token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
36
+ config-file: release-please-config.json
37
+ manifest-file: .release-please-manifest.json
38
+
39
+ release:
40
+ name: Release
41
+ needs: release-please
42
+ if: ${{ needs.release-please.outputs.release_created }}
43
+ permissions:
44
+ contents: write
45
+ uses: ./.github/workflows/release.yml
46
+ with:
47
+ tag_name: ${{ needs.release-please.outputs.tag_name }}
48
+
49
+ # PyPI trusted publishing must run from this non-reusable (top-level) workflow
50
+ # so the OIDC claims match the configured trusted publisher. It consumes the
51
+ # `dist` artifact built by the reusable release.yml (shared within the run).
52
+ publish:
53
+ name: Publish to PyPI
54
+ needs: release
55
+ runs-on: ubuntu-latest
56
+ environment:
57
+ name: pypi
58
+ url: https://pypi.org/p/kicad-bot
59
+ permissions:
60
+ id-token: write # OIDC trusted publishing
61
+ contents: read
62
+ steps:
63
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
64
+ with:
65
+ name: dist
66
+ path: dist/
67
+ - name: Publish via OIDC
68
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.13.0
@@ -0,0 +1,60 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ tag_name:
7
+ description: Tag to publish artifacts for (for example, v0.1.1)
8
+ required: true
9
+ type: string
10
+ workflow_call:
11
+ inputs:
12
+ tag_name:
13
+ description: Tag to publish artifacts for (for example, v0.1.1)
14
+ required: true
15
+ type: string
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ build:
22
+ name: Build sdist + wheel
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
26
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
27
+ with:
28
+ python-version: "3.12"
29
+ - name: Install build
30
+ run: python -m pip install build
31
+ - name: Build
32
+ run: python -m build
33
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
34
+ with:
35
+ name: dist
36
+ path: dist/
37
+ if-no-files-found: error
38
+
39
+ # NOTE: PyPI trusted publishing (OIDC) cannot run from inside a reusable
40
+ # workflow — the OIDC job_workflow_ref points at this callee, which PyPI
41
+ # cannot match against the configured trusted publisher. The publish job
42
+ # therefore lives in the top-level release-please.yml caller, which downloads
43
+ # the `dist` artifact built above. See pypi/warehouse#11096.
44
+
45
+ github-release:
46
+ name: Upload GitHub Release Assets
47
+ needs: build
48
+ runs-on: ubuntu-latest
49
+ permissions:
50
+ contents: write
51
+ steps:
52
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
53
+ with:
54
+ name: dist
55
+ path: dist/
56
+ - name: Upload release assets
57
+ uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
58
+ with:
59
+ tag_name: ${{ inputs.tag_name }}
60
+ files: dist/*
@@ -0,0 +1,52 @@
1
+ name: self-test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+ pull-requests: write
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ minimal-verify:
19
+ name: Verify (examples/minimal)
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
23
+
24
+ - name: Run kicad-bot (verify only)
25
+ id: kb
26
+ uses: ./
27
+ with:
28
+ run-verify: "true"
29
+ project-dir: examples/minimal
30
+ fail-on-drc: "true"
31
+ fail-on-erc: "true"
32
+ artifact-name: self-test-minimal
33
+
34
+ - name: Assert outputs exist
35
+ shell: bash
36
+ run: |
37
+ set -euo pipefail
38
+ test -f kicad-bot-output/report.md
39
+ test -f kicad-bot-output/kicad_bot_metrics.json
40
+ test -f kicad-bot-output/erc.json
41
+ test -f kicad-bot-output/drc.json
42
+ echo "report-path: ${{ steps.kb.outputs.report-path }}"
43
+ echo "erc-violations: ${{ steps.kb.outputs.erc-violations }}"
44
+ echo "drc-violations: ${{ steps.kb.outputs.drc-violations }}"
45
+ echo "passed: ${{ steps.kb.outputs.passed }}"
46
+
47
+ - name: Assert clean project passed
48
+ shell: bash
49
+ run: |
50
+ set -euo pipefail
51
+ test "${{ steps.kb.outputs.passed }}" = "true"
52
+ grep -q "kicad-bot:report" kicad-bot-output/pr_comment.md
@@ -0,0 +1,35 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ .pytest_cache/
13
+ .coverage
14
+ htmlcov/
15
+ coverage.xml
16
+
17
+ # kicad-bot runtime output
18
+ kicad-bot-output/
19
+ *_metrics.json
20
+ report.md
21
+ pr_comment.md
22
+
23
+ # KiCad / KiBot transients
24
+ *-backups/
25
+ fp-info-cache
26
+ *.kicad_sch-bak
27
+ *.kicad_pcb-bak
28
+ _autosave-*
29
+
30
+ # OS / editor
31
+ .DS_Store
32
+ Thumbs.db
33
+ desktop.ini
34
+ .idea/
35
+ .vscode/
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.4"
3
+ }
@@ -0,0 +1,44 @@
1
+ # Changelog
2
+
3
+ ## [0.1.4](https://github.com/embedded-pro/kicad-bot/compare/v0.1.3...v0.1.4) (2026-06-21)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **deps:** bump actions/checkout from 6.0.2 to 6.0.3 ([#12](https://github.com/embedded-pro/kicad-bot/issues/12)) ([2c15b12](https://github.com/embedded-pro/kicad-bot/commit/2c15b12298fca889751e5ad6d936be591d315e91))
9
+ * **deps:** bump github/codeql-action from 4.36.0 to 4.36.2 ([#13](https://github.com/embedded-pro/kicad-bot/issues/13)) ([3a8399f](https://github.com/embedded-pro/kicad-bot/commit/3a8399f452bef1707f97fa2fa1ba3e79da4e166c))
10
+
11
+ ## [0.1.3](https://github.com/embedded-pro/kicad-bot/compare/v0.1.2...v0.1.3) (2026-06-04)
12
+
13
+
14
+ ### Miscellaneous Chores
15
+
16
+ * fix wxPython source-build failure in KiBot stack install ([#10](https://github.com/embedded-pro/kicad-bot/issues/10)) ([84599e1](https://github.com/embedded-pro/kicad-bot/commit/84599e18e3bff02670e23bea886716f90d101132))
17
+
18
+ ## [0.1.2](https://github.com/embedded-pro/kicad-bot/compare/v0.1.1...v0.1.2) (2026-06-04)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * include all conventional commit types in release-please changelog sections ([#8](https://github.com/embedded-pro/kicad-bot/issues/8)) ([b0144e7](https://github.com/embedded-pro/kicad-bot/commit/b0144e77db67e4d3690fae5f972f30de3698c366))
24
+
25
+
26
+ ### Miscellaneous Chores
27
+
28
+ * chain publishing from release-please by making release.yml reusable ([#7](https://github.com/embedded-pro/kicad-bot/issues/7)) ([b68a80d](https://github.com/embedded-pro/kicad-bot/commit/b68a80dc043154b99ee3545c3f02c1f3d8b0e7f9))
29
+
30
+ ## [0.1.1](https://github.com/embedded-pro/kicad-bot/compare/v0.1.0...v0.1.1) (2026-06-04)
31
+
32
+
33
+ ### Bug Fixes
34
+
35
+ * unit test CI failure and add PyPI publishing docs ([#4](https://github.com/embedded-pro/kicad-bot/issues/4)) ([4501c71](https://github.com/embedded-pro/kicad-bot/commit/4501c714799238baaab52cf33bebbb13622187fd))
36
+
37
+ ## Changelog
38
+
39
+ All notable changes to this project are documented here. This file is maintained
40
+ automatically by [release-please](https://github.com/googleapis/release-please)
41
+ from [Conventional Commits](https://www.conventionalcommits.org/).
42
+
43
+ <!-- release-please-start -->
44
+ <!-- release-please-end -->
@@ -0,0 +1,72 @@
1
+ # Contributing to kicad-bot
2
+
3
+ Thanks for your interest in improving kicad-bot! This project is part of the
4
+ [embedded-pro](https://github.com/embedded-pro) family of CI actions and follows
5
+ the same conventions as its sibling repos.
6
+
7
+ ## Development setup
8
+
9
+ ```bash
10
+ python -m venv .venv
11
+ . .venv/bin/activate # Windows: .venv\Scripts\activate
12
+ pip install -e ".[dev]"
13
+ ```
14
+
15
+ Running the KiCad-backed capabilities locally also requires a KiCad 8+ install
16
+ (for `kicad-cli`) and, for BOM/diff/fab, the KiBot stack. See
17
+ [docs/troubleshooting.md](docs/troubleshooting.md) for the headless setup.
18
+
19
+ ## Checks
20
+
21
+ Every change must pass the same gates CI runs:
22
+
23
+ ```bash
24
+ ruff check . # lint
25
+ ruff format --check . # formatting
26
+ mypy # type-check
27
+ pytest tests/unit # hermetic unit tests (no KiCad needed)
28
+ pytest tests/integration # end-to-end tests (require kicad-cli; auto-skip if absent)
29
+ ```
30
+
31
+ ### Test layout
32
+
33
+ | Layer | Location | What it covers | Needs |
34
+ | ----- | -------- | -------------- | ----- |
35
+ | Unit | `tests/unit/` | Parsers, gates, metrics, report/PR-comment rendering — pure Python | nothing |
36
+ | Integration | `tests/integration/` | Full `kicad-bot-verify` pipeline against the `examples/` projects | real `kicad-cli` |
37
+ | Self-test | `.github/workflows/self-test.yml` | The composite action end-to-end on `examples/minimal` | the action |
38
+
39
+ Integration tests are skipped automatically when `kicad-cli` is not on PATH, so
40
+ the unit suite stays hermetic on machines without KiCad. In CI the `integration`
41
+ job installs KiCad and runs them for real — it is a good required status check
42
+ alongside `lint` and `unit`.
43
+
44
+ ## Commit messages
45
+
46
+ This repo releases via **release-please**, which derives version bumps and the
47
+ changelog from [Conventional Commits](https://www.conventionalcommits.org/).
48
+ Use prefixes such as:
49
+
50
+ - `feat:` — a new capability or input (minor bump)
51
+ - `fix:` — a bug fix (patch bump)
52
+ - `docs:`, `test:`, `chore:`, `refactor:`, `ci:` — no release on their own
53
+ - `feat!:` / `fix!:` or a `BREAKING CHANGE:` footer — major bump
54
+
55
+ ## Architecture
56
+
57
+ See [docs/architecture.md](docs/architecture.md) for the module layout and data
58
+ flow. In short: each capability is a self-contained module under
59
+ `src/kicad_bot/` exposing a `main()` console-script entry point, sharing argparse
60
+ plumbing from `cli.py` and output helpers from `report.py`, `pr_comment.py`, and
61
+ `metrics.py`.
62
+
63
+ ## Adding a capability
64
+
65
+ 1. Add `src/kicad_bot/<capability>.py` with a `main()` entry point.
66
+ 2. Register the console script in `pyproject.toml` (`kicad-bot-<capability>`).
67
+ 3. Add the `run-<capability>` toggle and any gates to `action.yml`.
68
+ 4. Add a runnable project under `examples/` and wire it into `self-test.yml`.
69
+ 5. Document it in `docs/capabilities.md` and `docs/usage.md`.
70
+
71
+ By contributing you agree your contributions are licensed under the project's
72
+ [Apache-2.0](LICENSE) license.