GitHub webhook handler and SSH deployment automation service.
- Node.js >=26; ESM.
POST /receives signed GitHub webhooks.GET /healthreturns service status and version.- Repository configuration is YAML mounted at
KNIT_CONFIG_PATH(default./repos). - YAML files use
<owner>__<repo>.yamlnaming in Kubernetes ConfigMaps.
Modern configuration uses SSH targets:
repository: owner/reponotifyKey: owner__repogit:
url: git@github.com:owner/repo.gitref: maintargets:
- name: devhost: dev.exampleuser: rootworkingDirectory: /opt/repopre: []post: []execution:
mode: sequentialstopOnError: truenotifyKey resolves to /run/secrets/discord-webhooks/<notifyKey>. Webhook URLs belong in Kubernetes Secrets, encrypted in GitOps with SOPS/age. They must not appear in configuration files. SSH assets are mounted at /run/secrets/eliware/ssh/.
Targets execute commands over SSH with strict host verification. identity and knownHosts may be host-installed or paths relative to the configured path. Modern targets are SSH-only.
New configurations must use YAML and SSH targets. Local Compose requires KNIT_CONFIG_PATH and KNIT_DISCORD_WEBHOOK_SECRET_HOST_PATH directories; systemd requires equivalent mounted/provisioned paths.
eliware/knit is configured as the fallback target for organization-level GitHub events. Its push deployment runs git pull, npm install, and npm test on dev.purinton.us:/opt/knit, then sends the result to Discord. Successful deployments do not restart the process; release a new image and let Argo CD roll it out for Knit code changes.
| Variable | Purpose |
|---|---|
PORT | Listen port; default 3456 |
GITHUB_WEBHOOK_SECRET | GitHub signature secret |
LOG_LEVEL | Logger level |
KNIT_CONFIG_PATH | Mounted configuration directory |
KNIT_DISCORD_WEBHOOK_SECRET_PATH | Mounted Discord webhook Secret directory |
npm install
npm test
npm run lint
npm startKubernetes releases use immutable container images and Argo CD GitOps. Knit can receive its own repository webhook and SSH-deploy /opt/knit; new Knit code is delivered by releasing an image, not by runtime self-updating.