diff --git a/.markdownlint.json b/.markdownlint.json index 80b0b9c..844ff6f 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,6 +1,7 @@ { "default": true, "MD003": { "style": "atx" }, + "MD013": false, "blanks-around-headings": false, "blanks-around-lists": false } diff --git a/Brewfile b/Brewfile index 1972abb..f0acbe6 100644 --- a/Brewfile +++ b/Brewfile @@ -1,5 +1,5 @@ #============================================================================== -# Brewfile - Harmon Boilerplates +# Brewfile - Harmon DevKit #============================================================================== # Core #------------------------------------------------------------------------------ diff --git a/CLAUDE.md b/CLAUDE.md index 2ab86b0..f3b5082 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -A collection of reusable boilerplates and templates for Docker Compose, Ansible, Terraform, shell scripts, serverless functions, and more. This is not a monorepo — it's a flat collection of independent templates organized by category under `boilerplates/`. +Harmon DevKit — a personal developer kit of reusable templates and boilerplates (Docker Compose, Ansible, shell scripts, serverless functions, and more), standalone scripts, and AI assets. This is not a monorepo — it's a flat collection of independent templates organized by category under `templates/`, with scripts under `scripts/` and AI assets under `ai/`. ## Commands @@ -53,6 +53,11 @@ Pre-commit is configured with `no-commit-to-branch` — direct commits to `main` - **PRs**: pre-commit hooks, ESLint, Prettier, security scans (Snyk + Whispers) - **Merge to main**: Auto-bumps patch version via git tag and creates a GitHub release with generated notes -## Boilerplate Categories +## Repository Layout -Templates live under `boilerplates/` organized as: `ansible.md`, `appleScripts/`, `automationTemplates/` (n8n, Kestra, Trigger.dev), `docker/`, `scriptTemplates/` (Go, Python, Shell), `serverlessFunctionTemplates/` (AWS Lambda, GCP, Netlify), `webTemplates/`. +- `templates/` — copy-paste boilerplates organized by category: `ansible.md`, `docker/` (genericStack, n8n-compose), `scriptTemplates/` (Go, Python, Shell), `serverlessFunctionTemplates/` (AWS Lambda, GCP, Netlify), `webTemplates/`. Each category directory has a README; the root README has a full template index. +- `scripts/` — standalone scripts and utilities: `appleScripts/` (AppleScript/Automator apps with accompanying notes), `cmd/` (command snippets). +- `ai/` — AI assets (skills, prompts, agents, rules, evals, etc.); mostly placeholder directories at this stage. +- `snippets/` — small reusable code snippets (placeholder). +- `docs/` — project docs, e.g. the new-project checklist. +- `test/` — tool configuration used by scans (e.g. `whisperConfig.yml` for Whispers); not actual tests. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f85bb44..3c56ab2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to Harmon Boilerplates +# Contributing to Harmon DevKit First of all, thank you for taking the time to contribute! 🎉 The following is a set of guidelines to ensure your contribution is as smooth as possible. We welcome all types of contributions, including issues, documentation updates, bug fixes, feature requests, and more! diff --git a/README.md b/README.md index d3a4007..d37deb7 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,42 @@ -# Harmon Boilerplates +# Harmon DevKit -My code boilerplates for various stacks such as Docker Compose, Ansible, Terraform, shell scripts, etc. Also a general code repo for code or scripts that don't really fit anywhere else. +My personal developer kit: reusable code templates and boilerplates for various stacks (Docker Compose, Ansible, shell scripts, serverless functions, etc.), standalone scripts, and AI assets (skills, prompts, agents). Also a general home for code that doesn't really fit anywhere else. Author: Evan Harmon -[![Validate](https://github.com/evanharmon1/harmon-boilerplates/actions/workflows/validate.yml/badge.svg)](https://github.com/evanharmon1/harmon-boilerplates/actions/workflows/validate.yml) -[![Build](https://github.com/evanharmon1/harmon-boilerplates/actions/workflows/build.yml/badge.svg)](https://github.com/evanharmon1/harmon-boilerplates/actions/workflows/build.yml) -[![Security](https://github.com/evanharmon1/harmon-boilerplates/actions/workflows/security.yml/badge.svg)](https://github.com/evanharmon1/harmon-boilerplates/actions/workflows/security.yml) +[![Validate](https://github.com/evanharmon1/harmon-devkit/actions/workflows/validate.yml/badge.svg)](https://github.com/evanharmon1/harmon-devkit/actions/workflows/validate.yml) +[![Build](https://github.com/evanharmon1/harmon-devkit/actions/workflows/build.yaml/badge.svg)](https://github.com/evanharmon1/harmon-devkit/actions/workflows/build.yaml) +[![Security](https://github.com/evanharmon1/harmon-devkit/actions/workflows/security.yml/badge.svg)](https://github.com/evanharmon1/harmon-devkit/actions/workflows/security.yml) [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/copier-org/copier) -[![Maintained](https://img.shields.io/badge/maintained%3F-yes-brightgreen.svg?style=flat-square)](https://github.com/evanharmon1/harmon-boilerplates) -[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/evanharmon1/harmon-boilerplates) -[![Known Vulnerabilities](https://snyk.io/test/github/evanharmon1/harmon-boilerplates/badge.svg?style=flat-square)](https://snyk.io/test/github/evanharmon1/harmon-boilerplates) +[![Maintained](https://img.shields.io/badge/maintained%3F-yes-brightgreen.svg?style=flat-square)](https://github.com/evanharmon1/harmon-devkit) +[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/evanharmon1/harmon-devkit) + +## Repository Structure + +| Directory | Contents | +| --- | --- | +| [`templates/`](./templates/) | Copy-paste boilerplates organized by category — see the [template index](#template-index) below | +| [`scripts/`](./scripts/) | Standalone scripts and utilities (AppleScript/Automator apps, command snippets) | +| [`ai/`](./ai/) | AI assets — skills, prompts, agents, rules, evals, etc. (work in progress) | +| [`snippets/`](./snippets/) | Small reusable code snippets (work in progress) | +| [`docs/`](./docs/) | Project docs, e.g. the new-project [checklist](./docs/CHECKLIST.md) | + +## Template Index + +| Template | Category | Description | +| --- | --- | --- | +| [`ansible.md`](./templates/ansible.md) | Ansible | Standard Ansible project directory structure and setup notes | +| [`docker/genericStack`](./templates/docker/genericStack/) | Docker | Generic multi-service Compose sandbox (Ubuntu, nginx, optional DB stack with Postgres/memcached/Adminer) plus `dc*` helper scripts | +| [`docker/n8n-compose`](./templates/docker/n8n-compose/) | Docker | n8n workflow automation behind Traefik with automatic HTTPS (Let's Encrypt) | +| [`scriptTemplates/shellScriptTemplate.sh`](./templates/scriptTemplates/shellScriptTemplate.sh) | Scripts | Shell script starter with safe defaults, traps, and arg parsing | +| [`scriptTemplates/pythonScriptTemplate.py`](./templates/scriptTemplates/pythonScriptTemplate.py) | Scripts | Python CLI starter with argparse, logging, and validation | +| [`scriptTemplates/goScriptTemplate.go`](./templates/scriptTemplates/goScriptTemplate.go) | Scripts | Go CLI starter with flag parsing, logging, and validation | +| [`serverlessFunctionTemplates/awsLambda.py`](./templates/serverlessFunctionTemplates/awsLambda.py) | Serverless | AWS Lambda handler (Python) with input validation and error responses | +| [`serverlessFunctionTemplates/gcpFunction.py`](./templates/serverlessFunctionTemplates/gcpFunction.py) | Serverless | Google Cloud Function (Python/Flask) with input validation and error responses | +| [`serverlessFunctionTemplates/netlifyFunction.js`](./templates/serverlessFunctionTemplates/netlifyFunction.js) | Serverless | Netlify Function (Node.js) that fetches and returns JSON from an API | +| [`webTemplates/netlifyForm.html`](./templates/webTemplates/netlifyForm.html) | Web | Netlify-ready HTML contact form with honeypot spam protection | + +See [`templates/README.md`](./templates/README.md) for conventions and per-category details. ## Inspired by Other Boilerplate Repos @@ -19,13 +45,13 @@ Author: Evan Harmon - - - -- -- -- +- +- +- ## Setup & Installation -If there isn't an existing boilerplate in this repo, start with looking at repo for an existing boilerplate there. There is a cli tool to use boilerplates from that repo and you can integrate other repos. +If there isn't an existing template in this repo, start with looking at the repo for an existing boilerplate there. There is a cli tool to use boilerplates from that repo and you can integrate other repos. ### Requirements @@ -45,7 +71,7 @@ Install required dependencies ## Usage -TODO: project usage +Templates are meant to be copied into your project and adapted — there is no scaffolding CLI (yet). Browse the [template index](#template-index), copy the file or directory you need, and edit the placeholders (names, ports, environment variables) for your project. Each template directory has a README with specifics. ### Task Runner @@ -65,10 +91,4 @@ TODO: project usage - .pre-commit-config.yaml - .shellcheckrc -- .ansible-lint-ignore - -### Building, Deploying, & CI/CD - -## Todo File - -[todo.md](./todo.md) +- .ansible-lint diff --git a/Taskfile.yml b/Taskfile.yml index 1bd7495..f923400 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,7 +1,7 @@ -# Taskfile for Harmon Boilerplates +# Taskfile for Harmon DevKit version: '3' tasks: - boostrap: + bootstrap: cmds: - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew install python #TODO: Might need to use a non-homebrew method diff --git a/docs/CHECKLIST.md b/docs/CHECKLIST.md index 2f95790..5991e16 100644 --- a/docs/CHECKLIST.md +++ b/docs/CHECKLIST.md @@ -1,4 +1,4 @@ -# Checklist - Harmon Boilerplates +# Checklist - Harmon DevKit - [ ] Raycast - Setup Raycast VS Code Workspace alias (use its cli?) - [ ] Framework/Application @@ -11,7 +11,7 @@ - Java - [Maven Archetype](https://maven.apache.org/guides/introduction/introduction-to-archetypes.html) - Shell - - `dev/templates/shellScriptTemplate` + - `templates/scriptTemplates/shellScriptTemplate.sh` - [ ] .gitignore - Configure gitignore with [gitignore.io - Create Useful .gitignore Files For Your Project](https://www.toptal.com/developers/gitignore) - [ ] Adapt doc files diff --git a/package.json b/package.json index bf15179..25550f7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "harmon-boilerplates", + "name": "harmon-devkit", "version": "0.0.1", - "description": "My boilerplates for various stacks such as Docker Compose, Ansible, Terraform, shell scripts, etc.", + "description": "My personal developer kit: code templates and boilerplates for various stacks (Docker Compose, Ansible, shell scripts, serverless functions, etc.), standalone scripts, and AI assets.", "scripts": { "start": "TODO: define npm command", "dev": "TODO: define npm command", @@ -26,5 +26,5 @@ "dotenv": "^16.0.0" }, "author": "Evan Harmon", - "license": "See LICENSE" + "license": "MIT" } diff --git a/requirements.txt b/requirements.txt index 35342b4..61f9d99 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -# Python requirements for Harmon Boilerplates +# Python requirements for Harmon DevKit whispers diff --git a/templates/README.md b/templates/README.md new file mode 100644 index 0000000..1a8c0ed --- /dev/null +++ b/templates/README.md @@ -0,0 +1,21 @@ +# Templates + +Copy-paste boilerplates organized by category. Templates are meant to be copied into your project and adapted — copy the file or directory you need and edit the placeholders (names, ports, environment variables) for your project. + +The full template index lives in the [root README](../README.md#template-index). + +## Categories + +| Directory | Contents | +| --- | --- | +| [`ansible.md`](./ansible.md) | Standard Ansible project directory structure and setup notes (work in progress) | +| [`docker/`](./docker/) | Docker Compose stacks | +| [`scriptTemplates/`](./scriptTemplates/) | CLI script starters for Shell, Python, and Go | +| [`serverlessFunctionTemplates/`](./serverlessFunctionTemplates/) | Serverless function handlers for AWS Lambda, Google Cloud Functions, and Netlify Functions | +| [`webTemplates/`](./webTemplates/) | Web/HTML snippets | + +## Conventions + +- Each category directory has a README describing its templates and any required setup (e.g. `.env` files). +- Templates carry a header comment with a description and usage notes where the format allows it. +- Linting/formatting for templates follows the repo-wide config (`.editorconfig`, `.pre-commit-config.yaml`) — see the root README. diff --git a/templates/docker/README.md b/templates/docker/README.md new file mode 100644 index 0000000..e5a0b5d --- /dev/null +++ b/templates/docker/README.md @@ -0,0 +1,8 @@ +# Docker Templates + +Docker Compose stacks meant to be copied and adapted. + +| Stack | Description | +| --- | --- | +| [`genericStack/`](./genericStack/) | Generic multi-service sandbox (Ubuntu, nginx, optional Postgres/memcached/Adminer stack) with `dc*` helper scripts | +| [`n8n-compose/`](./n8n-compose/) | n8n workflow automation behind Traefik with automatic HTTPS via Let's Encrypt | diff --git a/templates/docker/genericStack/README.md b/templates/docker/genericStack/README.md new file mode 100644 index 0000000..e5b6707 --- /dev/null +++ b/templates/docker/genericStack/README.md @@ -0,0 +1,34 @@ +# Generic Docker Compose Stack + +A generic multi-service Compose sandbox for quickly spinning up throwaway environments. All services share the local `./dockerVol` bind mount as their working directory, so files are easy to pass between host and containers. + +## Files + +| File | Purpose | +| --- | --- | +| `docker-compose.yml` | Main stack — Ubuntu and nginx services, plus commented-out service definitions (Fedora, Node, Python, ActiveMQ) to enable as needed | +| `docker-compose-db.yml` | Local dev database stack — Postgres 14 (data persisted to `./db_data`), memcached, and [Adminer](https://www.adminer.org/) DB admin UI on port 8080 | +| `dcu.cmd` | `docker-compose up --build -d` — build and start the stack | +| `dcs.cmd` | `docker-compose stop` — stop containers without removing them | +| `dcd.cmd` | `docker-compose down` — stop and remove containers | +| `dcr.cmd` | `docker-compose down -v` — stop and remove containers **and volumes** (destructive reset) | +| `dockerVol/` | Shared bind-mount directory for the main stack services | + +## Usage + +```bash +# Main sandbox stack +./dcu.cmd # up +docker compose exec ubuntu bash # shell into a service +./dcd.cmd # down + +# DB stack +docker compose -f docker-compose-db.yml up -d +psql -h 127.0.0.1 -p 5432 -U postgres # connect to Postgres +# Adminer UI: http://localhost:8080 +``` + +## Notes + +- The DB stack hardcodes dev credentials (`postgres`/`password123`) — it is for **local development only**; change credentials before any shared or remote use. +- The helper scripts use the legacy `docker-compose` v1 CLI; with modern Docker installs, substitute `docker compose`. diff --git a/templates/docker/n8n-compose/README.md b/templates/docker/n8n-compose/README.md new file mode 100644 index 0000000..89e27d5 --- /dev/null +++ b/templates/docker/n8n-compose/README.md @@ -0,0 +1,42 @@ +# n8n with Traefik (Docker Compose) + +Self-hosted [n8n](https://n8n.io/) workflow automation behind [Traefik](https://traefik.io/) as a reverse proxy, with automatic HTTPS certificates from Let's Encrypt (TLS challenge), HSTS/security headers, and HTTP→HTTPS redirect. Based on the [official n8n server setup docs](https://docs.n8n.io/hosting/installation/server-setups/docker-compose/). + +## Files + +| File | Purpose | +| --- | --- | +| `compose.yaml` | Traefik + n8n services, named volumes for certs (`traefik_data`) and n8n data (`n8n_data`) | +| `.env` | Required environment variables (see below) — **gitignored**, so a fresh clone won't have one; create it before `docker compose up` | +| `local-files/` | Bind-mounted into the n8n container at `/files` for reading/writing local files from workflows | + +## Setup + +1. Create a `.env` file next to `compose.yaml`: + + ```dotenv + # Where n8n will be reachable: https://${SUBDOMAIN}.${DOMAIN_NAME} + DOMAIN_NAME=example.com + SUBDOMAIN=n8n + + # Timezone used by Cron and other scheduling nodes + GENERIC_TIMEZONE=America/Chicago + + # Email for Let's Encrypt certificate registration + SSL_EMAIL=you@example.com + ``` + +2. Point DNS for `${SUBDOMAIN}.${DOMAIN_NAME}` at the host (Let's Encrypt must be able to reach it on ports 80/443). + +3. Start the stack: + + ```bash + docker compose up -d + ``` + +n8n is then available at `https://${SUBDOMAIN}.${DOMAIN_NAME}` (and bound locally at `127.0.0.1:5678`). + +## Notes + +- Traefik runs with `--api.insecure=true` (dashboard/API without auth). Fine for a homelab behind a firewall; disable or secure it for anything internet-facing. +- n8n data persists in the `n8n_data` named volume; removing volumes (`docker compose down -v`) wipes workflows and credentials. diff --git a/templates/scriptTemplates/README.md b/templates/scriptTemplates/README.md new file mode 100644 index 0000000..a434172 --- /dev/null +++ b/templates/scriptTemplates/README.md @@ -0,0 +1,13 @@ +# Script Templates + +CLI script starters. Each template implements the same basic skeleton — argument parsing, validation, logging/verbosity, and a placeholder processing function — so scripts start consistent across languages. + +| Template | Language | Highlights | +| --- | --- | --- | +| [`shellScriptTemplate.sh`](./shellScriptTemplate.sh) | Shell | Fail-fast options (`set -Eeuo pipefail`), cleanup trap, script-dir resolution, usage/help text. Based on [Minimal safe Bash script template](https://betterdev.blog/minimal-safe-bash-script-template/) | +| [`pythonScriptTemplate.py`](./pythonScriptTemplate.py) | Python | `argparse` with `--input/--output/--verbose/--version`, `logging` setup, input validation | +| [`goScriptTemplate.go`](./goScriptTemplate.go) | Go | `flag` parsing with the same flags, logger setup, input validation. Run with `go run`, or `go build -o cliapp` | + +## Usage + +Copy the template, rename it, replace the placeholder processing logic, and update the header comment and usage text. Repo-wide lint rules apply: ShellCheck for shell (`.shellcheckrc`) and Black formatting for Python (via pre-commit). diff --git a/templates/serverlessFunctionTemplates/README.md b/templates/serverlessFunctionTemplates/README.md new file mode 100644 index 0000000..4433ec4 --- /dev/null +++ b/templates/serverlessFunctionTemplates/README.md @@ -0,0 +1,13 @@ +# Serverless Function Templates + +Minimal serverless function handlers with input validation and structured error responses (400 for bad input, 500 for unexpected errors). The AWS and GCP examples implement the same toy calculation endpoint (add `num1` + `num2` from a JSON body) so the platform differences are easy to compare. + +| Template | Platform | Notes | +| --- | --- | --- | +| [`awsLambda.py`](./awsLambda.py) | AWS Lambda (Python) | Standard `lambda_handler(event, context)`; parses JSON from `event["body"]` (API Gateway-style) | +| [`gcpFunction.py`](./gcpFunction.py) | Google Cloud Functions (Python) | HTTP function using Flask's `request`/`jsonify` | +| [`netlifyFunction.js`](./netlifyFunction.js) | Netlify Functions (Node.js) | `exports.handler` that fetches JSON from an upstream API and returns it; uses `node-fetch` (on Node 18+ you can use the built-in `fetch` instead) | + +## Usage + +Copy the file into your project's functions directory, replace the example logic, and deploy with the platform's tooling (AWS SAM/console, `gcloud functions deploy`, or Netlify's `netlify/functions/` convention). diff --git a/templates/webTemplates/README.md b/templates/webTemplates/README.md new file mode 100644 index 0000000..37dffcd --- /dev/null +++ b/templates/webTemplates/README.md @@ -0,0 +1,11 @@ +# Web Templates + +HTML/web snippets. + +| Template | Description | +| --- | --- | +| [`netlifyForm.html`](./netlifyForm.html) | Contact form wired for [Netlify Forms](https://docs.netlify.com/forms/setup/) (`data-netlify="true"`) with a hidden honeypot field for spam protection and basic client-side validation (required fields, email/phone patterns) | + +## Usage + +Drop the form into a page deployed on Netlify — Netlify detects the `data-netlify` attribute at build time and handles submissions. Adjust fields and the `name="contact"` form name to suit; keep the hidden `form-name` input in sync with it.