AI Blog Writer
The ultimate GitHub Actions masterpiece. Bridge Git, Google Gemini AI, and Hashnode to automate your technical writing process from commit to publication.
AI Content Factory
Automated Pipeline: Topic → AI → Published Post
Secret Vault
GEMINI_API_KEY
Google AI Studio
HASHNODE_API_KEY
Hashnode Dev Settings
HASHNODE_TOKEN
Publication ID
Project Structure
├── topics/ # Your bullet points
├── posts/ # AI generated posts
├── scripts/ # Generator logic
└── .github/workflows/
Phase 1: The Orchestrator
Detecting changes and triggering the AI expansion.
# AUTO BLOG WRITER — GitHub Actions + Google Gemini + Hashnode
name: Auto Blog Writer
on:
push:
paths:
- "topics/**" # Only triggers when you add/edit a file in topics/
workflow_dispatch: # Also run manually from GitHub UI
inputs:
topic_file:
description: "Which topic file to process? (e.g. topics/my-topic.md)"
type: string
required: false
jobs:
write-and-publish:
name: "Write Blog Post with AI and Publish"
runs-on: ubuntu-latest
permissions:
contents: write # Needed to commit the generated post back
steps:
- name: "1. Download the repo"
uses: actions/checkout@v4
with:
persist-credentials: true
fetch-depth: 2 # Need 2 commits to detect which files changed
- name: "2. Set up Node.js"
uses: actions/setup-node@v4
with:
node-version: "20"
- name: "3. Find which topic file was just added or changed"
id: find-topic
run: |
if [ -n "${{ inputs.topic_file }}" ]; then
# Manual trigger — use the file they specified
TOPIC_FILE="${{ inputs.topic_file }}"
else
# Auto trigger — find which topics/ file changed in this push
TOPIC_FILE=$(git diff --name-only HEAD~1 HEAD -- 'topics/*.md' | head -1)
fi
if [ -z "$TOPIC_FILE" ]; then
echo "No topic file found. Skipping."
echo "found=false" >> $GITHUB_OUTPUT
else
echo "Found topic file: $TOPIC_FILE"
echo "found=true" >> $GITHUB_OUTPUT
echo "file=$TOPIC_FILE" >> $GITHUB_OUTPUT
fi
- name: "4. Write and publish the blog post"
if: steps.find-topic.outputs.found == 'true'
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
HASHNODE_API_KEY: ${{ secrets.HASHNODE_API_KEY }}
HASHNODE_PUBLICATION_TOKEN: ${{ secrets.HASHNODE_PUBLICATION_TOKEN }}
TOPIC_FILE: ${{ steps.find-topic.outputs.file }}
run: node scripts/auto-blog-writer.js
- name: "5. Commit generated post"
if: steps.find-topic.outputs.found == 'true'
run: |
git config user.name "Blog Writer Bot"
git config user.email "adityatrivedi612@gmail.com"
git add posts/
git add .published.json || true
if git diff --staged --quiet; then
echo "Nothing to commit."
else
git commit -m "📝 Auto-generated blog post [skip ci]"
git push
fiHybrid Detection
Detects topics via 'git diff' for auto-runs, or uses 'inputs.topic_file' for manual runs. No code duplication.
Write Access
Explicitly grants 'contents: write' so the bot can commit the generated markdown back to your repo.
[skip ci] Guard
Prevents infinite loops by telling GitHub not to trigger another run from this bot's commit.
Checkout with Fetch-Depth
By default, checkout only fetches 1 commit. We use 'fetch-depth: 2' so Git can compare HEAD with the previous commit to see which files changed.
The 'Find Topic' Logic
A Bash script that identifies the topic file. It prioritizes manual input; if empty, it uses 'git diff' to find the first renamed or added markdown file in 'topics/'.
Bot Identity & Push
Configures a custom bot name/email for the commit. It checks if there are actual changes using 'git diff --staged' before pushing to avoid empty commits.
Phase 2: The Generator
Inside the Node.js script that bridges AI and Publishing.
Prompt Engineering
The heart of the system. We feed Gemini a structured prompt that sets the tone (Conversational), audience (Developers), and format (Markdown).
GraphQL Publishing
Bypasses standard REST. We use GraphQL mutations to create a draft on Hashnode with the title and AI-generated content.
State Persistence
Maintains a '.published.json' file to track already processed topics, preventing duplicate posts if a workflow re-runs.
Get the Full Source Code
The complete GitHub Actions Series repository is open-sourced. Dive into the code for all 10 tutorials.
