All checks were successful
Frontend CI / build (push) Successful in 1m13s
### Description
#### Summary
This PR introduces a new `script/toolbox` directory containing a Python-based utility service designed to handle background tasks, specifically generating an RSS 2.0 feed (`generate_rss.py`). It includes the necessary Docker infrastructure to build and deploy this toolbox alongside the existing services.
Additionally, this change refactors the location of maintenance shell scripts to `script/pre-commit/` for better organization and optimizes the CI/CD deployment workflow by implementing Docker layer caching and removing redundant frontend build steps.
#### Key Changes
##### Toolbox & RSS
* **New Service:** Added `script/toolbox/` containing a Python 3.14 environment, `Dockerfile`, and `requirements.txt`.
* **RSS Logic:** Implemented `generate_rss.py` to fetch published posts from the PostgreSQL database, scrape site metadata, and generate a `feed.xml` file.
* **Documentation:** Added `README.md` and `.env.example` for the toolbox service.
##### CI/CD & Infrastructure
* **Workflow Update (`deployment.yaml`):**
* Added a new job to build and push the `toolbox` Docker image.
* Enabled `cache-from` and `cache-to` (registry caching) for Frontend, Backend, and Toolbox images to speed up build times.
* **Frontend CI:** Removed the redundant `pnpm run build` step from `frontend-ci.yaml`.
##### Refactoring & UI
* **Script Reorganization:** Moved `backend-check.sh`, `frontend-lint.sh`, and `sqlx-prepare.sh` into `script/pre-commit/` and updated their internal path resolution.
* **Pre-commit:** Updated `.pre-commit-config.yaml` to reflect the new script locations.
* **Frontend UI:** Added an RSS icon link to `Footer.svelte` pointing to the generated feed.
#### Testing & Review Notes
1. **Toolbox Build:** Verify the `toolbox` image builds successfully:
```bash
cd script/toolbox
docker build -t blog-toolbox .
```
2. **RSS Generation:**
* Run the container locally with correct `.env` variables.
* Execute `python generate_rss.py` inside the container.
* Verify the output `feed.xml` validates against RSS 2.0 standards.
3. **Pre-commit Hooks:** Run `pre-commit run --all-files` to ensure the path refactoring hasn't broken local linting/checking.
4. **Deployment:** Monitor the next Gitea Action run to confirm registry caching is functioning correctly.
### Package Changes
```
python-dotenv==1.2.1
psycopg2-binary==2.9.11
requests==2.32.5
```
### Screenshots
> Screenshot at Feeder app on Android
<img src="/attachments/d791ac12-307c-43a7-a146-c423f2600c02" width="200px"/>
### Reference
Resolve #227.
### Checklist
- [x] A milestone is set
- [x] The related issuse has been linked to this branch
Reviewed-on: #230
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
Toolbox Scripts
This directory contains utility scripts for the blog application.
RSS Generator (generate_rss.py)
This script connects to the PostgreSQL database, fetches published posts, and generates an RSS 2.0 feed XML file.
Usage
The toolbox container is designed to run in the background (sleeping). You can execute the generation script inside the running container.
1. Volume Configuration
To make the generated feed.xml accessible to your web server or host machine, you need to mount a volume when starting the container.
For example, if you want the feed to be generated at /var/www/blog/feed.xml on the host machine:
- Ensure the file exists on the host (e.g.,
touch /var/www/blog/feed.xml), otherwise it might be created as a directory. - Mount the host file directly to the path inside the container.
- Set the
RSS_OUTPUT_FILEenvironment variable to point to that internal path.
podman run -d \
--name blog-toolbox \
--env-file .env \
-v /var/www/blog/feed.xml:/app/feed.xml \
-e RSS_OUTPUT_FILE=/app/feed.xml \
blog-toolbox-image
2. Generate RSS Feed
Run the following command to generate the RSS feed:
podman exec -it blog-toolbox python generate_rss.py
Environment Variables
The script relies on the following environment variables:
| Variable | Description | Default |
|---|---|---|
DATABASE_HOST |
PostgreSQL database host | 127.0.0.1 |
DATABASE_PORT |
PostgreSQL database port | 5432 |
DATABASE_NAME |
Database name | postgres |
DATABASE_USER |
Database user | postgres |
DATABASE_PASSWORD |
Database password | (empty) |
SERVER_BASE_URL |
Base URL of the blog. Used for generating links and fetching site title/description. | http://localhost/ |
RSS_LANGUAGE |
Language code for the RSS feed | zh-TW |
RSS_OUTPUT_FILE |
Absolute path where the XML file will be written inside the container | feed.xml |
Features
- Dynamic Metadata: Fetches the site title and description from the
SERVER_BASE_URLHTML head. - Preview Images: Includes preview images in the feed as
<enclosure>elements, automatically detecting the correct MIME type and content length from HTTP response headers. - Semantic IDs: Uses semantic IDs for permanent links and GUIDs.
- UTF-8 Support: Properly handles Chinese and other Unicode characters in titles and descriptions.