This commit is contained in:
Bart van der Braak 2024-12-17 20:43:54 +00:00 committed by GitHub
commit e22574a90a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 814 additions and 1279 deletions

11
.dockerignore Normal file
View 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-*

View file

@ -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
![loading](https://github.com/bartvdbraak/hellob.art/assets/3996360/0e00b3fc-d5f9-490b-9aa7-07cb4b59f85f)
- 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
View file

@ -8,4 +8,3 @@ node_modules
!.env.example !.env.example
vite.config.js.timestamp-* vite.config.js.timestamp-*
vite.config.ts.timestamp-* vite.config.ts.timestamp-*
.vercel

View file

@ -1,4 +0,0 @@
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"
pnpm exec lint-staged

23
Dockerfile Normal file
View 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" ]

View file

@ -3,12 +3,6 @@
<p><em>current work and studies in a SvelteKit-based portfolio</em></p> <p><em>current work and studies in a SvelteKit-based portfolio</em></p>
</div> </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 ## 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. 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.

View file

@ -1,6 +1,6 @@
{ {
"name": "hellob.art", "name": "hellob.art",
"version": "1.0.0", "version": "1.1.0",
"type": "module", "type": "module",
"private": true, "private": true,
"scripts": { "scripts": {
@ -15,42 +15,40 @@
"prepare": "npx husky && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" "prepare": "npx husky && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-vercel": "^5.4.0", "@sveltejs/adapter-node": "^5.2.7",
"@sveltejs/kit": "^2.5.18", "@sveltejs/kit": "^2.7.1",
"@sveltejs/vite-plugin-svelte": "^3.1.1", "@sveltejs/vite-plugin-svelte": "^3.1.2",
"@types/eslint": "^8.56.10", "@types/eslint": "^8.56.12",
"@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.15.0", "@typescript-eslint/parser": "^7.18.0",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.20",
"eslint": "^8.57.0", "eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.41.0", "eslint-plugin-svelte": "^2.45.1",
"lint-staged": "^15.2.7", "lint-staged": "^15.2.10",
"postcss": "^8.4.39", "postcss": "^8.4.47",
"postcss-load-config": "^6.0.0", "postcss-load-config": "^6.0.1",
"prettier": "^3.3.2", "prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.5", "prettier-plugin-svelte": "^3.2.7",
"prettier-plugin-tailwindcss": "^0.6.0", "prettier-plugin-tailwindcss": "^0.6.8",
"svelte": "^4.2.18", "svelte": "^4.2.19",
"svelte-check": "^3.8.4", "svelte-check": "^3.8.6",
"tailwindcss": "^3.4.4", "tailwindcss": "^3.4.14",
"tslib": "^2.6.3", "tslib": "^2.8.0",
"typescript": "^5.5.3", "typescript": "^5.6.3"
"vite": "^5.3.2"
}, },
"dependencies": { "dependencies": {
"@resvg/resvg-js": "^2.6.2", "@resvg/resvg-js": "^2.6.2",
"@types/node": "^20.14.9", "@types/node": "^20.16.12",
"@vercel/analytics": "^1.3.1", "bits-ui": "^0.21.16",
"@vercel/speed-insights": "^1.0.12",
"bits-ui": "^0.21.11",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"lucide-svelte": "^0.399.0", "lucide-svelte": "^0.399.0",
"mode-watcher": "^0.3.1", "mode-watcher": "^0.3.1",
"satori": "^0.10.13", "satori": "^0.10.14",
"satori-html": "^0.3.2", "satori-html": "^0.3.2",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.5.4",
"tailwind-variants": "^0.2.1" "tailwind-variants": "^0.2.1",
"vite": "^5.4.9"
}, },
"lint-staged": { "lint-staged": {
"*.{js,ts,svelte,css,scss,postcss,md,json}": [ "*.{js,ts,svelte,css,scss,postcss,md,json}": [
@ -58,5 +56,6 @@
"prettier --check" "prettier --check"
], ],
"*.{js,ts,svelte}": "eslint" "*.{js,ts,svelte}": "eslint"
} },
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
} }

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
<link rel="mask-icon" href="%sveltekit.assets%/safari-pinned-tab.svg" color="#000000" /> <link rel="mask-icon" href="%sveltekit.assets%/safari-pinned-tab.svg" color="#000000" />
<meta name="msapplication-TileColor" content="#da532c" /> <meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" /> <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% %sveltekit.head%
</head> </head>
<body <body

View file

@ -3,7 +3,6 @@ import Logo from './logo.svelte';
import LogoIcon from '$lib/assets/logo-icon.png'; import LogoIcon from '$lib/assets/logo-icon.png';
import Github from './github.svelte'; import Github from './github.svelte';
import Svelte from './svelte.svelte'; import Svelte from './svelte.svelte';
import Vercel from './vercel.svelte';
import LinkedIn from './linkedin.svelte'; import LinkedIn from './linkedin.svelte';
export type Icon = LucideIcon; export type Icon = LucideIcon;
@ -13,6 +12,5 @@ export const Icons = {
logoIcon: LogoIcon, logoIcon: LogoIcon,
gitHub: Github, gitHub: Github,
svelte: Svelte, svelte: Svelte,
vercel: Vercel,
linkedIn: LinkedIn linkedIn: LinkedIn
}; };

View file

@ -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

View file

@ -26,13 +26,13 @@
</div> </div>
<Separator orientation="vertical" /> <Separator orientation="vertical" />
<div> <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" /> <Cloud class="inline h-[1rem] w-[1rem] sm:hidden" />
<a <a
href={siteConfig.links.vercel} href={siteConfig.links.coolify}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
class="font-medium underline underline-offset-4">Vercel</a class="font-medium underline underline-offset-4">Coolify</a
> >
</div> </div>
<Separator orientation="vertical" /> <Separator orientation="vertical" />

View file

@ -1,5 +1,4 @@
const SITE_URL = const SITE_URL = 'hellob.art';
import.meta.env.VERCEL_ENV === 'preview' ? import.meta.env.VERCEL_URL : 'hellob.art';
export const siteConfig = { export const siteConfig = {
name: 'hellob.art', name: 'hellob.art',
@ -14,7 +13,7 @@ export const siteConfig = {
gitHubProfile: 'https://github.com/bartvdbraak', gitHubProfile: 'https://github.com/bartvdbraak',
gitHubProject: 'https://github.com/bartvdbraak/hellob.art', gitHubProject: 'https://github.com/bartvdbraak/hellob.art',
shadcnSvelte: 'https://www.shadcn-svelte.com/', shadcnSvelte: 'https://www.shadcn-svelte.com/',
vercel: 'https://vercel.com/' coolify: 'https://coolify.io/'
}, },
keywords: `Bart van der Braak,DevOps,Azure,Triple,Cloud` keywords: `Bart van der Braak,DevOps,Azure,Triple,Cloud`
}; };

View file

@ -24,7 +24,7 @@ const timeline: TimelineItem[] = [
title: 'DevOps Engineer', title: 'DevOps Engineer',
subTitle: 'Blender', subTitle: 'Blender',
icon: Briefcase, icon: Briefcase,
startYear: 2021 startYear: 2024
}, },
{ {
title: 'Linux Foundation Certified Systems Administrator (LFCS)', title: 'Linux Foundation Certified Systems Administrator (LFCS)',

View file

@ -4,11 +4,6 @@
import '../styles/globals.css'; import '../styles/globals.css';
import { ModeWatcher } from 'mode-watcher'; import { ModeWatcher } from 'mode-watcher';
import { fly } from 'svelte/transition'; 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; export let data;
</script> </script>

View file

@ -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>

View file

@ -10,7 +10,7 @@ export async function GET() {
const robotsConfig = [ const robotsConfig = [
{ {
agent: '*', agent: '*',
disallow: import.meta.env.VERCEL_ENV === 'preview' ? ['/'] : ['/og.png/preview'] disallow: ['/og.png/preview']
} }
]; ];

View file

@ -1,4 +1,4 @@
import adapter from '@sveltejs/adapter-vercel'; import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */

View file

@ -3,11 +3,7 @@ import { defineConfig } from 'vite';
import fs from 'fs'; import fs from 'fs';
export default defineConfig({ export default defineConfig({
plugins: [base64(), rawFonts(['.woff']), sveltekit()], 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)
}
}); });
function rawFonts(ext: string[]) { function rawFonts(ext: string[]) {