In recent years, various methods for publishing static blogs have emerged, but many are either complex or difficult to maintain long-term. This article introduces a simple and efficient approach: using GitHub Issues as the publishing endpoint for a Hugo blog, leveraging GitHub Actions to automatically convert Issues into Hugo content and deploy to GitHub Pages. This method is particularly suitable for users who prefer using the GitHub mobile app to publish blog posts anytime, anywhere. Based on Lao T’s practical experience, this tutorial addresses issues such as downloading images from private repositories and extracting tags, and is suitable for both public and private repositories.
Why Choose GitHub Issues?
- Convenience: The GitHub mobile app is more stable than the web version in domestic network environments, and publishing requires just a few clicks—simpler than posting on WeChat Moments.
- No Limits: Issues have virtually no quantity or capacity restrictions, making them ideal for storing blog content.
- Automation: Through GitHub Actions, Issues can be automatically converted into Hugo content and trigger site builds.
- Flexibility: Supports images, tags, and categories, suitable for short “thoughts” or long articles.
Prerequisites
- A Hugo blog project already configured with GitHub Pages (public or private repository).
- A GitHub Personal Access Token (PAT) with
repopermissions (required for private repositories) andworkflowpermissions (to trigger workflows). Create it in GitHub Settings → Developer settings → Personal access tokens. - Basic knowledge of GitHub Actions and Hugo.
- A repository structure that includes a
content/posts/directory for storing generated articles.
Implementation Steps
1. Configure GitHub Actions Workflows
We need two workflow files:
deploy.yml: Converts Issues into Hugo content and commits it to the repository.hugo.yml: Builds the Hugo site and deploys it to GitHub Pages.
1.1 Create deploy.yml
Add the following content to .github/workflows/deploy.yml to handle converting Issues into Hugo content and triggering the Hugo build:
| |
Key Points:
- Trigger Conditions: When an Issue is opened with the “发布” label, or manually triggered.
- Prevent Recursion:
github.actor != 'IssueBot'ensures that commits by IssueBot do not trigger the workflow again. - Change Detection: Commits only occur when content changes (via file hash comparison).
- Trigger Hugo Build: Calls the Hugo workflow via the
repository_dispatchevent (trigger-hugo-build).
1.2 Create hugo.yml
Add the following content to .github/workflows/hugo.yml to build and deploy the Hugo site:
| |
Key Points:
- Trigger conditions:
pushto themasterbranch, manual triggers, orrepository_dispatchevents (trigger-hugo-build). - Permissions: Ensure
pages: writeandid-token: writefor GitHub Pages deployment.
1.3 Add Conversion Script issue_to_hugo.py
Add the following Python script in .github/workflows/issue_to_hugo.py to convert Issues into Hugo content, supporting private repository image downloads and tag extraction:
| |
Key Points:
- Image Download:
download_imageuses PAT authentication header (Authorization: token {token}), supporting private repository attachment downloads. - Tag Extraction: Extracts
$tag$format tags from the last line of the Issue body (supports spaces, e.g.,$what's up$). - Duplicate Check: Skips existing article directories (
YYYYMMDD_X). - Markdown Generation: Generates standard Hugo frontmatter andContent, images converted to local paths.
2. Setting Up PAT
Create PAT:
- Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic).
- Create a new PAT, check the boxes for
repo(including access to private repositories) andworkflow(to trigger workflows). - Copy the generated token.
Add to Repository:
- Navigate to the repository (e.g.,
h2dcc/lawtee.github.io) → Settings → Secrets and variables → Actions → Secrets. - Add a new secret named
PAT_TOKENand paste the PAT value.
- Navigate to the repository (e.g.,
3. Writing an Issue to Publish a Blog Post
Compose your blog post in a GitHub Issue using the following format:
- Add a “Publish” Label:
- Create a new Issue and add the
发布label along with category labels (e.g.,技术,生活).
- Create a new Issue and add the
- Body Format:
- Title: The Issue title serves as the blog post title.
- Cover Image: The first image in the body acts as the cover (in Markdown:
). - Body: Written in Markdown format, supporting images, headings, links, etc.
- Tags: Add tags in the last line using the
$tag$format (spaces are allowed, e.g.,$Hugo Post$).
- Example Issue:
1 2 3 4 5 6 7 ## My First Hugo Blog Post This is a blog post published via a GitHub Issue. Supports **Markdown** format, and images will be automatically downloaded locally. <!--more-->  $Hugo$ $博客$ $Hugo Post$ - Submit: Save the Issue to trigger the
deploy.ymlworkflow.
4. Workflow Execution Process
Trigger
deploy.yml:- When an Issue is opened (with the “发布” label) or triggered manually.
- The script
issue_to_hugo.pyruns:- Extracts the title, categories (from labels), body, cover image, and tags.
- Downloads images (using PAT authentication for private repositories).
- Generates a Markdown file at
content/posts/YYYYMMDD_X/index.md. - Commits to the
masterbranch.
- Triggers
hugo.ymlvia arepository_dispatchevent.
Trigger
hugo.yml:- Builds the Hugo site (
hugo --minify). - Deploys to GitHub Pages.
- Builds the Hugo site (
5. Verifying Publication
Check Actions Logs:
- Open the GitHub Actions tab.
- Confirm
Sync Issues to Hugo Contentruns:- Logs show
图片下载成功(Images downloaded successfully) and成功转换 issue #X(Successfully converted issue #X). - Commits to
master(e.g.,Automated: Sync GitHub Issues as content).
- Logs show
- Confirm
Deploy Hugo site to Pagesruns:- Check the
Build with HugoandDeploy to GitHub Pagessteps.
- Check the
Check Generated Files:
- Open
content/posts/YYYYMMDD_X/:index.mdcontains frontmatter (title,date,slug,categories,tags,image) and the body.- Local image files exist (e.g.,
X_uuid.jpg).
- Example
index.md:1 2 3 4 5 6 7 8 9 10 11 12 13--- title: "My First Hugo Blog Post" date: "2025-10-27" slug: "20251027_2" categories: ["技术"] tags: ["Hugo", "博客", "Hugo Post"] image: "cover_5cc86d74-ff70-401f-820d-520a99a504b9.jpg" --- ## My First Hugo Blog Post This is a blog post published via a GitHub Issue. Supports **Markdown** format, and images are automatically downloaded locally. <!--more--> 
- Open
Visit the Site:
- Go to the GitHub Pages site (e.g.,
https://h2dcc.github.ioor the Pages URL for private repositories). - Confirm the new post appears, images load correctly, and tags and categories are accurate.
- Go to the GitHub Pages site (e.g.,
6. Common Issues and Solutions
- Image Download Fails (404):
- Cause: Private repository images require PAT authentication.
- Solution: Ensure
PAT_TOKENhasrepopermissions and the script includes authentication headers.
- Hugo Build Not Triggered:
- Cause:
repository_dispatchevent failure. - Solution: Check the
Trigger Hugo buildstep logs indeploy.ymlto confirm thecurlrequest returns 204.
- Cause:
- Tags Not Extracted:
- Cause: Incorrect tag format or not placed in the last line.
- Solution: Ensure tags are in the
$tag$format on the last line, with spaces included within$(e.g.,$搞啥 呢$).
- Duplicate Posts:
- Cause: The script skips existing directories (
YYYYMMDD_X). - Solution: Delete
content/posts/YYYYMMDD_X/and rerun the process.
- Cause: The script skips existing directories (
7. Optimization Suggestions
- Single Issue Handling: Modify
deploy.ymlandissue_to_hugo.pyto process only the triggering Issue, reducing runtime. - Error Notifications: Add comments to the Issue to notify users of conversion failures.
- Mobile Optimization: Use the GitHub mobile app + Shortcut Maker to simplify the publishing process.
- Log Inspection: Enable
--debugmode to check detailed logs.
Summary
Publishing Hugo blog posts via GitHub Issues enables a streamlined workflow from quick mobile publishing to automatic deployment. Compared to traditional methods, this approach is simple, efficient, and ideal for bloggers who need to capture ideas on the go. Whether for public or private repositories, with PAT authentication and GitHub Actions, images, tags, and categories are handled seamlessly. Give it a try!
