Skip to content

Leac1m/web-hosting-platform

Repository files navigation

System Overview

A platform that enables programmatic deployment of GitHub repositories to hosted environments through GitHub App authentication and workflow automation.

Architecture Diagram

graph TB
    subgraph "GitHub"
        Repos["Repositories"]
        Actions["GitHub Actions"]
        Pages["GitHub Pages"]
    end

    subgraph "Platform"
        API["Express API"]
        Auth["GitHub App Auth"]
        Routes["Routes"]
        Services["Services"]
    end

    subgraph "Storage"
        Deploys["deployments/"]
        Workflows["workflows/"]
    end

    User["User"] --> API
    API --> Auth
    Auth --> Repos
    API --> Services
    Services --> Deploys
    Services --> Actions
    Actions --> Pages
Loading

Component Breakdown

Backend (server/)

server/
├── server.js              # Express app entry
├── routes/
│   ├── deployRoutes.js     # Deployment endpoints
│   ├── authRoutes.js       # Auth endpoints
│   └── githubRoutes.js     # GitHub API proxy
├── controllers/
│   └── githubController.js # Webhook handler
├── services/
│   ├── githubAppAuth.js    # GitHub App JWT flow
│   ├── githubRepoService.js
│   ├── githubPagesService.js
│   ├── workflowInjectionService.js
│   ├── deploymentManager.js
│   ├── buildService.js
│   └── pathValidator.js
├── tests/                  # Test suite
└── package.json

Frontend (frontend/)

frontend/
├── src/
│   ├── pages/
│   ├── components/
│   └── lib/
├── vite.config.js
└── package.json

Tech Stack

Component Technology
Backend Express.js (Node.js)
Frontend React + Vite
Auth GitHub App JWT
Storage Local filesystem
Deployment GitHub Actions API

GitHub App Authentication Flow

sequenceDiagram
    participant P as Platform
    participant G as GitHub API

    Note over P: App Installation

    P->>G: POST /app/jwt<br/>(Generate JWT)
    G-->>P: JWT Token

    P->>G: POST /app/installations/:id/access_tokens
    G-->>P: Installation Token

    Note over P: Per-Request

    P->>G: Authorization: Bearer <installation_token>
    G-->>P: API Response
Loading

Deployment Flow

Standard Deployment

sequenceDiagram
    participant U as User
    participant API as Platform API
    participant GH as GitHub API
    participant Actions as GitHub Actions
    participant Pages as GitHub Pages

    U->>API: POST /deploy<br/>{ repo, branch }
    API->>GH: Dispatch workflow
    GH->>Actions: Run deploy.yml
    Actions->>Actions: Build & create tar.gz
    Actions->>API: POST /deploy/upload<br/>tar.gz artifact
    API->>API: Extract to deployments/{owner-repo}/
    API-->>U: { hostingUrl: "/sites/owner-repo/" }

    U->>API: GET /sites/owner-repo/
    API-->>U: index.html
Loading

GitHub Pages Deployment

sequenceDiagram
    participant U as User
    participant API as Platform API
    participant GH as GitHub API
    participant Pages as GitHub Pages

    U->>API: POST /deploy<br/>{ repo, hostingTarget: github-pages }
    API->>GH: Create/Update workflow
    GH->>Pages: Deploy from workflow
    Pages-->>GH: Published URL
    API->>API: Cache Pages status
    API-->>U: { providerUrl, hostingUrl }
Loading

API Endpoints

Deployments

Endpoint Method Description
/deploy POST Trigger new deployment
/deploy/upload POST Upload build artifacts
/deploy/pages-status/:project GET Check GitHub Pages status
/deploy/pages-config/:project GET Get Pages configuration
/deploy/workflows/sync POST Sync workflow files

Authentication

Endpoint Method Description
/auth/login POST Initiate GitHub App auth
/auth/callback GET OAuth callback

GitHub Integration

Endpoint Method Description
/api/github/repos GET List installed repos
/webhooks/github POST GitHub webhook events

Deployment Storage Structure

Simple Mode

deployments/
└── owner-repo/
    ├── index.html
    ├── css/
    ├── js/
    └── assets/

Versioned Mode

deployments/
└── owner-repo/
    ├── current -> releases/v1-abc123/
    └── releases/
        ├── v1-abc123/
        ├── v2-def456/
        └── v3-ghi789/

Security

Path Traversal Prevention

const isSafeProjectName = (projectName) => /^[A-Za-z0-9._-]+$/.test(projectName)

const normalizedPath = path.normalize(relativePath)
if (normalizedPath.startsWith('..') || path.isAbsolute(normalizedPath)) {
  return res.status(404).send('Not Found')
}

GitHub Webhook Verification

const signature = crypto.createHmac('sha256', GITHUB_WEBHOOK_SECRET)
const isValid = crypto.timingSafeEqual(
  Buffer.from(signature),
  Buffer.from(expectedSignature)
)

Workflow Injection

Managed workflow files are injected with markers:

# Managed by Web Hosting Platform
# Template-Version: 1
name: Deploy

on:
  workflow_dispatch:
    inputs:
      # ...config

The service detects managed files by the # Managed by Web Hosting Platform marker and refuses to overwrite unmanaged files unless force=true.

Environment Variables

Variable Required Description
GITHUB_APP_ID Yes GitHub App ID
GITHUB_APP_PRIVATE_KEY_PATH Yes* Path to private key PEM
GITHUB_APP_PRIVATE_KEY_BASE64 Yes* Base64-encoded PEM
DEPLOY_SECRET Yes Bearer token for upload auth
ENABLE_GITHUB_PAGES No Enable Pages feature
ENABLE_WORKFLOW_INJECTION No Enable workflow sync
FRONTEND_URL No CORS origin (dev)

Testing

Test coverage includes:

  • buildService.test.js
  • cleanupTmp.test.js
  • deployFlow.smoke.test.js
  • deploymentManager.test.js
  • githubController.test.js
  • githubPagesService.test.js
  • githubRepoService.test.js
  • pathValidator.test.js
  • server.test.js
  • workflowInjectionService.test.js

About

Deploy GitHub repositories to hosted environments with one API call. Features: GitHub App auth, workflow automation, zero-downtime deploys.

Topics

Resources

Stars

Watchers

Forks

Contributors