deploy without node
Some checks failed
ci / site (push) Has been cancelled
publish-image / publish (push) Has been cancelled

This commit is contained in:
2026-02-10 02:52:14 -05:00
parent 03df2b3a6c
commit 3b0b97f139
25 changed files with 312 additions and 51 deletions

View File

@@ -7,11 +7,10 @@ The site MUST provide a blog index page at `/blog` that lists WordPress posts as
- excerpt/summary
- publish date
The card MUST render a meta row with:
The card MUST render a footer bar that includes:
- publish date on the left
- views on the right when available (if views are not provided by the dataset, the card MUST omit views without breaking layout)
The card MUST render a footer row showing the content source label (e.g., `blog`).
- a content source label (e.g., `blog`)
The listing MUST be ordered by publish date descending (newest first).
@@ -31,4 +30,4 @@ Each post card MUST be instrumented with Umami Track Events data attributes and
#### Scenario: Blog post card layout is standardized
- **WHEN** `/blog` renders a blog post card
- **THEN** the card shows featured image (when available), title, trimmed excerpt, meta row (date + optional views), and a footer source label
- **THEN** the card shows featured image (when available), title, trimmed excerpt, and a footer bar containing date, optional views, and a source label

View File

@@ -7,10 +7,10 @@ The standard card layout MUST be:
- featured image displayed prominently at the top (when available)
- title
- summary/excerpt text, trimmed to a fixed maximum length
- meta row showing:
- footer bar showing:
- publish date on the left
- views on the right (when available)
- footer row showing the content source (e.g., `youtube`, `podcast`, `blog`)
- views when available (if omitted, the footer MUST still render cleanly)
- the content source label (e.g., `youtube`, `podcast`, `blog`)
If a field is not available (for example, views for some sources), the card MUST still render cleanly with that field omitted.
@@ -20,9 +20,8 @@ If a field is not available (for example, views for some sources), the card MUST
#### Scenario: Card renders without views
- **WHEN** a content item has no views data
- **THEN** the card renders the meta row with date and omits views without breaking the layout
- **THEN** the card renders the footer bar with date + source and omits views without breaking the layout
#### Scenario: Card renders without featured image
- **WHEN** a content item has no featured image
- **THEN** the card renders a placeholder media area and still renders the remaining fields

View File

@@ -0,0 +1,25 @@
## 1. Discovery And Current State
- [x] 1.1 Identify current deploy target and mechanism (compose/swarm/k8s, image vs files) and document constraints in `README` or `ops/` docs
- [x] 1.2 Identify the content source(s) that define "latest content" (e.g., WordPress/API) and how builds currently fetch content
- [x] 1.3 Confirm current build output (static assets) and runtime server (e.g., nginx) requirements
## 2. Build And Publish A Deployable Artifact
- [x] 2.1 Ensure the repo can produce a deterministic production build inside CI (no host dependencies)
- [x] 2.2 Create or update a Dockerfile to build the site and package the built output into a runtime image
- [x] 2.3 Add build metadata to the image (tagging convention and/or embedded version file)
- [x] 2.4 Configure CI to build and publish the image to a registry accessible by the server
## 3. Server-Side Docker-Only Refresh Workflow
- [x] 3.1 Add or update the server Docker Compose/service definition to run the published image
- [x] 3.2 Add documented operator commands to refresh to the latest image (pull + restart)
- [x] 3.3 Add a verification command/procedure to show the currently deployed version (tag/digest/build metadata)
- [x] 3.4 Define rollback procedure to re-deploy a previous known-good tag/digest
## 4. Validation
- [x] 4.1 Validate a refresh on a test/staging server: pull latest image, restart, confirm content changes are visible
- [x] 4.2 Validate failure mode: simulate pull failure and confirm the existing site remains serving
- [x] 4.3 Update docs with a minimal "runbook" for operators (refresh, verify, rollback)

View File

@@ -1,25 +0,0 @@
## 1. Discovery And Current State
- [ ] 1.1 Identify current deploy target and mechanism (compose/swarm/k8s, image vs files) and document constraints in `README` or `ops/` docs
- [ ] 1.2 Identify the content source(s) that define "latest content" (e.g., WordPress/API) and how builds currently fetch content
- [ ] 1.3 Confirm current build output (static assets) and runtime server (e.g., nginx) requirements
## 2. Build And Publish A Deployable Artifact
- [ ] 2.1 Ensure the repo can produce a deterministic production build inside CI (no host dependencies)
- [ ] 2.2 Create or update a Dockerfile to build the site and package the built output into a runtime image
- [ ] 2.3 Add build metadata to the image (tagging convention and/or embedded version file)
- [ ] 2.4 Configure CI to build and publish the image to a registry accessible by the server
## 3. Server-Side Docker-Only Refresh Workflow
- [ ] 3.1 Add or update the server Docker Compose/service definition to run the published image
- [ ] 3.2 Add documented operator commands to refresh to the latest image (pull + restart)
- [ ] 3.3 Add a verification command/procedure to show the currently deployed version (tag/digest/build metadata)
- [ ] 3.4 Define rollback procedure to re-deploy a previous known-good tag/digest
## 4. Validation
- [ ] 4.1 Validate a refresh on a test/staging server: pull latest image, restart, confirm content changes are visible
- [ ] 4.2 Validate failure mode: simulate pull failure and confirm the existing site remains serving
- [ ] 4.3 Update docs with a minimal "runbook" for operators (refresh, verify, rollback)

View File

@@ -16,9 +16,15 @@ The site MUST provide a blog index page at `/blog` that lists WordPress posts as
- featured image (when available)
- title
- excerpt/summary
- publish date
The listing MUST be ordered by publish date descending (newest first).
The card MUST render a footer row that includes:
- publish date on the left
- views on the right when available (if views are not provided by the dataset, the card MUST omit views without breaking layout)
- a content source label (e.g., `blog`)
Each post card MUST be instrumented with Umami Track Events data attributes and MUST include at minimum:
- `data-umami-event`
- `data-umami-event-target_id`
@@ -33,6 +39,10 @@ Each post card MUST be instrumented with Umami Track Events data attributes and
- **WHEN** a user clicks a blog post card on `/blog`
- **THEN** the click emits an Umami event with `target_id`, `placement`, and `target_url`
#### Scenario: Blog post card layout is standardized
- **WHEN** `/blog` renders a blog post card
- **THEN** the card shows featured image (when available), title, trimmed excerpt, and a footer bar containing date, optional views, and a source label
### Requirement: Blog post detail
The site MUST provide a blog post detail page for each WordPress post that renders:
- title
@@ -83,4 +93,3 @@ If there are no WordPress posts available, the blog index MUST render a non-brok
#### Scenario: No posts available
- **WHEN** the cached WordPress dataset contains no posts
- **THEN** `/blog` renders a helpful empty state

View File

@@ -0,0 +1,32 @@
## Purpose
Define a standardized card layout so content cards across surfaces look consistent.
## Requirements
### Requirement: Standard card information architecture
All content cards rendered by the site MUST use a standardized layout so cards across different surfaces look consistent.
The standard card layout MUST be:
- featured image displayed prominently at the top (when available)
- title
- summary/excerpt text, trimmed to a fixed maximum length
- footer row showing:
- publish date on the left
- views when available (if omitted, the footer MUST still render cleanly)
- the content source label (e.g., `youtube`, `podcast`, `blog`)
If a field is not available (for example, views for some sources), the card MUST still render cleanly with that field omitted.
#### Scenario: Card renders with all fields
- **WHEN** a content item has an image, title, summary, publish date, views, and source
- **THEN** the card renders those fields in the standard card layout order
#### Scenario: Card renders without views
- **WHEN** a content item has no views data
- **THEN** the card renders the footer bar with date + source and omits views without breaking the layout
#### Scenario: Card renders without featured image
- **WHEN** a content item has no featured image
- **THEN** the card renders a placeholder media area and still renders the remaining fields

View File

@@ -0,0 +1,31 @@
## Purpose
Enable operators to refresh the deployed site to the latest content on a Docker-only host (no Node.js installed on the server).
## Requirements
### Requirement: Host update does not require Node.js
The system MUST provide an operator workflow to update the deployed site to the latest content without installing Node.js on the server host. Any build or content-fetch steps MUST run in containers and/or CI, not via host-installed Node.js.
#### Scenario: Operator updates without host Node.js
- **WHEN** the server host has Docker available but does not have Node.js installed
- **THEN** the operator can complete the update procedure using Docker commands only
### Requirement: Image-based content refresh is supported
The system MUST support refreshing the deployed site to the latest content by pulling a newly built deployable artifact (for example, a Docker image) and restarting the running service.
#### Scenario: Successful refresh to latest image
- **WHEN** the operator runs the documented refresh command
- **THEN** the server pulls the latest published image and restarts the service using that image
#### Scenario: Refresh failure does not break running site
- **WHEN** the operator runs the documented refresh command and the pull fails
- **THEN** the site remains running on the previously deployed image
### Requirement: Refresh is repeatable and auditable
The system MUST document the refresh procedure and provide a way to verify which version is deployed (for example, image tag/digest or build metadata).
#### Scenario: Operator verifies deployed version
- **WHEN** the operator runs the documented verification command
- **THEN** the system reports the currently deployed version identifier

View File

@@ -11,6 +11,9 @@ The normalized item MUST include at minimum:
- `publishedAt` (ISO-8601)
- `thumbnailUrl` (optional)
The system MUST support an optional summary field on normalized items when available from the source:
- `summary` (optional, short human-readable excerpt suitable for cards)
#### Scenario: Normalizing a YouTube video
- **WHEN** the system ingests a YouTube video item
- **THEN** it produces a normalized item containing `id`, `source: youtube`, `url`, `title`, and `publishedAt`
@@ -19,6 +22,10 @@ The normalized item MUST include at minimum:
- **WHEN** the system ingests a podcast RSS episode
- **THEN** it produces a normalized item containing `id`, `source: podcast`, `url`, `title`, and `publishedAt`
#### Scenario: Summary available
- **WHEN** an ingested item provides summary/description content
- **THEN** the normalized item includes a `summary` suitable for rendering in cards
### Requirement: YouTube ingestion with stats when available
The system MUST support ingesting YouTube videos for channel `youtube.com/santhoshj`.