bring repo into policy compliance; vendor assets; Gitea CI

Vendor the front-end assets and drop the third-party CDN dependencies
(BootstrapCDN is being sunset): the bootstrap 4.0.0 css/js, jquery
3.2.1 slim, and popper 1.12.9 now live under static/ and are served
from the app, byte-for-byte identical to the previous SRI-pinned files.

Migrate CI from Drone to a Gitea Actions workflow that runs
docker build . on push, with the checkout action pinned by SHA.

Bring the repo up to standard:

- add REPO_POLICIES.md, .editorconfig, .dockerignore, .golangci.yml,
  and a comprehensive root-anchored .gitignore
- rewrite the Makefile with the required test/lint/fmt/fmt-check/check/
  docker/hooks targets (golangci-lint, 30s test timeout, verbose rerun
  on failure, check modifies nothing)
- rewrite the Dockerfile as a hash-pinned multistage build: a lint
  stage (golangci-lint), a glibc build+test stage (the legacy sqlite
  driver needs cgo+glibc), and a debian-slim runtime carrying the
  binary, templates, and static assets
- add real tests for the hn package
- bring the code into golangci-lint (default: all) compliance: fix the
  malformed gorm struct tags, check previously-ignored errors, dispatch
  the zerolog error event, avoid a uint->Duration overflow, split long
  functions, and add doc comments — all behaviour-preserving
- expand the README with the required sections
This commit is contained in:
2026-07-26 23:55:21 +07:00
parent 000f5bbaa6
commit 3ab9637246
23 changed files with 1009 additions and 321 deletions

View File

@@ -1,18 +1,80 @@
# Orangesite Transparency Log
Live: https://orangesite.sneak.cloud
Orangesite is a WTFPL-licensed Go web application by
[@sneak](https://sneak.berlin) that records which stories drop off the Hacker
News front page and how long they lasted, as a small transparency log.
Shows stories that were on the orangesite front page within the last 24
hours, but aren't any more. Sorted by when they exited the frontpage, most
recent first.
Live: <https://orangesite.sneak.cloud>
Stories on the frontpage for less than a half hour (likely manually
moderator nuked if rank &gt; 25 or so) are marked red for convenience.
It shows stories that were on the HN front page within the last 24 hours but
are not any more, sorted by when they left the front page, most recent first.
Stories that were on the front page for less than half an hour (a likely sign
of moderator intervention) are marked in red.
# TODO
## Getting Started
* continue to resist the urge to use the orange
The service needs Go and a C compiler (the sqlite driver uses cgo). Run it
locally:
# Author
```sh
git clone https://git.eeqj.de/sneak/orangesite
cd orangesite
make run # builds ./server and serves on :8080
```
* [sneak@sneak.berlin](mailto:sneak@sneak.berlin)
Or build and run the container image (which runs `make check` as part of the
build):
```sh
make docker
docker run -p 8080:8080 -v orangesite-data:/data sneak/orangesite
```
Configuration is via environment variables:
- `DATABASE_PATH` — path to the sqlite database file (default
`/data/storage.sqlite`, or `./storage.sqlite` under `make run`).
- `DEBUG` — set to any non-empty value to enable debug logging and gorm SQL
logging.
## Rationale
The Hacker News front page turns over constantly, and stories sometimes
disappear far faster than their score and age would predict. Orangesite keeps
an independent record of front-page tenure so that departures — especially
unusually fast ones — remain visible after the fact.
## Design
The program is a single Go binary:
- `cmd/server` — the entrypoint; wires build-time version info into the `hn`
package and runs the server.
- `hn` — the application package:
- `fetcher.go` scrapes the HN top-stories API once a minute and records
each story's first appearance, rank changes, best rank reached, and the
moment it leaves the front page.
- `db.go` defines the gorm models, persisted to sqlite.
- `handlers.go` renders the index and about pages.
- `server.go` sets up the echo HTTP server, logging, and routes.
- `view/` — pongo2 HTML templates, rendered at request time.
- `static/` — vendored front-end assets (bootstrap, jquery, popper), served
under `/static` so the site depends on no third-party CDNs.
## TODO
- Continue to resist the urge to use the orange.
- Embed the `view/` templates and `static/` assets into the binary rather than
shipping them alongside it.
- Honour a `PORT` environment variable instead of hard-coding `:8080`.
- Add graceful shutdown instead of relying on `Fatal`.
- Harden the HTTP surface (security headers, server timeouts, request size
limits) before tagging a `1.0`.
## License
WTFPL — see the [`LICENSE`](LICENSE) file.
## Author
[@sneak](https://sneak.berlin) — <sneak@sneak.berlin>