Fix review issues: front matter, headings, consistency, typos
All checks were successful
check / check (push) Successful in 9s
All checks were successful
check / check (push) Successful in 9s
- Move title and last_modified to YAML front matter (all policy docs) - Make all document sections H1, subsections H2 - Update version rule to reference front matter format - Fix "our" → "your" typo in Go styleguide - Fix Python styleguide numbering (2. → 1.) - Fix README: "flat collection" → accurate description, remove stale TODO - Remove Makefile items from code styleguides (repo stuff, not code), add note linking to Repository Policies - Change zerolog → slog in Go styleguide - Fix JS styleguide npm reference: both work, but use make targets - Drop .json from healthcheck path, add JSON content-type requirement - Add Author/License to Go HTTP Server Conventions - Convert hyperlinks to backtick URLs in checklists for consistency - Add version/front matter to both checklists
This commit is contained in:
parent
3768b8ca02
commit
e97b48eea4
@ -48,15 +48,14 @@ share, and evolve prompts across projects.
|
|||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
The repository is a flat collection of Markdown files. Each file contains one or
|
The repository is a collection of Markdown files organized in the `prompts/`
|
||||||
more related prompts or policy documents. There is no build step or runtime
|
subdirectory. Each file contains one or more related prompts or policy
|
||||||
component; the prompts are consumed by copying them into other projects or
|
documents. There is no build step or runtime component; the prompts are consumed
|
||||||
referencing them directly.
|
by copying them into other projects or referencing them directly.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Add more prompt templates for common development tasks
|
- Add more prompt templates for common development tasks
|
||||||
- Add CI to lint Markdown
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,13 @@
|
|||||||
Version: 2026-02-22
|
---
|
||||||
|
title: Code Styleguide
|
||||||
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
# Code Styleguide
|
# All
|
||||||
|
|
||||||
## All
|
1. Every repo must have a `Makefile` and a `Dockerfile`. See
|
||||||
|
[Repository Policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
|
||||||
1. Every project/repo should have a `Makefile` in the root. At a minimum,
|
for required targets and conventions.
|
||||||
`make clean`, `make run`, `make fmt`, and `make test` should work. Choose a
|
|
||||||
sane default target (`test` for libraries, `run` or `publish` for binaries).
|
|
||||||
`fmt` should invoke the appropriate formatters for the files in the repo,
|
|
||||||
such as `go fmt`, `prettier`, `black`, etc. Other standard `Makefile` targets
|
|
||||||
include `deploy`, `lint`. Consider the `Makefile` the official documentation
|
|
||||||
about how to operate the repository.
|
|
||||||
|
|
||||||
1. If it's possible to write a `Dockerfile`, include at least a simple one. It
|
|
||||||
should be possible to build and run the project with `docker build .`.
|
|
||||||
|
|
||||||
1. For F/OSS-licensed software, try to include the full source code of the
|
1. For F/OSS-licensed software, try to include the full source code of the
|
||||||
current version (and any dependencies, such as vendored dependencies) in the
|
current version (and any dependencies, such as vendored dependencies) in the
|
||||||
@ -42,18 +36,16 @@ Version: 2026-02-22
|
|||||||
be enabled in prod.
|
be enabled in prod.
|
||||||
|
|
||||||
1. For services/servers, make a healthcheck available at
|
1. For services/servers, make a healthcheck available at
|
||||||
`/.well-known/healthcheck`. This is out of spec but it is my personal
|
`/.well-known/healthcheck`. The response must have a
|
||||||
standard. This should return a 200 OK if the service is healthy, along with a
|
`Content-Type: application/json` header and return a JSON object containing
|
||||||
JSON object containing the service's name, uptime, and any other relevant
|
the service's name, uptime, and a key of `"status"` with a value of `"ok"`.
|
||||||
information, and a key of "status" with a value of "ok" if the service is
|
Return a 200 for healthy, 5xx for unhealthy.
|
||||||
healthy. Make sure that in the event of a failure, the service returns a 5xx
|
|
||||||
status code for that route.
|
|
||||||
|
|
||||||
1. If possible, for services/servers, include a /metrics endpoint that returns
|
1. If possible, for services/servers, include a /metrics endpoint that returns
|
||||||
Prometheus-formatted metrics. This is not required for all services, but is a
|
Prometheus-formatted metrics. This is not required for all services, but is a
|
||||||
nice-to-have.
|
nice-to-have.
|
||||||
|
|
||||||
## Bash / Shell
|
# Bash / Shell
|
||||||
|
|
||||||
1. Use `[[` instead of `[` for conditionals. It's a shell builtin and doesn't
|
1. Use `[[` instead of `[` for conditionals. It's a shell builtin and doesn't
|
||||||
have to execute a separate process.
|
have to execute a separate process.
|
||||||
@ -73,7 +65,7 @@ Version: 2026-02-22
|
|||||||
1. Put all code in functions, even a main function. Define all functions then
|
1. Put all code in functions, even a main function. Define all functions then
|
||||||
call main at the bottom of the file.
|
call main at the bottom of the file.
|
||||||
|
|
||||||
## Docker Containers (for services)
|
# Docker Containers (for services)
|
||||||
|
|
||||||
1. Use `runit` with `runsvinit` as the entrypoint for all containers. This
|
1. Use `runit` with `runsvinit` as the entrypoint for all containers. This
|
||||||
allows for easy service management and logging. In startup scripts
|
allows for easy service management and logging. In startup scripts
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
Version: 2026-02-22
|
---
|
||||||
|
title: Code Styleguide — Go
|
||||||
# Golang
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
1. Try to hard wrap long lines at 77 characters or less.
|
1. Try to hard wrap long lines at 77 characters or less.
|
||||||
|
|
||||||
@ -70,11 +71,8 @@ Version: 2026-02-22
|
|||||||
1. Avoid obvious footguns. For example, use range instead of for loops for
|
1. Avoid obvious footguns. For example, use range instead of for loops for
|
||||||
iterating.
|
iterating.
|
||||||
|
|
||||||
1. Try to use zerolog for logging. It's fast and has a nice API. For
|
1. Use `log/slog` for structured logging. Import `sneak.berlin/go/simplelog`
|
||||||
smaller/quick projects, the standard library's `log` package (and
|
for sensible defaults. Example:
|
||||||
specifically `log/slog`) is fine. In that case, log structured logs whenever
|
|
||||||
possible, and import `sneak.berlin/go/simplelog` to configure it
|
|
||||||
appropriately. Example:
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@ -107,9 +105,9 @@ Version: 2026-02-22
|
|||||||
able-to-be-compiled state, linted, and any tests run. The Docker build
|
able-to-be-compiled state, linted, and any tests run. The Docker build
|
||||||
should fail if linting doesn't pass.
|
should fail if linting doesn't pass.
|
||||||
|
|
||||||
1. Include a `Makefile` with targets for at least `clean` and `test`. If there
|
1. Every repo must have a `Makefile`. See
|
||||||
are multiple binaries, include a target for each binary. If there are
|
[Repository Policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
|
||||||
multiple binaries, include a target for `all` that builds all binaries.
|
for required targets and conventions.
|
||||||
|
|
||||||
1. If you are writing a single-module library, `.go` files are okay in the repo
|
1. If you are writing a single-module library, `.go` files are okay in the repo
|
||||||
root.
|
root.
|
||||||
@ -132,7 +130,7 @@ Version: 2026-02-22
|
|||||||
single-file scripts.
|
single-file scripts.
|
||||||
|
|
||||||
1. HTTP HandleFuncs should be returned from methods or functions that need to
|
1. HTTP HandleFuncs should be returned from methods or functions that need to
|
||||||
handle HTTP requests. Don't use methods or our top level functions as
|
handle HTTP requests. Don't use methods or your top level functions as
|
||||||
handlers.
|
handlers.
|
||||||
|
|
||||||
1. Provide a .gitignore file that ignores at least `*.log`, `*.out`, and
|
1. Provide a .gitignore file that ignores at least `*.log`, `*.out`, and
|
||||||
@ -431,7 +429,7 @@ Version: 2026-02-22
|
|||||||
releasable". "Releasable" in this context means that it builds and functions
|
releasable". "Releasable" in this context means that it builds and functions
|
||||||
as expected, and that all tests and linting passes.
|
as expected, and that all tests and linting passes.
|
||||||
|
|
||||||
## Other Golang Tips and Best Practices (Optional)
|
# Other Golang Tips and Best Practices (Optional)
|
||||||
|
|
||||||
1. For any internet-facing http server, set appropriate timeouts and limits to
|
1. For any internet-facing http server, set appropriate timeouts and limits to
|
||||||
protect against slowloris attacks or huge uploads that can consume server
|
protect against slowloris attacks or huge uploads that can consume server
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
Version: 2026-02-22
|
---
|
||||||
|
title: Code Styleguide — JavaScript
|
||||||
# JavaScript / ECMAScript / ES6
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
1. Use `const` for everything. If you need to reassign, use `let`. Never use
|
1. Use `const` for everything. If you need to reassign, use `let`. Never use
|
||||||
`var`.
|
`var`.
|
||||||
@ -11,9 +12,12 @@ Version: 2026-02-22
|
|||||||
|
|
||||||
1. Use `prettier` for code formatting, with four spaces for indentation.
|
1. Use `prettier` for code formatting, with four spaces for indentation.
|
||||||
|
|
||||||
1. At a minimum, `npm run test` and `npm run build` should work (complete the
|
1. At a minimum, both `yarn run test`/`yarn run build` and
|
||||||
appropriate scripts in `package.json`). The `Makefile` should call these, do
|
`npm run test`/`npm run build` should work (complete the appropriate scripts
|
||||||
not duplicate the scripts in the `Makefile`.
|
in `package.json`). However, prefer `make test` and `make build` instead —
|
||||||
|
the Makefile is authoritative on how to interact with the repo. See
|
||||||
|
[Repository Policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
|
||||||
|
for details.
|
||||||
|
|
||||||
# Author
|
# Author
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
Version: 2026-02-22
|
---
|
||||||
|
title: Code Styleguide — Python
|
||||||
# Python
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
1. Format all code with `black`, with four space indents.
|
1. Format all code with `black`, with four space indents.
|
||||||
|
|
||||||
2. Put all code in functions. If you are writing a script, put the script in a
|
1. Put all code in functions. If you are writing a script, put the script in a
|
||||||
function called `main` and call `main()` at the end of the script using the
|
function called `main` and call `main()` at the end of the script using the
|
||||||
standard invocation:
|
standard invocation:
|
||||||
|
|
||||||
|
|||||||
@ -1,63 +1,66 @@
|
|||||||
# Existing Repo Checklist
|
---
|
||||||
|
title: Existing Repo Checklist
|
||||||
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
Use this checklist when beginning work in a repo that may not yet conform to our
|
Use this checklist when beginning work in a repo that may not yet conform to our
|
||||||
[repository policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md).
|
repository policies
|
||||||
|
(`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`).
|
||||||
|
|
||||||
Work on a feature branch. Check each item and fix any gaps before proceeding
|
Work on a feature branch. Check each item and fix any gaps before proceeding
|
||||||
with your task.
|
with your task.
|
||||||
|
|
||||||
## Formatting (do this first)
|
# Formatting (do this first)
|
||||||
|
|
||||||
- [ ] If the repo has never been formatted to our standards, run `make fmt` and
|
- [ ] If the repo has never been formatted to our standards, run `make fmt` and
|
||||||
commit the result as a standalone branch/commit/PR before any other
|
commit the result as a standalone branch/commit/PR before any other
|
||||||
changes. Formatting diffs can be large and should not be mixed with
|
changes. Formatting diffs can be large and should not be mixed with
|
||||||
functional changes.
|
functional changes.
|
||||||
|
|
||||||
## Required Files
|
# Required Files
|
||||||
|
|
||||||
- [ ] `README.md` exists with all required sections (Description, Getting
|
- [ ] `README.md` exists with all required sections (Description, Getting
|
||||||
Started, Rationale, Design, TODO, License, Author)
|
Started, Rationale, Design, TODO, License, Author)
|
||||||
- [ ] `LICENSE` file exists and matches the README
|
- [ ] `LICENSE` file exists and matches the README
|
||||||
- [ ] `REPO_POLICIES.md` exists and version date is current with the
|
- [ ] `REPO_POLICIES.md` exists and version date is current — fetch from
|
||||||
[authoritative source](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`
|
||||||
- [ ] `.gitignore` is comprehensive (OS, editor, language artifacts, secrets) —
|
- [ ] `.gitignore` is comprehensive (OS, editor, language artifacts, secrets) —
|
||||||
fetch from `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore`
|
fetch from `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore`
|
||||||
if missing
|
if missing
|
||||||
- [ ] [`.editorconfig`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfig)
|
- [ ] `.editorconfig` exists — fetch from
|
||||||
exists
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfig`
|
||||||
- [ ] `Dockerfile` and `.dockerignore` exist; Dockerfile runs `make check` as a
|
- [ ] `Dockerfile` and `.dockerignore` exist; Dockerfile runs `make check` as a
|
||||||
build step
|
build step
|
||||||
- [ ] Gitea Actions workflow in `.gitea/workflows/` runs `docker build .` on
|
- [ ] Gitea Actions workflow in `.gitea/workflows/` runs `docker build .` on
|
||||||
push — reference
|
push — reference
|
||||||
[check.yml](https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml`
|
||||||
- [ ] Language-specific config:
|
- [ ] Language-specific config:
|
||||||
- [ ] Go: `go.mod`, `go.sum`,
|
- [ ] Go: `go.mod`, `go.sum`, `.golangci.yml` (fetch from
|
||||||
[`.golangci.yml`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`)
|
||||||
- [ ] JS: `package.json`, `yarn.lock`,
|
- [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore`
|
||||||
[`.prettierrc`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc),
|
(fetch from
|
||||||
[`.prettierignore`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and
|
||||||
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`)
|
||||||
- [ ] Python: `pyproject.toml`
|
- [ ] Python: `pyproject.toml`
|
||||||
- [ ] Docs/writing:
|
- [ ] Docs/writing: `.prettierrc`, `.prettierignore` (same URLs as above)
|
||||||
[`.prettierrc`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc),
|
|
||||||
[`.prettierignore`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore)
|
|
||||||
|
|
||||||
## Makefile
|
# Makefile
|
||||||
|
|
||||||
- [ ] `Makefile` exists in root — reference the
|
- [ ] `Makefile` exists in root — reference
|
||||||
[model Makefile](https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile`
|
||||||
- [ ] Has targets: `test`, `lint`, `fmt`, `fmt-check`, `check`, `docker`,
|
- [ ] Has targets: `test`, `lint`, `fmt`, `fmt-check`, `check`, `docker`,
|
||||||
`hooks`
|
`hooks`
|
||||||
- [ ] `make check` does not modify any files in the repo
|
- [ ] `make check` does not modify any files in the repo
|
||||||
- [ ] `make test` has a 30-second timeout
|
- [ ] `make test` has a 30-second timeout
|
||||||
- [ ] `make check` passes on current branch
|
- [ ] `make check` passes on current branch
|
||||||
|
|
||||||
## Formatting
|
# Formatting
|
||||||
|
|
||||||
- [ ] Platform-standard formatter is configured (`black`, `prettier`, `go fmt`)
|
- [ ] Platform-standard formatter is configured (`black`, `prettier`, `go fmt`)
|
||||||
- [ ] Default formatter config, only exception: four-space indents (except Go)
|
- [ ] Default formatter config, only exception: four-space indents (except Go)
|
||||||
- [ ] All files pass `make fmt-check`
|
- [ ] All files pass `make fmt-check`
|
||||||
|
|
||||||
## Git Hygiene
|
# Git Hygiene
|
||||||
|
|
||||||
- [ ] Pre-commit hook is installed (`make hooks`)
|
- [ ] Pre-commit hook is installed (`make hooks`)
|
||||||
- [ ] No secrets in the repo (`.env`, keys, credentials)
|
- [ ] No secrets in the repo (`.env`, keys, credentials)
|
||||||
@ -65,14 +68,14 @@ with your task.
|
|||||||
pinned by cryptographic hash with version/date comment
|
pinned by cryptographic hash with version/date comment
|
||||||
- [ ] Using `yarn`, not `npm` (JS projects)
|
- [ ] Using `yarn`, not `npm` (JS projects)
|
||||||
|
|
||||||
## Directory Structure
|
# Directory Structure
|
||||||
|
|
||||||
- [ ] No unnecessary files in repo root
|
- [ ] No unnecessary files in repo root
|
||||||
- [ ] Files organized into canonical subdirectories (`bin/`, `cmd/`, `docs/`,
|
- [ ] Files organized into canonical subdirectories (`bin/`, `cmd/`, `docs/`,
|
||||||
`internal/`, `static/`, etc.)
|
`internal/`, `static/`, etc.)
|
||||||
- [ ] Go migrations in `internal/db/migrations/` and embedded in binary
|
- [ ] Go migrations in `internal/db/migrations/` and embedded in binary
|
||||||
|
|
||||||
## Final
|
# Final
|
||||||
|
|
||||||
- [ ] `make check` passes
|
- [ ] `make check` passes
|
||||||
- [ ] `docker build` succeeds
|
- [ ] `docker build` succeeds
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
Version: 2026-02-22
|
---
|
||||||
|
title: Go HTTP Server Conventions
|
||||||
# Go HTTP Server Conventions
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
This document defines the architectural patterns, design decisions, and
|
This document defines the architectural patterns, design decisions, and
|
||||||
conventions for building Go HTTP servers. All new projects must follow these
|
conventions for building Go HTTP servers. All new projects must follow these
|
||||||
standards.
|
standards.
|
||||||
|
|
||||||
## Table of Contents
|
# Table of Contents
|
||||||
|
|
||||||
1. [Required Libraries](#1-required-libraries)
|
1. [Required Libraries](#1-required-libraries)
|
||||||
2. [Project Structure](#2-project-structure)
|
2. [Project Structure](#2-project-structure)
|
||||||
@ -25,7 +26,7 @@ standards.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Required Libraries
|
# 1. Required Libraries
|
||||||
|
|
||||||
These libraries are **mandatory** for all new projects:
|
These libraries are **mandatory** for all new projects:
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ These libraries are **mandatory** for all new projects:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Project Structure
|
# 2. Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
project-root/
|
project-root/
|
||||||
@ -86,7 +87,7 @@ project-root/
|
|||||||
└── Dockerfile
|
└── Dockerfile
|
||||||
```
|
```
|
||||||
|
|
||||||
### Key Principles
|
## Key Principles
|
||||||
|
|
||||||
- **`cmd/{appname}/`**: Only the entry point. Minimal logic, just bootstrapping.
|
- **`cmd/{appname}/`**: Only the entry point. Minimal logic, just bootstrapping.
|
||||||
- **`internal/`**: All application packages. Not importable by external
|
- **`internal/`**: All application packages. Not importable by external
|
||||||
@ -96,9 +97,9 @@ project-root/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Dependency Injection (Uber fx)
|
# 3. Dependency Injection (Uber fx)
|
||||||
|
|
||||||
### Entry Point Pattern
|
## Entry Point Pattern
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// cmd/httpd/main.go
|
// cmd/httpd/main.go
|
||||||
@ -143,7 +144,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Params Struct Pattern
|
## Params Struct Pattern
|
||||||
|
|
||||||
Every component that receives dependencies uses a params struct with `fx.In`:
|
Every component that receives dependencies uses a params struct with `fx.In`:
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ type Handlers struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Factory Function Pattern
|
## Factory Function Pattern
|
||||||
|
|
||||||
All components expose a `New` function with this signature:
|
All components expose a `New` function with this signature:
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ func New(lc fx.Lifecycle, params SomeParams) (*Something, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Dependency Order
|
## Dependency Order
|
||||||
|
|
||||||
Providers are resolved automatically by fx, but conceptually follow this order:
|
Providers are resolved automatically by fx, but conceptually follow this order:
|
||||||
|
|
||||||
@ -203,9 +204,9 @@ Providers are resolved automatically by fx, but conceptually follow this order:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Server Architecture
|
# 4. Server Architecture
|
||||||
|
|
||||||
### Server Struct
|
## Server Struct
|
||||||
|
|
||||||
The Server struct is the central orchestrator:
|
The Server struct is the central orchestrator:
|
||||||
|
|
||||||
@ -236,7 +237,7 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Server Factory
|
## Server Factory
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
|
func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
|
||||||
@ -261,7 +262,7 @@ func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### HTTP Server Setup
|
## HTTP Server Setup
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/server/http.go
|
// internal/server/http.go
|
||||||
@ -291,7 +292,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Signal Handling and Graceful Shutdown
|
## Signal Handling and Graceful Shutdown
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (s *Server) serve() int {
|
func (s *Server) serve() int {
|
||||||
@ -335,9 +336,9 @@ func (s *Server) cleanShutdown() {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Routing (go-chi)
|
# 5. Routing (go-chi)
|
||||||
|
|
||||||
### Route Setup Pattern
|
## Route Setup Pattern
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/server/routes.go
|
// internal/server/routes.go
|
||||||
@ -380,7 +381,7 @@ func (s *Server) SetupRoutes() {
|
|||||||
s.router.Get("/login", auth(s.h.HandleLoginGET()).ServeHTTP)
|
s.router.Get("/login", auth(s.h.HandleLoginGET()).ServeHTTP)
|
||||||
|
|
||||||
// Health check (standard path)
|
// Health check (standard path)
|
||||||
s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck())
|
s.router.Get("/.well-known/healthcheck", s.h.HandleHealthCheck())
|
||||||
|
|
||||||
// Protected route groups
|
// Protected route groups
|
||||||
if viper.GetString("METRICS_USERNAME") != "" {
|
if viper.GetString("METRICS_USERNAME") != "" {
|
||||||
@ -392,7 +393,7 @@ func (s *Server) SetupRoutes() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Middleware Ordering (Critical)
|
## Middleware Ordering (Critical)
|
||||||
|
|
||||||
1. `middleware.Recoverer` - Panic recovery (must be first)
|
1. `middleware.Recoverer` - Panic recovery (must be first)
|
||||||
2. `middleware.RequestID` - Generate request IDs
|
2. `middleware.RequestID` - Generate request IDs
|
||||||
@ -402,7 +403,7 @@ func (s *Server) SetupRoutes() {
|
|||||||
6. `middleware.Timeout(60s)` - Request timeout
|
6. `middleware.Timeout(60s)` - Request timeout
|
||||||
7. `sentryhttp.Handler` - Sentry error reporting (if enabled)
|
7. `sentryhttp.Handler` - Sentry error reporting (if enabled)
|
||||||
|
|
||||||
### API Versioning
|
## API Versioning
|
||||||
|
|
||||||
Use route groups for API versioning:
|
Use route groups for API versioning:
|
||||||
|
|
||||||
@ -412,7 +413,7 @@ s.router.Route("/api/v1", func(r chi.Router) {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Static File Serving
|
## Static File Serving
|
||||||
|
|
||||||
Static files are served at `/s/` prefix:
|
Static files are served at `/s/` prefix:
|
||||||
|
|
||||||
@ -422,9 +423,9 @@ s.router.Mount("/s", http.StripPrefix("/s", http.FileServer(http.FS(static.Stati
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Handler Conventions
|
# 6. Handler Conventions
|
||||||
|
|
||||||
### Handler Base Struct
|
## Handler Base Struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/handlers/handlers.go
|
// internal/handlers/handlers.go
|
||||||
@ -457,7 +458,7 @@ func New(lc fx.Lifecycle, params HandlersParams) (*Handlers, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Closure-Based Handler Pattern
|
## Closure-Based Handler Pattern
|
||||||
|
|
||||||
All handlers return `http.HandlerFunc` using the closure pattern. This allows
|
All handlers return `http.HandlerFunc` using the closure pattern. This allows
|
||||||
initialization logic to run once when the handler is created:
|
initialization logic to run once when the handler is created:
|
||||||
@ -479,7 +480,7 @@ func (s *Handlers) HandleIndex() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### JSON Handler Pattern
|
## JSON Handler Pattern
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/handlers/now.go
|
// internal/handlers/now.go
|
||||||
@ -494,7 +495,7 @@ func (s *Handlers) HandleNow() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Response Helpers
|
## Response Helpers
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/handlers/handlers.go
|
// internal/handlers/handlers.go
|
||||||
@ -514,7 +515,7 @@ func (s *Handlers) decodeJSON(w http.ResponseWriter, r *http.Request, v interfac
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Handler Naming Convention
|
## Handler Naming Convention
|
||||||
|
|
||||||
- `HandleIndex()` - Main page
|
- `HandleIndex()` - Main page
|
||||||
- `HandleLoginGET()` / `HandleLoginPOST()` - Form handlers with HTTP method
|
- `HandleLoginGET()` / `HandleLoginPOST()` - Form handlers with HTTP method
|
||||||
@ -524,9 +525,9 @@ func (s *Handlers) decodeJSON(w http.ResponseWriter, r *http.Request, v interfac
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Middleware Conventions
|
# 7. Middleware Conventions
|
||||||
|
|
||||||
### Middleware Struct
|
## Middleware Struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/middleware/middleware.go
|
// internal/middleware/middleware.go
|
||||||
@ -550,7 +551,7 @@ func New(lc fx.Lifecycle, params MiddlewareParams) (*Middleware, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Middleware Signature
|
## Middleware Signature
|
||||||
|
|
||||||
All custom middleware methods return `func(http.Handler) http.Handler`:
|
All custom middleware methods return `func(http.Handler) http.Handler`:
|
||||||
|
|
||||||
@ -569,7 +570,7 @@ func (s *Middleware) Auth() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logging Middleware with Status Capture
|
## Logging Middleware with Status Capture
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type loggingResponseWriter struct {
|
type loggingResponseWriter struct {
|
||||||
@ -613,7 +614,7 @@ func (s *Middleware) Logging() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### CORS Middleware
|
## CORS Middleware
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (s *Middleware) CORS() func(http.Handler) http.Handler {
|
func (s *Middleware) CORS() func(http.Handler) http.Handler {
|
||||||
@ -628,7 +629,7 @@ func (s *Middleware) CORS() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Metrics Middleware
|
## Metrics Middleware
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (s *Middleware) Metrics() func(http.Handler) http.Handler {
|
func (s *Middleware) Metrics() func(http.Handler) http.Handler {
|
||||||
@ -654,9 +655,9 @@ func (s *Middleware) MetricsAuth() func(http.Handler) http.Handler {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Configuration (Viper)
|
# 8. Configuration (Viper)
|
||||||
|
|
||||||
### Config Struct
|
## Config Struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/config/config.go
|
// internal/config/config.go
|
||||||
@ -679,7 +680,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration Loading
|
## Configuration Loading
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||||
@ -737,7 +738,7 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration Precedence
|
## Configuration Precedence
|
||||||
|
|
||||||
1. **Environment variables** (highest priority via `AutomaticEnv()`)
|
1. **Environment variables** (highest priority via `AutomaticEnv()`)
|
||||||
2. **`.env` file** (loaded via `godotenv/autoload` import)
|
2. **`.env` file** (loaded via `godotenv/autoload` import)
|
||||||
@ -745,7 +746,7 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
|||||||
`~/.config/{appname}/{appname}.yaml`
|
`~/.config/{appname}/{appname}.yaml`
|
||||||
4. **Defaults** (lowest priority)
|
4. **Defaults** (lowest priority)
|
||||||
|
|
||||||
### Environment Loading
|
## Environment Loading
|
||||||
|
|
||||||
Import godotenv with autoload to automatically load `.env` files:
|
Import godotenv with autoload to automatically load `.env` files:
|
||||||
|
|
||||||
@ -757,9 +758,9 @@ import (
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Logging (slog)
|
# 9. Logging (slog)
|
||||||
|
|
||||||
### Logger Struct
|
## Logger Struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/logger/logger.go
|
// internal/logger/logger.go
|
||||||
@ -775,7 +776,7 @@ type Logger struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logger Setup with TTY Detection
|
## Logger Setup with TTY Detection
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
|
func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
|
||||||
@ -809,7 +810,7 @@ func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logger Methods
|
## Logger Methods
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (l *Logger) EnableDebugLogging() {
|
func (l *Logger) EnableDebugLogging() {
|
||||||
@ -830,7 +831,7 @@ func (l *Logger) Identify() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logging Patterns
|
## Logging Patterns
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Info with fields
|
// Info with fields
|
||||||
@ -866,9 +867,9 @@ s.log.Info("request",
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Database Wrapper
|
# 10. Database Wrapper
|
||||||
|
|
||||||
### Database Struct
|
## Database Struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/database/database.go
|
// internal/database/database.go
|
||||||
@ -885,7 +886,7 @@ type Database struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Database Factory with Lifecycle
|
## Database Factory with Lifecycle
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
|
func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
|
||||||
@ -912,7 +913,7 @@ func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Usage Pattern
|
## Usage Pattern
|
||||||
|
|
||||||
The Database struct is injected into handlers and other services:
|
The Database struct is injected into handlers and other services:
|
||||||
|
|
||||||
@ -933,9 +934,9 @@ func (s *Handlers) HandleSomething() http.HandlerFunc {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. Globals Package
|
# 11. Globals Package
|
||||||
|
|
||||||
### Package Variables and Struct
|
## Package Variables and Struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/globals/globals.go
|
// internal/globals/globals.go
|
||||||
@ -967,7 +968,7 @@ func New(lc fx.Lifecycle) (*Globals, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Setting Globals in Main
|
## Setting Globals in Main
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// cmd/httpd/main.go
|
// cmd/httpd/main.go
|
||||||
@ -985,7 +986,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build-Time Variable Injection
|
## Build-Time Variable Injection
|
||||||
|
|
||||||
Use ldflags to inject version information at build time:
|
Use ldflags to inject version information at build time:
|
||||||
|
|
||||||
@ -999,9 +1000,9 @@ build:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 12. Static Assets & Templates
|
# 12. Static Assets & Templates
|
||||||
|
|
||||||
### Static File Embedding
|
## Static File Embedding
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// static/static.go
|
// static/static.go
|
||||||
@ -1026,7 +1027,7 @@ static/
|
|||||||
└── jquery-3.5.1.slim.min.js
|
└── jquery-3.5.1.slim.min.js
|
||||||
```
|
```
|
||||||
|
|
||||||
### Template Embedding and Lazy Parsing
|
## Template Embedding and Lazy Parsing
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// templates/templates.go
|
// templates/templates.go
|
||||||
@ -1049,7 +1050,7 @@ func GetParsed() *template.Template {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Template Composition
|
## Template Composition
|
||||||
|
|
||||||
Templates use Go's template composition:
|
Templates use Go's template composition:
|
||||||
|
|
||||||
@ -1064,7 +1065,7 @@ Templates use Go's template composition:
|
|||||||
{{ template "pagefooter.html" . }} {{ template "htmlfooter.html" . }}
|
{{ template "pagefooter.html" . }} {{ template "htmlfooter.html" . }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Static Asset References
|
## Static Asset References
|
||||||
|
|
||||||
Reference static files with `/s/` prefix:
|
Reference static files with `/s/` prefix:
|
||||||
|
|
||||||
@ -1076,9 +1077,9 @@ Reference static files with `/s/` prefix:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 13. Health Check
|
# 13. Health Check
|
||||||
|
|
||||||
### Health Check Service
|
## Health Check Service
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// internal/healthcheck/healthcheck.go
|
// internal/healthcheck/healthcheck.go
|
||||||
@ -1114,7 +1115,7 @@ func New(lc fx.Lifecycle, params HealthcheckParams) (*Healthcheck, error) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Health Check Response
|
## Health Check Response
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type HealthcheckResponse struct {
|
type HealthcheckResponse struct {
|
||||||
@ -1144,19 +1145,19 @@ func (s *Healthcheck) Healthcheck() *HealthcheckResponse {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Standard Endpoint
|
## Standard Endpoint
|
||||||
|
|
||||||
Health check is served at the standard `.well-known` path:
|
Health check is served at the standard `.well-known` path:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck())
|
s.router.Get("/.well-known/healthcheck", s.h.HandleHealthCheck())
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 14. External Integrations
|
# 14. External Integrations
|
||||||
|
|
||||||
### Sentry Error Reporting
|
## Sentry Error Reporting
|
||||||
|
|
||||||
Sentry is conditionally enabled based on `SENTRY_DSN` environment variable:
|
Sentry is conditionally enabled based on `SENTRY_DSN` environment variable:
|
||||||
|
|
||||||
@ -1201,7 +1202,7 @@ if s.sentryEnabled {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Prometheus Metrics
|
## Prometheus Metrics
|
||||||
|
|
||||||
Metrics are conditionally enabled and protected by basic auth:
|
Metrics are conditionally enabled and protected by basic auth:
|
||||||
|
|
||||||
@ -1220,7 +1221,7 @@ if viper.GetString("METRICS_USERNAME") != "" {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment Variables Summary
|
## Environment Variables Summary
|
||||||
|
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
| ------------------ | -------------------------------- | ------- |
|
| ------------------ | -------------------------------- | ------- |
|
||||||
@ -1231,3 +1232,11 @@ if viper.GetString("METRICS_USERNAME") != "" {
|
|||||||
| `MAINTENANCE_MODE` | Enable maintenance mode | false |
|
| `MAINTENANCE_MODE` | Enable maintenance mode | false |
|
||||||
| `METRICS_USERNAME` | Basic auth username for /metrics | "" |
|
| `METRICS_USERNAME` | Basic auth username for /metrics | "" |
|
||||||
| `METRICS_PASSWORD` | Basic auth password for /metrics | "" |
|
| `METRICS_PASSWORD` | Basic auth password for /metrics | "" |
|
||||||
|
|
||||||
|
# Author
|
||||||
|
|
||||||
|
[@sneak](https://sneak.berlin) <[sneak@sneak.berlin](mailto:sneak@sneak.berlin)>
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
MIT. See [LICENSE](../LICENSE).
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
# New Repo Checklist
|
---
|
||||||
|
title: New Repo Checklist
|
||||||
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
Use this checklist when creating a new repository from scratch. Follow the steps
|
Use this checklist when creating a new repository from scratch. Follow the steps
|
||||||
in order. Full policies are at:
|
in order. Full policies are at
|
||||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`.
|
||||||
|
|
||||||
Template files can be fetched from:
|
Template files can be fetched from:
|
||||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/<path>`
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/<path>`
|
||||||
|
|
||||||
## 1. Initialize
|
# 1. Initialize
|
||||||
|
|
||||||
- [ ] `git init`
|
- [ ] `git init`
|
||||||
- [ ] Ask the user for the license (MIT, GPL, or WTFPL)
|
- [ ] Ask the user for the license (MIT, GPL, or WTFPL)
|
||||||
|
|
||||||
## 2. First Commit (README only)
|
# 2. First Commit (README only)
|
||||||
|
|
||||||
- [ ] Create `README.md` with all required sections:
|
- [ ] Create `README.md` with all required sections:
|
||||||
- [ ] **Description**: name, purpose, category, license, author
|
- [ ] **Description**: name, purpose, category, license, author
|
||||||
@ -24,28 +27,29 @@ Template files can be fetched from:
|
|||||||
- [ ] **Author**: [@sneak](https://sneak.berlin)
|
- [ ] **Author**: [@sneak](https://sneak.berlin)
|
||||||
- [ ] `git add README.md && git commit`
|
- [ ] `git add README.md && git commit`
|
||||||
|
|
||||||
## 3. Scaffolding (feature branch)
|
# 3. Scaffolding (feature branch)
|
||||||
|
|
||||||
- [ ] `git checkout -b initial-scaffolding`
|
- [ ] `git checkout -b initial-scaffolding`
|
||||||
|
|
||||||
### Fetch Template Files
|
## Fetch Template Files
|
||||||
|
|
||||||
- [ ] [`.gitignore`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore)
|
- [ ] `.gitignore` — fetch from
|
||||||
— fetch from prompts repo, extend for language-specific artifacts
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore`, extend for
|
||||||
- [ ] [`.editorconfig`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfig)
|
language-specific artifacts
|
||||||
— fetch from prompts repo
|
- [ ] `.editorconfig` — fetch from
|
||||||
- [ ] [`Makefile`](https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile) —
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfig`
|
||||||
fetch from prompts repo, adapt targets for the project's language and
|
- [ ] `Makefile` — fetch from
|
||||||
tools
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile`, adapt
|
||||||
- [ ] For JS/docs repos:
|
targets for the project's language and tools
|
||||||
[`.prettierrc`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc),
|
- [ ] For JS/docs repos: `.prettierrc` and `.prettierignore` — fetch from
|
||||||
[`.prettierignore`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and
|
||||||
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`
|
||||||
|
|
||||||
### Create Project Files
|
## Create Project Files
|
||||||
|
|
||||||
- [ ] `LICENSE` file matching the chosen license
|
- [ ] `LICENSE` file matching the chosen license
|
||||||
- [ ] [`REPO_POLICIES.md`](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
|
- [ ] `REPO_POLICIES.md` — fetch from
|
||||||
— fetch from prompts repo
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`
|
||||||
- [ ] `Dockerfile` and `.dockerignore`
|
- [ ] `Dockerfile` and `.dockerignore`
|
||||||
- All Dockerfiles must run `make check` as a build step
|
- All Dockerfiles must run `make check` as a build step
|
||||||
- Server: also builds and runs the application
|
- Server: also builds and runs the application
|
||||||
@ -53,14 +57,14 @@ Template files can be fetched from:
|
|||||||
- Image pinned by sha256 hash with version/date comment
|
- Image pinned by sha256 hash with version/date comment
|
||||||
- [ ] Gitea Actions workflow at `.gitea/workflows/check.yml` that runs
|
- [ ] Gitea Actions workflow at `.gitea/workflows/check.yml` that runs
|
||||||
`docker build .` on push — reference
|
`docker build .` on push — reference
|
||||||
[`check.yml`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml`
|
||||||
- [ ] Language-specific:
|
- [ ] Language-specific:
|
||||||
- [ ] Go: `go mod init sneak.berlin/go/<name>`,
|
- [ ] Go: `go mod init sneak.berlin/go/<name>`, `.golangci.yml` (fetch from
|
||||||
[`.golangci.yml`](https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml)
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`)
|
||||||
- [ ] JS: `yarn init`, `yarn add --dev prettier`
|
- [ ] JS: `yarn init`, `yarn add --dev prettier`
|
||||||
- [ ] Python: `pyproject.toml`
|
- [ ] Python: `pyproject.toml`
|
||||||
|
|
||||||
### Configure Makefile
|
## Configure Makefile
|
||||||
|
|
||||||
- [ ] `make test` — runs project tests (30-second timeout)
|
- [ ] `make test` — runs project tests (30-second timeout)
|
||||||
- [ ] `make lint` — runs linter
|
- [ ] `make lint` — runs linter
|
||||||
@ -70,7 +74,7 @@ Template files can be fetched from:
|
|||||||
- [ ] `make docker` — builds Docker image
|
- [ ] `make docker` — builds Docker image
|
||||||
- [ ] `make hooks` — installs pre-commit hook
|
- [ ] `make hooks` — installs pre-commit hook
|
||||||
|
|
||||||
## 4. Verify
|
# 4. Verify
|
||||||
|
|
||||||
- [ ] `make check` passes
|
- [ ] `make check` passes
|
||||||
- [ ] `make docker` succeeds
|
- [ ] `make docker` succeeds
|
||||||
@ -79,7 +83,7 @@ Template files can be fetched from:
|
|||||||
- [ ] No unnecessary files in repo root
|
- [ ] No unnecessary files in repo root
|
||||||
- [ ] All dates written as YYYY-MM-DD
|
- [ ] All dates written as YYYY-MM-DD
|
||||||
|
|
||||||
## 5. Merge and Set Up
|
# 5. Merge and Set Up
|
||||||
|
|
||||||
- [ ] Commit, merge to `main`
|
- [ ] Commit, merge to `main`
|
||||||
- [ ] `make hooks` to install pre-commit hook
|
- [ ] `make hooks` to install pre-commit hook
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
Version: 2026-02-22
|
---
|
||||||
|
title: Repository Policies
|
||||||
# Repository Policies
|
last_modified: 2026-02-22
|
||||||
|
---
|
||||||
|
|
||||||
This document covers repository structure, tooling, and workflow standards. Code
|
This document covers repository structure, tooling, and workflow standards. Code
|
||||||
style conventions are in separate documents:
|
style conventions are in separate documents:
|
||||||
@ -14,9 +15,9 @@ style conventions are in separate documents:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- Cross-project documentation (such as this file) must include a
|
- Cross-project documentation (such as this file) must include
|
||||||
`Version: YYYY-MM-DD` line near the top so it can be kept in sync with the
|
`last_modified: YYYY-MM-DD` in the YAML front matter so it can be kept in sync
|
||||||
authoritative source as policies evolve.
|
with the authoritative source as policies evolve.
|
||||||
|
|
||||||
- **ALL external references must be pinned by cryptographic hash.** This
|
- **ALL external references must be pinned by cryptographic hash.** This
|
||||||
includes Docker base images, Go modules, npm packages, GitHub Actions, and
|
includes Docker base images, Go modules, npm packages, GitHub Actions, and
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user