Template
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).
This commit is contained in:
commit
421b4202cc
24 files changed
+573
No files matched your search
@@ -0,0 +1,9 @@
|
||||
# Files Gitea fills in when a repository is created from this template: the
|
||||
# new repository's name and description go into their text and their path
|
||||
# (the board folder under hardware/ is renamed to the repository's name).
|
||||
# Gitea 1.27: plain globs only. Everything else (workflows, TEMPLATE.md) is
|
||||
# copied as it is.
|
||||
proplan.toml
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
hardware/*/README.md
|
||||
@@ -0,0 +1,54 @@
|
||||
name: Fabrication document
|
||||
|
||||
# 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, so main stays free of generated files. Adapted from
|
||||
# LVSolarBuck and PowerModule.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'docs/input.md'
|
||||
- 'hardware/**'
|
||||
- '.gitea/workflows/docgen.yml'
|
||||
|
||||
jobs:
|
||||
docgen:
|
||||
runs-on: kicad10_auto
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Inputs
|
||||
id: inputs
|
||||
run: |
|
||||
pcb=$(find hardware -mindepth 2 -maxdepth 2 -name '*.kicad_pcb' | sort | head -1)
|
||||
if [ -f docs/input.md ] && [ -n "$pcb" ]; then
|
||||
echo "pcb=$pcb" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "No docs/input.md or no board yet: nothing to build."
|
||||
fi
|
||||
|
||||
- name: Build
|
||||
if: steps.inputs.outputs.pcb != ''
|
||||
run: |
|
||||
mkdir -p output-docs
|
||||
typecad-docgen docs/input.md "${{ steps.inputs.outputs.pcb }}" -o output-docs/index.html
|
||||
|
||||
- name: Push to the docu branch
|
||||
if: steps.inputs.outputs.pcb != ''
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
git config --global user.email "${{ gitea.actor }}@noreply.localhost"
|
||||
git config --global user.name "${{ gitea.actor }}"
|
||||
REPO_URL=$(git config --get remote.origin.url)
|
||||
AUTHED_URL=${REPO_URL/https:\/\//https:\/\/${GITEA_TOKEN}@}
|
||||
git clone --depth 1 --branch docu "$AUTHED_URL" docu || git clone --depth 1 "$AUTHED_URL" docu
|
||||
cd docu
|
||||
git checkout -B docu
|
||||
git rm -rq . || true
|
||||
cp -r ../output-docs/* .
|
||||
git add -A
|
||||
if git diff --cached --quiet; then echo "No changes"; exit 0; fi
|
||||
git commit -m "chore: fabrication document"
|
||||
git push --force "$AUTHED_URL" docu
|
||||
@@ -0,0 +1,48 @@
|
||||
name: KiBot
|
||||
|
||||
# Checks every board (hardware/*/*.kicad_pro): ERC, DRC, schematic PDF,
|
||||
# gerbers, drill, pick and place, BOM; the outputs are kept as an artifact.
|
||||
# Adapted from LVSolarBuck (runner label kicad10_auto). Without a board yet
|
||||
# the job ends right away.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'hardware/**'
|
||||
- 'kibot.yaml'
|
||||
- '.gitea/workflows/kibot.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'hardware/**'
|
||||
- 'kibot.yaml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
boards:
|
||||
runs-on: kicad10_auto
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Find boards
|
||||
id: boards
|
||||
run: |
|
||||
found=$(find hardware -mindepth 2 -maxdepth 2 -name '*.kicad_pro' | sort | tr '\n' ' ')
|
||||
echo "projects=$found" >> "$GITHUB_OUTPUT"
|
||||
if [ -z "$found" ]; then echo "No KiCad project under hardware/ yet."; fi
|
||||
|
||||
- name: KiBot
|
||||
if: steps.boards.outputs.projects != ''
|
||||
run: |
|
||||
for pro in ${{ steps.boards.outputs.projects }}; do
|
||||
dir=$(dirname "$pro"); board=$(basename "$dir")
|
||||
echo "== $board"
|
||||
(cd "$dir" && kibot -c "$GITHUB_WORKSPACE/kibot.yaml" -d "$GITHUB_WORKSPACE/Generated/$board" -v) \
|
||||
|| echo "::warning::KiBot reported problems for $board"
|
||||
done
|
||||
|
||||
- name: Keep the outputs
|
||||
if: steps.boards.outputs.projects != ''
|
||||
uses: https://github.com/christopherHX/gitea-upload-artifact@v4
|
||||
with:
|
||||
name: kibot-outputs
|
||||
path: Generated
|
||||
@@ -0,0 +1,57 @@
|
||||
name: Release outputs
|
||||
|
||||
# On a tag v* (a prototype stage): the KiBot outputs of every board, zipped per
|
||||
# board, attached to the tag's release (created when missing). The job token
|
||||
# must be allowed to write releases. Adapted from LVSolarBuck; runs for the
|
||||
# first time at the first tag.
|
||||
on:
|
||||
push:
|
||||
tags: ['v*']
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: kicad10_auto
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: KiBot outputs per board
|
||||
run: |
|
||||
mkdir -p dist
|
||||
for pro in $(find hardware -mindepth 2 -maxdepth 2 -name '*.kicad_pro' | sort); do
|
||||
dir=$(dirname "$pro"); board=$(basename "$dir")
|
||||
(cd "$dir" && kibot -c "$GITHUB_WORKSPACE/kibot.yaml" -d "$GITHUB_WORKSPACE/out/$board") \
|
||||
|| echo "::warning::KiBot reported problems for $board"
|
||||
python3 -c 'import shutil, sys; shutil.make_archive(sys.argv[1], "zip", sys.argv[2])' \
|
||||
"dist/$board-${GITHUB_REF_NAME}" "out/$board"
|
||||
done
|
||||
ls -la dist
|
||||
|
||||
- name: Attach to the release
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
python3 - <<'EOF'
|
||||
import json, os, pathlib, urllib.error, urllib.request, uuid
|
||||
api = f"{os.environ['GITHUB_SERVER_URL']}/api/v1/repos/{os.environ['GITHUB_REPOSITORY']}"
|
||||
tag = os.environ["GITHUB_REF_NAME"]
|
||||
auth = {"Authorization": f"token {os.environ['TOKEN']}"}
|
||||
|
||||
def call(method, url, body=None, ctype="application/json"):
|
||||
req = urllib.request.Request(url, data=body, method=method, headers={**auth, "Content-Type": ctype})
|
||||
with urllib.request.urlopen(req) as r:
|
||||
return json.load(r)
|
||||
|
||||
try:
|
||||
rel = call("GET", f"{api}/releases/tags/{tag}")
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code != 404:
|
||||
raise
|
||||
rel = call("POST", f"{api}/releases", json.dumps({"tag_name": tag, "name": tag}).encode())
|
||||
for f in sorted(pathlib.Path("dist").glob("*.zip")):
|
||||
b = uuid.uuid4().hex
|
||||
head = (f"--{b}\r\nContent-Disposition: form-data; name=\"attachment\"; filename=\"{f.name}\"\r\n"
|
||||
"Content-Type: application/zip\r\n\r\n").encode()
|
||||
body = head + f.read_bytes() + f"\r\n--{b}--\r\n".encode()
|
||||
call("POST", f"{api}/releases/{rel['id']}/assets?name={f.name}", body, f"multipart/form-data; boundary={b}")
|
||||
print("attached", f.name)
|
||||
EOF
|
||||
Reference in new issue
Block a user