Skip to content

Commit 8d01f8a

Browse files
committed
feat: astro frontend
1 parent 55c4d46 commit 8d01f8a

24 files changed

+683
-69
lines changed

.devcontainer/Dockerfile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
FROM mcr.microsoft.com/devcontainers/ruby:3.4-bullseye
2+
3+
# Install Node.js 20
4+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
5+
&& apt-get install -y nodejs
6+
7+
# Install system dependencies
8+
RUN apt-get update && apt-get install -y \
9+
build-essential \
10+
git \
11+
curl \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
# Install development gems
15+
RUN gem install rubocop
16+
17+
# Install global npm packages
18+
RUN npm install -g prettier
19+
20+
# Create vscode user
21+
RUN groupadd --gid 1000 vscode \
22+
&& useradd --uid 1000 --gid vscode --shell /bin/bash --create-home vscode
23+
24+
# Set up workspace
25+
WORKDIR /workspace
26+
RUN chown -R vscode:vscode /workspace
27+
28+
# Switch to vscode user
29+
USER vscode
30+
31+
# Set up environment
32+
RUN echo 'export BUNDLE_PATH="/usr/local/bundle"' >> ~/.bashrc
33+
34+
# Expose port
35+
EXPOSE 3000
36+
37+
# Keep container running
38+
CMD ["sleep", "infinity"]

.devcontainer/devcontainer.json

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
11
{
22
"name": "html2rss-web",
3-
"image": "mcr.microsoft.com/devcontainers/ruby:3.4",
4-
"features": {
5-
"ghcr.io/devcontainers/features/git:1": {},
6-
"ghcr.io/devcontainers/features/github-cli:1": {}
7-
},
3+
"dockerComposeFile": "docker-compose.yml",
4+
"service": "app",
5+
"workspaceFolder": "/workspace",
6+
"shutdownAction": "stopCompose",
87
"customizations": {
98
"vscode": {
109
"extensions": [
11-
"redhat.vscode-yaml",
12-
"esbenp.prettier-vscode",
13-
"github.copilot",
14-
"github.copilot-chat",
15-
"shopify.ruby-lsp"
10+
"rebornix.ruby",
11+
"astro-build.astro-vscode",
12+
"esbenp.prettier-vscode"
1613
],
1714
"settings": {
18-
"ruby.rubocop.executePath": "bundle exec",
19-
"ruby.format": "rubocop",
20-
"ruby.lint": {
21-
"rubocop": true
22-
},
15+
"editor.formatOnSave": true,
16+
"editor.defaultFormatter": "esbenp.prettier-vscode",
2317
"files.associations": {
24-
"*.erb": "erb"
25-
}
18+
"*.astro": "astro"
19+
},
20+
"prettier.configPath": "./frontend/.prettierrc",
21+
"ruby.format": "rubocop",
22+
"ruby.lint": { "rubocop": true },
23+
"editor.tabSize": 2,
24+
"editor.insertSpaces": true,
25+
"files.trimTrailingWhitespace": true,
26+
"files.insertFinalNewline": true
2627
}
2728
}
2829
},
29-
"postCreateCommand": "make setup",
30-
"postStartCommand": "echo '🚀 html2rss-web Development Environment Ready!' && echo '' && echo '📋 Quick Start Commands:' && echo ' make dev # Start development server' && echo ' make test # Run tests' && echo ' make lint # Run linter' && echo ' make fix # Auto-fix linting issues' && echo ' make help # Show all commands' && echo '' && echo '🌐 Server will be available at: http://localhost:3000' && echo '📁 Project files are in: /workspaces/html2rss-web' && echo '' && echo '💡 Tip: Use Ctrl+C to stop the development server' && echo ''",
31-
"forwardPorts": [
32-
3000
33-
],
30+
"forwardPorts": [3000, 4321],
3431
"portsAttributes": {
3532
"3000": {
36-
"label": "html2rss-web",
33+
"label": "Ruby App",
3734
"onAutoForward": "notify"
35+
},
36+
"4321": {
37+
"label": "Astro Dev Server",
38+
"onAutoForward": "silent"
3839
}
3940
},
41+
"postCreateCommand": "make setup",
4042
"remoteUser": "vscode"
4143
}

.devcontainer/docker-compose.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: '3.8'
2+
3+
services:
4+
app:
5+
build:
6+
context: ..
7+
dockerfile: .devcontainer/Dockerfile
8+
volumes:
9+
- ../:/workspace:cached
10+
- bundle-cache:/usr/local/bundle
11+
ports:
12+
- "3000:3000"
13+
environment:
14+
- RACK_ENV=development
15+
- BUNDLE_PATH=/usr/local/bundle
16+
command: sleep infinity
17+
user: vscode
18+
working_dir: /workspace
19+
20+
volumes:
21+
bundle-cache:

.devcontainer/scripts/setup.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "Setting up html2rss-web development environment..."
5+
6+
# Install dependencies
7+
bundle install
8+
cd frontend && npm install && cd ..
9+
10+
# Create .env if missing
11+
if [ ! -f .env ]; then
12+
cat >.env <<EOF
13+
RACK_ENV=development
14+
HEALTH_CHECK_USERNAME=dev
15+
HEALTH_CHECK_PASSWORD=dev
16+
AUTO_SOURCE_ENABLED=true
17+
AUTO_SOURCE_USERNAME=dev
18+
AUTO_SOURCE_PASSWORD=dev
19+
AUTO_SOURCE_ALLOWED_ORIGINS=localhost:3000
20+
EOF
21+
fi
22+
23+
# Create directories
24+
mkdir -p tmp/rack-cache-body tmp/rack-cache-meta
25+
26+
# Build frontend
27+
cd frontend && npm run build && cd ..
28+
29+
echo "Setup complete! Run 'make dev' to start the server."

.github/copilot-instructions.md

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
## Overview
44

55
- Ruby web app that converts websites into RSS 2.0 feeds.
6-
- Built with **Roda**, using the **html2rss** gem (+ `html2rss-configs`).
6+
- Built with **Roda** backend + **Astro** frontend, using the **html2rss** gem (+ `html2rss-configs`).
77
- **Principle:** _All features must work without JavaScript._ JS is only progressive enhancement.
8+
- **Frontend:** Modern Astro-based UI with component architecture, served alongside Ruby backend.
89

910
## Core Rules
1011

@@ -13,24 +14,33 @@
1314
- ✅ Validate all inputs. Pass outbound requests through **SSRF filter**.
1415
- ✅ Add caching headers where appropriate (`Rack::Cache`).
1516
- ✅ Errors: friendly messages for users, detailed logging internally.
16-
- ✅ CSS: Water.css + small overrides in `public/styles.css`.
17-
- ✅ Specs: RSpec, unit + integration, use VCR for external requests.
17+
-**Frontend**: Use Astro components in `frontend/src/`. Keep it simple.
18+
-**CSS**: Use frontend styles in `frontend/public/styles.css`. Water.css for fallback.
19+
-**Specs**: RSpec for Ruby, build tests for frontend.
1820

19-
## Dont
21+
## Don't
2022

21-
- ❌ Don’t depend on JS for core flows.
22-
- ❌ Don’t bypass SSRF filter or weaken CSP.
23-
- ❌ Don’t add databases, ORMs, or background jobs.
24-
- ❌ Don’t leak stack traces or secrets in responses.
23+
- ❌ Don't depend on JS for core flows.
24+
- ❌ Don't bypass SSRF filter or weaken CSP.
25+
- ❌ Don't add databases, ORMs, or background jobs.
26+
- ❌ Don't leak stack traces or secrets in responses.
27+
- ❌ Don't add complex frontend frameworks (React, Vue, etc.). Keep Astro simple.
28+
- ❌ Don't modify `frontend/dist/` - it's generated by build process.
2529

2630
## Project Structure
2731

2832
- `app.rb` – main Roda app
2933
- `app/` – core modules (config, cache, ssrf, health)
3034
- `routes/` – route handlers (`hash_branch`)
3135
- `helpers/` – pure helper modules (`module_function`)
32-
- `views/` – ERB templates
36+
- `views/` – ERB templates (fallback)
3337
- `public/` – static assets (CSS/JS, minimal)
38+
- `frontend/` – Astro frontend application
39+
- `src/pages/` – Astro pages (index.astro, gallery.astro)
40+
- `src/layouts/` – Astro layouts (Layout.astro)
41+
- `public/` – frontend static assets
42+
- `package.json` – Node.js dependencies
43+
- `astro.config.mjs` – Astro configuration
3444
- `config/feeds.yml` – feed definitions
3545
- `spec/` – RSpec tests + VCR cassettes
3646

.github/workflows/bundle-update.yml

Lines changed: 0 additions & 17 deletions
This file was deleted.

.github/workflows/frontend.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Frontend CI
2+
3+
on:
4+
push:
5+
paths:
6+
- "frontend/**"
7+
pull_request:
8+
paths:
9+
- "frontend/**"
10+
11+
jobs:
12+
frontend-lint:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v5
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: "20"
21+
cache: "npm"
22+
cache-dependency-path: frontend/package-lock.json
23+
24+
- name: Install dependencies
25+
run: |
26+
cd frontend
27+
npm ci
28+
29+
- name: Check code formatting
30+
run: |
31+
cd frontend
32+
npm run format:check
33+
34+
- name: Build frontend
35+
run: |
36+
cd frontend
37+
npm run build
38+
39+
- name: Verify build output
40+
run: |
41+
ls -la frontend/dist/
42+
test -f frontend/dist/index.html
43+
test -f frontend/dist/gallery/index.html
44+
test -f frontend/dist/styles.css
45+
46+
frontend-test:
47+
runs-on: ubuntu-latest
48+
steps:
49+
- uses: actions/checkout@v5
50+
51+
- name: Setup Node.js
52+
uses: actions/setup-node@v4
53+
with:
54+
node-version: "20"
55+
cache: "npm"
56+
cache-dependency-path: frontend/package-lock.json
57+
58+
- name: Install dependencies
59+
run: |
60+
cd frontend
61+
npm ci
62+
63+
- name: Check for vulnerabilities
64+
run: |
65+
cd frontend
66+
npm audit --audit-level=moderate
67+
68+
- name: Build and verify
69+
run: |
70+
cd frontend
71+
npm run build
72+
# Verify the built HTML is valid
73+
grep -q "html2rss-web" dist/index.html
74+
grep -q "Feed Gallery" dist/gallery/index.html

.github/workflows/test_build_push.yml

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,34 @@ jobs:
2121
- run: bundle exec rubocop -F
2222
- run: bundle exec yard doc --fail-on-warning --no-output
2323

24+
frontend:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v5
28+
29+
- name: Setup Node.js
30+
uses: actions/setup-node@v4
31+
with:
32+
node-version: "20"
33+
cache: "npm"
34+
cache-dependency-path: frontend/package-lock.json
35+
36+
- name: Install frontend dependencies
37+
run: |
38+
cd frontend
39+
npm ci
40+
41+
- name: Build frontend
42+
run: |
43+
cd frontend
44+
npm run build
45+
46+
- name: Verify build output
47+
run: |
48+
ls -la frontend/dist/
49+
test -f frontend/dist/index.html
50+
test -f frontend/dist/gallery/index.html
51+
2452
rspec:
2553
runs-on: ubuntu-latest
2654
steps:
@@ -33,13 +61,27 @@ jobs:
3361
- run: bundle exec rspec
3462

3563
docker-test:
36-
needs: hadolint
64+
needs: [hadolint, frontend]
3765
runs-on: ubuntu-latest
3866
steps:
3967
- uses: actions/checkout@v5
4068
- uses: ruby/setup-ruby@v1
4169
with:
4270
bundler-cache: true
71+
- name: Setup Node.js for Docker build
72+
uses: actions/setup-node@v4
73+
with:
74+
node-version: "20"
75+
cache: "npm"
76+
cache-dependency-path: frontend/package-lock.json
77+
- name: Install frontend dependencies
78+
run: |
79+
cd frontend
80+
npm ci
81+
- name: Build frontend
82+
run: |
83+
cd frontend
84+
npm run build
4385
- run: |
4486
bundle exec rake
4587
@@ -49,6 +91,7 @@ jobs:
4991
- docker-test
5092
- hadolint
5193
- ruby
94+
- frontend
5295
runs-on: ubuntu-latest
5396
permissions:
5497
contents: read
@@ -60,6 +103,23 @@ jobs:
60103
- name: Checkout code
61104
uses: actions/checkout@v5
62105

106+
- name: Setup Node.js for Docker build
107+
uses: actions/setup-node@v4
108+
with:
109+
node-version: "20"
110+
cache: "npm"
111+
cache-dependency-path: frontend/package-lock.json
112+
113+
- name: Install frontend dependencies
114+
run: |
115+
cd frontend
116+
npm ci
117+
118+
- name: Build frontend
119+
run: |
120+
cd frontend
121+
npm run build
122+
63123
- name: Set up QEMU
64124
uses: docker/setup-qemu-action@v3
65125

0 commit comments

Comments
 (0)