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
3 changes: 3 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BasedOnStyle: Google
ColumnLimit: 100
SortIncludes: Never
11 changes: 9 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ permissions:
contents: read

jobs:
shellcheck:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: sudo apt-get update && sudo apt-get install -y shellcheck
- run: make shellcheck
- run: sh scripts/install-lint-tools.sh
- run: make lint

micropython:
runs-on: ubuntu-latest
Expand Down
9 changes: 9 additions & 0 deletions .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config:
default: true
MD013: false # long lines are fine in prose
MD033: false # allow inline HTML
MD041: false # README may start with a badge or image
MD024:
siblings_only: true
ignores:
- "**/node_modules/**"
8 changes: 8 additions & 0 deletions .yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extends: default
rules:
line-length: disable
document-start: disable
truthy:
allowed-values: ["true", "false", "on"]
comments:
min-spaces-from-content: 1
26 changes: 23 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
FQBN ?= esp32:esp32:esp32
SKETCHES := examples/esp32-mqtt examples/esp32-http
CSOURCES := $(wildcard examples/*/*.ino examples/*/*.c examples/*/*.h)

.PHONY: commit-check lint compile shellcheck micropython arduino
.PHONY: commit-check lint compile shellcheck markdownlint links clang-format actionlint yamllint gitleaks micropython arduino

commit-check: lint compile

lint: shellcheck
lint: shellcheck markdownlint links clang-format actionlint yamllint gitleaks
@echo "lint passed."

compile: micropython arduino

shellcheck:
shellcheck examples/curl/*.sh
shellcheck examples/curl/*.sh scripts/*.sh

markdownlint:
markdownlint-cli2 "**/*.md"

links:
sh scripts/lychee.sh '**/*.md' examples

clang-format:
clang-format --dry-run --Werror $(CSOURCES)

actionlint:
actionlint

yamllint:
yamllint --strict .

gitleaks:
gitleaks dir . --no-banner --redact

micropython:
mpy-cross -o /tmp/picow-main.mpy examples/picow-mqtt/main.py
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Each example is one sketch or script with a short README.
make commit-check
```

This runs shellcheck, a MicroPython compile check, and `arduino-cli compile` for both ESP32 sketches.
This runs `make lint` and then compiles the examples. `make lint` runs shellcheck, markdownlint, a lychee link check, clang-format on the sketches, actionlint, yamllint and gitleaks. The compile step runs a MicroPython compile check and `arduino-cli compile` for both ESP32 sketches. On Linux, `sh scripts/install-lint-tools.sh` installs the lint tools; on macOS use `brew install shellcheck markdownlint-cli2 lychee clang-format actionlint yamllint gitleaks`.

## License

Expand Down
2 changes: 1 addition & 1 deletion examples/curl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ INF_API=https://api.example.com DEVICE_ID=<uuid> DEVICE_TOKEN=<token> ./infinime

## Expected output

```
```text
Posting reported state: temp=21.5
Reading state back
{
Expand Down
2 changes: 1 addition & 1 deletion examples/esp32-http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ arduino-cli compile --fqbn esp32:esp32:esp32 examples/esp32-http

## Expected output (serial, 115200)

```
```text
WiFi..... connected
POST /devices/states -> 200, sent {"device":"<id>","reported":{"data":{"temp":24.1,"uptime":5}}}
GET /devices/states -> 200, desired: "desired":{"timestamp":"...","data":{"led":true}
Expand Down
6 changes: 4 additions & 2 deletions examples/esp32-http/esp32-http.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// ---- Config: change these ----
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASS = "your-password";
const char* API_URL = "https://api.example.com"; // infinimesh REST gateway
const char* API_URL = "https://api.example.com"; // infinimesh REST gateway
const char* DEVICE_ID = "00000000-0000-0000-0000-000000000000"; // device uuid
const char* DEVICE_TOKEN = "paste the device token here";

Expand Down Expand Up @@ -52,7 +52,9 @@ void readDesired() {
String res = http.getString();
int i = res.indexOf("\"desired\"");
Serial.printf("GET /devices/states -> 200, desired: %s\n",
i >= 0 ? res.substring(i, res.indexOf('}', res.indexOf("\"data\"", i)) + 1).c_str() : "none");
i >= 0
? res.substring(i, res.indexOf('}', res.indexOf("\"data\"", i)) + 1).c_str()
: "none");
} else {
Serial.printf("GET /devices/states -> %d\n", code);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/esp32-mqtt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ arduino-cli compile --fqbn esp32:esp32:esp32 examples/esp32-mqtt

## Expected output (serial, 115200)

```
```text
WiFi..... connected, IP 192.168.1.42
MQTT connected
Published {"temp":23.4,"uptime":12} (id 12345)
Expand Down
8 changes: 4 additions & 4 deletions examples/esp32-mqtt/esp32-mqtt.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// ---- Config: change these ----
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASS = "your-password";
const char* MQTT_URI = "mqtts://mqtt.example.com:8883"; // your infinimesh MQTT host
const char* MQTT_URI = "mqtts://mqtt.example.com:8883"; // your infinimesh MQTT host
const char* DEVICE_ID = "00000000-0000-0000-0000-000000000000"; // device uuid
const int PUBLISH_QOS = 1; // 0 or 1
const int PUBLISH_QOS = 1; // 0 or 1

// CA that signed the server certificate. For Let's Encrypt use ISRG Root X1.
// For a local test, paste core's hack/server.crt.
Expand Down Expand Up @@ -60,8 +60,8 @@ static void onEvent(void* args, esp_event_base_t base, int32_t id, void* data) {
Serial.printf("PUBACK for message %d\n", event->msg_id);
break;
case MQTT_EVENT_DATA:
Serial.printf("Desired state on %.*s: %.*s\n",
event->topic_len, event->topic, event->data_len, event->data);
Serial.printf("Desired state on %.*s: %.*s\n", event->topic_len, event->topic,
event->data_len, event->data);
break;
case MQTT_EVENT_ERROR:
Serial.println("MQTT error (check certificates, host and device id)");
Expand Down
24 changes: 12 additions & 12 deletions examples/picow-mqtt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ None.
2. Install the MQTT library: `mpremote mip install umqtt.simple`
3. Make the device key and certificate (EC P-256 is fastest) and convert them to DER:

```bash
openssl ecparam -name prime256v1 -genkey -noout -out device.key
openssl req -new -x509 -sha256 -key device.key -out device.crt -days 365 -subj "/CN=my-pico"
openssl x509 -in device.crt -outform DER -out device.der
openssl ec -in device.key -outform DER -out key.der
openssl x509 -in isrgrootx1.pem -outform DER -out ca.der # or your server CA
```
```bash
openssl ecparam -name prime256v1 -genkey -noout -out device.key
openssl req -new -x509 -sha256 -key device.key -out device.crt -days 365 -subj "/CN=my-pico"
openssl x509 -in device.crt -outform DER -out device.der
openssl ec -in device.key -outform DER -out key.der
openssl x509 -in isrgrootx1.pem -outform DER -out ca.der # or your server CA
```

4. Register `device.crt` when you create the device (see [../esp32-mqtt/README.md](../esp32-mqtt/README.md)).
5. Edit the config at the top of `main.py`, then copy the files:

```bash
mpremote cp device.der key.der ca.der main.py :
mpremote reset
```
```bash
mpremote cp device.der key.der ca.der main.py :
mpremote reset
```

## Expected output

```
```text
WiFi connected 192.168.1.43
MQTT connected
Published {"temp": 21.5, "uptime": 14}
Expand Down
14 changes: 14 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Link check. Local hosts and example domains are skipped.
exclude = [
"^https?://localhost",
"^https?://127\\.0\\.0\\.1",
"nip\\.io",
"infinimesh\\.local",
"example\\.(com|org)",
"^mqtts?://",
]
exclude_path = [".git"]
max_retries = 2
timeout = 20
accept = ["200..=299", "403", "429"]
include_fragments = false
14 changes: 14 additions & 0 deletions scripts/install-lint-tools.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
# Installs the lint tools on a Linux x86_64 CI runner.
set -eu
BIN="${BIN:-/usr/local/bin}"
ACTIONLINT=1.7.7
GITLEAKS=8.28.0
LYCHEE=0.20.1

pip install --quiet yamllint==1.37.1 clang-format==23.1.3
npm install --global --silent markdownlint-cli2@0.23.3

curl -fsSL "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT}/actionlint_${ACTIONLINT}_linux_amd64.tar.gz" | sudo tar xz -C "$BIN" actionlint
curl -fsSL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS}/gitleaks_${GITLEAKS}_linux_x64.tar.gz" | sudo tar xz -C "$BIN" gitleaks
curl -fsSL "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE}/lychee-x86_64-unknown-linux-gnu.tar.gz" | sudo tar xz -C "$BIN" lychee
9 changes: 9 additions & 0 deletions scripts/lychee.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
# Link check. Falls back to local links only when there is no network.
set -eu
if curl -fsS -m 5 -o /dev/null https://github.com; then
lychee --config lychee.toml --no-progress "$@"
else
echo "no network, checking local links only"
lychee --config lychee.toml --no-progress --offline "$@"
fi
Loading