Compare commits

...

13 Commits

18 changed files with 2397 additions and 15 deletions

4
.env.dist Normal file
View File

@@ -0,0 +1,4 @@
NODE_VERSION=24
CADDY_VERSION=2.10.2
LHCI_VERSION=0.15.x
ZENIKA_VERSION=124-with-node

7
.gitignore vendored
View File

@@ -5,6 +5,7 @@ dist/
# dependencies
node_modules/
.pnpm-store/
# logs
npm-debug.log*
@@ -22,3 +23,9 @@ pnpm-debug.log*
# jetbrains setting folder
.idea/
# vscode
.vscode/
# Lighthouse CI reports
.lighthouseci/

1
.husky/commit-msg Normal file
View File

@@ -0,0 +1 @@
pnpm exec commitlint --edit "$1"

2
.husky/pre-commit Normal file
View File

@@ -0,0 +1,2 @@
pnpm run lint
pnpm run check

24
.lighthouserc.cjs Normal file
View File

@@ -0,0 +1,24 @@
module.exports = {
ci: {
collect: {
staticDistDir: '/app/dist',
settings: {
chromeFlags: '--no-sandbox --disable-setuid-sandbox --headless=new --disable-gpu --disable-dev-shm-usage',
targets: ['filesystem'],
},
numberOfRuns: 1
},
assert: {
assertions: {
'categories:performance': ['error', {minScore: 0.9}],
'categories:accessibility': ['error', {minScore: 0.9}],
'categories:best-practices': ['error', {minScore: 0.9}],
'categories:seo': ['error', {minScore: 0.9}],
},
},
upload: {
target: 'filesystem',
outputDir: './.lighthouseci', // C'est ici que Jenkins ira chercher les fichiers
},
},
};

9
Caddyfile Normal file
View File

@@ -0,0 +1,9 @@
:80 {
root * /usr/share/caddy
file_server
# Client cache
header {
Cache-Control "public, max-age=86400"
}
}

34
Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
ARG NODE_VERSION
ARG CADDY_VERSION
# --- BUILD ---
FROM node:${NODE_VERSION}-alpine AS build
RUN corepack enable && corepack prepare pnpm@latest --activate
ENV ASTRO_TELEMETRY_DISABLED=1
WORKDIR /app
# Copy depedencies
COPY package.json pnpm-lock.yaml ./
# Install pnpm with cache
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
PNPM_HOME="/pnpm" pnpm install --frozen-lockfile
# Copy all
COPY . .
# Check files
RUN pnpm run lint
RUN pnpm run check
# Build
RUN pnpm build
# --- DEPLOY ---
FROM caddy:${CADDY_VERSION}-alpine
COPY --from=build /app/dist /usr/share/caddy
COPY Caddyfile /etc/caddy/Caddyfile
EXPOSE 80

83
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,83 @@
pipeline {
agent any
environment {
DOCKER_HOST = "unix:///var/run/docker.sock"
APP_VERSION = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
}
stages {
stage('Build') {
steps {
// Get Caddy version
sh "cp .env.dist .env"
// Push portfolio version
sh "echo '\nPORTFOLIO_VERSION=${env.APP_VERSION}' >> .env"
echo "Building new portfolio version..."
sh "docker compose build"
}
}
stage('Lighthouse Audit') {
steps {
// Create volumes but no run with safety
sh "docker rm -f audit-tmp lighthouse-audit || true"
sh "docker compose --profile audit create --no-build --remove-orphans lighthouse-audit"
// Extract astro data from temp container to tmp-dist folder
sh "docker create --name audit-tmp portfolio:${env.APP_VERSION}"
sh "mkdir -p ./tmp-dist"
sh "docker cp audit-tmp:/usr/share/caddy/. ./tmp-dist"
sh "docker rm -f audit-tmp"
// Inject data from tmp-dist and config to audit container
sh "docker cp ./tmp-dist/. lighthouse-audit:/app/dist/"
sh "docker cp .lighthouserc.cjs lighthouse-audit:/app/dist/audit-config.cjs"
sh "rm -rf ./tmp-dist"
// Now run
sh "docker start -a lighthouse-audit"
// Get reports
sh "mkdir -p ./.lighthouseci"
sh "docker cp lighthouse-audit:/app/.lighthouseci/. ./.lighthouseci/"
// Clean
sh "docker rm -f lighthouse-audit"
}
}
stage('Deploy') {
// Deploy only master branch
when {
branch 'master'
}
steps {
echo "Deploy new portfolio version..."
sh "docker compose up -d"
// Update caddy-reverse-proxy cache
sh "docker exec caddy-reverse-proxy caddy reload --config /etc/caddy/Caddyfile"
// Keep updated docker-compose.yml and Caddyfile for safety
sh "cp docker-compose.yml /backup-portfolio/docker-compose.yml"
sh "docker cp portfolio:/etc/caddy/Caddyfile /backup-portfolio/Caddyfile"
}
}
}
post {
always {
echo "Publish Lighthouse audit..."
publishHTML([
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: false,
reportDir: '.lighthouseci',
reportFiles: '*.html',
reportName: 'Lighthouse Report'
])
echo "Clean unused image"
sh "docker image prune -f"
}
success { echo "Success !" }
failure { echo "Failed." }
}
}

1
commitlint.config.js Normal file
View File

@@ -0,0 +1 @@
export default { extends: ['@commitlint/config-conventional'] };

36
docker-compose.yml Normal file
View File

@@ -0,0 +1,36 @@
services:
portfolio:
build:
context: .
args:
- NODE_VERSION=${NODE_VERSION}
- CADDY_VERSION=${CADDY_VERSION}
image: portfolio:${PORTFOLIO_VERSION}
container_name: portfolio
restart: always
networks:
- reverse-proxy
lighthouse-audit:
profiles:
- audit
image: zenika/alpine-chrome:${ZENIKA_VERSION}
container_name: lighthouse-audit
user: "0:0"
volumes:
- audit_dist:/app/dist
- audit_reports:/app/.lighthouseci
- npm_cache:/root/.npm
environment:
- CHROME_PATH=/usr/bin/chromium-browser
working_dir: /app
command: npx --prefer-offline @lhci/cli@${LHCI_VERSION} autorun --config=/app/dist/audit-config.cjs
volumes:
audit_dist:
audit_reports:
npm_cache:
networks:
reverse-proxy:
external: true

24
eslint.config.mjs Normal file
View File

@@ -0,0 +1,24 @@
import eslintPluginAstro from 'eslint-plugin-astro';
import tsParser from '@typescript-eslint/parser';
export default [
// Configuration pour les fichiers Astro
...eslintPluginAstro.configs.recommended,
{
files: ["**/*.astro"],
languageOptions: {
parser: eslintPluginAstro.parser,
parserOptions: {
parser: tsParser,
extraFileExtensions: [".astro"],
},
},
rules: {
// Tes règles personnalisées ici
},
},
// On ignore le dossier de build
{
ignores: ["dist/*", ".astro/*"]
}
];

28
local-lighthouse.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
# Clean old audits and containers
rm -rf ./.lighthouseci
docker rm -f lighthouse-audit || true
# Load env file and avoid warning for unused portofolio version
if [ -f .env.dist ]; then
export $(grep -v '^#' .env.dist | xargs)
fi
export PORTFOLIO_VERSION="local-audit"
# Create container but no start
docker compose --profile audit create --no-build --remove-orphans lighthouse-audit
# Inject data and config to container
docker cp ./dist/. lighthouse-audit:/app/dist/
docker cp .lighthouserc.cjs lighthouse-audit:/app/dist/audit-config.cjs
# Now run
docker start -a lighthouse-audit
# Get reports
mkdir -p ./.lighthouseci
docker cp lighthouse-audit:/app/.lighthouseci/. ./.lighthouseci/
# Clean container
docker rm -f lighthouse-audit

View File

@@ -6,13 +6,34 @@
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
"astro": "astro",
"lint": "eslint .",
"check": "astro check",
"prepare": "husky"
},
"dependencies": {
"@astrojs/check": "^0.9.6",
"@astrojs/mdx": "^4.3.13",
"@astrojs/rss": "^4.0.14",
"@astrojs/sitemap": "^3.6.0",
"astro": "^5.16.6",
"sharp": "^0.34.3"
},
"devDependencies": {
"@commitlint/cli": "^20.3.1",
"@commitlint/config-conventional": "^20.3.1",
"@typescript-eslint/eslint-plugin": "^8.52.0",
"@typescript-eslint/parser": "^8.52.0",
"astro-eslint-parser": "^1.2.2",
"eslint": "^9.39.2",
"eslint-plugin-astro": "^1.5.0",
"husky": "^9.1.7",
"typescript": "^5.9.3"
},
"pnpm": {
"onlyBuiltDependencies": [
"esbuild",
"sharp"
]
}
}
}

2126
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

3
pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,3 @@
ignoredBuiltDependencies:
- esbuild
- sharp

View File

@@ -3,7 +3,7 @@ const today = new Date();
---
<footer>
&copy; {today.getFullYear()} Your name here. All rights reserved.
&copy; {today.getFullYear()} Lucas Royer. All rights reserved.
<div class="social-links">
<a href="https://m.webtoo.ls/@astro" target="_blank">
<span class="sr-only">Follow Astro on Mastodon</span>

View File

@@ -13,7 +13,7 @@ import { SITE_DESCRIPTION, SITE_TITLE } from '../consts';
<body>
<Header />
<main>
<h1>🧑‍🚀 Hello, Astronaut!</h1>
<h1>🧑‍🚀 Welcome, there !</h1>
<p>
Welcome to the official <a href="https://astro.build/">Astro</a> blog starter template. This template
serves as a lightweight, minimally-styled starting point for anyone looking to build a personal

View File

@@ -1,6 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"],
"compilerOptions": {
"strictNullChecks": true