13 Commits
Author SHA1 Message Date
Klagarge 09f0dc42e4 chore(home): add metadatas
Build site / build (push) Successful in 2m44s
Build site / deploy (push) Successful in 7s
2026-10-11 23:46:05 +02:00
Klagarge 8e2303fcdf refactor: change main categories
Build site / build (push) Successful in 2m48s
Build site / deploy (push) Successful in 6s
2026-10-11 23:32:36 +02:00
Klagarge 4917abe9e6 ops: add toc on side 2026-10-11 23:26:28 +02:00
Klagarge b52629d1f6 feat(home): add gardening with yuca and dracaena 2026-10-11 23:23:48 +02:00
Klagarge b9159581f3 ops: add strip-exif function in justfile 2026-10-11 23:23:14 +02:00
Klagarge 9e9163f01b chore: add IDE in gitignore 2026-10-11 23:22:57 +02:00
Klagarge 54a69b51ae ops: add lib with tag function 2026-10-11 23:22:42 +02:00
Klagarge 975ba4f312 fix: remove act check
Build site / build (push) Successful in 50s
Build site / deploy (push) Successful in 3s
2026-10-11 20:09:47 +02:00
Klagarge 6cd5ed61c4 Merge branch 'refactor: migrate to calepin'
Build site / build (push) Successful in 51s
Build site / deploy (push) Successful in 2s
Reviewed-on: #1
2026-10-11 18:06:17 +00:00
Klagarge 1adca36802 ci: publish to the pages branch on main pushes
Build site / build (push) Successful in 52s
Build site / deploy (push) Skipped
Assisted-by: Delta:zai-glm-5.3
2026-10-11 20:00:54 +02:00
Klagarge 3b1ef34bce feat: enable PDF output for pages
Assisted-by: Delta:zai-glm-5.3
2026-10-11 18:56:04 +02:00
Klagarge 6b33be6956 chore: add a recipe for local act runs
Assisted-by: Delta:zai-glm-5.3
2026-10-11 00:22:23 +02:00
Klagarge f94a5cbe17 ci: use upload-artifact v3 for gitea
Assisted-by: Delta:zai-glm-5.3
2026-10-11 00:22:23 +02:00
18 changed files with 214 additions and 57 deletions

No files matched your search

+49 -2
View File
@@ -1,6 +1,8 @@
name: Build site
on: push
on:
- push
- workflow_dispatch
jobs:
build:
@@ -16,8 +18,53 @@ jobs:
- name: Build site
run: ./scripts/calepin.sh compile site public
# The official upload-artifact@v4 refuses to run on Gitea (it detects a
# non-GitHub server and aborts with GHESNotSupportedError). v3 uses the
# artifact API that Gitea implements. On Gitea >= 1.22 with a current
# act_runner, christopherhx/gitea-upload-artifact@v4 is a drop-in
# replacement if you want the v4 API.
- name: Upload site artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: public
path: public/
deploy:
needs: build
# Publish only from main; move the gate to publish from another branch.
if: github.ref == 'refs/heads/main'
# Write access for the automatic Actions token to push the pages branch.
permissions:
contents: write
# NOTE: must match your act_runner labels (e.g. ubuntu-latest, ubuntu-24.04).
runs-on: ubuntu-latest
steps:
- name: Download site artifact
uses: actions/download-artifact@v3
with:
name: public
path: public
- name: Check artifact layout
run: test -f public/index.html
# Publishing interfaces with prod; it never runs under local act tests
# (act sets env.ACT, the Gitea runner does not). The force-push to the
# `pages` branch is what triggers the git-pages webhook.
- name: Publish to pages branch
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
if [ -z "$GITEA_TOKEN" ]; then
echo "::error::Missing GITEA_TOKEN (the automatic Actions token)."
exit 1
fi
cd public
git init -q -b pages .
git config user.name "Yggdrasil CI"
git config user.email "ci@noreply.kb28.ch"
git add -A
git commit -q -m "Publish site from ${GITHUB_SHA}"
repo_host="${GITHUB_SERVER_URL#*://}"
repo_host="${repo_host%/}"
git push -q --force "https://${GITHUB_REPOSITORY_OWNER}:${GITEA_TOKEN}@${repo_host}/${GITHUB_REPOSITORY}.git" pages
+2
View File
@@ -8,3 +8,5 @@ tools/
# IDE
.idea/
.zed/
.vscode/
+8
View File
@@ -21,3 +21,11 @@ watch: tools
# Remove generated output and build caches
clean:
./scripts/clean.sh
# Remove all EXIF metadata from a file
strip-exif file:
exiftool -all= -overwrite_original {{ quote(file) }}
# Run the CI workflow locally with act (requires act + docker)
ci:
act push -W .gitea/workflows/build.yml -j build --artifact-server-path /tmp/act-artifacts
+17 -4
View File
@@ -24,6 +24,7 @@ checksum-verified into `tools/` on first use (no global installs, no cargo):
just preview # build, then serve the site locally
just watch # rebuild on change and serve
just clean # remove public/ and build caches
just ci # run the CI workflow locally with act (needs act + docker)
## Adding a page
@@ -49,6 +50,10 @@ target = "<category>/<page>.typ"
Sidebar labels come from the page's `#metadata(...)` line, not from the config.
Every page also renders a printable PDF twin (`pdf = true` in
`calepin.toml`, selectable in the page's view picker). Add `pdf: false` to a
page's `#metadata(...)` to skip its PDF, as `404.typ` does.
## Adding a category
1. Create `site/<category>/` with an `index.typ`, using
@@ -68,8 +73,16 @@ sidebar.
## Deployment
`just build` produces a fully static site in `public/`: HTML pages plus
`sitemap.xml`, `robots.txt`, and `llms.txt`. The Gitea Actions workflow in
`just build` produces a fully static site in `public/`: HTML pages with
printable PDF twins, plus `sitemap.xml`, `robots.txt`, and `llms.txt`. The
Gitea Actions workflow in
`.gitea/workflows/build.yml` builds the site on every push with the same
pinned toolchain and uploads `public/` as an artifact for deployment to any
static host.
pinned toolchain and uploads `public/` as an artifact.
Pushes to `main` are also published: the `deploy` job force-pushes `public/`
to the repo's `pages` branch using the automatic Actions token (no secrets to
configure). A Gitea webhook on the repo then notifies the self-hosted
[git-pages](https://codeberg.org/git-pages/git-pages) server, which clones
the `pages` branch and serves the site. The push step is gated with
`if: ${{ !env.ACT }}` so local `act` runs never publish, and
`workflow_dispatch` enables manual publishes from the Gitea UI.
+1
View File
@@ -1,4 +1,5 @@
#set document(title: [Not found])
#metadata((pdf: false)) <website-metadata>
#title()
+14 -16
View File
@@ -2,7 +2,7 @@ title = "Yggdrasil"
description = "Personal knowledge base."
base-url = "https://yggdrasil.kb28.ch"
theme = "themes/yggdrasil"
pdf = false
pdf = true
minify = true
search = "pagefind"
logo = "assets/yggdrasil.svg"
@@ -22,12 +22,16 @@ include = [
]
exclude = ["drafts/**"]
[toc]
enabled = true
depth = 2
floating = true
[menus]
main = [
{ label = "Home", target = "home/index.typ" },
{ label = "IT", target = "it/index.typ" },
{ label = "OT", target = "ot/index.typ" },
{ label = "Security", target = "security/index.typ" },
{ label = "Computer Science", target = "cs/index.typ" },
{ label = "HomeLab", target = "homelab/index.typ" },
{ label = "Medias", target = "medias/index.typ" },
]
social = [
@@ -54,24 +58,18 @@ item = [
[[sidebar.section]]
title = "IT"
title = "Computer Science"
item = [
{ target = "it/index.typ" },
{ glob = "it/*" }
{ target = "cs/index.typ" },
{ glob = "cs/*" }
]
[[sidebar.section]]
title = "OT"
item = [
{ target = "ot/index.typ" },
{ glob = "ot/*" }
]
[[sidebar.section]]
title = "Security"
title = "HomeLab"
item = [
{ target = "security/index.typ" },
{ glob = "security/*" }
{ target = "homelab/index.typ" },
{ glob = "homelab/*" }
]
[[sidebar.section]]
+7
View File
@@ -0,0 +1,7 @@
#set document(title: [Computer Science])
#metadata((title: "Overview", translation_key: "cs-index")) <website-metadata>
#title()
Placeholder page for the Computer Science category.
The real content comes later.
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

+52 -2
View File
@@ -1,6 +1,56 @@
#import "/lib/lib.typ": *
#set document(title: [Gardening])
#metadata((title: "Gardening", translation_key: "home-gardening")) <website-metadata>
#metadata((
title: "Gardening",
translation_key: "home-gardening",
date: "2026-10-11",
tags: ("plants", "yucca", "dracaena", "light", "water"),
author: "Rémi Herdero",
summary: "Some plants description and advices for keep them alive"
)) <website-metadata>
#title()
Placeholder page — the real content comes later.
= Yucca elephantipes <home:gardening:yucca>
#calepin.elements.columns(
columns: 2,
wrap: true,
[
Yucca (@fig:plant:yucca_elephantipes) from central America is accustomed to arid conditions.
#tag(fill: yellow.lighten(30%))[Light ++]
#tag(fill: blue.lighten(50%))[Water --]
This plant love light and should be placed on one of the most brightful parts of the room. It even tolerates direct sunlight very well.
The Yucca stores water in its thick trunk. You need to let the soil dry out almost completely between waterings. Generally speaking, watering once *every 2 to 3 weeks* is more than enough. It's better to forget about it for a while than to overwater it, otherwise its roots will decay. Usually we can put around #frackable(1, 2) liter every 2 Weeks. But it's important to check the dirt is dry before watering.
],[
#figure(
image("assets/yucca_elephantipes.jpg", width: 60%),
caption: "Yucca elephantipes"
) <fig:plant:yucca_elephantipes>
]
)
= Dracaena marginata <home:gardening:dracaena>
#calepin.elements.columns(
columns: 2,
wrap: true,
[
The Dracaena (@fig:plant:dracaena_marginata) come from Madagascar.
#tag(fill: yellow.lighten(30%))[Light +]
#tag(fill: blue.lighten(50%))[Water -]
This plant prefer lot of indirect light. Avoid to place it in direct sunlight because it can burn its leaves.
The Dracaena don't need a lot of water. Before watering, make sure the first 3 or 4 centimeters of soil are dry. In average, water the plant once with #frackable(1, 2) litre *every 10 to 14 days*. The extremity of the leaves tend to turn brown when the air is too dry or the water contain too much calcium or chlorine.
], [
#figure(
image("assets/dracaena_marginata.jpg", width: 60%),
caption: [Dracaena marginata]
) <fig:plant:dracaena_marginata>
]
)
-6
View File
@@ -1,6 +0,0 @@
#set document(title: [Washing clothes])
#metadata((title: "Washing clothes", translation_key: "home-washing-clothes")) <website-metadata>
#title()
Placeholder page — the real content comes later.
+6
View File
@@ -0,0 +1,6 @@
#set document(title: [Backup])
#metadata((title: "Backup", translation_key: "homelab-backup")) <website-metadata>
#title()
Placeholder page — the real content comes later.
+7
View File
@@ -0,0 +1,7 @@
#set document(title: [HomeLab])
#metadata((title: "Overview", translation_key: "homelab")) <website-metadata>
#title()
Placeholder page for the homelab category.
The real content comes later.
-7
View File
@@ -1,7 +0,0 @@
#set document(title: [IT])
#metadata((title: "Overview", translation_key: "it-index")) <website-metadata>
#title()
Placeholder page for the IT category.
The real content comes later.
+51
View File
@@ -0,0 +1,51 @@
// #import "@preview/calepin:0.1.0" as calepin
#import "@preview/hes-so-core:0.1.0"
#import "@preview/frackable:0.2.0": *
// #import "@preview/cetz:0.5.2"
//
// #let drawing(..args) = {
// let canvas = cetz.canvas(..args)
// context if target() == "html" {
// html.frame(canvas)
// } else {
// canvas
// }
// }
#let tag(body, fill: yellow, stroke: auto) = {
let stroke-color = if stroke == auto {
fill.darken(25%)
} else if type(stroke) == color {
stroke
} else if type(stroke) == stroke {
stroke.paint
} else {
fill.darken(25%)
}
let stroke-rule = if stroke == auto {
1pt + stroke-color
} else if type(stroke) == color {
1pt + stroke
} else {
stroke
}
context if target() == "html" {
let bg-hex = fill.to-hex()
let border-hex = stroke-color.to-hex()
html.elem("span", attrs: (
style: "display: inline-block; background-color: " + bg-hex
+ "; border: 1px solid " + border-hex
+ "; color: #1f2933; border-radius: 1em; padding: 0.2em 0.6em; font-size: 0.85em; font-weight: 500; line-height: 1.2;"
))[#body]
} else {
box(
fill: fill,
stroke: stroke-rule,
radius: 1em,
inset: (x: 0.5em, y: 0.5em)
)[#body]
}
}
-7
View File
@@ -1,7 +0,0 @@
#set document(title: [OT])
#metadata((title: "Overview", translation_key: "ot-index")) <website-metadata>
#title()
Placeholder page for the OT category.
The real content comes later.
-7
View File
@@ -1,7 +0,0 @@
#set document(title: [Security])
#metadata((title: "Overview", translation_key: "security")) <website-metadata>
#title()
Placeholder page for the security category.
The real content comes later.
-6
View File
@@ -1,6 +0,0 @@
#set document(title: [SSH])
#metadata((title: "SSH", translation_key: "security-ssh")) <website-metadata>
#title()
Placeholder page — the real content comes later.