対象: root/programs/CS(C# 側)
配置: root/programs
本書は、リリース時に何を・どの順で確認し、どこまでを機械が行い、どこからを人が行うかを 1 枚にまとめたもの。
一次情報は本書ではない。 迷ったら次を見ること。
内容 一次情報 ビルド構成・バージョン管理 CS/Frameworks/ANALYSIS.md7 章全ビルドの実行と判定 BUILDING.md単体テストの実行と判定 TESTING.mdサンプルの疎通確認 SMOKETEST.mdNuGet パッケージ化・公開の手順 CS/NuGet/README.md
| # | フェーズ | 手段 | 実施者 |
|---|---|---|---|
| 0 | 準備 | 手作業 | 人(エージェントは充足状況の確認・報告まで) |
| 1 | 検証(ビルド・単体テスト・疎通) | 1_BuildAll.ps1 / 2_RunAllTests.ps1 / 3_SmokeTest.ps1 |
エージェント可 |
| 2 | 検証(UI 系・ツール) | 手作業(GUI 操作) | 人(自動化は見送り。7 節) |
| 3 | パッケージ化 | CS\0_Release4Nuget.bat → _NuGetPack.bat |
エージェント可(指示があれば) |
| 4 | 公開 | _NuGetPush.bat + Wiki 手順 |
人のみ |
| 5 | 後始末 | 手作業 | 人(エージェントは差分の報告まで) |
取り消しにくい・外部に出る・システム設定を変えるものは人が行う。
この線引きは AGENTS.md(git 操作をしない/公開リポジトリへの投稿は承認を得てから)と同じ考え方。
| 人が行うフェーズ | 人が行う理由 |
|---|---|
| 0 準備 | Start-Service aspnet_state はシステム設定の変更。DB の初期化も同様。エージェントは不足を検知して対処方法とともに報告するに留める |
| 2 検証(UI 系) | GUI 操作のため |
| 4 公開 | _NuGetPush.bat は外部公開で取り消しが困難。かつ API キーを扱う |
| 5 後始末 | revert の確定はワーキング ツリーの検収と同じ扱い |
フェーズ 1 をエージェントが実行してよいのは、失敗しても被害が無く、結果がワーキング ツリーに残るだけだから。
フェーズ 3 は成果物をローカルに作るだけだが、CS\z_Common.bat の DEBUG_TYPE 変更を伴い、
フェーズ 4 と地続きのため、指示があったときだけ実行する。
フェーズ 1 は 3 本を順に実行するだけで済む。
cd root\programs
.\1_BuildAll.ps1 # 全ビルド.\2_RunAllTests.ps1 # 単体テスト.\3_SmokeTest.ps1 # サンプルの疎通クリーン ビルドから通しで 約 9.5 分。
2_RunAllTests.ps1 と 3_SmokeTest.ps1 は終了コードだけで合否が分かるが、
1_BuildAll.ps1 は既知の署名エラーで 1 になるため、内容の確認が要る(3 節)。
- Visual Studio を閉じた
…
1_DeleteDir.batが.vsを削除するため - SQL Server の Northwind に接続できる
- Northwind が初期状態(
Shippers3 件 /Orders830 件)
… 汚れている場合の戻し方はTESTING.md「テスト データの戻し方」
…Orders2(Northwind 標準ではない)は3_SmokeTest.ps1が無ければ作るため、事前準備は不要 - サービスが開始されている(
Start-Service、aspnet_state、要管理者権限)- Start-Service … アプリが 使うデータストア(Dockerコンテナ)を起動、初期化する。
- aspnet_state … net48 の Web アプリが使うASP.NET 状態サービスを起動する。
- IIS Express がインストールされている
-
0_SetVersion.ps1でバージョンを更新した```powershell cd root\programs .\0_SetVersion.ps1 -Version 3.3.0-alpha1 -WhatIf # 変更内容の確認 .\0_SetVersion.ps1 -Version 3.3.0-alpha1 # 実行 ``` … **バージョンの定義箇所は 2 系統に分かれており、手作業では追随を忘れやすい**ため、 一括で更新する(#531) | 更新先 | 書き込む値 | |---|---| | `CS/Frameworks/Infrastructure/Directory.Build.props` の `OpenTouryoVersion` | `3.3.0-alpha1`(指定値そのまま) | | net48 6 本の `Properties\AssemblyInfo.cs` の `AssemblyVersion` | `3.3.0.0`(サフィックスを落とし 4 桁目に `0`) | … net48 の対象は**パッケージに入る 6 本**。 `DamPstGrS` は net48 が無く、`Business` は非パッケージかつ別系統のため対象外 ``` Public / Public.Security / Framework / Framework.RichClient Public\Db\DamManagedOdp / Public\Db\DamMySQL ``` … **該当行が見つからなければ NG で停止する**(黙って素通りさせない)。 同じ版で再実行しても「変更なし」になる -
Business系は 1.0.0 のままであることを確認した … 意図的に別系統。0_SetVersion.ps1は触らない -
nuspec の
<dependencies>が csproj のPackageReferenceと一致している … 依存を増減したら nuspec 側も合わせる。相互依存の版は$version$で自動追随
プレリリース版は、サフィックス付きで指定する(
3.3.0-alpha1)。 サフィックスはOpenTouryoVersionにだけ入り、アセンブリの版には入らない。 SDK 形式 csproj の<Version>も、AssemblyVersion/FileVersionにはVersionPrefix(3.3.0)を、InformationalVersionには全体を割り当てる。 その挙動に合わせてある。
CS/NuGet/README.md1 節(0)の 「α・β版などを使用して 2 回以上繰り返す」は、次のように回す。.\0_SetVersion.ps1 -Version 3.3.0-alpha1 # プレ公開(develop 段階) .\0_SetVersion.ps1 -Version 3.3.0 # 本番(master マージ+タグ後)
OpenTouryoVersionはアセンブリに焼き込まれる。*_netcore100.csprojが<Version>$(OpenTouryoVersion)</Version>で参照するため、 書き換えたら必ずリビルド(フェーズ 3 の0_Release4Nuget.bat)が要る。 先にパッケージ化すると、古いアセンブリに新しい版番号が付く。
_NuGetPack.batが、net48 のAssemblyVersionとOpenTouryoVersionの 一致を検査して、ずれていれば停止する(#531)。 追随を忘れたまま公開すると、同じパッケージの net48 と net10.0 で アセンブリの版が食い違い、公開後には直せない。NG Public : 3.0.0 expected 3.1.0 [ERROR] The net48 AssemblyVersion does not match 3.1.0
0_SetVersion.ps1を使っていれば、この検査に引っかかることはない。 手で書き換えた場合や、片方だけ revert した場合の保険である。
_NuGetPack.batは、詰めたアセンブリの版も検査する(#531)。 上の検査はソースどうしを突き合わせているだけなので、0_SetVersion.ps1の後に0_Release4Nuget.batを飛ばしても通ってしまう。in\へ複製した後の実際の DLL を見て、ずれていれば停止する。NG in\net48\OpenTouryo.Public.dll : 3.3.0.0 expected 3.4.0.x [ERROR] The packaged assemblies do not carry 3.4.0 so the rebuild was skipped. Run CS\0_Release4Nuget.bat,
_T_NuGetPack.bat(テスト用)には、この検査は無い。 テスト用パッケージは版を引数で受け取り、OpenTouryoVersionを読まない。 版はパッケージに名前を付けるだけで、アセンブリには書き込まれないため、 食い違いようがない。
補足 : パッケージの版とアセンブリの版は、一致しなくてよい(NuGet の制約ではなく慣習)。 テスト公開した
Erutcurtsarfni.Oyruot.Public 3.3.0-alpha2は、 パッケージが3.3.0-alpha2、中の DLL が3.0.0.0で、正常に動作した。検査が見ているのは、パッケージの版とアセンブリの版の一致ではなく、 同じパッケージに入る net48 と net10.0 のアセンブリどうしが揃っているかである。
Directory.Build.propsの XML コメントに--(ハイフン 2 個)を書くと MSBuild がプロジェクトの読み込みに失敗する。区切り線に使わないこと。
| スクリプト | 見るもの | 期待値 | 文書 |
|---|---|---|---|
1_BuildAll.ps1 |
ビルドが通るか | エラー 0 件 | BUILDING.md |
2_RunAllTests.ps1 |
出力が前回と同じか | HEAD の Result*.txt |
TESTING.md |
3_SmokeTest.ps1 |
起動して想定どおり動くか | 定義側の判定条件 | SMOKETEST.md |
-
1_BuildAll.ps1のエラーが「既知の 1 件」だけである …-SkipCleanは使わない。前回の成果物が残っていると通ったように見える -
2_RunAllTests.ps1が終了コード 0(8 ケース) -
3_SmokeTest.ps1が終了コード 0(23 件)
1_BuildAll.ps1は現状ここで終了コード 1 になる。WSClnt_sample (net48)の ClickOnce 署名エラー(MSB3482)が残るため。 終了コードだけで判断せず、エラー一覧が下記 1 件だけであることを確認すること(4 節)。[WSClnt_sample (net48)] ... error MSB3482: 署名中にエラーが発生しました: ... WSClientWinCone_sample.exe の署名に失敗しました。 SignTool Error: No certificates were found that met all the given criteria.証明書をストアに入れた環境では 0 になる。
-IgnoreErrors "MSB3482"を付けると判定から外れて 0 になる(除外内容は一覧に残る)。 リリース判定では付けないこと。 目視で 1 件だけであることを確かめるのが本筋で、 この引数は人が見ない CI(BUILDING.md9 節)のためのもの。
所要時間の実測(クリーン ビルドから通しで 約 9.5 分)。
| スクリプト | 所要 |
|---|---|
1_BuildAll.ps1(31 ステップ) |
5.8 分 |
2_RunAllTests.ps1(8 ケース) |
1.3 分 |
3_SmokeTest.ps1(23 件) |
4.0 分 |
上の表はすべて C# 側(-Lang の既定)である。VB 側は -Lang VB で別に回す。
.\0_RunAll.ps1 -Lang VB # 1 と 3 だけを VB で通す(2 は対象外)- NuGet パッケージは C# 側から作る。 VB 側はリリース成果物ではない
- VB にテスト プロジェクトは無く、単体テストは C# の
Frameworks\Testsに集約されている - 所要は全ビルド 4.3 分 + 疎通 1.5 分(6 件)
リリースのたびに回す必要は無いが、VB 側に手を入れたリリースでは通すこと。
詳細は BUILDING.md 10 節と SMOKETEST.md 10 節。
1_BuildAll.ps1 → 2_RunAllTests.ps1 → 3_SmokeTest.ps1 の順で行う。
1_BuildAll.ps1 はクリーンを行い、4_Build_CopyAssemblies.bat がテストとサンプルの
参照先(Build_net48 / Build_netcore100)を更新するため、
逆順では古いアセンブリを見ることになる。
| スクリプト | NG の意味 |
|---|---|
1_BuildAll.ps1 |
コンパイル エラー、または restore の失敗 |
2_RunAllTests.ps1 |
退行/期待結果の陳腐化/テスト データの汚染のいずれか |
3_SmokeTest.ps1 |
起動時の失敗(構成・ネイティブ DLL・前提サービス)が多い |
2_RunAllTests.ps1 の「実測のみ/期待のみ」に件数の差が出た場合は、
まずテスト データの汚染を疑う(TESTING.md 5 節)。
2_RunAllTests.ps1 はワーキング ツリーの Result*.txt を書き換える(従来のバッチ運用と同じ)。
この生 diff を目視してはいけない。 実行日時が全行に入るため、 内容が同じでもほぼ全行が差分になる。実測では 6 ファイルで約 2,458 行。
-[2025/11/18 15:19:08,286],[INFO ],[1],,,,----->>,...
+[2026/08/01 22:40:19,772],[INFO ],[1],,,,----->>,...判定は 2_RunAllTests.ps1 の「正規化後の差分」で行う。 それが 0 なら内容は同じ。
生 diff を読むのは、正規化後に差分が出たときだけでよい。
- 正規化後の差分が 0 であることを確認した
-
Result*.txtをコミットするかどうかを判断した … 内容が変わっていないならコミットしなくてよい(日時だけの差分が積み上がるため)。 仕様変更で内容が変わった場合は、新しい基準としてコミットする
自動化から外した対象。起動して主要な画面が出ることを確認する。
| 区分 | net48 | net10.0 |
|---|---|---|
| 2 層 C/S | 2CSClientWin_sample2CSClientWPF_sampleAsyncEvent_sampleCustCtrl_sampleGenDaoAndBatUpd_sampleTimeStamp_sample |
2CSClientWin_sample2CSClientWPF_sampleCustCtrl_sampleGenDaoAndBatUpd_sampleTimeStamp_sample |
| WS クライアント | WSClientWin_sampleWSClientWPF_sampleWSClientWin2_sampleWSClientWinCone_sample |
WSClientWin_sampleWSClientWPF_sampleWSClientWin2_sample |
- 2 層 C/S 系(net48 6 本 / net10.0 5 本)が起動し、CRUD 画面が操作できる
- WS クライアント系(net48 4 本 / net10.0 3 本)が起動する
WS クライアントの疎通には別リポジトリが要る。 呼び先の Web サービスは
OpenTouryoProject/ResourceServerTemplatesへ移設済みで、本リポジトリだけでは接続先が無い。
| ツール | 確認内容 |
|---|---|
DaoGen_Tool(墨壺) |
GUI 起動のみ。CUI(/HELP /CUI /MODE ...)は 3_SmokeTest.ps1 が網羅済み |
DPQuery_Tool |
GUI 起動 |
EncAndDecUtil |
GUI 起動(CUI 版は 2_RunAllTests.ps1 が網羅済み) |
DeployZipPackWithHTTP |
GUI 起動 + 圧縮・解凍(ZIP 部品の唯一の利用者。#528) |
-
DaoGen_Toolが GUI で起動し、D 層定義・SQL が生成できる … 生成ロジック自体は CUI 側で自動確認済み。ここで見るのは GUI が動くこと -
DPQuery_Toolが GUI で起動する -
EncAndDecUtilが GUI で起動する -
DeployZipPackWithHTTPが GUI で起動し、圧縮と解凍ができる …ZipperV2/UnZipperV2を使う唯一の利用者。ZIP 部品を変えたら必ず見ること。 設定と履歴はcurrent.json/histories.json(旧.binは読まない)
-
WSClientWinCone_sampleの ClickOnce 署名エラー(MSB3482)を確認した … 拇印で証明書ストアを検索するため、当該証明書が無い環境ではビルドできない。 環境依存でありコード側の不具合ではない(BUILDING.md4 節)
手順の一次情報は CS/NuGet/README.md。
ここに書き写すと二重管理になるため、要点と抜けやすい点だけを挙げる。
- 正式版は、
develop→masterをマージ(--no-ff)し、タグを打った後に詰めた … パッケージは詰めた時のコミットに永久に固定される。 同じバージョンは一度しか公開できないため、develop 段階で出すなら プレリリース版(3.3.0-alpha1など)にする(README.md1 節(0)・7 節) …masterは PR 経由でしか入らない。 ブランチ保護で レビュー 1 名 + CI(build)の成功が必須。CI は約 14 分かかる (ローカルの検証 3 本に加え、CI 側は DB の導入と初期化が入るため) - そのコミットを push 済みである … 未 push だと Source Link が 404 になる。公開後には直せない
-
CS\0_Release4Nuget.batを実行した …1_DeleteDir→2_Build_NuGet_net48→1_DeleteDir→2_Build_NuGet_netcore100→4_Build_CopyAssembliesのみ。サンプルはビルドしない …DEBUG_TYPEはこのバッチが指定する。手で書き換えない(#531) -
CS\NuGet\_NuGetPack.batでパッケージ化した … ビルドとパッケージ化は同じコミットで行う。 PDB のコミットはビルド時、nuspec のコミットはパッケージ化時に決まるため、 間にコミットすると食い違う(README.md2 節 確認 4) …in\とout\はこのバッチが先に消すので、手で片付けなくてよい (README.md6 節) -
README.md2 節の確認 5 点を通した -
set NUGET_API_KEY=<キー>の上でCS\NuGet\out\sp\_NuGetPush.batを実行し、push した … 最新はsp(シンボル付き)のみでよい。キーを bat に直書きしない(#531) - Wiki の手順(NuGet 利用リポジトリの参照貼り直し)を実施した
revert する項目は無くなった(#531)。忘れやすい作業を、そもそも作らない形に変えた。
| 以前 revert していたもの | 現在 |
|---|---|
CS\z_Common.bat の DEBUG_TYPE |
0_Release4Nuget.bat が指定するので書き換えない |
_NuGetPush.bat の API キー |
環境変数 NUGET_API_KEY で渡すので、コンソールを閉じれば消える |
- API キーを
Revokeした(Deleteはしない) …Revokeは即座に無効化するが、行はRevokedとして残り、 次回はRegenerateで再び使える。スコープ(グロブ)の設定を作り直さずに済む …Deleteはキーの定義ごと消えるため、その系統をもう使わないときだけ … 有効期限を最短にしてあるなら、失効に任せてもよい(README.md8 節) -
%AppData%\NuGet\NuGet.Configの<apikeys>にキーが残っていない … 過去にnuget.exe SetApiKeyを使っていた場合、そこに永続化されている。 削除オプションが無いため、該当する<add>行を手で削除する(README.md8 節) -
git statusに意図しない変更が残っていない … 特にResult*.txt(2_RunAllTests.ps1が再生成する)とCS\Frameworks\Tests\EncAndDecUtilCUI\*.cer/*.pfx(Git 管理外の作業用コピー)
| 対象 | 自動化 | 理由 |
|---|---|---|
| 全ビルド(31 ステップ) | 済 | 既存バッチを呼ぶだけで済む |
| 単体テスト(8 ケース) | 済 | 期待結果ファイルが既にあり、正規化で機械比較できる |
| バッチ・CLI サンプル(9 件) | 済 | プロセス実行のみ。DB 疎通まで確認できる |
DaoGen_Tool の CUI(6 件) |
済 | #508 で CUI 化。DB → 定義 CSV → Dao・SQL まで通せる |
| Web アプリ(3 件) | 済 | ログインまで通せば認証・セッションまで確認できる |
| UI 系サンプル(18 本) | 見送り | UI Automation が必要。画面定義の変更で壊れやすく維持費が高い。 通す B 層/D 層は Web 系・バッチ系と重複し、回帰検出力の増分が小さい |
| GUI ツール(4 本) | 見送り | 同上。DaoGen_Tool は生成ロジックを CUI 側で確認済みのため、手作業で見るのは GUI が起動することだけでよい。 DeployZipPackWithHTTP は ZIP の圧縮・解凍まで見る(CUI が無いため) |
| Web サービス | 不可 | 本リポジトリにホストが無い(別リポジトリへ移設済み) |
自動化した対象が「起動する」ことは、手作業側の確認範囲を狭める。
DaoGen_Tool は CUI で生成ロジックまで確認できるようになったため、
GUI 側で見るのは画面が動くことだけになった。
-
AGENTS.mdのポリシー遵守(git 操作をしない) … 検証でResult*.txtが書き換わるが、コミットの要否とタイミングは人が判断する - 検証は
1_BuildAll.ps1→2_RunAllTests.ps1→3_SmokeTest.ps1の順(3 節) -
1_BuildAll.ps1に-SkipCleanを付けない(リリース判定では前回成果物を残さない) - NG を「既知」で片付けない。 既知として扱ってよいのは
WSClientWinCone_sampleの署名エラーと NuGet 脆弱性警告のみ(4 節・BUILDING.md3 節) -
2_RunAllTests.ps1の NG は、退行/期待結果の陳腐化/テスト データの汚染を切り分けてから報告 - 前提サービス・DB の状態を勝手に変えない。 不足は対処方法とともに報告する
(
3_SmokeTest.ps1がaspnet_stateを自動起動しないのと同じ理由) - フェーズ 1(検証)は自分で実行してよい。 フェーズ 0・2・4・5 は人が行う(1 節)
- 公開(
_NuGetPush.bat)は実行しない。 外部公開で取り消しが困難、かつ API キーを扱う。 パッケージ化(フェーズ 3)は指示があったときだけ - Issue のクローズ・ラベル変更は人が行う。エージェントは提案に留める
- 後始末(6 節)の revert 漏れが無いか
git statusで確認して報告