Versioning (0.1.0)

This commit is contained in:
Olaf
2026-08-25 09:07:29 +02:00
parent d896d3d068
commit 5d60bd801c
17 changed files with 61 additions and 4 deletions
+1
View File
@@ -8,6 +8,7 @@ APP_HEALTHCHECK_TIMEOUT=5s
APP_HEALTHCHECK_START_PERIOD=10s
APP_HEALTHCHECK_RETRIES=3
LINKLOG_APP_NAME=LinkLog
LINKLOG_VERSION=0.1.0
LINKLOG_SECRET_KEY=replace-with-a-long-random-secret
LINKLOG_TOKEN_EXPIRY_DAYS=30
# Optional comma-separated override. Leave empty to use the built-in list.
+1
View File
@@ -16,3 +16,4 @@ __pycache__/
*.log
backend/data/avatars/
LinkLog.afdesign~lock~
+15 -1
View File
@@ -9,13 +9,27 @@ WEB_LOGO := frontend/static/logo.svg
EXTENSION_LOGO := webextension/logo.svg
ICON_FILES := webextension/icon-16.png webextension/icon-32.png webextension/icon-48.png webextension/icon-96.png
GENERATED_LOGOS := $(WEB_LOGO) $(EXTENSION_LOGO) $(ICON_FILES)
EXTENSION_VERSION := $(shell sed -n 's/^[[:space:]]*"version":[[:space:]]*"\([^"]*\)".*/\1/p' webextension/manifest.json | head -n 1)
XPI_FILE := LinkLog-$(EXTENSION_VERSION).xpi
XPI_UNSIGNED_DIR := XPI/unsigned
XPI_SIGNED_DIR := XPI/signed
XPI_OUTPUT := $(XPI_UNSIGNED_DIR)/$(XPI_FILE)
EXTENSION_FILES := manifest.json logo.svg icon-16.png icon-32.png icon-48.png icon-96.png options.css options.html options.js popup.css popup.html popup.js
.PHONY: all logos check-tools clean-generated
.PHONY: all logos xpi check-tools clean-generated
all: logos
logos: check-tools $(GENERATED_LOGOS)
xpi: logos
@test -n "$(EXTENSION_VERSION)" || { echo "Error: extension version is missing from webextension/manifest.json" >&2; exit 1; }
@mkdir -p $(XPI_UNSIGNED_DIR) $(XPI_SIGNED_DIR)
@rm -f $(XPI_OUTPUT)
@cd webextension && zip -q -9 "../$(XPI_OUTPUT)" $(EXTENSION_FILES)
@echo "Created $(XPI_OUTPUT)"
check-tools:
@command -v $(MAGICK) >/dev/null 2>&1 || { echo "Error: ImageMagick '$(MAGICK)' is required. Install ImageMagick and retry." >&2; exit 1; }
+11
View File
@@ -2,6 +2,8 @@
LinkLog is a Firefox extension and Python web service for saving links with a title, comment, timestamp, and tracking parameters removed. The service stores links in SQLite and can publish them through plugins, including Mastodon.
For full transparency: The author used vibe coding to create this software.
## Project Layout
```text
@@ -25,6 +27,7 @@ For local development:
The backend currently uses FastAPI, uvicorn, SQLite, and Pydantic. `httpx2` is included for the Starlette-compatible test client.
Jinja2 is included for server-rendered HTML templates.
The backend version is `0.1.0` and is exposed through the FastAPI/OpenAPI metadata. It can be overridden with `LINKLOG_VERSION`.
LinkLog is licensed under the GNU General Public License, version 3 or any later version. See [LICENSE](LICENSE).
## Local Installation
@@ -93,6 +96,14 @@ make logos
The generated files are `frontend/static/logo.svg`, `webextension/logo.svg`, and `webextension/icon-16.png`, `icon-32.png`, `icon-48.png`, and `icon-96.png`. Override the ImageMagick executable with `make MAGICK=magick logos` when needed.
Create an installable Firefox XPI bundle with:
```sh
make xpi
```
This creates `XPI/unsigned/LinkLog-0.1.0.xpi` from the `webextension/` package and excludes macOS metadata and minified artifacts. The version is read from `webextension/manifest.json`. The `XPI/signed/` directory is reserved for signed release bundles.
Appending a username to the root URL, such as `/alice`, opens that user's public feed and profile information.
Configuration APIs require a bearer token returned by the login endpoint. User configuration uses the identity in that token. Plugin administration additionally requires an administrator account; the development `alice` account is seeded as an administrator, while `bob` is a standard user.
+18
View File
@@ -493,3 +493,21 @@ Add a copyright statement to source files refer to GNU license
### Assistant outcome
Added `Copyright © 2026 Olaf Kolkman` and `SPDX-License-Identifier: GPL-3.0-or-later` headers to all 47 non-minified application, test, frontend, extension, build, deployment, and source-logo files. Generated/runtime assets were left untouched. Python and JavaScript compilation, Compose validation, whitespace checks, and the strict backend suite passed with 15 tests.
### User
Add the version to the name of the resulting xpi
### Assistant outcome
Updated the Makefile to read the extension version from `webextension/manifest.json` and produce a versioned archive such as `LinkLog-0.1.0.xpi`. Updated `.gitignore` and README documentation. The generated XPI contains 12 expected extension files and passes `unzip -tq` integrity validation.
### User
Set the version number of the backend to 0.1.0
### Assistant outcome
Added backend setting `version = 0.1.0`, wired it into FastAPI and OpenAPI metadata, and exposed `LINKLOG_VERSION` as an environment override. Added regression coverage and documented the setting. Compose validation and the strict backend suite passed with 15 tests.
### User
Add the creation of an xpi bundle for the webextention to the Makefile
### Assistant outcome
Added a portable `xpi` Makefile target that regenerates logo assets and packages the Firefox extension into `LinkLog.xpi`, excluding metadata and minified artifacts. Added README instructions, ignored the generated XPI, and verified the archive contents and integrity with `unzip -tq`.
+3
View File
@@ -85,6 +85,9 @@
81. in the footer make the link the same color as the mother text, when clicked use a tint from the Catpuccin theme
82. Add a GNU License file
83. Add a copyright statement to source files refer to GNU license
84. Add the version to the name of the resulting xpi
85. Set the version number of the backend to 0.1.0
84. Add the creation of an xpi bundle for the webextention to the Makefile
## Future entries
+4 -2
View File
@@ -1,9 +1,11 @@
# VIBE
This code has mostly been vibe coded. For full transparency we maintain a log of prompts and results.
This folder contains an append-only record of the visible Link Log development conversation.
- `CHAT_LOG.md` records user requests and assistant responses or outcomes in chronological order.
- `PROMPTS.md` records user prompts separately for quick reference.
- [`CHAT_LOG.md`](./CHAT_LOG.md) records user requests and assistant responses or outcomes in chronological order.
- [`PROMPTS.md`](PROMPTS.md) records user prompts separately for quick reference.
Only the user-visible conversation is recorded. System, developer, environment, and private tool instructions are intentionally excluded.
Binary file not shown.
+1
View File
@@ -13,6 +13,7 @@ DB_PATH = BASE_DIR / 'data' / 'linklog.db'
@dataclass
class Settings:
app_name: str = os.getenv('LINKLOG_APP_NAME', 'LinkLog')
version: str = os.getenv('LINKLOG_VERSION', '0.1.0')
database_url: str = os.getenv('LINKLOG_DATABASE_URL', f'sqlite:///{DB_PATH}')
secret_key: str = os.getenv('LINKLOG_SECRET_KEY', 'dev-secret-key-change-me')
token_expiry_days: int = int(os.getenv('LINKLOG_TOKEN_EXPIRY_DAYS', '30'))
+2 -1
View File
@@ -12,10 +12,11 @@ from backend.app.api.auth import router as auth_router
from backend.app.api.links import router as links_router
from backend.app.api.public import router as public_router
from backend.app.api.user_config import router as user_config_router
from backend.app.core.config import settings
from backend.app.database import AVATARS_DIR
from backend.app.services.link_service import list_public_links
app = FastAPI(title='LinkLog API')
app = FastAPI(title='LinkLog API', version=settings.version)
app.mount('/static', StaticFiles(directory='frontend/static'), name='static')
app.mount('/media', StaticFiles(directory=AVATARS_DIR), name='media')
app.include_router(auth_router, prefix='/api/auth')
+1
View File
@@ -22,6 +22,7 @@ def login_headers(username='alice'):
def test_login_returns_token():
assert app.version == '0.1.0'
response = client.post('/api/auth/login', json={
'username': 'alice',
'password': 'secret123',
+2
View File
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Copyright © 2026 Olaf Kolkman -->
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1804 1712" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-669.006,-255.89)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 950 B

After

Width:  |  Height:  |  Size: 950 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

+2
View File
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Copyright © 2026 Olaf Kolkman -->
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1804 1712" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-669.006,-255.89)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB