97 lines
3.9 KiB
Markdown
97 lines
3.9 KiB
Markdown
# Changelog
|
|||
|
|
|
||
|
|
All notable changes to **volumen** are documented in this file.
|
||
|
|
|
||
|
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||
|
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||
|
|
|
||
|
|
## [0.1.0] — 2026-06-20
|
||
|
|
|
||
|
|
First public release: a small, file-based Markdown blog engine in CRuby. Posts
|
||
|
|
are plain files, the engine exposes them as a JSON API and ships a self-hosted
|
||
|
|
admin — no database, no external services.
|
||
|
|
|
||
|
|
### Added
|
||
|
|
|
||
|
|
**Content & storage**
|
||
|
|
|
||
|
|
- File-based store: each post is a `.md` file with a TOML frontmatter block
|
||
|
|
delimited by `+++`. No database.
|
||
|
|
- Post fields: `title`, `slug`, `date`, `lang`, `author`, `tags`, `draft`,
|
||
|
|
`excerpt`, `cover`, `all_langs`, and `translations` (a `lang → slug` map).
|
||
|
|
- Drafts (`draft = true`) are hidden from the public API.
|
||
|
|
- Excerpt falls back to the first paragraph (~200 chars) when none is set.
|
||
|
|
- Estimated reading time (~200 words/min) computed per post.
|
||
|
|
- Multilingual posts: per-language slugs via `translations`, plus `all_langs`
|
||
|
|
to surface a single post under every language.
|
||
|
|
|
||
|
|
**Markdown rendering**
|
||
|
|
|
||
|
|
- GFM rendering via kramdown: tables, fenced code blocks, task lists, and
|
||
|
|
strikethrough.
|
||
|
|
- Automatic heading IDs for in-page anchors.
|
||
|
|
- Raw HTML in post bodies is passed through (authors are the trusted admin).
|
||
|
|
|
||
|
|
**Public JSON API (`/api/volumen`)**
|
||
|
|
|
||
|
|
- Read-only endpoints: `site`, `posts`, `posts/{slug}`, `tags`, `feed.xml`
|
||
|
|
(RSS), and `sitemap.xml`.
|
||
|
|
- `posts` supports pagination (`page`, `limit`, returning `total` and
|
||
|
|
`page_size`) and filtering by `lang` and `tag`.
|
||
|
|
- Permissive CORS so a separate front end can consume the API.
|
||
|
|
|
||
|
|
**Admin (`/admin`)**
|
||
|
|
|
||
|
|
- Server-rendered admin with a sidebar layout and full post CRUD.
|
||
|
|
- Dual-mode editor: Markdown source (primary) and a visual WYSIWYG, switchable
|
||
|
|
per post, with a toggleable live preview persisted across sessions.
|
||
|
|
- Image upload from the editor toolbar into `content_dir/media`; any image
|
||
|
|
format is accepted (WebP and AVIF included) and served with the correct
|
||
|
|
`Content-Type`.
|
||
|
|
- Cover image field with upload, URL, clear, and preview.
|
||
|
|
|
||
|
|
**Multi-user & roles**
|
||
|
|
|
||
|
|
- Multiple admin users stored in `users.toml`, managed from a settings page.
|
||
|
|
- Two roles: `admin` (full access incl. user management) and `author` (posts
|
||
|
|
only).
|
||
|
|
- Change password and username; last-admin and self-deletion safeguards.
|
||
|
|
|
||
|
|
**Configuration & CLI**
|
||
|
|
|
||
|
|
- TOML configuration, auto-generated with a commented template on first run.
|
||
|
|
- Configurable `host`/`port` (defaults to `9090`), `content_dir`,
|
||
|
|
`users_file`, and `site` metadata.
|
||
|
|
- CLI: `serve`, `hash-password`, `version`, `help`, with `--config`,
|
||
|
|
`--content`, `--host`, and `--port` overrides.
|
||
|
|
|
||
|
|
**Deployment**
|
||
|
|
|
||
|
|
- `install.sh` installs the Ruby toolchain from distro packages on Fedora and
|
||
|
|
openEuler (and prints guidance on other distros), creates the service user
|
||
|
|
and directories, and installs a systemd unit.
|
||
|
|
- Deployment docs for systemd and FreeBSD (`rc.d`), plus an nginx reverse-proxy
|
||
|
|
setup that runs the admin same-origin, with brute-force rate-limiting and an
|
||
|
|
optional IP allowlist on the login endpoint.
|
||
|
|
|
||
|
|
**Project & tooling**
|
||
|
|
|
||
|
|
- Documentation set: architecture, configuration, API reference, deployment,
|
||
|
|
and security.
|
||
|
|
- `just` task set (`install`, `run`, `dev`, `build`, `test`, `uninstall`) and
|
||
|
|
Forgejo Actions CI (RuboCop + tests on Ruby 3.3/3.4, gem build on release).
|
||
|
|
- `CONTRIBUTING.md` and a minitest suite; clean RuboCop.
|
||
|
|
|
||
|
|
### Security
|
||
|
|
|
||
|
|
- Passwords hashed with scrypt and verified in constant time.
|
||
|
|
- Per-form CSRF tokens on every state-changing admin request.
|
||
|
|
- Session cookies are `HttpOnly` and `SameSite=Strict`, and gain the `Secure`
|
||
|
|
attribute automatically on HTTPS requests (detected via `request.ssl?` /
|
||
|
|
`X-Forwarded-Proto`), so the cookie never travels over plain HTTP in
|
||
|
|
production.
|
||
|
|
- Configurable, stable `session_key` so sessions survive restarts.
|
||
|
|
- Generic login error message to avoid username enumeration.
|
||
|
|
|
||
|
|
[0.1.0]: https://codeberg.org/petrbalvin/volumen/releases/tag/v0.1.0
|