summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/ci.ts77
-rw-r--r--.dockerignore4
-rw-r--r--.eleventy.js18
-rw-r--r--.gitignore3
-rw-r--r--Dockerfile21
-rw-r--r--package.json13
-rw-r--r--src/_layouts/base.njk23
-rw-r--r--src/feed.njk34
-rw-r--r--src/index.njk23
-rw-r--r--src/posts/hello-world.md34
10 files changed, 250 insertions, 0 deletions
diff --git a/.ci/ci.ts b/.ci/ci.ts
new file mode 100644
index 0000000..ac4c9b4
--- /dev/null
+++ b/.ci/ci.ts
@@ -0,0 +1,77 @@
+#!/usr/bin/env node
+
+import {
+ AnsiblePlaybookJob,
+ BuildDockerImageJob,
+ DefaultGitHookPipelineBuilder,
+ NpmPublishJob,
+ FetchCodeJob,
+ CoolifyWebhookJob,
+ Job,
+} from "@emprespresso/ci_model";
+import { join } from "path";
+
+const REGISTRY = "img.liz.coffee";
+const NAMESPACE = "emprespresso";
+const IMG = "lizdotcoffee";
+const REMOTE = "https://code.liz.coffee";
+
+const getPipeline = () => {
+ const gitHookPipeline = new DefaultGitHookPipelineBuilder();
+ const branch = gitHookPipeline.getBranch();
+ if (!branch) return gitHookPipeline.build();
+
+ const commonBuildArgs = {
+ context: gitHookPipeline.getSourceDestination(),
+ registry: REGISTRY,
+ namespace: NAMESPACE,
+ imageTag: branch,
+ };
+
+ const adeliePackageBuild: BuildDockerImageJob = {
+ type: "build_docker_image.js",
+ arguments: {
+ ...commonBuildArgs,
+ repository: IMG,
+ buildTarget: IMG,
+ dockerfile: "Dockerfile",
+ },
+ };
+ gitHookPipeline.addStage({
+ parallelJobs: [adeliePackageBuild],
+ });
+
+ const webhookUrl = getReleaseDeployment(branch);
+ if (webhookUrl === null) {
+ return gitHookPipeline.build();
+ }
+
+ const release: CoolifyWebhookJob = {
+ type: "coolify_webhook.js",
+ arguments: {
+ webhookUrl: webhookUrl!!,
+ },
+ };
+ gitHookPipeline.addStage({ parallelJobs: [release] });
+
+ return gitHookPipeline.build();
+};
+
+const getReleaseDeployment = (branch: string) => {
+ switch (branch) {
+ case "release":
+ return "https://plane.liz.coffee/api/v1/deploy?uuid=c8k4wow4gckss8008cg4g8ko&force=false";
+ case "main":
+ return "https://plane.liz.coffee/api/v1/deploy?uuid=zoookks8o8wkk48gswgg0coo&force=false";
+ default:
+ return null;
+ }
+};
+
+const main = () => {
+ const data = getPipeline().serialize();
+ process.stdout.write(data);
+};
+
+main();
+
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..efaa2cf
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,4 @@
+node_modules
+_site
+.git
+.DS_Store
diff --git a/.eleventy.js b/.eleventy.js
new file mode 100644
index 0000000..3088c8d
--- /dev/null
+++ b/.eleventy.js
@@ -0,0 +1,18 @@
+import pluginRss from "@11ty/eleventy-plugin-rss";
+
+export default function(eleventyConfig) {
+ eleventyConfig.addPlugin(pluginRss);
+
+ eleventyConfig.addPassthroughCopy("src/assets");
+
+ return {
+ dir: {
+ input: "src",
+ output: "_site",
+ includes: "_includes",
+ layouts: "_layouts"
+ },
+ markdownTemplateEngine: "njk",
+ htmlTemplateEngine: "njk"
+ };
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..24c9945
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+node_modules/
+_site/
+.DS_Store
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..a7b7f41
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+FROM node:22-alpine AS builder
+
+WORKDIR /build
+
+COPY lizdotcoffee/package*.json ./lizdotcoffee/
+WORKDIR /build/lizdotcoffee
+RUN npm install
+
+WORKDIR /build
+COPY lizdotcoffee ./lizdotcoffee
+
+WORKDIR /build/lizdotcoffee
+RUN npm run build
+
+FROM nginx:alpine as lizdotcoffee
+
+COPY --from=builder /build/lizdotcoffee/_site /usr/share/nginx/html
+
+EXPOSE 80
+
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..1c91581
--- /dev/null
+++ b/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "lizdotcoffee",
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "eleventy --serve",
+ "build": "eleventy"
+ },
+ "devDependencies": {
+ "@11ty/eleventy": "^3.0.0",
+ "@11ty/eleventy-plugin-rss": "^2.0.2"
+ }
+}
diff --git a/src/_layouts/base.njk b/src/_layouts/base.njk
new file mode 100644
index 0000000..84df4f4
--- /dev/null
+++ b/src/_layouts/base.njk
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{% if title %}{{ title }} - {% endif %}liz.coffee</title>
+ <link rel="stylesheet" href="/assets/adelie.css">
+ <link rel="alternate" type="application/atom+xml" title="liz.coffee" href="/feed.xml">
+ {% if pageStyles %}
+ <style>{{ pageStyles | safe }}</style>
+ {% endif %}
+</head>
+<body>
+ <main>
+ {{ content | safe }}
+ </main>
+
+ <script src="/assets/adelie.js"></script>
+ {% if pageScripts %}
+ <script>{{ pageScripts | safe }}</script>
+ {% endif %}
+</body>
+</html>
diff --git a/src/feed.njk b/src/feed.njk
new file mode 100644
index 0000000..b5c45e3
--- /dev/null
+++ b/src/feed.njk
@@ -0,0 +1,34 @@
+---
+permalink: /feed.xml
+eleventyExcludeFromCollections: true
+metadata:
+ title: liz.coffee
+ subtitle: A cute little blog with interactive toys
+ url: https://liz.coffee/
+ feedUrl: https://liz.coffee/feed.xml
+ author:
+ name: Lizzy
+---
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>{{ metadata.title }}</title>
+ <subtitle>{{ metadata.subtitle }}</subtitle>
+ <link href="{{ metadata.feedUrl }}" rel="self"/>
+ <link href="{{ metadata.url }}"/>
+ <updated>{{ collections.all | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
+ <id>{{ metadata.url }}</id>
+ <author>
+ <name>{{ metadata.author.name }}</name>
+ </author>
+ {%- for post in collections.all | reverse -%}
+ {%- if post.data.title -%}
+ <entry>
+ <title>{{ post.data.title }}</title>
+ <link href="{{ metadata.url }}{{ post.url }}"/>
+ <updated>{{ post.date | dateToRfc3339 }}</updated>
+ <id>{{ metadata.url }}{{ post.url }}</id>
+ <content type="html">{{ post.templateContent | htmlToAbsoluteUrls(metadata.url) }}</content>
+ </entry>
+ {%- endif -%}
+ {%- endfor -%}
+</feed>
diff --git a/src/index.njk b/src/index.njk
new file mode 100644
index 0000000..064c05e
--- /dev/null
+++ b/src/index.njk
@@ -0,0 +1,23 @@
+---
+layout: base.njk
+title: Home
+---
+
+<h1>liz.coffee</h1>
+
+<p>A cute little blog with interactive toys.</p>
+
+<h2>Posts</h2>
+
+<ul>
+{%- for post in collections.all | reverse -%}
+ {%- if post.data.title -%}
+ <li>
+ <a href="{{ post.url }}">{{ post.data.title }}</a>
+ {%- if post.data.date -%}
+ <span> - {{ post.data.date | date: "%Y-%m-%d" }}</span>
+ {%- endif -%}
+ </li>
+ {%- endif -%}
+{%- endfor -%}
+</ul>
diff --git a/src/posts/hello-world.md b/src/posts/hello-world.md
new file mode 100644
index 0000000..22eef26
--- /dev/null
+++ b/src/posts/hello-world.md
@@ -0,0 +1,34 @@
+---
+layout: base.njk
+title: Hello World
+date: 2025-12-14
+---
+
+# Hello World!
+
+This is my first blog post. I can write regular markdown here.
+
+## Interactive Toy Example
+
+Here's a little interactive toy:
+
+<div id="color-toy" style="padding: 2rem; background: #f0f0f0; border-radius: 8px; text-align: center;">
+ <button id="change-color">Click me!</button>
+ <p id="color-display" style="margin-top: 1rem; font-weight: bold;">Color: #f0f0f0</p>
+</div>
+
+<script>
+ const btn = document.getElementById('change-color');
+ const display = document.getElementById('color-display');
+ const toy = document.getElementById('color-toy');
+
+ btn.addEventListener('click', () => {
+ const randomColor = '#' + Math.floor(Math.random()*16777215).toString(16);
+ toy.style.background = randomColor;
+ display.textContent = 'Color: ' + randomColor;
+ });
+</script>
+
+## More Content
+
+And I can continue writing markdown after the interactive bit!