Blog Publishing Agent Workflow
This document outlines the “AI Agent” workflow we have constructed. This system automates the lifecycle of a blog post from ideation in Obsidian to deployment on your self-hosted Jekyll server.
The Pipeline:
- Create: Obsidian Templater script generates a structured post.
- Sync: Local Shell Script (
deploy_blog.sh) pushes changes to the server. - Build: Remote Shell Script (
blogupdate.sh) compiles the Jekyll site. - Trigger: Obsidian “Shell Commands” plugin executes the pipeline with one click.
1. The Creator (Obsidian Template)
File: Meta/Templates/JekyllBlogPost.md
Purpose: Standardizes frontmatter, handles file naming (date + slug), and sorts posts into the correct directory (Blog or Documentation).
<%*
const date = tp.date.now("YYYY-MM-DD");
const title = await tp.system.prompt("Enter Post Title");
const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
const filename = `${date}-${slug}`;
const category = await tp.system.suggester(["Blog", "Documentation"], ["Blog", "Documentation"]);
const folder = category.toLowerCase() === "documentation" ? "Blog/documentation/_posts" : "Blog/blog/_posts";
await tp.file.move(`Gemini/${folder}/${filename}`);
const tagsInput = await tp.system.prompt("Enter tags (comma separated - single word) ");
const tags = tagsInput.split(",").map(t => t.trim()).filter(t => t.length > 0);
const headerImage = await tp.system.prompt("Header Image Path (optional)");
%>---
title: <% title %>
created: <% date %>
updated: <% date %>
categories: [<% category %>]
tags:
<%* tags.forEach(tag => { %> - <% tag %>
<%* }); %>
<%* if (headerImage) { %>image: <% headerImage %>
<%* } %>---
<% tp.file.cursor() %>
2. The Bridge (Local Sync Script)
File: Gemini/deploy_blog.sh
Purpose: Uses rsync to mirror your local Obsidian blog folder to the remote server. It handles both markdown posts and media assets.
#!/bin/bash
# ————— CONFIGURATION —————
REMOTE_USER="<user>"
REMOTE_HOST="192.168.0.31"
# Local source directory (current Gemini/Blog folder)
LOCAL_DIR_POSTS="/Users/<user>/Documents/HawkVault/Gemini/Blog/"
# Remote destination directory (Jekyll _posts folder)
REMOTE_DIR_POSTS="/home/<user>/blog/"
# Optional: Media/Assets sync
LOCAL_DIR_MEDIA="/Users/<user>/Documents/HawkVault/Gemini/Blog/media/"
REMOTE_DIR_MEDIA="/home/<user>/blog/assets/img/"
# ——————————————————————
# Check if local directory exists
if [ ! -d "$LOCAL_DIR_POSTS" ]; then
echo "Error: Local directory $LOCAL_DIR_POSTS does not exist."
exit 1
fi
echo "🚀 Starting blog deployment..."
echo "📂 Syncing posts from $LOCAL_DIR_POSTS to $REMOTE_HOST:$REMOTE_DIR_POSTS"
# Run rsync
rsync -avz --progress "$LOCAL_DIR_POSTS" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR_POSTS}"
# Sync Media
if [ -d "$LOCAL_DIR_MEDIA" ]; then
echo "🖼️ Syncing media from $LOCAL_DIR_MEDIA to $REMOTE_HOST:$REMOTE_DIR_MEDIA"
rsync -avz --progress "$LOCAL_DIR_MEDIA" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR_MEDIA}"
fi
3. The Engine (Remote Build Script)
File: /home/<user>/blog/blogupdate.sh (On Remote Server 192.168.0.31)
Purpose: Runs the Jekyll build process in the correct Ruby environment and copies the generated HTML to the web server root.
Note: Includes --future flag to ensure posts created today (in different timezones) are still published.
#!/bin/bash
# Define the absolute paths
BUNDLE_PATH="/home/<user>/gems/bin/bundle"
BLOG_ROOT="/home/<user>/blog"
# Grouped execution for reliable directory change
(
# 1. Change to the blog directory
cd "$BLOG_ROOT" || { echo "ERROR: Failed to change directory to $BLOG_ROOT"; exit 1; }
# 2. Build the site. Bundle exec will now find 'jekyll' in vendor/bundle
JEKYLL_ENV=production "$BUNDLE_PATH" exec jekyll b --future || { echo "ERROR: Jekyll build failed."; exit 1; }
)
# 3. Copy files to the web server root
sudo cp -r "$BLOG_ROOT/_site/"* /var/www/html/
3.1 Prerequisites (Server Side)
- Timezone: Synced to
Australia/Adelaideusingntpsec. - Dependencies:
faraday-retrygem installed to support remote plugins.
4. The Trigger (Shell Commands Plugin)
This connects the pieces. You have configured the Shell Commands plugin in Obsidian to run the following sequence.
Command Name: Deploy Blog
Execution:
- Execute Local Script:
sh /Users/<user>/Documents/HawkVault/Gemini/deploy_blog.sh - Execute Remote Build (via SSH):
ssh <user>@192.168.0.x "/home/<user>/blog/blogupdate.sh"
Usage:
- Open Command Palette (
Cmd + P). - Type
Deploy Blog. - Press Enter.
5. How to Use This Agent
- Create New Post:
- Create a new note.
- Run Templater and select
JekyllBlogPost. - Fill in the prompts (Title, Category, Tags).
- Write your content.
- Publish:
- Run the Deploy Blog command via the Command Palette.
- Verify:
- Visit your blog URL. The new post will be live.











Comments