mirror of
https://github.com/bartvdbraak/hellob.art.git
synced 2025-04-26 17:11:21 +00:00
Merge a55a0a5596
into 16221dec61
This commit is contained in:
commit
e22574a90a
19 changed files with 814 additions and 1279 deletions
11
.dockerignore
Normal file
11
.dockerignore
Normal file
|
@ -0,0 +1,11 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
dist
|
||||
build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
170
.github/workflows/unlighthouse.yaml
vendored
170
.github/workflows/unlighthouse.yaml
vendored
|
@ -1,170 +0,0 @@
|
|||
name: Unlighthouse
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
unlighthouse:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
COMMENT_ID: unlighthouse-node${{matrix.node-version}}
|
||||
PORT: 8000
|
||||
CLOUDFLARE_PROJECT: hellobart-unlighthouse
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20]
|
||||
steps:
|
||||
- name: Create initial comment
|
||||
uses: marocchino/sticky-pull-request-comment@v2.9.0
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
header: ${{ env.COMMENT_ID }}
|
||||
message: |
|
||||
⚡️ Lighthouse report
|
||||
|
||||

|
||||
|
||||
- name: Set variables based on trigger
|
||||
run: |
|
||||
if [[ ${{ github.ref == 'refs/heads/main' }} == true ]]; then
|
||||
echo "CLOUDFLARE_BRANCH=main" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_URL=https://${{ env.CLOUDFLARE_PROJECT }}.pages.dev" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CLOUDFLARE_BRANCH=pull-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_URL=https://pull-${{ github.event.pull_request.number }}.${{ env.CLOUDFLARE_PROJECT }}.pages.dev" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4.1.7
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4.0.0
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.0.2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Retrieve Vercel Preview URL
|
||||
uses: zentered/vercel-preview-url@v1.3.0
|
||||
id: vercel_preview_url
|
||||
env:
|
||||
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
|
||||
with:
|
||||
vercel_project_id: ${{ vars.VERCEL_PROJECT_ID }}
|
||||
|
||||
- name: Await Vercel Deployment
|
||||
uses: UnlyEd/github-action-await-vercel@v2.0.0
|
||||
env:
|
||||
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
|
||||
with:
|
||||
deployment-url: ${{ steps.vercel_preview_url.outputs.preview_url }}
|
||||
timeout: 360
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install -g @unlighthouse/cli puppeteer
|
||||
|
||||
- name: Run Unlighthouse
|
||||
run: |
|
||||
unlighthouse-ci \
|
||||
--site "${{ github.ref == 'refs/heads/main' && 'https://hellob.art' || steps.vercel_preview_url.outputs.preview_url }}" \
|
||||
--reporter jsonExpanded \
|
||||
--build-static
|
||||
|
||||
- name: Upload report to Cloudflare pages
|
||||
uses: cloudflare/wrangler-action@v3.7.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
command: pages deploy .unlighthouse --project-name="${{ env.CLOUDFLARE_PROJECT }}" --branch=${{ env.CLOUDFLARE_BRANCH }}
|
||||
|
||||
- name: Create result content
|
||||
id: create_result_content
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
const result = JSON.parse(fs.readFileSync('.unlighthouse/ci-result.json', 'utf8'));
|
||||
|
||||
const formatScore = score => `${Math.round(score * 100)} (${score})`;
|
||||
const getEmoji = score => score >= 0.9 ? '🟢' : score >= 0.5 ? '🟠' : '🔴';
|
||||
const getColor = score => score >= 0.9 ? '4c1' : score >= 0.5 ? 'ffa400' : 'eb0f00';
|
||||
|
||||
const score = res => `${getEmoji(res)} ${formatScore(res)}`;
|
||||
|
||||
const reportUrl = `${{ env.CLOUDFLARE_URL }}`;
|
||||
|
||||
const comment = [
|
||||
`⚡️ Lighthouse report for the changes in this PR:`,
|
||||
'| Category | Score |',
|
||||
'| --- | --- |',
|
||||
`| Performance | ${score(result.summary.categories.performance.averageScore)} |`,
|
||||
`| Accessibility | ${score(result.summary.categories.accessibility.averageScore)} |`,
|
||||
`| Best practices | ${score(result.summary.categories['best-practices'].averageScore)} |`,
|
||||
`| SEO | ${score(result.summary.categories.seo.averageScore)} |`,
|
||||
`| *Overall* | ${score(result.summary.score)} |`,
|
||||
'',
|
||||
'*Lighthouse scores for individual routes:*',
|
||||
'',
|
||||
'| Path | Performance | Accessibility | Best practices | SEO | Overall |',
|
||||
'| --- | --- | --- | --- | --- | --- |',
|
||||
`${result.routes.map(route => `| ${route.path} | ${score(route.categories.performance.score)} | ${score(route.categories.accessibility.score)} | ${score(route.categories['best-practices'].score)} | ${score(route.categories.seo.score)} | ${score(route.score)} |`).join('\n')}`,
|
||||
'',
|
||||
'*Lighthouse metrics:*',
|
||||
'',
|
||||
'| Metric | Average Value |',
|
||||
'| --- | --- |',
|
||||
`${Object.entries(result.summary.metrics).map(([metric, { averageNumericValue }]) => `| ${metric} | ${averageNumericValue} |`).join('\n')}`,
|
||||
'',
|
||||
`View the full Lighthouse report [here](${reportUrl}).`,
|
||||
].join('\n');
|
||||
|
||||
core.setOutput("comment", comment);
|
||||
core.setOutput("score", `${Math.round(result.summary.score * 100)}`);
|
||||
core.setOutput("scoreColor", getColor(result.summary.score));
|
||||
|
||||
- name: Update comment with result
|
||||
uses: marocchino/sticky-pull-request-comment@v2.9.0
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
header: ${{ env.COMMENT_ID }}
|
||||
message: ${{ steps.create_result_content.outputs.comment }}
|
||||
|
||||
- name: Create Lighthouse Score badge
|
||||
uses: schneegans/dynamic-badges-action@v1.7.0
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
auth: ${{ secrets.GIST_SECRET }}
|
||||
gistID: 795a3d6af5b0db5754cf7279898c3c16
|
||||
filename: hellob.art-unlighthouse.json
|
||||
namedLogo: Lighthouse
|
||||
label: lighthouse
|
||||
message: ${{ steps.create_result_content.outputs.score }}
|
||||
color: ${{ steps.create_result_content.outputs.scoreColor }}
|
||||
|
||||
- name: Update comment on failure
|
||||
uses: marocchino/sticky-pull-request-comment@v2.9.0
|
||||
if: failure() && github.ref != 'refs/heads/main'
|
||||
with:
|
||||
header: ${{ env.COMMENT_ID }}
|
||||
message: |
|
||||
⚡️ Lighthouse report failed
|
||||
|
||||
See deployment for any errors
|
||||
|
||||
- name: Update comment on cancel
|
||||
uses: marocchino/sticky-pull-request-comment@v2.9.0
|
||||
if: cancelled() && github.ref != 'refs/heads/main'
|
||||
with:
|
||||
header: ${{ env.COMMENT_ID }}
|
||||
message: |
|
||||
⚡️ Lighthouse report cancelled
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,4 +8,3 @@ node_modules
|
|||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
.vercel
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
pnpm exec lint-staged
|
23
Dockerfile
Normal file
23
Dockerfile
Normal file
|
@ -0,0 +1,23 @@
|
|||
FROM node:22-slim AS base
|
||||
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
FROM base AS prod
|
||||
|
||||
RUN mkdir /app
|
||||
COPY pnpm-lock.yaml /app
|
||||
WORKDIR /app
|
||||
RUN pnpm fetch --prod
|
||||
|
||||
COPY . /app
|
||||
RUN pnpm install vite && pnpm run build
|
||||
|
||||
FROM base
|
||||
COPY --from=prod /app/node_modules /app/node_modules
|
||||
COPY --from=prod /app/build /app/build
|
||||
EXPOSE 8000
|
||||
CMD [ "node", "/app/build/index.js" ]
|
|
@ -3,12 +3,6 @@
|
|||
<p><em>current work and studies in a SvelteKit-based portfolio</em></p>
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<a href="https://sonarcloud.io/summary/new_code?id=bartvdbraak_hellob.art"><img src="https://sonarcloud.io/api/project_badges/measure?project=bartvdbraak_hellob.art&metric=alert_status" /></a>
|
||||
<a href="https://hellobart-unlighthouse.pages.dev"><img src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/bartvdbraak/795a3d6af5b0db5754cf7279898c3c16/raw/hellob.art-unlighthouse.json" /></a>
|
||||
<a href="https://github.com/bartvdbraak/hellob.art/deployments/activity_log?environment=Production"><img src="https://img.shields.io/github/deployments/bartvdbraak/hellob.art/production?label=vercel&logo=vercel" /></a>
|
||||
</div>
|
||||
|
||||
## Description
|
||||
|
||||
This is a personal website built with Svelte and SvelteKit. It includes a variety of components and routes, and it's styled with Tailwind CSS. The project is set up with a number of quality assurance tools, including ESLint, Prettier, and Husky.
|
||||
|
|
59
package.json
59
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hellob.art",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -15,42 +15,40 @@
|
|||
"prepare": "npx husky && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-vercel": "^5.4.0",
|
||||
"@sveltejs/kit": "^2.5.18",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
||||
"@types/eslint": "^8.56.10",
|
||||
"@typescript-eslint/eslint-plugin": "^7.15.0",
|
||||
"@typescript-eslint/parser": "^7.15.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"@sveltejs/adapter-node": "^5.2.7",
|
||||
"@sveltejs/kit": "^2.7.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
||||
"@types/eslint": "^8.56.12",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.41.0",
|
||||
"lint-staged": "^15.2.7",
|
||||
"postcss": "^8.4.39",
|
||||
"postcss-load-config": "^6.0.0",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.6.0",
|
||||
"svelte": "^4.2.18",
|
||||
"svelte-check": "^3.8.4",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.5.3",
|
||||
"vite": "^5.3.2"
|
||||
"eslint-plugin-svelte": "^2.45.1",
|
||||
"lint-staged": "^15.2.10",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-load-config": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.2.7",
|
||||
"prettier-plugin-tailwindcss": "^0.6.8",
|
||||
"svelte": "^4.2.19",
|
||||
"svelte-check": "^3.8.6",
|
||||
"tailwindcss": "^3.4.14",
|
||||
"tslib": "^2.8.0",
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@resvg/resvg-js": "^2.6.2",
|
||||
"@types/node": "^20.14.9",
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"@vercel/speed-insights": "^1.0.12",
|
||||
"bits-ui": "^0.21.11",
|
||||
"@types/node": "^20.16.12",
|
||||
"bits-ui": "^0.21.16",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-svelte": "^0.399.0",
|
||||
"mode-watcher": "^0.3.1",
|
||||
"satori": "^0.10.13",
|
||||
"satori": "^0.10.14",
|
||||
"satori-html": "^0.3.2",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwind-variants": "^0.2.1"
|
||||
"tailwind-merge": "^2.5.4",
|
||||
"tailwind-variants": "^0.2.1",
|
||||
"vite": "^5.4.9"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,ts,svelte,css,scss,postcss,md,json}": [
|
||||
|
@ -58,5 +56,6 @@
|
|||
"prettier --check"
|
||||
],
|
||||
"*.{js,ts,svelte}": "eslint"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
|
||||
}
|
||||
|
|
1763
pnpm-lock.yaml
1763
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,7 @@
|
|||
<link rel="mask-icon" href="%sveltekit.assets%/safari-pinned-tab.svg" color="#000000" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<script defer src="https://analytics.braak.pro/script.js" data-website-id="c928a72c-8989-48fc-af0f-cd721af9a600"></script>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body
|
||||
|
|
|
@ -3,7 +3,6 @@ import Logo from './logo.svelte';
|
|||
import LogoIcon from '$lib/assets/logo-icon.png';
|
||||
import Github from './github.svelte';
|
||||
import Svelte from './svelte.svelte';
|
||||
import Vercel from './vercel.svelte';
|
||||
import LinkedIn from './linkedin.svelte';
|
||||
|
||||
export type Icon = LucideIcon;
|
||||
|
@ -13,6 +12,5 @@ export const Icons = {
|
|||
logoIcon: LogoIcon,
|
||||
gitHub: Github,
|
||||
svelte: Svelte,
|
||||
vercel: Vercel,
|
||||
linkedIn: LinkedIn
|
||||
};
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<svg
|
||||
width="15"
|
||||
height="15"
|
||||
viewBox="0 0 15 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...$$restProps}
|
||||
><path
|
||||
d="M7.49998 1L6.92321 2.00307L1.17498 12L0.599976 13H1.7535H13.2464H14.4L13.825 12L8.07674 2.00307L7.49998 1ZM7.49998 3.00613L2.3285 12H12.6714L7.49998 3.00613Z"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
></path></svg
|
||||
>
|
Before Width: | Height: | Size: 373 B |
|
@ -26,13 +26,13 @@
|
|||
</div>
|
||||
<Separator orientation="vertical" />
|
||||
<div>
|
||||
<span class="hidden sm:inline">Hosted on</span>
|
||||
<span class="hidden sm:inline">Selfhosted with</span>
|
||||
<Cloud class="inline h-[1rem] w-[1rem] sm:hidden" />
|
||||
<a
|
||||
href={siteConfig.links.vercel}
|
||||
href={siteConfig.links.coolify}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
class="font-medium underline underline-offset-4">Vercel</a
|
||||
class="font-medium underline underline-offset-4">Coolify</a
|
||||
>
|
||||
</div>
|
||||
<Separator orientation="vertical" />
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const SITE_URL =
|
||||
import.meta.env.VERCEL_ENV === 'preview' ? import.meta.env.VERCEL_URL : 'hellob.art';
|
||||
const SITE_URL = 'hellob.art';
|
||||
|
||||
export const siteConfig = {
|
||||
name: 'hellob.art',
|
||||
|
@ -14,7 +13,7 @@ export const siteConfig = {
|
|||
gitHubProfile: 'https://github.com/bartvdbraak',
|
||||
gitHubProject: 'https://github.com/bartvdbraak/hellob.art',
|
||||
shadcnSvelte: 'https://www.shadcn-svelte.com/',
|
||||
vercel: 'https://vercel.com/'
|
||||
coolify: 'https://coolify.io/'
|
||||
},
|
||||
keywords: `Bart van der Braak,DevOps,Azure,Triple,Cloud`
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ const timeline: TimelineItem[] = [
|
|||
title: 'DevOps Engineer',
|
||||
subTitle: 'Blender',
|
||||
icon: Briefcase,
|
||||
startYear: 2021
|
||||
startYear: 2024
|
||||
},
|
||||
{
|
||||
title: 'Linux Foundation Certified Systems Administrator (LFCS)',
|
||||
|
|
|
@ -4,11 +4,6 @@
|
|||
import '../styles/globals.css';
|
||||
import { ModeWatcher } from 'mode-watcher';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { inject } from '@vercel/analytics';
|
||||
import { injectSpeedInsights } from '@vercel/speed-insights/sveltekit';
|
||||
inject({ mode: dev ? 'development' : 'production' });
|
||||
injectSpeedInsights();
|
||||
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<script>
|
||||
import { OgImage } from '$lib/components/site';
|
||||
import meInline from '$lib/assets/og/me-inline.jpg';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
const imageData = fs.readFileSync(path.join(process.cwd(), meInline), 'base64');
|
||||
</script>
|
||||
|
||||
<section class="h-[630px] w-[1200px]">
|
||||
<OgImage {imageData} />
|
||||
</section>
|
|
@ -10,7 +10,7 @@ export async function GET() {
|
|||
const robotsConfig = [
|
||||
{
|
||||
agent: '*',
|
||||
disallow: import.meta.env.VERCEL_ENV === 'preview' ? ['/'] : ['/og.png/preview']
|
||||
disallow: ['/og.png/preview']
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import adapter from '@sveltejs/adapter-vercel';
|
||||
import adapter from '@sveltejs/adapter-node';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
|
|
|
@ -3,11 +3,7 @@ import { defineConfig } from 'vite';
|
|||
import fs from 'fs';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [base64(), rawFonts(['.woff']), sveltekit()],
|
||||
define: {
|
||||
'import.meta.env.VERCEL_URL': JSON.stringify(process.env.VERCEL_URL),
|
||||
'import.meta.env.VERCEL_ENV': JSON.stringify(process.env.VERCEL_ENV)
|
||||
}
|
||||
plugins: [base64(), rawFonts(['.woff']), sveltekit()]
|
||||
});
|
||||
|
||||
function rawFonts(ext: string[]) {
|
||||
|
|
Loading…
Reference in a new issue