[CLAUDE] Api: bỏ dấu phẩy trong tên 2 template .docx — vá MSB4186 làm CI #489 đỏ (gotcha #93)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 9m28s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 9m28s
CI run #489 ĐỎ sau 2m42s ở test-gate Infrastructure — nhưng lỗi thật ở BUILD, không phải test: Microsoft.NET.Publish.targets(851,9): error MSB4186: Invalid static method invocation syntax: "[MSBuild]::MakeRelative($(MSBuildProjectDirectory), …nhan cong, vat tu.docx)". Method not found. MSBuild property-function tách tham số bằng DẤU PHẨY ⇒ đường dẫn chứa ", " biến lời gọi 2-tham-số thành 3 ⇒ không có overload ⇒ MSB4186, chặn ngay ở build nên test chưa kịp khởi động. 🔴 LOCAL KHÔNG TÁI HIỆN ĐƯỢC: global.json để rollForward=latestFeature ⇒ CI nhảy SDK 10.0.202 còn local 10.0.104. Đo: grep -c "MakeRelative" trong Publish.targets của SDK local = 0 (control dương "ContentWithTargetPath" = 8 ⇒ thước sống) — dòng mã gây lỗi KHÔNG TỒN TẠI trên máy dev. "Local 699 PASS" là đúng-với-local, không phải đo ẩu. Vá: đổi tên 2 file bỏ phẩy ("nhan cong, vat tu" → "nhan cong va vat tu"), sửa 2 chuỗi seed DbInitializer + 4 chú thích nguồn trong lib/contractBody. Control: 4 template cũ cùng thư mục không có phẩy ⇒ CI xanh nhiều tháng; 2 file mới có phẩy ⇒ đỏ ngay run đầu; biến duy nhất = phẩy. + gotcha #93 + luật khắc tại chỗ trong DbInitializer: tên file dưới wwwroot CẤM chứa dấu phẩy. Đo lại sau vá: build 0 error (bin/obj dọn sạch trước) · test 699 PASS · 0 file wwwroot còn phẩy · 2 cặp file body002_0*.ts vẫn trùng sha256. 🔸 CHƯA vá lớp gốc (SDK drift CI⟂local): siết rollForward sang latestPatch/disable sẽ đóng cả lớp NHƯNG runner đang có 10.0.202 — pin về 10.0.1xx mà runner không cài thì CI chết hẳn thay vì đỏ một run. Phải đo SDK trên runner trước; quyết định của chủ dự án. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@ -1515,3 +1515,30 @@ for h in resp.points: # ← .points không phải iterable trực tiếp
|
||||
34. Nếu Gitea Actions run CANCELLED ngay sau khi push 2 commit sát nhau → auto-cancel cùng-branch: đọc run CUỐI của range + verify artifact-level (bundle/marker/seeder-log), KHÔNG đọc CANCELLED thành deploy-fail; side-effect @startup chỉ chạy 1 lần cho cả cụm (#86)
|
||||
35. Nếu probe endpoint để hỏi **authz** mà nhận **415/411** → đó là mã **PRE-AUTH**, vô nghĩa cho câu hỏi authz: request bị loại ở tầng **action-selection / IIS** TRƯỚC authorization filter. Re-probe đúng dạng body (multipart cho endpoint upload; có body cho SignalR negotiate) rồi mới đọc 401/403 (#87)
|
||||
36. Nếu login prod 500 "transient failure UseSqlServer" + DB RECOVERY_PENDING sau sự cố disk đầy → check **cờ nén NTFS** trên .mdf/.ldf (`compact <file>`, Msg 5118): SET OFFLINE → backup copy → restart service nhả handle → `compact /U` → SET ONLINE. CẤM nén cây SQL DATA (#88)
|
||||
|
||||
### 93. Dấu PHẨY trong tên file asset ⇒ `MSB4186` — CI đỏ mà LOCAL không tài nào tái hiện (Session 194)
|
||||
|
||||
**Triệu chứng:** commit thêm 2 file `.docx` vào `wwwroot/templates/`. Local: build 0 error, **699 test PASS**, `tsc` sạch. Push → CI run **#489 ĐỎ sau 2m42s**, chết giữa test-gate Infrastructure, **chưa tới build FE, chưa tới deploy**.
|
||||
|
||||
```
|
||||
Microsoft.NET.Publish.targets(851,9): error MSB4186: Invalid static method invocation syntax:
|
||||
"[MSBuild]::MakeRelative($(MSBuildProjectDirectory), …\SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong, vat tu.docx)".
|
||||
Method '[MSBuild]::MakeRelative' not found.
|
||||
```
|
||||
|
||||
**Cơ chế:** MSBuild property-function **tách tham số bằng dấu phẩy**. Tên file chứa `, ` biến lời gọi 2-tham-số thành **3 tham số** ⇒ không có overload ⇒ `MSB4186`. Lỗi ở **BUILD**, nên test không kịp khởi động — đọc log thấy "test fail" là đọc nhầm tầng.
|
||||
|
||||
🔴 **Vì sao LOCAL KHÔNG BAO GIỜ BẮT ĐƯỢC — đây mới là phần đắt:**
|
||||
`global.json` = `{"sdk":{"version":"10.0.104","rollForward":"latestFeature"}}`. `latestFeature` **cho phép nhảy feature-band** ⇒ local `10.0.104`, CI `10.0.202`. Đo quyết định:
|
||||
```
|
||||
grep -c "MakeRelative" <SDK 10.0.104>/Microsoft.NET.Publish.targets = 0 ← dòng gây lỗi KHÔNG TỒN TẠI ở local
|
||||
grep -c "ContentWithTargetPath" cùng file = 8 ← CONTROL DƯƠNG (thước sống)
|
||||
ls "C:\Program Files\dotnet\sdk\" = 10.0.104, 9.0.311 (không có 10.0.2xx)
|
||||
```
|
||||
⇒ *"Local 699 PASS"* là **đúng-với-local**, không phải đo ẩu. Chạy lại bao nhiêu lần cũng không đỏ.
|
||||
|
||||
**Control có sẵn ngay trong thư mục, không cần dựng thêm:** 4 template CŨ cùng chỗ **không có phẩy** → CI xanh nhiều tháng (control dương). 2 file mới **có phẩy** → đỏ ngay run đầu (control âm). Biến duy nhất đổi = dấu phẩy.
|
||||
|
||||
**LUẬT:** 🔴 **tên file dưới `wwwroot/` CẤM chứa dấu phẩy.** Khoảng trắng thì OK (4 file cũ đều có). Đổi tên phải sửa kèm chuỗi seed trong `DbInitializer.cs` (2 điểm tham chiếu).
|
||||
|
||||
**Họ hàng với #92:** cùng lớp *build-env CI trôi khỏi local*, nhưng #92 ở tầng **npm** (đã khoá bằng lockfile + `npm ci`), còn đây ở tầng **.NET SDK** — vẫn **thả trôi** qua `rollForward: latestFeature`. Siết thành `latestPatch`/`disable` sẽ đóng cả lớp, **nhưng rủi ro thật**: runner đang có `10.0.202`; pin về feature-band `10.0.1xx` mà runner không cài bản đó thì **CI chết hẳn** thay vì chỉ đỏ một run. Cần đo SDK có trên runner TRƯỚC khi siết — quyết định của chủ dự án.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// ═══ HĐ TRỌN GÓI NHÂN CÔNG & VẬT TƯ — `SOL-CCM-FO-002.02` (`HD-TP-VT`, ContractType = 8) ═══
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong, vat tu.docx`
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong va vat tu.docx`
|
||||
// (đọc `word/document.xml`, gộp mọi `<w:t>` trong cùng `<w:p>` bằng chuỗi RỖNG). Đối chiếu
|
||||
// `runs/2026-08-13-S194-yc032-hd-thauphu-2form/form-002-02-structure.md` (122 đoạn + 4 bảng ·
|
||||
// 91 ô = 36 ô đơn + 55 ô bảng).
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// ═══ HĐ TRỌN GÓI NHÂN CÔNG & THIẾT BỊ — `SOL-CCM-FO-002.03` (`HD-TP-TB`, ContractType = 9) ══
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.03.v01 Hop dong trong goi nhan cong, thiet bi.docx`
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.03.v01 Hop dong trong goi nhan cong va thiet bi.docx`
|
||||
// (đọc `word/document.xml`, gộp mọi `<w:t>` trong cùng `<w:p>` bằng chuỗi RỖNG — 201 đoạn +
|
||||
// 11 bảng). ⚠️ `form-002-03-structure.md` §1 bị LỖI TRÍCH ở ~40 block (in ra XML thô thay vì
|
||||
// chữ) và cắt câu ở ~150 ký tự ⇒ chữ ở đây đọc THẲNG từ .docx, không chép từ file structure đó.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// ═══ HĐ TRỌN GÓI NHÂN CÔNG & VẬT TƯ — `SOL-CCM-FO-002.02` (`HD-TP-VT`, ContractType = 8) ═══
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong, vat tu.docx`
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong va vat tu.docx`
|
||||
// (đọc `word/document.xml`, gộp mọi `<w:t>` trong cùng `<w:p>` bằng chuỗi RỖNG). Đối chiếu
|
||||
// `runs/2026-08-13-S194-yc032-hd-thauphu-2form/form-002-02-structure.md` (122 đoạn + 4 bảng ·
|
||||
// 91 ô = 36 ô đơn + 55 ô bảng).
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// ═══ HĐ TRỌN GÓI NHÂN CÔNG & THIẾT BỊ — `SOL-CCM-FO-002.03` (`HD-TP-TB`, ContractType = 9) ══
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.03.v01 Hop dong trong goi nhan cong, thiet bi.docx`
|
||||
// Nguồn chữ: `wwwroot/templates/SOL-CCM-FO-002.03.v01 Hop dong trong goi nhan cong va thiet bi.docx`
|
||||
// (đọc `word/document.xml`, gộp mọi `<w:t>` trong cùng `<w:p>` bằng chuỗi RỖNG — 201 đoạn +
|
||||
// 11 bảng). ⚠️ `form-002-03-structure.md` §1 bị LỖI TRÍCH ở ~40 block (in ra XML thô thay vì
|
||||
// chữ) và cắt câu ở ~150 ký tự ⇒ chữ ở đây đọc THẲNG từ .docx, không chép từ file structure đó.
|
||||
|
||||
@ -3843,6 +3843,14 @@ public static class DbInitializer
|
||||
|
||||
private static async Task SeedContractTemplatesAsync(ApplicationDbContext db, ILogger logger)
|
||||
{
|
||||
// 🔴 LUẬT (S194 — CI run #489 ĐỎ thật): TÊN FILE dưới `wwwroot/` CẤM CHỨA DẤU PHẨY.
|
||||
// MSBuild property-function tách tham số bằng dấu phẩy ⇒ `[MSBuild]::MakeRelative(a, b)`
|
||||
// với đường dẫn có "," biến thành lời gọi 3 tham số ⇒ `MSB4186: Method not found`,
|
||||
// CHẶN NGAY Ở BUILD (test chưa kịp khởi động).
|
||||
// 🔴 Bẫy đắt nhất: LOCAL KHÔNG TÁI HIỆN ĐƯỢC. `global.json` để `rollForward: latestFeature`
|
||||
// ⇒ CI nhảy SDK 10.0.202 còn local 10.0.104; `grep -c MakeRelative` trong
|
||||
// `Microsoft.NET.Publish.targets` = **0 ở SDK local**, tức dòng mã gây lỗi KHÔNG TỒN TẠI
|
||||
// trên máy dev. Cùng họ gotcha #92 (build-env CI trôi khỏi local) nhưng ở tầng .NET SDK.
|
||||
// Chỉ IsActive=true nếu file thực tế tồn tại trong wwwroot/templates/.
|
||||
// 3 file .doc (FO-002.02/03/06) chưa convert sẽ IsActive=false.
|
||||
var templates = new (string FormCode, string Name, ContractType? Type, string FileName, string Format, string? Description)[]
|
||||
@ -3854,10 +3862,10 @@ public static class DbInitializer
|
||||
// tách loại, `FormFeatures.cs:33` lọc template THEO `ContractType` ⇒ giữ nguyên thì
|
||||
// dropdown "Mẫu" của 2 loại mới RỖNG (reviewer B-5). Mỗi biến-thể nay trỏ đúng loại nó.
|
||||
("SOL-CCM-FO-002.02", "Hợp đồng trọn gói — Nhân công + Vật tư", ContractType.HopDongThauPhuVatTu,
|
||||
"SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong, vat tu.docx", "docx",
|
||||
"SOL-CCM-FO-002.02.v01 Hop dong tron goi nhan cong va vat tu.docx", "docx",
|
||||
"Template HĐ thầu phụ trọn gói — Nhân công & Vật tư (01A)"),
|
||||
("SOL-CCM-FO-002.03", "Hợp đồng trọn gói — Nhân công + Thiết bị", ContractType.HopDongThauPhuThietBi,
|
||||
"SOL-CCM-FO-002.03.v01 Hop dong trong goi nhan cong, thiet bi.docx", "docx",
|
||||
"SOL-CCM-FO-002.03.v01 Hop dong trong goi nhan cong va thiet bi.docx", "docx",
|
||||
"Template HĐ thầu phụ trọn gói — Nhân công & Thiết bị (01B)"),
|
||||
("SOL-CCM-FO-002.04", "Điều kiện chung hợp đồng trọn gói", null,
|
||||
"SOL-CCM-FO-002.04.v01 Dieu kien chung hop dong tron goi.docx", "docx",
|
||||
|
||||
Reference in New Issue
Block a user