Skip to content

Refactor code structure for improved readability and maintainability #32

Refactor code structure for improved readability and maintainability

Refactor code structure for improved readability and maintainability #32

Workflow file for this run

name: Build, Test & Deploy to IONOS
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
build-test-deploy:
runs-on: ubuntu-latest
steps:
- name: 📥 Checkout Repository
uses: actions/checkout@v4
- name: 🔧 Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: 📦 Install Dependencies
run: npm ci
- name: 🧪 Run Tests with Coverage
run: npm test -- --no-watch --code-coverage --browsers=ChromeHeadless
- name: 📊 Generate Coverage Badge
run: |
COVERAGE=$(grep -oP 'Lines\s*:\s*\K[\d.]+' coverage/portfolio/index.html | head -1 || echo "0")
echo "Coverage: $COVERAGE%"
echo "COVERAGE=$COVERAGE" >> $GITHUB_ENV
- name: 📚 Generate TypeDoc Documentation
run: npm run docs
continue-on-error: true
- name: 🏗️ Build Production
run: npm run build -- --configuration production
- name: 📁 Prepare Deployment Structure
run: |
mkdir -p deploy
cp -r dist/portfolio/browser/* deploy/
cp -r coverage/portfolio deploy/coverage
cp -r docs deploy/jsdoc
# Create simple .htaccess for deployment
cat > deploy/.htaccess << 'EOF'
RewriteEngine On
RewriteBase /portfolio/
DirectoryIndex index.html
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# API Routes Protection - Don't redirect to index.html
RewriteCond %{REQUEST_URI} ^/portfolio/api/
RewriteRule . - [L]
# Angular SPA Routing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/portfolio/api/
RewriteRule . index.html [L]
# ------------------------------------------------------
# 🚀 Cache Static Assets
# ------------------------------------------------------
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType application/json "access plus 0 seconds"
</IfModule>
# ------------------------------------------------------
# 🔐 Security Headers
# ------------------------------------------------------
<IfModule mod_headers.c>
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header unset Server
</IfModule>
EOF
- name: 📤 Deploy to IONOS via SFTP
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: Dylan700/sftp-upload-action@v1.1.4
with:
server: ${{ secrets.FTP_HOST }}
username: ${{ secrets.FTP_USERNAME }}
password: ${{ secrets.FTP_PASSWORD }}
port: 22
uploads: |
./deploy/ => ./portfolio/
delete: false
- name: ✅ Deployment Complete
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
echo "🎉 Deployment successful!"
echo "🌐 App: https://portfolio.dev2k.org"
echo "📊 Coverage: https://portfolio.dev2k.org/coverage/index.html"
echo "📚 Docs: https://portfolio.dev2k.org/jsdoc/index.html"
- name: 💬 Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
// COVERAGE is set in the "Run Tests & Coverage" step via GITHUB_ENV
const coverage = '${{ env.COVERAGE }}' || 'N/A';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## ✅ Build & Test Successful\n\n- 🧪 Tests: Passed\n- 📊 Coverage: ${coverage}%\n\nReady to merge!`
})