Conversation
- Add Node static-site generator (scripts/build.mjs) rendering posts/*.md to public/ via marked + gray-matter; npm run build/serve. - Add sample post and .gitignore (node_modules/, public/). - Replace placeholder CI with publish.yml: scheduled daily build + auto-deploy to GitHub Pages from main. - Document develop-default branch policy in AGENTS.md and README; enable npm ci in .codex/setup.sh. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR implements a complete static site generation system for OpenBlog, transforming it from a scaffold into a working blog platform. It adds a Node.js build pipeline that parses Markdown posts, generates HTML pages, and automates deployment to GitHub Pages via CI/CD. ChangesStatic Site Generation and Publication
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Git as Git/GitHub
participant CI as GitHub Actions
participant Generator as Build Script
participant Pages as GitHub Pages
Dev->>Git: git push to main
Git->>CI: Trigger publish workflow
CI->>CI: Checkout code
CI->>CI: Install Node.js 20
CI->>Generator: Run npm run build
Generator->>Generator: Read posts/, parse YAML
Generator->>Generator: Render HTML from Markdown
Generator->>Generator: Write public/
CI->>CI: Upload public/ artifact
CI->>Pages: Deploy via actions/deploy-pages@v4
Pages->>Dev: Site live at GitHub Pages URL
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
README.md (1)
112-124:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winCritical: Branch policy contradicts AGENTS.md and project learnings.
Line 123 states "默认分支为
main" (default branch ismain), but this directly contradicts:
- AGENTS.md lines 34-37: "
develop— integration branch. This is the default branch for all work and pushes."- Retrieved learnings: "Default branch for all work and pushes is 'develop'"
- The branch rules section above (lines 114-115) which correctly identifies
developas the defaultLine 123 should state that
developis the default branch for development work.🔧 Proposed fix
本仓库对 AI 编码 Agent 友好。若你使用 **OpenAI Codex** 等 Agent 协作开发: - 先阅读 [AGENTS.md](AGENTS.md) 了解仓库约定与目标结构。 - 环境准备脚本位于 [.codex/setup.sh](.codex/setup.sh)。 -- 默认分支为 `main`,集成分支为 `develop`;Pull Request 请提交到 `main`。 +- 默认分支为 `develop`,生产分支为 `main`;日常开发请提交到 `develop`,仅在发布时合并到 `main`。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 112 - 124, The README contains a contradictory sentence that says "默认分支为 `main`" while the branch rules and AGENTS.md declare `develop` as the default branch; update the sentence that currently reads "默认分支为 `main`" so it instead states "默认分支为 `develop`" (or otherwise clarifies that `develop` is the default branch for development and PRs), ensuring the README's "参与开发" section and the referenced AGENTS.md remain consistent with the earlier branch rules that designate `develop` as the integration/default branch.Source: Learnings
🧹 Nitpick comments (2)
.github/workflows/publish.yml (2)
35-35: ⚡ Quick winConsider disabling credential persistence in checkout.
Adding
persist-credentials: falseto the checkout action prevents theGITHUB_TOKENfrom being persisted in the local git config, reducing the risk if a subsequent step is compromised. While this workflow doesn't push code back to the repository, it's a good defensive practice.🔒 Proposed fix
- - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/publish.yml at line 35, Update the actions/checkout step (uses: actions/checkout@v4) to disable credential persistence by adding persist-credentials: false to the step configuration so the GITHUB_TOKEN is not written to local git config; locate the checkout step in the workflow and insert the persist-credentials key under that step with a boolean false value.
21-29: ⚡ Quick winConsider scoping GitHub Pages permissions to the deploy job.
The
pages: writeandid-token: writepermissions are currently set at the workflow level but are only required by thedeployjob. Following the principle of least privilege, these should be scoped to the job that needs them.🔒 Proposed fix to scope permissions
permissions: contents: read - pages: write - id-token: write # Allow only one concurrent deployment. concurrency: @@ -52,6 +50,9 @@ deploy: needs: build runs-on: ubuntu-latest + permissions: + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/publish.yml around lines 21 - 29, Move the high-privilege permissions out of the workflow-level permissions block and scope them to the job that performs the deployment: remove or reduce "pages: write" and "id-token: write" from the top-level permissions section and add a permissions block to the deploy job that explicitly sets pages: write and id-token: write (keeping other permissions like contents: read at the workflow level if needed); update the deploy job definition (the job named "deploy" in the workflow) to include the per-job permissions so only that job has pages and id-token write access.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Around line 15-30: The fenced code block in AGENTS.md showing the repository
layout lacks a language specifier; update the opening fence to include a
language (e.g., change ``` to ```plaintext or ```text) so the block becomes
"```plaintext" and leave the closing fence intact; this ensures proper syntax
highlighting and linting compliance for the repository layout block.
In `@package.json`:
- Line 9: The inline dev server command in the "serve" script uses a typo
calling s.writeCode?0:0 inside the h.createServer request handler (args q,s)
which does not set the HTTP status; replace that expression with a proper call
to s.writeHead(404) before returning so the response is sent with the correct
404 status (ensure the handler still calls s.end('Not found') after writeHead).
Locate the anonymous request handler used in the serve script (the
h.createServer callback) and update the error branch accordingly.
In `@README.md`:
- Around line 103-110: The fenced code block in README.md containing the
directory listing (lines with "posts/", "scripts/build.mjs", "public/",
".github/workflows/") lacks a language specifier; update the opening fence from
``` to include a language like plaintext or text (e.g., ```plaintext) so the
block is properly highlighted and passes linting.
---
Outside diff comments:
In `@README.md`:
- Around line 112-124: The README contains a contradictory sentence that says
"默认分支为 `main`" while the branch rules and AGENTS.md declare `develop` as the
default branch; update the sentence that currently reads "默认分支为 `main`" so it
instead states "默认分支为 `develop`" (or otherwise clarifies that `develop` is the
default branch for development and PRs), ensuring the README's "参与开发" section
and the referenced AGENTS.md remain consistent with the earlier branch rules
that designate `develop` as the integration/default branch.
---
Nitpick comments:
In @.github/workflows/publish.yml:
- Line 35: Update the actions/checkout step (uses: actions/checkout@v4) to
disable credential persistence by adding persist-credentials: false to the step
configuration so the GITHUB_TOKEN is not written to local git config; locate the
checkout step in the workflow and insert the persist-credentials key under that
step with a boolean false value.
- Around line 21-29: Move the high-privilege permissions out of the
workflow-level permissions block and scope them to the job that performs the
deployment: remove or reduce "pages: write" and "id-token: write" from the
top-level permissions section and add a permissions block to the deploy job that
explicitly sets pages: write and id-token: write (keeping other permissions like
contents: read at the workflow level if needed); update the deploy job
definition (the job named "deploy" in the workflow) to include the per-job
permissions so only that job has pages and id-token write access.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0d706c20-c946-4547-8187-1e674aa4b024
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (9)
.codex/setup.sh.github/workflows/blank.yml.github/workflows/publish.yml.gitignoreAGENTS.mdREADME.mdpackage.jsonposts/2026-06-11-hello-openblog.mdscripts/build.mjs
💤 Files with no reviewable changes (1)
- .github/workflows/blank.yml
| ## Repository layout | ||
|
|
||
| ``` | ||
| . | ||
| ├── AGENTS.md # this file | ||
| ├── README.md | ||
| ├── README.md # positioning + usage | ||
| ├── package.json # scripts: build, serve | ||
| ├── posts/ # Markdown articles (the content source) | ||
| │ └── *.md # front matter: title, date, tags, summary | ||
| ├── scripts/ | ||
| │ └── build.mjs # static-site generator (Markdown -> public/) | ||
| ├── public/ # build output (git-ignored, regenerated) | ||
| └── .github/ | ||
| └── workflows/ | ||
| └── blank.yml # placeholder CI (echoes hello world) | ||
| └── publish.yml # scheduled generate + publish to Pages | ||
| ``` |
There was a problem hiding this comment.
Missing language specifier on fenced code block.
The fenced code block at line 17 should specify a language for proper syntax highlighting and linting compliance.
📝 Proposed fix
## Repository layout
-```
+```plaintext
.
├── AGENTS.md # this file
├── README.md # positioning + usage📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## Repository layout | |
| ``` | |
| . | |
| ├── AGENTS.md # this file | |
| ├── README.md | |
| ├── README.md # positioning + usage | |
| ├── package.json # scripts: build, serve | |
| ├── posts/ # Markdown articles (the content source) | |
| │ └── *.md # front matter: title, date, tags, summary | |
| ├── scripts/ | |
| │ └── build.mjs # static-site generator (Markdown -> public/) | |
| ├── public/ # build output (git-ignored, regenerated) | |
| └── .github/ | |
| └── workflows/ | |
| └── blank.yml # placeholder CI (echoes hello world) | |
| └── publish.yml # scheduled generate + publish to Pages | |
| ``` | |
| ## Repository layout | |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 17-17: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@AGENTS.md` around lines 15 - 30, The fenced code block in AGENTS.md showing
the repository layout lacks a language specifier; update the opening fence to
include a language (e.g., change ``` to ```plaintext or ```text) so the block
becomes "```plaintext" and leave the closing fence intact; this ensures proper
syntax highlighting and linting compliance for the repository layout block.
| "type": "module", | ||
| "scripts": { | ||
| "build": "node scripts/build.mjs", | ||
| "serve": "node scripts/build.mjs && node -e \"import('node:http').then(h=>import('node:fs').then(f=>import('node:path').then(p=>{const t={'.html':'text/html;charset=utf-8','.css':'text/css','.js':'text/javascript'};h.createServer((q,s)=>{let u=decodeURIComponent(q.url.split('?')[0]);if(u==='/')u='/index.html';const fp=p.join('public',u);f.readFile(fp,(e,d)=>{if(e){s.writeCode?0:0;s.statusCode=404;return s.end('Not found')}s.setHeader('Content-Type',t[p.extname(fp)]||'application/octet-stream');s.end(d)})}).listen(8080,()=>console.log('OpenBlog dev server: http://localhost:8080'))})))\"" |
There was a problem hiding this comment.
Fix typo in HTTP response handling.
The inline server has a typo: s.writeCode?0:0 should be s.writeHead(404) to properly send the HTTP 404 status code. The current code attempts to access a non-existent writeCode property.
🐛 Proposed fix
- "serve": "node scripts/build.mjs && node -e \"import('node:http').then(h=>import('node:fs').then(f=>import('node:path').then(p=>{const t={'.html':'text/html;charset=utf-8','.css':'text/css','.js':'text/javascript'};h.createServer((q,s)=>{let u=decodeURIComponent(q.url.split('?')[0]);if(u==='/')u='/index.html';const fp=p.join('public',u);f.readFile(fp,(e,d)=>{if(e){s.writeCode?0:0;s.statusCode=404;return s.end('Not found')}s.setHeader('Content-Type',t[p.extname(fp)]||'application/octet-stream');s.end(d)})}).listen(8080,()=>console.log('OpenBlog dev server: http://localhost:8080'))})))\""
+ "serve": "node scripts/build.mjs && node -e \"import('node:http').then(h=>import('node:fs').then(f=>import('node:path').then(p=>{const t={'.html':'text/html;charset=utf-8','.css':'text/css','.js':'text/javascript'};h.createServer((q,s)=>{let u=decodeURIComponent(q.url.split('?')[0]);if(u==='/')u='/index.html';const fp=p.join('public',u);f.readFile(fp,(e,d)=>{if(e){s.writeHead(404);return s.end('Not found')}s.setHeader('Content-Type',t[p.extname(fp)]||'application/octet-stream');s.end(d)})}).listen(8080,()=>console.log('OpenBlog dev server: http://localhost:8080'))})))\""📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "serve": "node scripts/build.mjs && node -e \"import('node:http').then(h=>import('node:fs').then(f=>import('node:path').then(p=>{const t={'.html':'text/html;charset=utf-8','.css':'text/css','.js':'text/javascript'};h.createServer((q,s)=>{let u=decodeURIComponent(q.url.split('?')[0]);if(u==='/')u='/index.html';const fp=p.join('public',u);f.readFile(fp,(e,d)=>{if(e){s.writeCode?0:0;s.statusCode=404;return s.end('Not found')}s.setHeader('Content-Type',t[p.extname(fp)]||'application/octet-stream');s.end(d)})}).listen(8080,()=>console.log('OpenBlog dev server: http://localhost:8080'))})))\"" | |
| "serve": "node scripts/build.mjs && node -e \"import('node:http').then(h=>import('node:fs').then(f=>import('node:path').then(p=>{const t={'.html':'text/html;charset=utf-8','.css':'text/css','.js':'text/javascript'};h.createServer((q,s)=>{let u=decodeURIComponent(q.url.split('?')[0]);if(u==='/')u='/index.html';const fp=p.join('public',u);f.readFile(fp,(e,d)=>{if(e){s.writeHead(404);return s.end('Not found')}s.setHeader('Content-Type',t[p.extname(fp)]||'application/octet-stream');s.end(d)})}).listen(8080,()=>console.log('OpenBlog dev server: http://localhost:8080'))})))\"" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` at line 9, The inline dev server command in the "serve" script
uses a typo calling s.writeCode?0:0 inside the h.createServer request handler
(args q,s) which does not set the HTTP status; replace that expression with a
proper call to s.writeHead(404) before returning so the response is sent with
the correct 404 status (ensure the handler still calls s.end('Not found') after
writeHead). Locate the anonymous request handler used in the serve script (the
h.createServer callback) and update the error branch accordingly.
| ## 目录结构 | ||
|
|
||
| ``` | ||
| posts/ # Markdown 文章(内容源) | ||
| scripts/build.mjs # 静态站点生成器 | ||
| public/ # 构建产物(自动生成,已 gitignore) | ||
| .github/workflows/ # 定时生成 + 自动发布到 Pages | ||
| ``` |
There was a problem hiding this comment.
Missing language specifier on fenced code block.
The fenced code block at line 105 should specify a language for proper syntax highlighting and linting compliance.
📝 Proposed fix
-```
+```plaintext
posts/ # Markdown 文章(内容源)
scripts/build.mjs # 静态站点生成器
public/ # 构建产物(自动生成,已 gitignore)
.github/workflows/ # 定时生成 + 自动发布到 Pages</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
## 目录结构
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 105-105: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` around lines 103 - 110, The fenced code block in README.md
containing the directory listing (lines with "posts/", "scripts/build.mjs",
"public/", ".github/workflows/") lacks a language specifier; update the opening
fence from ``` to include a language like plaintext or text (e.g., ```plaintext)
so the block is properly highlighted and passes linting.
概要
把 OpenBlog 从占位仓库升级为一个可运行的「AI 自动生成 + 自动发布」博客系统,并发起首次发布(develop → main)。
改动
scripts/build.mjs:posts/*.md→public/(marked + gray-matter,支持 front matter)。.gitignore(忽略node_modules/、public/)。.github/workflows/publish.yml:每日定时 + push main + 手动触发 → 部署到 GitHub Pages。移除占位blank.yml。develop为默认分支、main为发布分支;.codex/setup.sh启用npm ci。验证
npm install && npm run build通过,生成public/index.html与文章页。发布门槛
合并需 code review 评分 ≥ 80。合并到
main会触发自动部署到 Pages。🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores