Skip to content

feat: integrate OGP image generation into generate command (--with-ogimage) - #160

Open
rokuosanai wants to merge 24 commits into
rokuosan:mainfrom
rokuosanai:feat/ogimage-generate-integration
Open

feat: integrate OGP image generation into generate command (--with-ogimage)#160
rokuosanai wants to merge 24 commits into
rokuosan:mainfrom
rokuosanai:feat/ogimage-generate-integration

Conversation

@rokuosanai

Copy link
Copy Markdown
Contributor

Summary

Implements milestone 3 of #21 — integrates OGP image generation into the generate command via an opt-in --with-ogimage flag.

Changes

  • pkg/core/generator.go — Add OnArticleSaved callback hook to ArticleGenerator for post-processing after each article save. The callback is non-blocking — errors are logged as warnings and processing continues.
  • cmd/cli/subcommand/generate.go — Add --with-ogimage boolean flag. When set:
    • Creates an ogimage.Renderer and registers it as the OnArticleSaved callback
    • After each article is saved, generates ogp.jpeg in the article's output directory
    • When not set, behavior is completely unchanged (opt-in)
  • cmd/cli/cli_test.go — Updated to verify ogimage subcommand registration
  • Tests — Unit tests for --with-ogimage flag existence, CLI flag parsing

Depends on

Usage

github-issue-cms generate --token YOUR_TOKEN --with-ogimage

Closes #155
Closes #21

- Add ParseArticleFromMarkdown to core package for reading Hugo-compatible
  markdown files with YAML frontmatter back into core.Article
- Add 'ogimage' subcommand to CLI with -f/--file and -t/--template flags
- Convert Article to OGPData and render via pkg/ogimage
- Output ogp.jpeg into the configured image output directory
- Register ogimage command in root CLI

Closes rokuosan#154
- Add --with-ogimage flag to generate subcommand (opt-in)
- Add OnArticleSaved callback hook to ArticleGenerator for post-processing
- When --with-ogimage is set, OGP images are generated alongside each article
- OGP images saved as ogp.jpeg in the article's output directory
- Preserves existing behavior when flag is not set

Closes rokuosan#155
…an#158 review)

If browser.Connect() fails after launcher.Launch() succeeds, the
chromium process would leak because Leakless(false) was set. Now
we call l.Kill() on connection failure to clean up the orphaned
process.
…uosan#159)

- articleToOGPData: return zero-value OGPData when article is nil
- resolveOGPOutputPath: return error when article is nil or Output config missing
- Add filepath.Clean for path safety
…adversarial review)

CRITICAL: Previously all articles saved ogp.jpeg to the same directory,
causing each article to overwrite the previous one's OGP image.
Now uses article.Key as a subdirectory for per-article isolation.

Also:
- Add nil guards in generateOGPForArticle and resolveOGPArticlePath
- Add context cancellation check before expensive render
- Add filepath.Clean for path safety
- Add tests for new path resolution and nil cases
…dit rokuosan#159)

- Normalize Windows CRLF line endings to LF
- Handle closing frontmatter delimiter at EOF (--- without trailing newline)
- Add frontmatter prefix validation before parsing
…audit rokuosan#160)

- Track ogpOK/ogpFail counters to show accurate OGP image generation stats
- Previously errors were silently swallowed — now user sees how many OGP images succeeded/failed
- Remove unused strconv import
@rokuosan

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b89184e2d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/cli/subcommand/generate.go Outdated
Comment thread cmd/cli/subcommand/generate.go Outdated
rokuosan#160 review)

P1: resolveOGPArticlePath now checks the article filename pattern.
For page bundles (index.md), OGP goes alongside in the same directory.
For flat layouts, uses article Key as subdirectory to prevent overwrites.
This matches the actual file layout used by FileSystemArticleRepository.

P2: Apply frontmatter overrides before converting to OGPData so the
OGP image matches the rendered markdown, not raw GitHub metadata.
Export ApplyFrontMatterOverrides from core package for reuse.
@rokuosan

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4fe446677a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/cli/subcommand/generate.go Outdated
Comment thread pkg/core/generator.go Outdated
Comment thread cmd/cli/subcommand/generate.go Outdated
…eview)

- Flat layout: save OGP as adjacent file <name>.ogp.jpeg next to <name>.md
  instead of orphaned <key>/ogp.jpeg subdirectory (P1)
- Log hook failures and failure summary at Error level so they're visible
  at default verbosity (P1)
- Pass frontmatter-overridden article to path resolver so OGP lands in
  the same directory as the markdown (P2)
@rokuosan

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1e3d441eb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkg/core/generator.go
Comment on lines +125 to +129
if err := g.onArticleSaved(article); err != nil {
// Log at Error level: the CLI's default verbosity filters
// out Warn, which would make hook failures (e.g. OGP image
// generation) completely invisible in a normal run.
g.logger.Error("Post-save hook failed for article", "issue", issue.GetNumber(), "error", err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Propagate cancellation from the final post-save hook

When the context is cancelled while the final article's OGP image is rendering—for example, the user presses Ctrl-C—Renderer.Render returns a cancellation error, but this block only logs and discards it. Because there is no subsequent loop iteration to execute the ctx.Err() check, Generate returns success and the CLI exits with status 0 despite the interrupted image generation; check and return ctx.Err() after invoking the hook.

Useful? React with 👍 / 👎.

rokuosan and others added 2 commits July 29, 2026 20:13
…review)

- Only strip known markdown extensions (.md/.markdown) before appending
  .ogp.jpeg; other extensions (e.g. .post, .txt) now get the suffix
  appended to the full filename so the image always stays adjacent
- Add test cases for .post and .markdown filenames
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate OGP generation into generate (--with-ogimage) OGP Image generation

2 participants