Skip to content

lawale/seance

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Séance

Publish Markdown files to Ghost CMS. Two ways to do it: a browser-based uploader for quick manual posts, and a GitHub Action that syncs your repo's .md files to Ghost on every push.

What's in the repo

action.yml              # GitHub Action definition
src/                    # Action source code
dist/index.js           # Compiled action bundle
docs/index.html         # Static web UI — drag-and-drop uploader

Web UI

A single HTML file. No build step, no dependencies to install. Open it in a browser or host it on GitHub Pages.

Setup

  1. In your Ghost Admin, go to Settings > Integrations > Add custom integration
  2. Copy the Admin API Key (looks like 64hexchars:64hexchars)
  3. Open docs/index.html in your browser
  4. Paste your Ghost URL and API key, hit Save

Your credentials stay in localStorage. Nothing leaves your browser except the API calls to your Ghost instance.

Usage

Drop .md files onto the upload area (or click to browse). Each file becomes a draft post in Ghost. You'll get a direct link to edit each one in Ghost Admin.

Frontmatter

Séance reads YAML frontmatter from your Markdown files. All fields are optional; if you skip title, the filename gets used instead.

---
title: How we migrated to Postgres
tags: [engineering, databases]
excerpt: What went wrong and what we'd do differently.
slug: postgres-migration
feature_image: https://cdn.example.com/og-image.png
featured: true
status: draft
---

Your post content starts here.
Field Type What it does
title string Post title. Falls back to filename.
tags string or list Assigns Ghost tags. Creates them if they don't exist.
excerpt string Custom excerpt shown in post previews.
slug string URL slug. Ghost auto-generates one if omitted.
feature_image URL string Featured image URL for the post.
featured boolean Pin post as featured.
status string draft (default) or published.

GitHub Action

Keep blog posts in a Git repo as .md files. On push, Séance diffs against the previous commit and syncs changes to Ghost: new files become posts, modified files update existing posts, deleted files get unpublished (set to draft).

Quick start

Add this workflow to your blog repo at .github/workflows/publish.yml:

name: Publish to Ghost
on:
  push:
    branches: [main]
    paths: ['posts/**']

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2  # Required — Séance needs the parent commit for diffing
      - uses: your-username/seance@v1
        with:
          ghost-url: ${{ secrets.GHOST_URL }}
          ghost-admin-api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}

Action inputs

Input Required Default Description
ghost-url yes Your Ghost instance URL
ghost-admin-api-key yes Admin API key (id:secret format)
posts-dir no posts/ Directory containing your .md files
default-status no draft Status for new posts without status in frontmatter

Action outputs

Output Description
created Number of posts created
updated Number of posts updated
unpublished Number of posts set to draft (from deleted files)
errors Number of files that failed

How it works

  1. Runs git diff between the current and previous commit
  2. For each added/modified .md file: parses frontmatter, converts to HTML, uploads relative images to Ghost, creates or updates the post (matched by slug)
  3. For deleted .md files: reads the old file from git history to get the slug, sets the post to draft

Images

Two options, both work:

  • External URLs — reference images hosted on S3, a CDN, wherever. They pass through as-is.
  • Relative paths — put images next to your .md files (e.g. ./images/diagram.png). Séance uploads them to Ghost's media library and rewrites the URLs automatically.

Important: fetch-depth: 2

The action needs the parent commit to diff against. Without fetch-depth: 2 in your checkout step, GitHub's shallow clone won't have it and the action will fail.

Running locally

Open the file directly:

open docs/index.html

If your Ghost instance blocks file:// origins (CORS), serve it locally instead:

cd docs && python3 -m http.server 8080

Then visit http://localhost:8080.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors