feat: add skills, version pinning, CI/CD, and generated-file headers
Validate and Test / validate-patches (push) Failing after 2m7s
Validate and Test / validate-patches (push) Failing after 2m7s
- Create skills: rego-pd-validator, usb-gadget-configfs, led-matrix-msgpack-rpc - Update pd-audio-synthesis skill with Uno Q specifics - Add Pd version check (min 0.54.0) to start-synth.sh - Add DO NOT EDIT headers to generated pd patches - Add Gitea Actions CI workflow for patch validation - Add ConditionPathExists guards to legacy systemd services - Add 'just ci' recipe for CI
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
name: Validate and Test
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-patches:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install conftest
|
||||||
|
- name: Validate all .pd patches
|
||||||
|
run: |
|
||||||
|
python3 pd-validator/validate.py pd/*.pd
|
||||||
@@ -341,6 +341,10 @@ kconfig:
|
|||||||
validate:
|
validate:
|
||||||
python3 pd-validator/validate.py pd/*.pd
|
python3 pd-validator/validate.py pd/*.pd
|
||||||
|
|
||||||
|
# CI: run full validation suite (same as validate but used by Gitea Actions)
|
||||||
|
ci:
|
||||||
|
python3 pd-validator/validate.py pd/*.pd
|
||||||
|
|
||||||
# Install udev rules for hotplug role changes
|
# Install udev rules for hotplug role changes
|
||||||
install-udev-rules:
|
install-udev-rules:
|
||||||
@ssh {{SSH_OPTS}} "{{BOARD_USER}}@{{BOARD_HOST}}" "\
|
@ssh {{SSH_OPTS}} "{{BOARD_USER}}@{{BOARD_HOST}}" "\
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#N canvas 0 0 950 490 10;
|
#N canvas 0 0 950 490 10;
|
||||||
|
# DO NOT EDIT — generated by scripts/gen_mpk_sim.py;
|
||||||
#X obj 10 10 loadbang ;
|
#X obj 10 10 loadbang ;
|
||||||
#X msg 10 30 ;;
|
#X msg 10 30 ;;
|
||||||
#X msg 10 50 connect 192.168.9.167 8081;;
|
#X msg 10 50 connect 192.168.9.167 8081;;
|
||||||
|
|||||||
+59
-27
@@ -1,33 +1,65 @@
|
|||||||
#N canvas 0 0 500 600 10;
|
#N canvas 0 0 900 550 10;
|
||||||
#X obj 40 20 midi-in;
|
# DO NOT EDIT — generated by scripts/gen_synth_pd.py;
|
||||||
#X obj 40 80 stripnote;
|
#X obj 20 20 notein;
|
||||||
#X obj 40 140 mtof;
|
#X obj 80 50 pack 0 0;
|
||||||
#X obj 40 180 osc~;
|
#X obj 80 80 unpack 0 0;
|
||||||
#X obj 160 180 osc~;
|
#X obj 20 110 s midi-pitch;
|
||||||
#X obj 40 220 *~ 1;
|
#X obj 80 110 s midi-vel;
|
||||||
#X obj 160 220 *~ 1;
|
#X obj 400 20 netreceive -u 8081;
|
||||||
#X obj 100 260 +~;
|
#X obj 400 60 route midi;
|
||||||
#X obj 100 300 lop~ 10000;
|
#X obj 400 100 route 144 128;
|
||||||
#X obj 40 340 env~ 2 10 1 40;
|
#X obj 400 140 unpack 0 0;
|
||||||
#X obj 100 380 *~;
|
#X obj 480 140 unpack 0 0;
|
||||||
#X obj 100 440 audio-out;
|
#X obj 400 180 s midi-pitch;
|
||||||
#X text 200 180 osc~ 1 (main);
|
#X obj 480 180 s midi-vel;
|
||||||
#X text 320 180 osc~ 2 (+7ct);
|
#X obj 20 160 r midi-vel;
|
||||||
#X text 155 220 mix;
|
#X obj 20 190 r midi-pitch;
|
||||||
#X text 155 300 lop~;
|
#X obj 20 220 stripnote;
|
||||||
#X text 155 340 envelope;
|
#X obj 20 260 mtof;
|
||||||
#X text 155 380 amp;
|
#X obj 20 290 env~ 50 200 0.7 400;
|
||||||
|
#X obj 140 260 osc~;
|
||||||
|
#X obj 140 290 *~ 0.3;
|
||||||
|
#X obj 220 260 osc~;
|
||||||
|
#X obj 220 290 *~ 0.3;
|
||||||
|
#X obj 180 330 +~;
|
||||||
|
#X obj 180 360 *~ 0.5;
|
||||||
|
#X obj 180 400 lop~;
|
||||||
|
#X obj 180 460 *~;
|
||||||
|
#X obj 320 460 *~;
|
||||||
|
#X obj 250 530 dac~;
|
||||||
|
#X obj 350 330 hsl 128 15 100 18000 10000 0 0 0 empty Cutoff -2 -8 0 10 -262144 -1 -1 7200 1;
|
||||||
|
#X obj 350 430 hsl 128 15 0 100 40 0 0 0 empty Volume -2 -8 0 10 -262144 -1 -1 7200 1;
|
||||||
|
#X obj 350 460 / 100;
|
||||||
#X connect 0 0 1 0;
|
#X connect 0 0 1 0;
|
||||||
#X connect 0 1 1 1;
|
#X connect 0 1 1 1;
|
||||||
#X connect 1 0 2 0;
|
#X connect 1 0 2 0;
|
||||||
#X connect 1 1 9 1;
|
|
||||||
#X connect 2 0 3 0;
|
#X connect 2 0 3 0;
|
||||||
#X connect 2 0 4 0;
|
#X connect 2 1 4 0;
|
||||||
#X connect 3 0 5 0;
|
#X connect 5 0 6 0;
|
||||||
#X connect 4 0 6 0;
|
#X connect 6 0 7 0;
|
||||||
#X connect 5 0 7 0;
|
|
||||||
#X connect 6 0 7 1;
|
|
||||||
#X connect 7 0 8 0;
|
#X connect 7 0 8 0;
|
||||||
|
#X connect 7 1 9 0;
|
||||||
#X connect 8 0 10 0;
|
#X connect 8 0 10 0;
|
||||||
#X connect 9 0 10 1;
|
#X connect 8 1 11 0;
|
||||||
#X connect 10 0 11 0;
|
#X connect 9 0 10 0;
|
||||||
|
#X connect 9 1 11 0;
|
||||||
|
#X connect 12 0 14 1;
|
||||||
|
#X connect 13 0 14 0;
|
||||||
|
#X connect 14 0 15 0;
|
||||||
|
#X connect 15 0 17 0;
|
||||||
|
#X connect 15 0 19 0;
|
||||||
|
#X connect 17 0 18 0;
|
||||||
|
#X connect 19 0 20 0;
|
||||||
|
#X connect 18 0 21 0;
|
||||||
|
#X connect 20 0 21 1;
|
||||||
|
#X connect 21 0 22 0;
|
||||||
|
#X connect 22 0 23 0;
|
||||||
|
#X connect 23 0 24 0;
|
||||||
|
#X connect 14 0 16 0;
|
||||||
|
#X connect 16 0 24 1;
|
||||||
|
#X connect 24 0 25 0;
|
||||||
|
#X connect 27 0 23 1;
|
||||||
|
#X connect 28 0 29 0;
|
||||||
|
#X connect 29 0 25 1;
|
||||||
|
#X connect 25 0 26 0;
|
||||||
|
#X connect 25 0 26 1;
|
||||||
|
|||||||
@@ -93,7 +93,10 @@ def gen():
|
|||||||
connect(c, msg, 0, ns, 0)
|
connect(c, msg, 0, ns, 0)
|
||||||
|
|
||||||
# ── Write (Pd format: #X obj for objects, #X msg/text/floatatom/symbol for others) ──
|
# ── Write (Pd format: #X obj for objects, #X msg/text/floatatom/symbol for others) ──
|
||||||
lines = ["#N canvas 0 0 950 490 10;"]
|
lines = [
|
||||||
|
"#N canvas 0 0 950 490 10;",
|
||||||
|
"# DO NOT EDIT — generated by scripts/gen_mpk_sim.py;",
|
||||||
|
]
|
||||||
obj_types = {"bng","t","del","netsend","loadbang","hsl","comment"}
|
obj_types = {"bng","t","del","netsend","loadbang","hsl","comment"}
|
||||||
for x, y, *args in o:
|
for x, y, *args in o:
|
||||||
etype = args[0]
|
etype = args[0]
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ def gen():
|
|||||||
connect(c, panscale, 0, dac, 1)
|
connect(c, panscale, 0, dac, 1)
|
||||||
|
|
||||||
# ── Write ──
|
# ── Write ──
|
||||||
lines = ["#N canvas 0 0 900 550 10;"]
|
lines = [
|
||||||
|
"#N canvas 0 0 900 550 10;",
|
||||||
|
"# DO NOT EDIT — generated by scripts/gen_synth_pd.py;",
|
||||||
|
]
|
||||||
for x, y, t, *args in o:
|
for x, y, t, *args in o:
|
||||||
joined = " ".join(str(a) for a in args)
|
joined = " ".join(str(a) for a in args)
|
||||||
lines.append(f"#X obj {x} {y} {joined};")
|
lines.append(f"#X obj {x} {y} {joined};")
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ if ! command -v pd &>/dev/null; then
|
|||||||
die "Pure Data not found. Install: apt install puredata"
|
die "Pure Data not found. Install: apt install puredata"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
MIN_PD_VERSION="0.54.0"
|
||||||
|
PD_VERSION=$(pd --version 2>&1 | grep -oP '[\d]+\.[\d]+-?[\d]*' | head -1 || echo "0.0.0")
|
||||||
|
if printf '%s\n' "$MIN_PD_VERSION" "$PD_VERSION" | sort -V | head -1 | grep -q "^$MIN_PD_VERSION$"; then
|
||||||
|
info "Pd version $PD_VERSION (>= $MIN_PD_VERSION)"
|
||||||
|
else
|
||||||
|
die "Pd version $PD_VERSION is too old. Need >= $MIN_PD_VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "$PATCH" ]; then
|
if [ ! -f "$PATCH" ]; then
|
||||||
die "Patch not found: $PATCH"
|
die "Patch not found: $PATCH"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Pure Data Synth (auto-detect: gadget or host)
|
Description=Pure Data Synth (auto-detect: gadget or host)
|
||||||
|
ConditionPathExists=/home/arduino/uno-q-audio-synth/pd/synth.pd
|
||||||
Documentation=https://github.com/arduino/uno-q-audio-synth
|
Documentation=https://github.com/arduino/uno-q-audio-synth
|
||||||
After=usb-role-detect.service
|
After=usb-role-detect.service
|
||||||
Wants=usb-role-detect.service
|
Wants=usb-role-detect.service
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Pure Data I2S DAC Synth (standalone)
|
Description=Pure Data I2S DAC Synth (standalone)
|
||||||
|
ConditionPathExists=/home/arduino/uno-q-audio-synth/pd/synth.pd
|
||||||
After=network.target sound.target
|
After=network.target sound.target
|
||||||
Wants=usb-gadget-audio.service
|
Wants=usb-gadget-audio.service
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Pure Data USB Audio Synth (Gadget Mode)
|
Description=Pure Data USB Audio Synth (Gadget Mode)
|
||||||
|
ConditionPathExists=/home/arduino/uno-q-audio-synth/pd/synth.pd
|
||||||
After=usb-gadget-audio.service midi-bridge.service
|
After=usb-gadget-audio.service midi-bridge.service
|
||||||
Wants=usb-gadget-audio.service midi-bridge.service
|
Wants=usb-gadget-audio.service midi-bridge.service
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user