接上篇 用Org Mode + Hugo写博客,并通过Github Action自动部署到Github Pages

痛点

代码仓库里会同时保存org文件和markdown文件,markdown文件其实是中间产物,不想保存。

如何解决

首先,Emacs是可以执行Emacs Script的,写个脚本,然后在Github Action里执行即可。Emacs环境哪里来?purcell大神已经准备好了。

废话不多说,直接上代码。

Export org files in directory DIR to markdown with emacs script and ox-hugo.

Emacs Script

#!/usr/bin/env sh
# filename: batch-export-org-files-to-md-with-ox-hugo.el
:; set -e # -*- mode: emacs-lisp; lexical-binding: t -*-
:; emacs --no-site-file --script "$0" -- "$@" || __EXITCODE=$?
:; exit ${__EXITCODE:-0}

;;; Code:
(defvar bootstrap-version)
(defvar straight-base-dir)
(defvar straight-fix-org)
(defvar straight-vc-git-default-clone-depth 1)
(defvar publish--straight-repos-dir)

(setq gc-cons-threshold 83886080 ; 80MiB
      straight-base-dir (expand-file-name "../.." (or load-file-name buffer-file-name))
      straight-fix-org t
      straight-vc-git-default-clone-depth 1
      publish--straight-repos-dir (expand-file-name "straight/repos/" straight-base-dir))

(let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" straight-base-dir))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
	(url-retrieve-synchronously
	 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
	 'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;;; org && ox-hugo
(straight-use-package '(org :type built-in))
(straight-use-package
 '(ox-hugo :type git
	   :host github
	   :repo "kaushalmodi/ox-hugo"
	   :nonrecursive t))

(defun batch-export-org-files-to-md (dir)
  "Export all org files in directory DIR to markdown."
  (let ((files (directory-files-recursively dir "\\`[^.#].*\\.org\\'")))
    (dolist (file files)
      (message "process %s" file)
      (with-current-buffer (find-file-noselect file)
	(org-hugo-export-wim-to-md t)))))

;;; export
(setq org-hugo-base-dir "xxx")
;;; (setq org-hugo-base-dir (concat default-directory "../hugo/"))
(setq org-file-dir "xxx"))
;;;(setq org-file-dir (concat default-directory "../org/"))
(batch-export-org-files-to-md org-file-dir)

Use in Cli

cd /path/to && sh batch-export-org-files-to-md-with-ox-hugo.el

Use in Github Action

name: GitHub Pages

on:
  push:
    branches:
      - main  # Set a branch to deploy
  pull_request:

jobs:
  deploy:
    runs-on: ubuntu-20.04
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod
      
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.89.4'
          #extended: true

      - name: Setup Emacs
        uses: purcell/setup-emacs@master
        with:
          version: 27.1

      - name: Export Markdown
        run: |
          # 将org文件导出成md文件
          cd /path/to && sh batch-export-org-files-to-md.el

      - name: Build
        run: |
           hugo --source hugo --minify --buildFuture --buildExpired

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        if: ${{ github.ref == 'refs/heads/main' }}
        with:
          # github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          # publish_branch: gh-pages
          # publish_dir: hugo/public
          deploy_key: ${{ secrets.DEPLOY_KEY }}
          external_repository: {username}/{username}.github.io
          # 默认是master目录,github上可修改
          publish_branch: master
          publish_dir: hugo/public

嵌入Gist

1
2
3
#+BEGIN_EXPORT html
<script src="https://gist.github.com/superbear/28fb0dbbca505b5d7d83e10e35b822a4.js"></script>
#+END_EXPORT

等等,直接用markdown写是不是就没有这个痛点了?嗯😄。

存在的问题

目前是全量导出,找到指定目录下的全部org文件,然后转成markdown文件。 这样每提交一篇文章,就需要处理全部存量文章。另外,全部文章的更新时间都会跟着变,这个和HUGO_AUTO_SET_LASTMOD这个property设置有关。详见:ox-hugo last modified 。待改成增量导出。

遇到的问题

1、org导出markdown文件了,但未生成静态文件
原因:时区问题。Github Action是按UTC时间执行的,而文件的发布日期是东八区的,这样Hugo可能会看到发布日期还未到,就不处理了1
解决方案:修改Github Action job的时区,可一并解决文件修改时间不对的问题;或修改Hugo运行时的配置,增加–buildFuture参数。

参考文档

using ox-hugo without duplicating content in the repository

Github action which installs a given Emacs version

如何编写EmacsScript