Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: Bug report
about: Report a wrong symbol/footprint/component, broken provenance, or validation failure
labels: bug
---

**Component ID**

`openpcb.core....`

**What is wrong**

(e.g., footprint pad numbering does not match symbol pins, attribution missing, 3D model size off)

**Expected**

What it should be (link to upstream KiCad source if applicable).

**Output of `bun validate --release --strict`**

```
paste here
```

**Additional context**
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/component_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: Component request
about: Request a new symbol / footprint / component to be added
labels: enhancement, new-component
---

**Component**

- Manufacturer Part Number (MPN):
- Category: [passive / IC / connector / opto / transistor / diode / ...]
- Datasheet URL:
- Footprint package (IPC-7351B name if known):

**Source**

- Available in KiCad libraries? Yes / No
- KiCad symbol library + name:
- KiCad footprint library + name:

**Why this part**

Use case, expected popularity, board this would unblock.
15 changes: 15 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Summary

<!-- What's added/changed. -->

## Checklist

- [ ] `bun validate --release --strict` passes
- [ ] `bun test` passes
- [ ] New assets follow the `openpcb.core.<kind>.<category>.<slug>` ID convention
- [ ] Provenance fields populated (source, license, attribution, upstreamUrl, upstreamCommit, sourceHash, convertedAt, conversionTool)
- [ ] Symbol pins ↔ footprint pads cross-reference checked
- [ ] 3D model `.glb` committed alongside `.model.json` metadata (or N/A)
- [ ] No new `dist/` artifacts committed (CI handles packing)

## Notes
39 changes: 36 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,39 @@ jobs:
- name: Validate source
run: bun run validate

- name: Restore signing key
if: ${{ env.OPCLIB_SIGNING_KEY != '' }}
env:
OPCLIB_SIGNING_KEY: ${{ secrets.OPCLIB_SIGNING_KEY }}
run: |
install -m 700 -d "$RUNNER_TEMP/keys"
KEY_PATH="$RUNNER_TEMP/keys/opclib-signing.pem"
printf '%s' "$OPCLIB_SIGNING_KEY" > "$KEY_PATH"
chmod 600 "$KEY_PATH"
echo "OPCLIB_SIGN_KEY_PATH=$KEY_PATH" >> "$GITHUB_ENV"

- name: Pack release
env:
OPCLIB_SIGNING_KEY: ${{ secrets.OPCLIB_SIGNING_KEY }}
OPCLIB_KEY_ID: ${{ vars.OPCLIB_KEY_ID }}
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "Packing version ${VERSION}"
bun tools/pack.ts --version="${VERSION}"
SIGN_ARGS=""
if [ -n "${OPCLIB_SIGN_KEY_PATH:-}" ] && [ -n "${OPCLIB_KEY_ID:-}" ]; then
SIGN_ARGS="--sign-key=${OPCLIB_SIGN_KEY_PATH} --key-id=${OPCLIB_KEY_ID}"
echo "Signing enabled (keyId=${OPCLIB_KEY_ID})"
else
echo "Signing disabled (no key/keyId configured)"
fi
bun tools/pack.ts --version="${VERSION}" $SIGN_ARGS

- name: Generate SHA256SUMS
run: |
VERSION="${GITHUB_REF_NAME#v}"
cd dist
sha256sum "openpcb-core-library-${VERSION}.opclib" > SHA256SUMS
cat SHA256SUMS

- name: Verify package
run: |
Expand Down Expand Up @@ -80,12 +108,17 @@ jobs:
run: |
VERSION="${GITHUB_REF_NAME#v}"
ARTIFACT="dist/openpcb-core-library-${VERSION}.opclib"
SUMS="dist/SHA256SUMS"
ASSETS=("$ARTIFACT" "$SUMS")
if [ -f keys/openpcb-core.pub ]; then
ASSETS+=("keys/openpcb-core.pub")
fi
if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
gh release upload "${GITHUB_REF_NAME}" "$ARTIFACT" --clobber
gh release upload "${GITHUB_REF_NAME}" "${ASSETS[@]}" --clobber
else
gh release create "${GITHUB_REF_NAME}" \
--verify-tag \
--title "${GITHUB_REF_NAME}" \
--notes "OpenPCB Core Library ${VERSION}" \
"$ARTIFACT"
"${ASSETS[@]}"
fi
4 changes: 2 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ jobs:
- name: Run tests
run: bun test

- name: Validate library source
run: bun tools/validate.ts
- name: Validate library source (strict / release)
run: bun tools/validate.ts --release --strict

- name: Pack release candidate
# Tags `ci-<run_id>` so artifact filenames don't collide with real releases.
Expand Down
5 changes: 5 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Code of Conduct

The OpenPCB Core Library community follows the [Contributor Covenant 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).

Report violations to **conduct@openpcb.app**. See the full text at the link above.
79 changes: 79 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Contributing to OpenPCB Core Library

CoreLibrary is the canonical JSON source of the default component library shipped with OpenPCB. Components are KiCad-derived with strict provenance and signed `.opclib` releases.

## Quick start

```bash
git clone https://github.com/OpenPCB-app/CoreLibrary.git
cd CoreLibrary
bun install
bun validate # validate the source tree
bun test # run boundary + import + pack tests
bun pack --version 0.0.0-dev
```

Requirements: Bun ≥1.3.

## ID convention

Every symbol, footprint, component, and 3D model has a dotted ID:

```
openpcb.core.<kind>.<category>.<slug>
```

Examples:

- `openpcb.core.symbol.passive.resistor_iec`
- `openpcb.core.footprint.passive.R_0603_1608Metric`
- `openpcb.core.component.passive.resistor.r0603`
- `openpcb.core.3d.passive.r0603`

Slugs are lowercase, words separated by `_`. Use IPC-7351B names for footprints (`R_0603_1608Metric`, not `0603`).

## Adding a component from KiCad

```bash
bun tools/import-kicad.ts \
--symbol-lib path/to/Device.kicad_sym \
--symbol-name R \
--footprint-lib path/to/Resistor_SMD.pretty/R_0603_1608Metric.kicad_mod \
--category passive \
--slug r0603
```

The importer produces symbol, footprint, and component JSON files with full provenance metadata (`source`, `upstreamUrl`, `upstreamCommit`, `convertedAt`, etc.). Always commit a passing `bun validate --release --strict` before opening a PR.

## Required provenance fields (strict mode)

KiCad-derived assets must declare:

- `source`, `license`, `attribution[]`
- `sourceFormat`, `sourceFileName`, `sourceLibrary`, `sourceItemName`
- `sourceHash` (SHA-256 of upstream)
- `upstreamUrl`, `upstreamCommit`
- `convertedAt`, `conversionTool`

See existing files under `symbols/`, `footprints/` for reference.

## 3D models

Pre-generated `.glb` files are committed alongside `.model.json` metadata; do not skip the GLB. If a STEP is unavailable, leave the entry out — do not ship a hollow placeholder.

## Tests

`bun test` covers:

- Schema validation (Ajv against `schemas/*.json`)
- Cross-references: every component's symbol pins must match its footprint pads
- Uniqueness of IDs and UUIDs
- shared-package boundary (no in-repo duplicates of `@openpcb/*` packages)

## Release

Maintainers only — see `README.md` "Releasing" section. Tag pattern is `v<major>.<minor>.<patch>` (aligned with OpenPCB app: `v0.1.0-beta.N` during beta).

## License

CoreLibrary contents are licensed under **CC-BY-SA-4.0 with the OpenPCB Library Exception** (mirrors KiCad library licensing). See [LICENSE.md](LICENSE.md), [ATTRIBUTION.md](ATTRIBUTION.md), and [NOTICE.md](NOTICE.md).
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ bun tools/import-kicad.ts # import symbols/footprints from a KiCad library

`dist/*.opclib` is generated by `bun pack` and is not committed to the repository.

## Releasing

1. Bump content/version as needed, run `bun run validate --release`.
2. Tag the release: `git tag v1.2.3 && git push origin v1.2.3`.
3. CI (`.github/workflows/release.yml`) typecheck → test → validate → pack → sign (if `OPCLIB_SIGNING_KEY` secret present) → SHA256SUMS → publish GitHub Release with `.opclib`, `SHA256SUMS`, and `keys/openpcb-core.pub`.

Signing prerequisites (one-time):

- Generate an Ed25519 key pair (see `keys/README.md`).
- Commit the `.pub` file to `keys/openpcb-core.pub`. Copy it into OpenPCB's `resources/keys/`.
- Add the PEM-encoded private key as GitHub secret `OPCLIB_SIGNING_KEY`.
- Set repo variable `OPCLIB_KEY_ID` (e.g. `openpcb-core-2026`).

Without the secret, packs ship unsigned (OpenPCB will warn but still import in dev mode).

## KiCad provenance

This library contains data converted or adapted from the KiCad official
Expand Down
7 changes: 7 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Security Policy

Report security issues — including malformed `.opclib` exploits, signature bypass, or supply-chain concerns in the import pipeline — to **security@openpcb.app**. Do not open a public GitHub issue.

You can also use [GitHub Security Advisories](https://github.com/OpenPCB-app/CoreLibrary/security/advisories/new) for private disclosure.

Acknowledgement within 72 hours. Coordinated disclosure typically within 90 days.
30 changes: 30 additions & 0 deletions keys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Signing Keys

Ed25519 signing for `.opclib` releases.

## Layout

- `openpcb-core.pub` — public verification key, committed; also copied into OpenPCB's `resources/keys/`.
- Private key never committed. Stored as GitHub Actions secret `OPCLIB_SIGNING_KEY` (PEM, pkcs8). The active key id is set via repo variable `OPCLIB_KEY_ID` (e.g. `openpcb-core-2026`).

## Generate a new key pair

```bash
node -e '
const { generateKeyPairSync } = require("node:crypto");
const { writeFileSync } = require("node:fs");
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
writeFileSync("openpcb-core.priv.pem", privateKey.export({ type: "pkcs8", format: "pem" }));
writeFileSync("openpcb-core.pub", publicKey.export({ type: "spki", format: "pem" }));
'
```

Commit `openpcb-core.pub`. Upload the `.priv.pem` contents to the `OPCLIB_SIGNING_KEY` GitHub Actions secret. Set `OPCLIB_KEY_ID` repo variable to a stable identifier embedded in every signature (e.g. `openpcb-core-2026`).

## Rotation

1. Generate new pair with a new `keyId`.
2. Commit the new `.pub` and copy to `OpenPCB/resources/keys/` (both keys live there simultaneously so verifiers accept old + new during the cutover).
3. Update `OPCLIB_KEY_ID` repo variable and `OPCLIB_SIGNING_KEY` secret.
4. Cut a release; verify signature in OpenPCB.
5. After a deprecation window, remove the old `.pub`.
3 changes: 3 additions & 0 deletions keys/openpcb-core.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEASe5TFAA3VD+EyGUEKfQMQUp1glInlrx3Pdcja9MOZ3Y=
-----END PUBLIC KEY-----
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openpcb-core-library",
"version": "1.0.0",
"version": "0.1.0-beta.0",
"description": "OpenPCB Core Library — readable JSON source for the default component library.",
"license": "SEE LICENSE.md",
"private": true,
Expand All @@ -23,7 +23,7 @@
"dependencies": {
"@openpcb/kicad-import": "github:OpenPCB-app/shared#kicad-import-v0.1.0",
"@openpcb/kicad-parsers": "github:OpenPCB-app/shared#kicad-parsers-v0.1.2",
"@openpcb/opclib-pack": "github:OpenPCB-app/shared#opclib-pack-v0.1.0",
"@openpcb/opclib-pack": "github:OpenPCB-app/shared#opclib-pack-v0.2.0",
"@openpcb/rendering-core": "github:OpenPCB-app/shared#rendering-core-v0.1.2",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
Expand Down
2 changes: 1 addition & 1 deletion tests/shared-package-boundary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe("shared package boundary", () => {
"github:OpenPCB-app/shared#rendering-core-v0.1.2",
);
expect(pkg.dependencies?.["@openpcb/opclib-pack"]).toBe(
"github:OpenPCB-app/shared#opclib-pack-v0.1.0",
"github:OpenPCB-app/shared#opclib-pack-v0.2.0",
);
});
});
Loading
Loading