iT邦幫忙

2026 iThome 鐵人賽

DAY 29
0

Day28_欸 Codex,網站上線後又想修改,該怎麼辦?

前言

Day27 把網站部署到 Google Cloud,第一版總算能離開開發電腦,讓其他人從瀏覽器開啟。不過,軟體上線不代表從此不能動。真正開始使用後,通常才會發現按鈕不順手、規格少想了一種情況,或突然冒出一個很想加入的新功能。

這次要替 ProjectManagementWeb 加上「使用者大頭貼」。功能聽起來不大,實際上會同時碰到前端畫面、後端 API、資料庫與共用規格。如果直接對 Agent 說「幫忙加上傳大頭貼」,它為了把空白補起來,可能會自行決定圖片存放位置、誰能修改,甚至連舊圖要不要保留都一起猜掉。

所以這一篇先不急著寫 Code。要先替變更安排一條安全的路,再讓 Codex 盤點現況、提出問題,最後把確認過的決定寫成變更申請。這就像裝潢已經營業的店面:先把施工區圍起來、確認圖面,才開始敲牆。

先替變更安排一條路

Day25 已經介紹過 Git Flow。這次要把它真正用在第二版開發上。

可以先把幾種分支想成不同的工作區:

分支 白話理解 這次怎麼用
main 目前可交付的展示品 不直接在上面施工
develop 下一版的共用工作桌 收集已完成、準備進入下一版的修改
feature/* 單一功能的施工區 開發大頭貼功能
bugfix/* 一般問題的維修區 修正尚未發版的缺陷
release/* 發版前的驗收區 只處理測試、版本與發版準備
hotfix/* 正式環境的緊急維修區 從 main 修正,再同步回 develop

https://ithelp.ithome.com.tw/upload/images/20260927/20126487auYwL09G1E.png

圖上的箭頭是團隊約定的路線,不是 Git 自己會執行的自動規則。若 GitHub 還沒有分支保護,使用者仍可能直接 Push 到 main;若 CI/CD 還沒建立,Pull Request 也不會憑空多出 Build 與 Test。規範先告訴大家「應該怎麼走」,真正的自動檢查會留到 Day29。

既有專案不能直接套範本

ProjectManagementWeb 分成 Frontend、Backend 與 Spec 三個獨立 Repository。它們各自有自己的分支、Commit 與 Pull Request,所以不能只在其中一個 Repository 建立分支,就當作三邊都準備好了。

而且這不是全新專案。建立 feature/* 前,要先檢查 develop 是否包含功能需要的最新變更。如果 main 有尚未同步回來的正式版修正,應先處理分支差異;不要因為流程圖畫了一條箭頭,就假設兩邊內容相同。

多人協作為什麼更需要 Git Flow?

一個人開發時,直接在 main 修改,出問題通常只會打亂自己的工作。多人同時開發就不同了。有人正在修改登入功能,另一個人正在調整資料庫;如果大家都在同一條分支上工作,很容易把尚未完成的內容一起推上去,也可能在解決衝突時誤刪別人的修改。

Git Flow 像是團隊共用的交通規則。每項工作先進入自己的 feature/* 或 bugfix/*,完成後再透過 Pull Request 回到 develop。其他成員可以在 PR 裡看到改了哪些檔案、測試是否執行,以及這次變更會影響誰,不必只靠聊天訊息拼湊現況。

develop 也提供一個正式發版前的集合點。兩項功能各自測試通過,不代表放在一起仍然正常;前端可能已經使用新的 API 欄位,後端卻還沒合併對應修改。先在 develop 整合,可以在進入 main 前發現這類落差。

遇到正式環境的緊急問題時,hotfix/* 會從 main 開出,修正後再同步回 develop。少了回合併這一步,下一版可能會把同一個錯誤重新帶回正式環境。

ProjectManagementWeb 又分成三個 Repository,因此多人協作時還要把相關 PR 互相連結。例如 Spec 先確認規格,Backend 提供 API,Frontend 才能依契約串接。三邊不一定同時完成,但每個人都要知道目前相容的是哪一組版本。

先請 Codex 讀取三個 Repository 的現況,再提出要新增或調整的檔案:

請分析目前專案的 Git Repository 結構、現有 Branch、Commit History、CI/CD 設定與專案類型,並為此專案建立一套可長期維護的 GitFlow 開發規範,並且寫在docs/git-flow.md。  
目標是讓未來的人員與 AI Coding Agent 都能依照相同規則進行開發、版本管理與 Release。  
請不要直接修改既有 Git History,也不要強制刪除目前存在的 Branch。  
請採用以下 GitFlow 為基礎:

- main
    - Production 正式版本
    - 只能透過 Pull Request / Merge Request 合併
    - 不允許直接開發
- develop
    - 下一版本主要整合分支
    - Feature 完成後合併到此分支
- feature/*
    - 新功能開發
    - 從 develop 建立
    - 完成後合併回 develop  
        格式:  
        feature/<ticket-id>-<description>  
        例如:  
        feature/123-user-login
- bugfix/*
    - 一般 Bug 修正
    - 從 develop 建立
    - 完成後合併回 develop  
        格式:  
        bugfix/<ticket-id>-<description>
- release/*
    - Release Candidate
    - 從 develop 建立
    - 僅允許進行:
        - Bug Fix
        - Version Update
        - Release Note
        - Config 調整
    - 完成後合併到:
        - main
        - develop  
            格式:  
            release/<version>  
            例如:  
            release/1.2.0
- hotfix/*
    - Production 緊急修正
    - 從 main 建立
    - 修正後必須合併到:
        - main
        - develop  
            格式:  
            hotfix/<version>-<description>  
            例如:  
            hotfix/1.2.1-login-error  
            請採用 Conventional Commits:  
            格式:

<type>(<scope>): <description>  
支援:

- feat
- fix
- refactor
- docs
- test
- chore
- build
- ci
- perf
- style
- revert  
    例如:  
    feat(auth): 新增 JWT 登入功能  
    fix(order): 修正訂單金額計算錯誤  
    refactor(api): 重構 API exception handling  
    Commit Description 請使用繁體中文。  
    所有以下 Branch 合併:
- feature → develop
- bugfix → develop
- release → main
- hotfix → main  
    都必須透過 Pull Request。  
    PR 必須包含:  
    說明此次修改內容。  
    列出主要修改項目。  
    說明:
- Unit Test
- Integration Test
- Manual Test  
    測試結果。  
    說明可能的影響範圍。  
    如果部署後發生問題,如何回復。  
    預設使用:  
    Squash Merge  
    但以下情況保留完整 Commit:
- release
- hotfix  
    禁止:
- 直接 Push main
- 直接 Push develop
- Force Push main
- Force Push develop  
    採用 Semantic Versioning:  
    MAJOR.MINOR.PATCH  
    例如:  
    1.0.0  
    1.1.0  
    1.1.1  
    2.0.0  
    定義:  
    MAJOR:  
    Breaking Change  
    MINOR:  
    Backward-compatible Feature  
    PATCH:  
    Backward-compatible Bug Fix  
    Release 合併到 main 後建立:  
    v<version>  
    例如:  
    v1.2.0  
    Tag 必須對應:  
    main branch 的 Release Commit。  
    標準 Release:  
    develop  
    ↓  
    release/x.y.z  
    ↓  
    QA / Test  
    ↓  
    main  
    ↓  
    Tag vX.Y.Z  
    ↓  
    Production Deployment  
    ↓  
    merge back develop  
    Production 問題:  
    main  
    ↓  
    hotfix/x.y.z-description  
    ↓  
    修正  
    ↓  
    Test  
    ↓  
    main  
    ↓  
    Tag  
    ↓  
    Production Deployment  
    ↓  
    merge back develop  
    請依目前專案實際 CI/CD 平台調整。  
    預設:  
    feature/*  
    bugfix/*  
    → Build + Test  
    develop  
    → Build + Test  
    → Deploy DEV  
    release/*  
    → Build + Test  
    → Deploy STAGING  
    main  
    → Build + Test  
    → Deploy PRODUCTION  
    Tag v*  
    → Production Release  
    AI Agent 開始修改程式前必須:

1. 檢查目前 Branch
2. 不可直接在 main 修改
3. 不可直接在 develop 修改
4. 判斷工作類型:
    - feature
    - bugfix
    - hotfix
    - refactor
5. 建立符合規範的 Branch  
    例如:  
    feature/123-add-payment-api  
    完成修改後:
6. 執行 Build
7. 執行 Test
8. 檢查 git diff
9. 檢查是否包含敏感資訊
10. 產生 Conventional Commit
11. 提供 PR 說明  
    AI 不得自行:

- Force Push
- Rewrite Git History
- Delete Remote Branch
- Merge main
- Release Production  
    除非使用者明確要求。  
    請建立以下文件:  
    .github/PULL_REQUEST_TEMPLATE.md  
    內容包含:
- Summary
- Changes
- Test
- Risk
- Rollback  
    並建立:  
    docs/git-flow.md  
    內容說明:
- Branch Strategy
- Branch Naming
- Commit Convention
- Pull Request
- Release Flow
- Hotfix Flow
- Versioning
- Tagging
- CI/CD Mapping  
    如果 Repository 已存在:
- CONTRIBUTING.md
- AGENTS.md
- CLAUDE.md  
    請優先整合規則,而不是建立重複文件。  
    開始修改之前,請先:

1. 分析目前 Git Repository。
2. 顯示目前 Branch。
3. 顯示主要 Branch 關係。
4. 檢查是否已存在 GitFlow 或類似規則。
5. 檢查 CI/CD workflow。
6. 提出預計新增或修改的檔案。  
    請先提供:  
    目前 Repository Git 狀態。  
    建議 GitFlow。  
    預計修改檔案。  
    可能風險。  
    在完成分析後再進行修改。  
    不要修改現有 Commit History。

確認內容後,三個 Repository 各自有一份 docs/git-flow.md,並以 .github/PULL_REQUEST_TEMPLATE.md 提醒提交者填寫修改摘要、測試結果、風險與回復方式。

這裡要分清楚「文件」和「系統設定」。把「main 只能透過 PR 合併」寫進文件,是團隊規則;還要到 GitHub 設定 Branch protection 或 Ruleset,才會由平台幫忙阻擋違規操作。同樣地,文件裡列出的 CI/CD Mapping 目前是目標,不代表 GitHub Actions 已經開始執行。

替大頭貼功能建立獨立分支

規則確認後,接著替這次修改建立獨立的施工區。為了避免 Agent 一收到需求就開始改程式,Prompt 直接寫明「先不要開發」:

我想開發一個,使用者在帳號驗證過後,可以上傳大頭貼的功能,並且可以在使用者資料中顯示,請幫我開一個開發分支,先不要進行開發

https://ithelp.ithome.com.tw/upload/images/20260927/20126487TRgWBtjOU1.png

畫面中 Codex 回報三個 Repository 都建立了同名分支,也核對本機與遠端的 Commit。名稱相同方便追蹤,但它們仍是三條獨立分支;日後也要各自 Commit、Push 與建立 Pull Request。

開一個新的 Session,先談需求

分支準備好後,可以開一個新的 Session,讓 Codex 專心處理這次變更。新的 Session 不應靠猜測理解前因後果,因此 Prompt 要把目標、限制與停止條件寫清楚:

請開發一個人資料上傳大頭貼的功能,內容如下:

1. 該功能需要經過信箱驗證過後才可以啟用
2. 該功能不用綁任何權限,但是只有自己的帳戶可以修改自己的大頭貼
3. 大頭貼的尺寸為 **1080 × 1080 像素,格式只支援**JPG / JPEG與PNG
4. 上傳的圖片超過尺寸,要提供畫面進行剪裁後,在進行顯示,上傳的圖檔要在Server存檔備份

請提出你的修改計劃跟目前與可能會遇到的風險,有問題請暫停並且跟我確認,我看到計劃,並且我確認沒問題後後,在進行修改

https://ithelp.ithome.com.tw/upload/images/20260927/20126487biJeGl8X0M.png

這次 Codex 沒有立刻動工,而是先發現幾個會改變設計的問題。例如圖片究竟要放在 SQL Server、伺服器檔案系統,還是物件儲存空間?原圖要不要保留?重新上傳時,舊圖該覆寫還是留下歷史版本?

這些不是換一個類別名稱就能解決的小事。保存方式會影響資料庫容量、備份、權限與部署架構,必須由需求提出者決定。

把討論結果寫成變更申請

一開始的需求是「把上傳檔案存在 Server 備份」,討論後改成只保存剪裁完成的圖片,而且重新上傳就覆寫舊值。這兩句代表完全不同的資料生命週期。如果只把最後一句留在聊天視窗裡,幾天後很容易又回到原本的理解。

因此,需要請 Codex 把已確認的內容寫成變更申請:

1. 可以
2. 我想修改一下,資料庫欄位只存修改過後剪裁的圖片,並且「只存最終圖片、覆寫舊值」,不用存原圖的備份檔了
3. 有
   
若有問題請再提出,如果沒問題,請把修改計劃,寫在Modify的資料夾裡面,並且產生ChangeRequest_YYYYMMDD的markdown,以後做修改規格追縱,檔案建立完成後,我確認過後才開始進行修改

https://ithelp.ithome.com.tw/upload/images/20260927/20126487h1BGWmJExn.png

變更申請裡特別註明:「存進資料庫」代表圖片會隨資料保存,不等於已經有獨立備份。因為新圖片會覆寫舊值,如果未來想還原舊圖,還要另外設計版本保存或資料庫備份策略。

這也是留下文件的價值。它不只記錄要做什麼,也會記錄這次刻意不做什麼。

先替已確認的規格留下一個存檔點

審閱變更申請後,先提交這份文件,替規格留下存檔點。以下保留當時實際使用的 Prompt:

修幫我下一個Commit與Push,並且用一句話說明修改的內容

這個 Commit 不是宣告功能已完成,而是替「開工前雙方同意的版本」留下可追查的基準。

確認後才開始實作

規格確認後,才把施工許可交給 Agent:

修改計劃已確認,請根據ChangeRequest_20260927.md進行修改,並且附上對應的測試案例與修正,並且同步目前的文間與測試案例進行測試

整段流程可以拆成兩個階段。第一個階段先釐清需求、建立分支,再把確認過的決定寫進 Change Request:

https://ithelp.ithome.com.tw/upload/images/20260927/20126487rE0l7GfoDy.png

規格確認並留下存檔點後,第二個階段才開始修改程式、執行測試與準備 Pull Request:

https://ithelp.ithome.com.tw/upload/images/20260927/20126487hKW3a0MXVn.png

這套流程看起來多繞了一圈,實際上是在成本較低的階段找問題。需求文件改一句話很快;等 API、資料庫與畫面都完成後才發現理解錯誤,修改成本就高得多。

自動化測試通過,還是要手動驗收

Day23 產生測試案例,Day24 也實際碰過「測試通過,但畫面操作不合理」的情況。大頭貼功能同樣不能只看綠色勾勾。

自動化測試適合守住格式、尺寸、授權與 API 回應;手動測試則要真的操作剪裁畫面,看看滑鼠和手機觸控是否順手、錯誤訊息看不看得懂,以及新圖片有沒有在該出現的位置更新。

至少要實際走過這些情況:

  • 未驗證 E-mail 的帳號看得到原因,但不能上傳。
  • 已驗證的 Viewer 可以修改自己的大頭貼,不能修改別人的。
  • JPG、JPEG、PNG 可以剪裁與預覽;尺寸不足或內容損壞時會被拒絕。
  • 上傳後,個人設定、側邊導覽與使用者詳情都顯示新圖片。
  • 再上傳一次會覆寫舊圖;重新整理與重新登入後,仍讀得到最新圖片。
  • 上傳失敗時保留舊圖,不會留下只改一半的狀態。

Agent 可以幫忙執行檢查,最後的操作感受與需求取捨仍要由人判斷。

用 .NET Skills 補上專門的工作手冊

這次後端是 ASP.NET Core,因此也查看了 .NET 團隊整理的 Agent Skills。Skill 可以想成給 Agent 使用的工作手冊:它會針對某一類任務補上檢查步驟與注意事項,但不會取代需求、測試環境或人工審查。

這個 Repository 目前把能力拆成多個 Plugin。和 ProjectManagementWeb 比較直接相關的有:

Plugin 適合處理的工作
dotnet-aspnetcore ASP.NET Core API、Middleware、Endpoint 等 Web 開發
dotnet-data EF Core、資料存取與查詢效能
dotnet-test 執行、產生與分析 .NET 測試
dotnet-msbuild Build 失敗、MSBuild 設定與效能問題
dotnet-diag 效能調查、Trace、Dump 與執行期診斷
dotnet-upgrade .NET 版本升級與相容性調整

目前官方 Repository 建議 Codex CLI 透過 Plugin Marketplace 安裝。先加入 Marketplace:

codex plugin marketplace add dotnet/skills

接著在 Codex 輸入 /plugins,打開 dotnet-agent-skills 分頁,再依專案需要安裝 Plugin。不要看到清單很長就全部套用;例如這次要修改 ASP.NET Core API、EF Core 與測試,就先選與這三項工作有關的 Skill。

Skill 也不是品質保證書。Agent 說「已執行測試」時,仍要確認實際指令、測試數量與結果;如果 SQL Server 測試環境沒有啟動,Integration Test 被略過,就不能把它寫成全部通過。

小結

軟體完成第一版後,需求繼續變動很正常。這次沒有直接叫 Codex 修改大頭貼功能,而是先建立功能分支,再把模糊想法整理成可審核的變更申請。確認圖片格式、權限、保存方式與不做的項目後,才讓 Agent 開始實作。

Git Flow 負責把不同工作隔開,Change Request 留下「為什麼這樣改」,測試與人工驗收則回答「結果能不能交付」。三者處理的是不同問題,少掉任何一個,都可能讓後續維護只能靠記憶猜測。

目前這些檢查仍需要人提醒 Agent 執行。下一篇會接著把重複的 Build、Test 與部署步驟交給 CI/CD,讓每次 Push 或 Pull Request 都走過同一套檢查。

參考資料


上一篇
Day27_是時候展現你的作品了,將網站部署至 Google Cloud
系列文
Codex的規格驅動開發 :30 天打造 .NET 內部專案管理系統 共 29 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言