Skip to content

hibi-com/developersblog

Repository files navigation

Multi-Platform Blog Publisher

English | ζ—₯本θͺž

An automated multi-platform blog publishing system.
Write blog posts in Japanese, auto-translate to English, and deploy to multiple platforms automatically.

πŸš€ Features

  • Draft Creation: Create blog posts from templates via GitHub Actions, automatically generating Pull Requests
  • Preview: Auto-deploy preview sites for each PR
  • Article Management: Unpublish or delete published articles
  • Multi-platform Deployment:
    • πŸ‡―πŸ‡΅ Japanese: Qiita, Zenn, note
    • πŸ‡ΊπŸ‡Έ English: dev.to, Medium, daily.dev

πŸ“ Directory Structure

β”œβ”€β”€ draft_entries/
β”‚   β”œβ”€β”€ ja/          # Japanese drafts
β”‚   └── en/          # English drafts (auto-generated)
β”œβ”€β”€ entries/
β”‚   β”œβ”€β”€ ja/          # Published Japanese articles
β”‚   └── en/          # Published English articles
β”œβ”€β”€ templates/       # Article templates
β”œβ”€β”€ images/          # Article images (auto-uploaded to Cloudflare Images)
β”‚   └── yyyy/mm/dd/  # Date-based directories
└── .github/
    β”œβ”€β”€ templates/   # Preview HTML templates
    └── workflows/   # GitHub Actions workflows

πŸ“ Template List

Choose from the following templates when creating a draft:

Template Description Use Case
tech-article Technical articles Technical explanations, knowledge sharing
tutorial Tutorial format Hands-on, step-by-step guides
review Reviews Product/service/tool reviews
retrospective Retrospectives Monthly reviews, project retrospectives
news Announcements Release notes, announcements
til Today I Learned Daily learnings, small discoveries

Adding Custom Templates

Add new Markdown files to the templates/ directory to create custom templates.

Available variables in templates:

  • ${TITLE} - Article title
  • ${DATE} - Creation date (YYYY-MM-DD)
  • ${SLUG} - Article slug (used for Stack Overflow tags, etc.)

πŸ”§ Setup

1. Enable GitHub Pages

To use the preview feature, enable GitHub Pages:

  1. Go to repository Settings > Pages
  2. Select gh-pages branch as Source
  3. Click Save

github-pages-setup-image

2. Repository Secrets Configuration

Configure the following secrets in Settings > Secrets and variables > Actions.

github-actions-secret-manager-setup-image

Required Secrets

Secret Name Description How to Obtain
OPENAI_API_KEY OpenAI API Key (for translation) OpenAI Platform
openai-api-key-get-image
PAT_TOKEN Personal Access Token (for sample repo creation/deletion) GitHub Settings with repo permission
github-accesstoken-get-image
CLOUDFLARE_ACCOUNT_ID Cloudflare Account ID Cloudflare Dashboard URL
cloudflare-account-id-get-image
CLOUDFLARE_API_TOKEN Cloudflare API Token API Tokens with Images edit permission
cloudflare-api-token-get-image
CLOUDFLARE_ACCOUNT_HASH Cloudflare Images Account Hash Cloudflare Dashboard > Images > Overview
cloudflare-image-account-hash-get-image
QIITA_ACCESS_TOKEN Qiita Access Token Qiita Settings with read_qiita and write_qiita enabled
qiita-accesstoken-get-image
NOTE_EMAIL note Login Email Your note account
NOTE_PASSWORD note Login Password Your note account
DEVTO_API_KEY dev.to API Key dev.to Settings API Keys section
devto-api-key-get-image
MEDIUM_ACCESS_TOKEN Medium Integration Token Medium Settings Integration tokens
medium-accesstoken-get-image
MEDIUM_USER_ID Medium User ID Via API (see below)

3. Getting Medium User ID

medium-user-id-get-image

curl -H "Authorization: Bearer YOUR_MEDIUM_ACCESS_TOKEN" \
  https://api.medium.com/v1/me

The data.id in the response is your User ID.

4. Zenn Integration

Zenn uses GitHub repository integration for automatic deployment.

  1. Log in to Zenn
  2. Configure GitHub integration from Deploy Settings
    zenn-account-link-for-github-image
  3. Link this repository

5. daily.dev Integration

daily.dev discovers articles via RSS feeds or other platforms.

  1. Articles published on dev.to or Medium are automatically discovered
  2. To register a custom RSS feed: https://daily.dev/submit-source

6. Create GitHub Labels

Create labels from repository Settings > Labels.

System Labels (Required)

Label Name Color Description
draft #fbca04 πŸ“ Draft article
published #0e8a16 πŸš€ Published article
needs-review #d93f0b πŸ‘€ Needs review
wip #1d76db 🚧 Work in progress
japanese #bc002d πŸ‡―πŸ‡΅ Japanese article
english #012169 πŸ‡ΊπŸ‡Έ English article

Category Labels (Optional)

When added to a PR, these labels are auto-synced to the article's categories.

Label Name Color Description
javascript #f1e05a JavaScript
typescript #3178c6 TypeScript
react #61dafb React
nextjs #000000 Next.js
nodejs #339933 Node.js
python #3776ab Python
devops #326ce5 DevOps
github-actions #2088ff GitHub Actions
docker #2496ed Docker
aws #ff9900 AWS
database #336791 Database
security #d73a4a Security
performance #7057ff Performance
testing #0e8a16 Testing
career #e99695 Career
learning #bfdadc Learning / TIL

πŸ“ Writing Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. Run "Create Blog Draft and PR" from Actions                 β”‚
β”‚     β†’ Select template β†’ Create draft β†’ Auto-generate PR         β”‚
β”‚     β†’ (Optional) Auto-create sample repository                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  2. Write while checking preview site                           β”‚
β”‚     β†’ Add images β†’ Auto-upload to Cloudflare Images             β”‚
β”‚     β†’ Add labels β†’ Auto-sync to categories                      β”‚
β”‚     β†’ CI (textlint, markdownlint, cspell, etc.) quality check   β”‚
β”‚     β†’ Auto-translate to English                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  3. Review approval β†’ Article status changes to "publishable"   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  4. Merge PR β†’ Auto-deploy to each platform                     β”‚
β”‚        Japanese β†’ Qiita, Zenn, note                             β”‚
β”‚        English  β†’ dev.to, Medium, daily.dev                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. Create Draft

  1. Open the Actions tab
  2. Select Create Blog Draft
  3. Click Run workflow
  4. Enter the following:
    • Blog Title: Article title
    • Slug: For filename (alphanumeric and hyphens)
    • Template: Select according to article type
    • Create sample repository: Check if you need a sample code repository
    • Sample repository template: Specify template repository (leave empty for blank repo)

2. Writing

  1. Check the created Pull Request
  2. Preview URL will be posted in comments - write while checking it
  3. Edit Markdown files in draft_entries/ja/
  4. Add images to images/YYYY-MM-DD/ (auto-uploaded to CDN)
  5. Add labels to PR (auto-synced to categories)
  6. On push, automatically:
    • Preview site updates
    • CI (textlint, markdownlint, cspell, prettier) quality check
    • Auto-translate to English (saved to draft_entries/en/)

3. Review & Approval

  1. Check both Japanese and English content in preview
  2. Fix CI errors
  3. When you Approve the review, article status automatically changes to "publishable"

4. Merge & Auto-Deploy

When you merge the PR, only articles with draft: false are automatically deployed to:

  • πŸ‡―πŸ‡΅ Japanese: Qiita, Zenn, note
  • πŸ‡ΊπŸ‡Έ English: dev.to, Medium, daily.dev

πŸ“¦ Article Management

Unpublish an Article

You can temporarily unpublish a published article and move it back to drafts.

  1. Open the Actions tab
  2. Select Unpublish Article (Move to Draft)
  3. Enter the following:
    • article_path: Article path (e.g., entries/ja/2024-01-01-my-article.md)
    • reason: Reason for unpublishing (optional)

What happens:

  • Moves from entries/ to draft_entries/
  • Changes front matter draft: false β†’ draft: true
  • Changes Qiita article to private
  • Changes dev.to article to draft

Delete an Article

You can delete an article and all related resources.

  1. Open the Actions tab
  2. Select Delete Article
  3. Enter the following:
    • article_path: Article path
    • delete_sample_repo: Check to also delete sample repository
    • confirm: Type DELETE (deletion confirmation)

What gets deleted:

  • Article files (both Japanese and English)
  • Local image files
  • Cloudflare Images
  • Platform articles (Qiita, dev.to)
  • Sample repository (optional)

⚠️ This operation cannot be undone.

πŸ’¬ Questions & Feedback

Questions about articles are accepted on Stack Overflow.
Each article has a Stack Overflow tag (the article slug). Use that tag when asking questions.

πŸ› οΈ Workflow List

Draft & Writing

Workflow Trigger Description
create-draft.yaml Manual (workflow_dispatch) Create draft from template, create PR, create sample repo
upload-images.yaml PR (images/**) Upload images to Cloudflare Images
sync-labels.yaml PR (labeled/unlabeled) Sync labels to categories
preview.yaml PR (draft_entries/**) Deploy preview site
translate-draft.yaml PR (draft_entries/ja/**) Japanese β†’ English translation
publish-draft.yaml PR review approval Change draft β†’ publishable

CI

Workflow Trigger Description
ci.yml PR (draft_entries/**) Quality check with textlint, markdownlint, cspell, prettier

Deploy

Workflow Trigger Description
deploy-japanese.yaml push to master Deploy to Qiita, Zenn, note
deploy-english.yaml push to master Deploy to dev.to, Medium, daily.dev

Article Management

Workflow Trigger Description
unpublish-article.yaml Manual (workflow_dispatch) Unpublish article and move to drafts
delete-article.yaml Manual (workflow_dispatch) Delete article and related resources

πŸ” CI Check Contents

The following checks run automatically when you create a PR:

Check Tool Description
Japanese text textlint Technical writing checks for Japanese
Markdown syntax markdownlint Markdown syntax and style checks
Spelling cspell English spelling checks
Formatting prettier Code format checks

Running Locally

npm run lint

βš™οΈ Customization

Template Customization

Edit files in the templates/ directory or add new templates.

Translation Prompt Adjustment

Edit the system prompt in translate-draft.yaml to customize translation style.

Adding Deploy Targets

To add new platforms, add jobs to the corresponding workflow files.

System Label Configuration

Edit the systemLabels array in sync-labels.yaml to set labels that don't sync to categories.

Lint Configuration Customization

Config File Description
.textlintrc textlint rule settings
.markdownlint.json markdownlint rule settings
.cspell.json cspell dictionary and exclusion settings
.prettierrc prettier format settings

πŸ“‹ Troubleshooting

Preview not displaying

  • Check if GitHub Pages is enabled
  • Check if gh-pages branch exists

Images not uploading

  • Check if Cloudflare secrets are correctly configured
  • Check if image files are placed in images/ directory

Categories not syncing

  • Check if labels are added to PR
  • Check if labels are not system labels (draft, blog, etc.)

Translation not running

  • Check if OPENAI_API_KEY is correctly configured
  • Check if changed files are in draft_entries/ja/

Deploy failing

  • Check if API keys/tokens for each platform are correct
  • Check if API limits have been reached
  • Check if article status is draft: false

Sample repository not being created

  • Check if PAT_TOKEN is correctly configured
  • Check if token has repo permission

CI errors

  • Check error details and fix the relevant parts
  • Adjust config files if no fix is needed

πŸ“ž Contact

Feel free to open Issues or Pull Requests.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors