mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2026-09-23 19:03:18 +00:00
Compare commits
35 Commits
be04b24eb0
...
v2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 4eb57011ba | |||
| 70d5871e94 | |||
| 10ea289563 | |||
| 62a2aa5827 | |||
| b0c8316b0d | |||
|
|
d5104f5680 | ||
| fc646d8826 | |||
| 1bff38ed64 | |||
| dd0454274b | |||
| fd4d1e77c8 | |||
| d1043c4cb0 | |||
|
|
62a6a8cb66 | ||
| 4d1092fe5e | |||
| 2ed4164dc3 | |||
| 85e1f437e0 | |||
|
|
0733af88ba | ||
| 31bed38478 | |||
| 3f75ebd327 | |||
| 169891fcf0 | |||
|
|
578d84de0c | ||
| 20b36e518d | |||
| d3a37f2268 | |||
|
|
fe6c2a0f11 | ||
|
|
21f24a3c0d | ||
|
|
20566ca0c4 | ||
|
|
f998ceb298 | ||
|
|
abc17e8b1e | ||
|
|
c188a6089d | ||
|
|
b76bbba4a3 | ||
|
|
362ca6f499 | ||
|
|
13e0331460 | ||
|
|
5d39720d54 | ||
| 49a0d2fe6d | |||
| dae34991e9 | |||
| b7874eab1d |
47
.github/dependabot.yml
vendored
Normal file
47
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
time: "00:00"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "ci"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
time: "00:00"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "docker"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker-compose"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
time: "00:00"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "docker"
|
||||||
|
|
||||||
|
- package-ecosystem: "pip"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
time: "00:00"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "python"
|
||||||
|
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/app"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
time: "00:00"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "javascript"
|
||||||
30
.github/workflows/cancel.yml
vendored
Normal file
30
.github/workflows/cancel.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: Cancel runs
|
||||||
|
|
||||||
|
on:
|
||||||
|
delete:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
actions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cancel:
|
||||||
|
name: Cancel the runs of a closed branch
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'pull_request' || github.event.ref_type == 'branch'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Cancel every queued or running workflow of the branch
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GH_REPO: ${{ github.repository }}
|
||||||
|
BRANCH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.event.ref }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
gh run list --branch "${BRANCH}" --limit 100 \
|
||||||
|
--json databaseId,status \
|
||||||
|
--jq '.[] | select(.status != "completed") | .databaseId' \
|
||||||
|
| sed "/^${GITHUB_RUN_ID}$/d" \
|
||||||
|
| xargs -r -n1 gh run cancel
|
||||||
79
.github/workflows/ci.yml
vendored
79
.github/workflows/ci.yml
vendored
@@ -8,6 +8,10 @@ on:
|
|||||||
tags-ignore:
|
tags-ignore:
|
||||||
- "**"
|
- "**"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ci-${{ github.repository }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
@@ -31,8 +35,8 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
security-events: write
|
security-events: write
|
||||||
|
|
||||||
publish:
|
version:
|
||||||
name: Publish image
|
name: Detect release version
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs:
|
||||||
- security
|
- security
|
||||||
@@ -41,11 +45,14 @@ jobs:
|
|||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
outputs:
|
||||||
|
found: ${{ steps.semver.outputs.found }}
|
||||||
|
version: ${{ steps.semver.outputs.version }}
|
||||||
|
image: ${{ steps.image.outputs.name }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
@@ -64,16 +71,34 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Compute image name
|
- name: Compute image name
|
||||||
if: steps.semver.outputs.found == 'true'
|
|
||||||
id: image
|
id: image
|
||||||
run: echo "name=ghcr.io/$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
|
run: echo "name=ghcr.io/$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
publish:
|
||||||
|
name: Publish image (${{ matrix.arch }})
|
||||||
|
runs-on: ${{ matrix.runner }}
|
||||||
|
needs:
|
||||||
|
- version
|
||||||
|
if: needs.version.outputs.found == 'true'
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: amd64
|
||||||
|
runner: ubuntu-latest
|
||||||
|
- arch: arm64
|
||||||
|
runner: ubuntu-24.04-arm
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
if: steps.semver.outputs.found == 'true'
|
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
||||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
|
||||||
|
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
if: steps.semver.outputs.found == 'true'
|
|
||||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -81,10 +106,42 @@ jobs:
|
|||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build and publish image
|
- name: Build and publish image
|
||||||
if: steps.semver.outputs.found == 'true'
|
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
||||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
|
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
|
platforms: linux/${{ matrix.arch }}
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.image.outputs.name }}:${{ steps.semver.outputs.version }}
|
tags: ${{ needs.version.outputs.image }}:${{ needs.version.outputs.version }}-${{ matrix.arch }}
|
||||||
|
|
||||||
|
manifest:
|
||||||
|
name: Join architectures
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- version
|
||||||
|
- publish
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
||||||
|
|
||||||
|
- name: Login to GHCR
|
||||||
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create the multi-arch manifest
|
||||||
|
env:
|
||||||
|
IMAGE: ${{ needs.version.outputs.image }}
|
||||||
|
VERSION: ${{ needs.version.outputs.version }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker buildx imagetools create -t "${IMAGE}:${VERSION}" \
|
||||||
|
"${IMAGE}:${VERSION}-amd64" \
|
||||||
|
"${IMAGE}:${VERSION}-arm64"
|
||||||
|
docker buildx imagetools inspect "${IMAGE}:${VERSION}"
|
||||||
|
|||||||
18
.github/workflows/lint.yml
vendored
18
.github/workflows/lint.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Run actionlint
|
- name: Run actionlint
|
||||||
run: docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:latest
|
run: docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:latest
|
||||||
@@ -25,10 +25,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
@@ -69,7 +69,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Run shellcheck
|
- name: Run shellcheck
|
||||||
run: docker run --rm -v "$PWD:/mnt" -w /mnt koalaman/shellcheck:stable scripts/*.sh
|
run: docker run --rm -v "$PWD:/mnt" -w /mnt koalaman/shellcheck:stable scripts/*.sh
|
||||||
@@ -80,10 +80,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -107,12 +107,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Run hadolint
|
- name: Run hadolint
|
||||||
id: hadolint
|
id: hadolint
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5
|
uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387
|
||||||
with:
|
with:
|
||||||
dockerfile: ./Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
format: sarif
|
format: sarif
|
||||||
|
|||||||
2
.github/workflows/security.yml
vendored
2
.github/workflows/security.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v4
|
uses: github/codeql-action/init@v4
|
||||||
|
|||||||
26
.github/workflows/tests.yml
vendored
26
.github/workflows/tests.yml
vendored
@@ -14,10 +14,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -35,10 +35,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -56,10 +56,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -77,10 +77,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -104,10 +104,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -135,10 +135,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ jobs:
|
|||||||
xvfb
|
xvfb
|
||||||
|
|
||||||
- name: Run Cypress tests
|
- name: Run Cypress tests
|
||||||
uses: cypress-io/github-action@f790eee7a50d9505912f50c2095510be7de06aa7 # v6.10.9
|
uses: cypress-io/github-action@01e3b659a495b41649cdd0aa82e1d1624e26520b # v7.4.4
|
||||||
with:
|
with:
|
||||||
working-directory: app
|
working-directory: app
|
||||||
install: false
|
install: false
|
||||||
|
|||||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.2.1] - 2026-09-23
|
||||||
|
|
||||||
|
* Images: releases ship arm64 next to amd64, for ARM servers and Apple Silicon
|
||||||
|
* CI: each architecture builds on its own native runner, no QEMU emulation
|
||||||
|
* CI: one run per branch, so two pushes stop racing through the same jobs
|
||||||
|
* CI: closing a pull request or deleting a branch cancels its pending runs
|
||||||
|
* Dependencies: Dependabot watches actions, images, compose, pip and npm daily
|
||||||
|
* Runtime: Python 3.14 and Node 25 base images
|
||||||
|
* Frontend: Bootstrap 5.3.8, jQuery 4, Font Awesome 7, marked 18, Cypress 16
|
||||||
|
|
||||||
|
## [2.2.0] - 2026-09-23
|
||||||
|
|
||||||
|
* Images: releases ship arm64 next to amd64, for ARM servers and Apple Silicon
|
||||||
|
* CI: each architecture builds on its own native runner, no QEMU emulation
|
||||||
|
|
||||||
## [2.1.3] - 2026-09-11
|
## [2.1.3] - 2026-09-11
|
||||||
|
|
||||||
* CSP: UI strings ship as a JSON data block, not a CSP-blocked inline script
|
* CSP: UI strings ship as a JSON data block, not a CSP-blocked inline script
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
FROM node:22-slim AS assets
|
FROM node:25-slim AS assets
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY app/package.json ./
|
COPY app/package.json ./
|
||||||
COPY app/scripts ./scripts
|
COPY app/scripts ./scripts
|
||||||
RUN npm install --omit=dev --no-audit --no-fund
|
RUN npm install --omit=dev --no-audit --no-fund
|
||||||
|
|
||||||
FROM python:3.12-slim AS base
|
FROM python:3.14-slim AS base
|
||||||
|
|
||||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
PYTHONUNBUFFERED=1 \
|
PYTHONUNBUFFERED=1 \
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
"bootstrap": "5.3.8",
|
||||||
"bootstrap": "5.2.2",
|
"@fortawesome/fontawesome-free": "^7.3.1",
|
||||||
"bootstrap-icons": "1.9.1",
|
"bootstrap-icons": "1.13.1",
|
||||||
"jquery": "3.6.0",
|
"jquery": "4.0.0",
|
||||||
"marked": "^4.3.0"
|
"marked": "^18.0.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"cypress": "^14.5.1",
|
"cypress": "^16.1.0",
|
||||||
"eslint": "^10.9.0",
|
"eslint": "^10.9.0",
|
||||||
"globals": "^17.11.0"
|
"globals": "^17.11.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "portfolio-ui"
|
name = "portfolio-ui"
|
||||||
version = "2.1.3"
|
version = "2.2.1"
|
||||||
description = "A lightweight YAML-driven portfolio and landing-page generator."
|
description = "A lightweight YAML-driven portfolio and landing-page generator."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|||||||
Reference in New Issue
Block a user