Skip to content

Commit 22f0ec8

Browse files
Merge pull request #23 from recursivezero/main
Release: add deploy workflow
2 parents a149acd + e9c15bb commit 22f0ec8

File tree

5 files changed

+47
-22
lines changed

5 files changed

+47
-22
lines changed

.github/workflows/deploy.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Deploy App
2+
run-name: Deploy Tiny App to Cloud Server
3+
4+
on:
5+
push:
6+
branches: [release]
7+
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
environment: production
12+
steps:
13+
- name: Deploy via SSH
14+
uses: appleboy/ssh-action@master
15+
with:
16+
host: ${{ secrets.HOST }}
17+
username: ${{ secrets.USERNAME }}
18+
key: ${{ secrets.SSH_PRIVATE_KEY }}
19+
script: |
20+
cd /opt/tz_apps/tiny
21+
# Fetch latest code
22+
git pull origin release
23+
24+
# Install dependencies (Production mode, no dev deps)
25+
/root/.local/bin/poetry install --only main --sync
26+
27+
# Restart the service
28+
sudo systemctl restart tiny.service
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
appleboy
12
projectx
3+
RZRO
24
xkeshav

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ All notable changes to this repository will be documented in this file.
1111

1212
- Restructure folder structure
1313
- added poetry dev script
14+
15+
## [1.0.0] Sun, Feb 15, 2026
16+
17+
- Added In-Memory cache strategy
18+
- DB dependency optional
19+
- Change UI

app/main.py

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pathlib import Path
33
from typing import Optional
44

5-
from fastapi import FastAPI, Form, Request
5+
from fastapi import FastAPI, Form, Request, status
66
from fastapi.responses import HTMLResponse, PlainTextResponse, RedirectResponse
77
from fastapi.staticfiles import StaticFiles
88
from fastapi.templating import Jinja2Templates
@@ -28,7 +28,6 @@
2828
from app.utils.qr import generate_qr_with_logo
2929

3030

31-
3231
# -----------------------------
3332
# Lifespan: env + DB connect ONCE
3433
# -----------------------------
@@ -103,37 +102,27 @@ async def create_short_url(
103102
original_url: str = Form(""),
104103
generate_qr: Optional[str] = Form(None),
105104
qr_type: str = Form("short"),
106-
):
105+
) -> RedirectResponse:
107106
session = request.session
108107
qr_enabled = bool(generate_qr)
109108
original_url = sanitize_url(original_url)
110109

111-
if not original_url:
112-
session["error"] = "URL cannot be empty."
113-
return RedirectResponse("/", status_code=303)
114-
115-
if not is_valid_url(original_url):
116-
session["error"] = (
117-
"Please enter a valid URL (must start with http:// or https://)."
118-
)
119-
return RedirectResponse("/", status_code=303)
110+
# Basic validation (FastAPI can also handle this via Pydantic)
111+
if not original_url or not is_valid_url(original_url):
112+
session["error"] = "Please enter a valid URL."
113+
return RedirectResponse("/", status_code=status.HTTP_303_SEE_OTHER)
120114

121115
# 1. Try Cache First
122116
short_code: Optional[str] = get_short_from_cache(original_url)
123117

124-
if short_code:
125-
session["info_message"] = "Already shortened before — fetched from cache."
126-
else:
118+
if not short_code:
127119
# 2. Try Database
128120
existing = db_data.find_by_original_url(original_url)
129121
# Pull the value and check it in one go
130122
db_code = existing.get("short_code") if existing else None
131123
if isinstance(db_code, str):
132124
short_code = db_code
133-
set_cache_pair(short_code, original_url) # Cache it for future
134-
session["info_message"] = (
135-
"Already shortened before — fetched from database."
136-
)
125+
set_cache_pair(short_code, original_url) # Cache it for future requests
137126

138127
# 3. Generate New if still None
139128
if not short_code:
@@ -147,7 +136,7 @@ async def create_short_url(
147136
if not isinstance(short_code, str):
148137
# This acts as a final safety net for production
149138
session["error"] = "Internal server error: Code generation failed."
150-
return RedirectResponse("/", status_code=303)
139+
return RedirectResponse("/", status_code=status.HTTP_303_SEE_OTHER)
151140

152141
# Mypy now knows short_code is strictly 'str'
153142
new_short_url = build_short_url(short_code, DOMAIN)
@@ -162,7 +151,7 @@ async def create_short_url(
162151
}
163152
)
164153

165-
return RedirectResponse("/", status_code=303)
154+
return RedirectResponse("/", status_code=status.HTTP_303_SEE_OTHER)
166155

167156

168157
@app.get("/recent", response_class=HTMLResponse)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "tiny"
3-
version = "1.0.1"
3+
version = "1.0.2"
44
description = "A package for URL Shortener with QR Code generation"
55
authors = [
66
{ name = "recursivezero", email = "152776938+recursivezero@users.noreply.github.com" },

0 commit comments

Comments
 (0)