Skip to content

chore: upgrade CI#290

Merged
PaiJi merged 2 commits intomainfrom
chore/upgrade-CI
Feb 8, 2026
Merged

chore: upgrade CI#290
PaiJi merged 2 commits intomainfrom
chore/upgrade-CI

Conversation

@PaiJi
Copy link
Copy Markdown
Member

@PaiJi PaiJi commented Feb 7, 2026

Summary by CodeRabbit

发布说明

  • Chores(维护)
    • 引入可复用的镜像构建与烟雾测试工作流组件,提升 CI 可维护性与复用性。
    • 将构建触发调整为发布事件触发并保留手动触发,减少无意义构建。
    • 在管道中新增独立的构建、烟雾测试与推送/通知阶段,增强流程可观测性与可靠性。
    • 简化镜像推送步骤并优化本地镜像加载与测试流程。
  • Style
    • 更新忽略规则,新增对环境文件的忽略。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

本次变更将若干 CI 流水线拆分为可复用的 GitHub Actions 工作流:新增可复用的 Docker 构建与烟雾测试工作流;将原有构建/测试/推送流程改为复用这些工作流并重构触发器与作业依赖;新增部署到 CN 生产的流水线并更新 .dockerignore。

Changes

Cohort / File(s) Summary
主流水线与触发器
​.github/workflows/build-cn-image.yml
将触发从 push on main 改为 release (published),保留 workflow_dispatch;改为调用可复用构建与烟雾测试作业,重构 push-and-notify 以依赖 docker-smoke,移除内联 Buildx 与本地 env 文件生成与本地构建步骤。
可复用:Docker 构建
​.github/workflows/reusable-docker-build.yml
新增可复用构建工作流,支持 environment、image_tags 与 env 输入,设置 buildx、生成 .env、执行 docker build(不直接推送)、导出 image.tar 并上传为 artifact。
可复用:烟雾测试
​.github/workflows/reusable-smoke-test.yml
新增可复用烟雾测试工作流,下载并加载 image.tar,运行容器并查找主机端口,轮询指定 HTTP 路径进行健康检查,包含清理与超时处理。
原地烟雾测试迁移
​.github/workflows/smoke-test.yml
将原有内联 docker 构建与 curl 健康检查替换为对可复用构建与烟雾测试工作流的调用;新增 target_environment 输入,调整作业依赖(docker-smoke 需要 build-image)。
生产部署到 CN
​.github/workflows/deploy-prod-cn.yml
新增部署流水线,使用可复用构建与烟雾测试作业链:build-image -> docker-smoke -> push-and-notify;push-and-notify 下载镜像 artifact、加载、登录到腾讯镜像仓库并推送两种标签,然后调用 webhook。
仓库配置
.dockerignore
新增忽略 .env,调整 .next 顺序并确保末尾换行。

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant GH as GitHub Actions (workflow)
    participant ReuseBuild as reusable-docker-build
    participant ReuseSmoke as reusable-smoke-test
    participant Registry as Container Registry (Tencent)
    participant Webhook as Deployment Webhook

    GH->>ReuseBuild: 调用 build-image (environment, image_tags, env, secrets)
    ReuseBuild-->>GH: 上传 artifact `docker-image` (image.tar)
    GH->>ReuseSmoke: 需要 build-image -> 调用 docker-smoke (artifact, port, path, timeout)
    ReuseSmoke-->>GH: 返回 smoke test 成功/失败
    GH->>GH: push-and-notify 下载并加载 image.tar
    GH->>Registry: 登录并推送 tags (latest, sha)
    GH->>Webhook: 触发部署通知 (POST)
Loading

评估代码审查工作量

🎯 3 (中等) | ⏱️ ~25 分钟

诗歌庆祝

🐰 我在流水线里跳跃轻敲,
新模块来啦不再乱跑,
构建出镜像,测试来报到,
推送完成鸣响小小的敲,
啪嗒一跳,部署更美好!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive 标题'chore: upgrade CI'过于宽泛,未能具体说明CI升级的核心内容。虽然涉及多个工作流文件的重构,但标题未反映主要变更点,如引入可重用工作流、改变触发机制等关键改进。 建议修改标题以更具体地描述主要变更,例如'refactor: migrate CI workflows to reusable components'或'chore: restructure CI with reusable docker build and smoke-test workflows'。
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/upgrade-CI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread .github/workflows/reusable-docker-build.yml Fixed
Comment thread .github/workflows/reusable-smoke-test.yml Fixed
Copy link
Copy Markdown

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

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: d59306e33b

ℹ️ 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 .github/workflows/reusable-docker-build.yml Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

📦 Next.js Bundle Analysis for furrycons-site

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 333.85 KB (🟡 +4 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/reusable-docker-build.yml:
- Around line 46-57: The Docker image built in the "Build Docker image" step
using docker/build-push-action@v6 isn't loaded into the local daemon
(Buildx/BuildKit default), so the subsequent `docker save` in the "Export image
tar" step fails; update the Build step (the step named "Build Docker image" that
uses docker/build-push-action@v6) to include load: true under its with: block
(alongside context, push, tags) so the built image is loaded locally and `docker
save` can find the first tag.
- Around line 54-57: 在 "Export image tar" 步骤中不要把 ${{ inputs.image_tags }} 直接内联到
run 块以免命令注入;改为通过 step 的 env 字段传入(例如设置 IMAGE_TAGS: ${{ inputs.image_tags }}),然后在
run 中使用安全的参数扩展/引号(例如 printf "%s" "$IMAGE_TAGS" | tr ',' '\n' | head -n 1)来提取第一个
tag。同样处理其他直接内联的输入(如 ${{ inputs.env_vars }}):通过 env 传递并在 run 中以双引号引用对应的环境变量以避免
shell 元字符被解释。
- Around line 38-44: The workflow step "Create Env" writes REVALIDATE_TOKEN and
SENTRY_AUTH_TOKEN into a .env file which is then included in the Docker build
context (Dockerfile uses COPY . .), leaking secrets; to fix, either add ".env"
to the repository .dockerignore so the created .env is not sent to Docker build
context, or refactor the build to use Docker BuildKit secrets (docker build
--secret id=revalidate,src=/run/secrets/revalidate etc.) and remove the "echo
... >> .env" secret writes in the "Create Env" step; update the workflow to pass
secrets via build args/secrets and/or use a transient in-memory secret mount
rather than writing REVALIDATE_TOKEN and SENTRY_AUTH_TOKEN to disk.
🧹 Nitpick comments (4)
.github/workflows/reusable-docker-build.yml (1)

24-30: 建议添加 permissions 块以遵循最小权限原则

CodeQL 静态分析提示此工作流缺少 permissions 声明。虽然可复用工作流会继承调用方的权限,但显式声明可以作为额外的安全防线。建议至少添加 contents: read

🛡️ 建议修复
+permissions:
+  contents: read
+
 jobs:
   build-image:
     runs-on: ubuntu-latest
.github/workflows/build-cn-image.yml (2)

19-23: env_vars 混合使用多行 YAML 和逗号分隔符,可能产生空行

env_vars 使用了 YAML | 块标量(自带换行),同时每行末尾又有逗号。在可复用工作流中 tr ',' '\n' 会将逗号替换为额外的换行,导致 .env 文件中出现空行。虽然不影响功能,但建议统一使用一种分隔方式——要么纯逗号分隔(单行),要么纯多行(去掉逗号)。

♻️ 建议:去掉行末逗号,纯多行格式

如果改为纯多行格式,需要同时修改 reusable-docker-build.yml 中的 .env 生成逻辑,去掉 tr ',' '\n',直接 append 即可:

      env_vars: |
-        NEXT_PUBLIC_ENABLE_TRACK=${{ vars.ENABLE_TRACK }},
-        NEXT_PUBLIC_REGION=${{ vars.NEXT_PUBLIC_REGION }},
-        NEXT_PUBLIC_WEBSITE_URL=${{ vars.NEXT_PUBLIC_WEBSITE_URL }},
-        FEC_API_TOKEN=${{ vars.FEC_API_TOKEN }}
+        NEXT_PUBLIC_ENABLE_TRACK=${{ vars.ENABLE_TRACK }}
+        NEXT_PUBLIC_REGION=${{ vars.NEXT_PUBLIC_REGION }}
+        NEXT_PUBLIC_WEBSITE_URL=${{ vars.NEXT_PUBLIC_WEBSITE_URL }}
+        FEC_API_TOKEN=${{ vars.FEC_API_TOKEN }}

60-63: 镜像 tag 在多处硬编码,建议提取为变量

hkccr.ccs.tencentyun.com/furrycons/frontend:latest 和 sha tag 在 image_tags(Line 17-18)和 push(Line 62-63)中重复出现。如果 registry 地址或镜像名变更,需要多处同步修改。考虑在工作流顶层定义 env 变量或使用 reusable workflow 的 outputs 来传递 tag 列表。

.github/workflows/reusable-smoke-test.yml (1)

35-44: 建议添加 permissions

reusable-docker-build.yml 相同,CodeQL 提示此工作流缺少权限声明。由于冒烟测试不需要任何 GitHub token 权限,建议声明空权限块。

🛡️ 建议修复
+permissions: {}
+
 jobs:
   docker-smoke:
     name: Docker smoke test

Comment thread .github/workflows/reusable-docker-build.yml Outdated
Comment thread .github/workflows/reusable-docker-build.yml Outdated
Comment thread .github/workflows/reusable-docker-build.yml Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/deploy-prod-cn.yml:
- Around line 65-68: In the "Call Webhook" step the webhook variable is unquoted
and curl doesn't fail on HTTP errors; update the curl invocation that uses ${{
vars.WEBHOOK_URL }} to (1) quote the expanded variable (use "${{
vars.WEBHOOK_URL }}"), (2) add fail-on-error flags like --fail (and optionally
--show-error/--silent choices) so non-2xx responses fail the step, and (3) add a
pre-check that the variable is not empty (exit with a clear message if it is) to
avoid silent/no-op runs.
- Around line 19-23: Remove the trailing commas from the multiline env_vars
block so the INPUT_ENV_VARS parsing (the printf '%s\n' "$INPUT_ENV_VARS" | tr
',' '\n' >> .env pipeline) does not convert those commas into empty lines;
specifically edit the env_vars entries (NEXT_PUBLIC_ENABLE_TRACK,
NEXT_PUBLIC_REGION, NEXT_PUBLIC_WEBSITE_URL, FEC_API_TOKEN) to be
newline-separated with no trailing commas.
🧹 Nitpick comments (3)
.github/workflows/reusable-smoke-test.yml (1)

84-93: 轮询超时时间与 timeout_minutes 输入参数不一致

timeout_minutes(默认 15 分钟)用于 job 级别超时,但实际的 HTTP 轮询循环硬编码为最多 60 秒(60 次 × 1 秒)。如果应用启动较慢(例如 Next.js 冷启动),60 秒可能不够,而 timeout_minutes 参数给人一种可以控制轮询时长的错觉。

建议将轮询次数/间隔参数化,或至少在 timeout_minutes 的描述中注明实际轮询上限为 60 秒。

.github/workflows/deploy-prod-cn.yml (2)

49-51: docker load 步骤缺少 set -euo pipefail

与烟雾测试工作流中的良好实践不同,这里的 run 块没有设置 set -euo pipefail。如果 docker load 失败,shell 不会立即退出。

♻️ 建议修复
      - name: Load image
        run: |
+          set -euo pipefail
           docker load -i image.tar

60-63: 镜像标签硬编码重复

push 步骤中的镜像标签与 build-imageimage_tags 的值重复。目前可接受,但如果后续标签变更,需要同步修改两处。可以考虑通过 reusable workflow 的 outputs 传递标签列表,减少维护负担。

Comment on lines +19 to +23
env_vars: |
NEXT_PUBLIC_ENABLE_TRACK=${{ vars.ENABLE_TRACK }},
NEXT_PUBLIC_REGION=${{ vars.NEXT_PUBLIC_REGION }},
NEXT_PUBLIC_WEBSITE_URL=${{ vars.NEXT_PUBLIC_WEBSITE_URL }},
FEC_API_TOKEN=${{ vars.FEC_API_TOKEN }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd "reusable-docker-build.yml" --type f

Repository: FurryConsChina/website

Length of output: 48


🏁 Script executed:

ls -la .github/workflows/ | head -20

Repository: FurryConsChina/website

Length of output: 526


🏁 Script executed:

cat -n .github/workflows/deploy-prod-cn.yml

Repository: FurryConsChina/website

Length of output: 2542


🏁 Script executed:

cat -n .github/workflows/reusable-docker-build.yml

Repository: FurryConsChina/website

Length of output: 2793


多行 env_vars 格式会在 .env 文件中产生空行

根据 reusable-docker-build.yml 第 49 行的解析逻辑 (printf '%s\n' "$INPUT_ENV_VARS" | tr ',' '\n' >> .env),逗号被转换为换行符。由于第 20-22 行有尾随逗号,这将导致 .env 文件中产生不必要的空行,虽然不影响功能(.env 解析器通常忽略空行),但不够清晰。

建议移除第 20-22 行的尾随逗号:

建议的修改
      env_vars: |
        NEXT_PUBLIC_ENABLE_TRACK=${{ vars.ENABLE_TRACK }}
        NEXT_PUBLIC_REGION=${{ vars.NEXT_PUBLIC_REGION }}
        NEXT_PUBLIC_WEBSITE_URL=${{ vars.NEXT_PUBLIC_WEBSITE_URL }}
        FEC_API_TOKEN=${{ vars.FEC_API_TOKEN }}

如此可维护仅使用换行符作为分隔符,避免 tr 命令产生的空行。

🤖 Prompt for AI Agents
In @.github/workflows/deploy-prod-cn.yml around lines 19 - 23, Remove the
trailing commas from the multiline env_vars block so the INPUT_ENV_VARS parsing
(the printf '%s\n' "$INPUT_ENV_VARS" | tr ',' '\n' >> .env pipeline) does not
convert those commas into empty lines; specifically edit the env_vars entries
(NEXT_PUBLIC_ENABLE_TRACK, NEXT_PUBLIC_REGION, NEXT_PUBLIC_WEBSITE_URL,
FEC_API_TOKEN) to be newline-separated with no trailing commas.

Comment on lines +65 to +68
- name: Call Webhook
run: |
curl -X POST ${{ vars.WEBHOOK_URL }} \
-H "Content-Type: application/json"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Webhook URL 未加引号,存在注入和静默失败风险

${{ vars.WEBHOOK_URL }} 直接在 shell 中展开且未加引号。如果变量为空或包含特殊字符,命令会出错或产生意外行为。此外,curl 缺少 -f/--fail 标志,HTTP 错误(如 4xx/5xx)不会导致步骤失败。

🔧 建议修复
      - name: Call Webhook
        run: |
-          curl -X POST ${{ vars.WEBHOOK_URL }} \
-            -H "Content-Type: application/json"
+          set -euo pipefail
+          curl -fsSL -X POST "${{ vars.WEBHOOK_URL }}" \
+            -H "Content-Type: application/json"
📝 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.

Suggested change
- name: Call Webhook
run: |
curl -X POST ${{ vars.WEBHOOK_URL }} \
-H "Content-Type: application/json"
- name: Call Webhook
run: |
set -euo pipefail
curl -fsSL -X POST "${{ vars.WEBHOOK_URL }}" \
-H "Content-Type: application/json"
🤖 Prompt for AI Agents
In @.github/workflows/deploy-prod-cn.yml around lines 65 - 68, In the "Call
Webhook" step the webhook variable is unquoted and curl doesn't fail on HTTP
errors; update the curl invocation that uses ${{ vars.WEBHOOK_URL }} to (1)
quote the expanded variable (use "${{ vars.WEBHOOK_URL }}"), (2) add
fail-on-error flags like --fail (and optionally --show-error/--silent choices)
so non-2xx responses fail the step, and (3) add a pre-check that the variable is
not empty (exit with a clear message if it is) to avoid silent/no-op runs.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 8, 2026

📦 Next.js Bundle Analysis for furrycons-site

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 333.85 KB (🟡 +7 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

@PaiJi PaiJi merged commit a4fbaae into main Feb 8, 2026
9 checks passed
@PaiJi PaiJi deleted the chore/upgrade-CI branch February 8, 2026 09:02
This was referenced Feb 8, 2026
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.

2 participants