Skip to content

Commit 7dc6813

Browse files
authored
Merge pull request #12 from martian56/11-add-cicd-for-frontend
[FEAT] Add cicd for frontend
2 parents 672285b + 738ad34 commit 7dc6813

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: Frontend - Build & Deploy
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
env:
13+
VITE_API_URL: ${{ secrets.VITE_API_URL }}
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Use Node.js 24
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: '24.3.0'
22+
cache: 'npm'
23+
cache-dependency-path: 'web/package-lock.json'
24+
25+
- name: Install dependencies
26+
run: npm --prefix web ci --legacy-peer-deps
27+
28+
- name: Build (TS compile + Vite build)
29+
run: npm --prefix web run build
30+
31+
# Uncomment this if you want linting enabled
32+
# - name: Lint
33+
# run: npm --prefix web run lint
34+
35+
deploy:
36+
runs-on: ubuntu-latest
37+
needs: build-and-test
38+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
39+
env:
40+
VITE_API_URL: ${{ secrets.VITE_API_URL }}
41+
steps:
42+
- name: Checkout repository
43+
uses: actions/checkout@v4
44+
45+
- name: Use Node.js 24
46+
uses: actions/setup-node@v4
47+
with:
48+
node-version: '24.3.0'
49+
cache: 'npm'
50+
cache-dependency-path: 'web/package-lock.json'
51+
52+
- name: Install dependencies
53+
run: npm --prefix web ci --legacy-peer-deps
54+
55+
- name: Build (TS compile + Vite build)
56+
run: npm --prefix web run build
57+
58+
- name: Setup Python for upload step
59+
uses: actions/setup-python@v4
60+
with:
61+
python-version: '3.12.5'
62+
63+
- name: Install upload dependencies
64+
run: |
65+
python -m pip install --upgrade pip
66+
pip install requests
67+
68+
- name: Upload `dist` to hosting service
69+
env:
70+
UFAZIEN_HOSTING_BASE_URL: ${{ secrets.UFAZIEN_HOSTING_BASE_URL }}
71+
UFAZIEN_HOSTING_EMAIL: ${{ secrets.UFAZIEN_HOSTING_EMAIL }}
72+
UFAZIEN_HOSTING_PASSWORD: ${{ secrets.UFAZIEN_HOSTING_PASSWORD }}
73+
UFAZIEN_HOSTING_WEBSITE_ID: ${{ secrets.UFAZIEN_HOSTING_WEBSITE_ID }}
74+
shell: bash
75+
run: |
76+
set -euo pipefail
77+
cd web
78+
79+
if [ ! -d dist ]; then
80+
echo "❌ dist folder not found - nothing to upload"
81+
exit 1
82+
fi
83+
84+
echo "✅ dist folder found, starting upload..."
85+
86+
python3 <<'PYTHON_SCRIPT'
87+
import os, requests, glob
88+
89+
BASE = os.environ.get('UFAZIEN_HOSTING_BASE_URL')
90+
EMAIL = os.environ.get('UFAZIEN_HOSTING_EMAIL')
91+
PASSWORD = os.environ.get('UFAZIEN_HOSTING_PASSWORD')
92+
WEBSITE_ID = os.environ.get('UFAZIEN_HOSTING_WEBSITE_ID')
93+
94+
if not all([BASE, EMAIL, PASSWORD, WEBSITE_ID]):
95+
raise SystemExit('Missing one or more required environment variables.')
96+
97+
login_url = f"{BASE}/auth/login/"
98+
print('🔐 Logging in to hosting API...')
99+
resp = requests.post(login_url, json={'email': EMAIL, 'password': PASSWORD}, timeout=30)
100+
if resp.status_code not in (200, 201):
101+
print('❌ Login failed:', resp.status_code, resp.text)
102+
raise SystemExit('Login failed')
103+
104+
tokens = resp.json()
105+
access = tokens.get('access') or tokens.get('token')
106+
if not access:
107+
print('❌ No access token found in login response:', tokens)
108+
raise SystemExit('No access token')
109+
110+
headers = {'Authorization': f'Bearer {access}'}
111+
dist_root = 'dist'
112+
files_to_upload = []
113+
114+
for path in glob.glob(os.path.join(dist_root, '**'), recursive=True):
115+
if os.path.isfile(path):
116+
rel = os.path.relpath(path, dist_root)
117+
files_to_upload.append(('files', (rel, open(path, 'rb'))))
118+
119+
if not files_to_upload:
120+
print('⚠️ No files found in dist to upload.')
121+
raise SystemExit('No files')
122+
123+
upload_url = f"{BASE}/hosting/websites/{WEBSITE_ID}/upload_files/"
124+
print(f'📤 Uploading {len(files_to_upload)} files to {upload_url}...')
125+
126+
resp = requests.post(upload_url, files=files_to_upload, headers=headers, data={'website_id': WEBSITE_ID}, timeout=120)
127+
print('🧾 Upload response:', resp.status_code)
128+
print(resp.text)
129+
130+
if resp.status_code not in (200, 201):
131+
raise SystemExit('❌ Upload failed')
132+
133+
print('✅ Upload succeeded')
134+
PYTHON_SCRIPT

0 commit comments

Comments
 (0)