diff --git a/.woodpecker.yml b/.woodpecker.yml index 2ab8be6..efaf89d 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -9,6 +9,33 @@ clone: steps: # COMPONENT_STEPS_BELOW + + # Woodpecker CI step for landing Astro app + # Add this step to your .woodpecker.yml + + build-landing: + image: woodpeckerci/plugin-kaniko + settings: + registry: registry.threesix.ai + repo: tree-test-1770068050/landing + tags: + - latest + - ${CI_COMMIT_SHA:0:8} + context: . + dockerfile: apps/landing/Dockerfile + cache: true + skip-tls-verify: true + when: + branch: main + event: push + + deploy-landing: + image: bitnami/kubectl:latest + commands: + - kubectl set image deployment/tree-test-1770068050-landing landing=registry.threesix.ai/tree-test-1770068050/landing:${CI_COMMIT_SHA:0:8} -n projects || echo "Deployment not found, skipping" + when: + branch: main + event: push # Do not remove the marker above - component steps are inserted here verify: diff --git a/CLAUDE.md b/CLAUDE.md index 3fe1ebf..f165f2a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,4 +46,7 @@ tree-test-1770068050/ ## Components - +| Component | Type | Path | +|-----------|------|------| +| **landing** | Astro app | `apps/landing/` | + diff --git a/Procfile b/Procfile index 8e897c6..b7e314b 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,3 @@ # Local development processes # Components will be added below as they're created +landing: cd apps/landing && npm run dev diff --git a/apps/landing/.eslintrc.cjs b/apps/landing/.eslintrc.cjs new file mode 100644 index 0000000..99b08a3 --- /dev/null +++ b/apps/landing/.eslintrc.cjs @@ -0,0 +1,21 @@ +module.exports = { + root: true, + extends: [ + 'eslint:recommended', + 'plugin:astro/recommended', + ], + overrides: [ + { + files: ['*.astro'], + parser: 'astro-eslint-parser', + parserOptions: { + parser: '@typescript-eslint/parser', + extraFileExtensions: ['.astro'], + }, + }, + { + files: ['*.ts', '*.mts'], + parser: '@typescript-eslint/parser', + }, + ], +}; diff --git a/apps/landing/Dockerfile b/apps/landing/Dockerfile new file mode 100644 index 0000000..0f79e43 --- /dev/null +++ b/apps/landing/Dockerfile @@ -0,0 +1,34 @@ +# Build stage - using pnpm for workspace dependency resolution +FROM node:20-alpine AS build + +# Install pnpm +RUN npm install -g pnpm + +WORKDIR /workspace + +# Copy workspace configuration files +COPY pnpm-workspace.yaml package.json pnpm-lock.yaml* ./ + +# Copy shared packages (required for workspace:* dependencies) +COPY packages/ ./packages/ + +# Copy the app component +COPY apps/landing/ ./apps/landing/ + +# Install dependencies using pnpm (resolves workspace:* correctly) +RUN pnpm install --frozen-lockfile || pnpm install + +# Build the app +WORKDIR /workspace/apps/landing +RUN pnpm build + +# Production stage +FROM nginx:alpine + +# Copy built assets +COPY --from=build /workspace/apps/landing/dist /usr/share/nginx/html +COPY apps/landing/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 3001 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/apps/landing/astro.config.mjs b/apps/landing/astro.config.mjs new file mode 100644 index 0000000..b06644c --- /dev/null +++ b/apps/landing/astro.config.mjs @@ -0,0 +1,10 @@ +import { defineConfig } from 'astro/config'; +import tailwind from '@astrojs/tailwind'; + +export default defineConfig({ + integrations: [tailwind()], + output: 'static', + server: { + port: 3001, + }, +}); diff --git a/apps/landing/component.yaml b/apps/landing/component.yaml new file mode 100644 index 0000000..3c26fa6 --- /dev/null +++ b/apps/landing/component.yaml @@ -0,0 +1,6 @@ +name: landing +type: app +port: 3001 +path: apps/landing +stack: astro +dependencies: [] diff --git a/apps/landing/nginx.conf b/apps/landing/nginx.conf new file mode 100644 index 0000000..1e23deb --- /dev/null +++ b/apps/landing/nginx.conf @@ -0,0 +1,26 @@ +server { + listen 3001; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + # Gzip compression + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml; + + # Cache static assets + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # SPA fallback + location / { + try_files $uri $uri/ /index.html; + } + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; +} diff --git a/apps/landing/package.json b/apps/landing/package.json new file mode 100644 index 0000000..ea0cfff --- /dev/null +++ b/apps/landing/package.json @@ -0,0 +1,27 @@ +{ + "name": "landing", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev --port 3001", + "start": "astro dev --port 3001", + "build": "astro build", + "preview": "astro preview --port 3001", + "lint": "eslint . --ext .js,.mjs,.ts,.astro", + "format": "prettier --write ." + }, + "dependencies": { + "@tree-test-1770068050/logger": "workspace:*", + "astro": "^4.0.0" + }, + "devDependencies": { + "@astrojs/tailwind": "^5.0.0", + "@typescript-eslint/parser": "^7.13.1", + "astro-eslint-parser": "^0.16.0", + "eslint": "^8.57.0", + "eslint-plugin-astro": "^0.34.0", + "prettier": "^3.2.0", + "prettier-plugin-astro": "^0.13.0", + "tailwindcss": "^3.4.0" + } +} diff --git a/apps/landing/public/favicon.svg b/apps/landing/public/favicon.svg new file mode 100644 index 0000000..5b8757b --- /dev/null +++ b/apps/landing/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/landing/src/layouts/Layout.astro b/apps/landing/src/layouts/Layout.astro new file mode 100644 index 0000000..526794e --- /dev/null +++ b/apps/landing/src/layouts/Layout.astro @@ -0,0 +1,25 @@ +--- +interface Props { + title: string; + description?: string; +} + +const { title, description = 'tree-test-1770068050 - landing' } = Astro.props; +--- + + + + + + + + + {title} + + + + + + diff --git a/apps/landing/src/lib/logger.ts b/apps/landing/src/lib/logger.ts new file mode 100644 index 0000000..73f19e5 --- /dev/null +++ b/apps/landing/src/lib/logger.ts @@ -0,0 +1,13 @@ +import { createLogger, installGlobalHandlers } from '@tree-test-1770068050/logger'; + +export const logger = createLogger({ + level: import.meta.env.DEV ? 'debug' : 'info', + service: 'landing', + // Set endpoint to send logs to your backend: + // endpoint: '/api/logs', +}); + +// Install global error handlers (client-side only) +if (typeof window !== 'undefined') { + installGlobalHandlers(logger); +} diff --git a/apps/landing/src/pages/index.astro b/apps/landing/src/pages/index.astro new file mode 100644 index 0000000..5357809 --- /dev/null +++ b/apps/landing/src/pages/index.astro @@ -0,0 +1,37 @@ +--- +import Layout from '../layouts/Layout.astro'; +--- + + +
+
+
+

+ landing +

+

+ Welcome to your Astro app. This is part of the + tree-test-1770068050 monorepo. +

+

+ Edit this file at + apps/landing/src/pages/index.astro +

+ +
+
+
+
diff --git a/apps/landing/tailwind.config.mjs b/apps/landing/tailwind.config.mjs new file mode 100644 index 0000000..83cac5e --- /dev/null +++ b/apps/landing/tailwind.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], + theme: { + extend: {}, + }, + plugins: [], +};