From cad39918ef0576afe199f177a6b091a27c35b342 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 20:05:27 +0000 Subject: [PATCH 1/4] feat: update complete-unit-tests.md to support multi-phase coverage iteration CmdDatas/Commands tests are nearly complete (4 remaining). Update the workflow to support iterating through: - Phase 1: Finish remaining CmdDatas commands (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) - Phase 2: Expand Commands/ coverage (8700 src lines, ~11% tested) - Phase 3: Add Intermissions/ tests (2200 lines, 0% tested) Each step now detects the current phase and provides appropriate test patterns, source references, and file placement guidance. Agent-Logs-Url: https://github.com/7474/SRC/sessions/b0a62599-173f-4e91-a6a8-22f475c567a3 Co-authored-by: 7474 <4744735+7474@users.noreply.github.com> --- .github/workflows/complete-unit-tests.md | 341 ++++++++++++++++++----- 1 file changed, 275 insertions(+), 66 deletions(-) diff --git a/.github/workflows/complete-unit-tests.md b/.github/workflows/complete-unit-tests.md index bc777cdd..b8c00f3f 100644 --- a/.github/workflows/complete-unit-tests.md +++ b/.github/workflows/complete-unit-tests.md @@ -1,14 +1,16 @@ --- description: | - SRC# 移植プロジェクトのユニットテスト補完を自動実行するワークフロー。 - SRC.Sharp/SRCCore/CmdDatas/Commands/ の実装済みコマンドのうち、 - テストが不足しているものを特定し、SRC.Sharp.Help/src/ のヘルプドキュメントを - 期待値として自動的にユニットテストを追加する。 - - This workflow automatically completes unit tests for the SRC# migration project. - It identifies implemented commands under SRC.Sharp/SRCCore/CmdDatas/Commands/ - that lack test coverage and adds unit tests using SRC.Sharp.Help/src/ help - documentation as the expected behavior specification. + SRC# 移植プロジェクトのカバレッジ補強を自動実行するワークフロー。 + フェーズ1: SRC.Sharp/SRCCore/CmdDatas/Commands/ の残コマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を完了する。 + フェーズ2: SRC.Sharp/SRCCore/Commands/ (戦闘・ゲーム操作ロジック) のテストを拡充する。 + フェーズ3: SRC.Sharp/SRCCore/Intermissions/ のテストをゼロから追加する。 + 各フェーズを日次で反復し、PR 1件あたり 1000 行以内を目安に段階的にカバレッジを向上させる。 + + This workflow incrementally raises test coverage for the SRC# migration project. + Phase 1: Finish remaining CmdDatas commands (ABGMCmd, AIfCmd, ATalkCmd, FontCmd). + Phase 2: Expand coverage for Commands/ (battle/game-action logic; ~8700 lines, ~11% covered). + Phase 3: Add tests for Intermissions/ (2200 lines, currently 0% covered). + Each phase iterates daily, targeting less than 1000 diff lines per PR. NOTE: This workflow runs on windows-latest because SRC.Sharp contains Windows-targeting projects (SRCSharpForm, SRCTestForm targeting net8.0-windows). Running on Windows avoids @@ -78,15 +80,20 @@ safe-outputs: engine: copilot --- -# ユニットテスト補完エージェント / Unit Test Completion Agent +# カバレッジ補強エージェント / Coverage Reinforcement Agent あなたは SRC# 移植プロジェクト (`${{ github.repository }}`) の自動テストエンジニアです。 -実装済みコマンドのうち、ユニットテストが不足しているものを特定し、 -ヘルプドキュメントの記載を期待値としてテストを追加してください。 +以下のフェーズ順に、テストが不足している領域を特定してテストを追加してください。 +1 回の実行では PR が 1000 行以内に収まる分量のみを対象にしてください。 You are an automated test engineer for the SRC# migration project (`${{ github.repository }}`). -Your task is to identify implemented commands that lack unit tests and add tests using -the help documentation as the expected behavior specification. +Identify under-tested areas in the priority order below and add tests. +Keep each PR under 1000 diff lines — do only one chunk per run. + +**フェーズ優先順位 / Phase Priority** +1. **フェーズ1 (CmdDatas 残件)**: `SRC.Sharp/SRCCore/CmdDatas/Commands/` に残るコマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を優先的に完了する。 +2. **フェーズ2 (Commands/ 拡充)**: `SRC.Sharp/SRCCore/Commands/` のゲームロジック (`Command.*.cs`) を対象にテストを追加する。ソース ~8700 行に対しテストは ~1000 行しかない。 +3. **フェーズ3 (Intermissions/ 追加)**: `SRC.Sharp/SRCCore/Intermissions/Intermission.cs` はテストがゼロ (2200 行)。追加する。 ## Step 0: 既存PRの確認 / Check for Existing Open PRs @@ -108,10 +115,9 @@ an Agentic Workflow run is already in progress. Use `noop` safe output to skip: オープン PR がない場合のみ、以下の Step 1 以降を続けてください。 Only proceed to Step 1 and beyond if no such open PR exists. -## Step 1: コマンド実装の列挙 / List Command Implementations +## Step 1: 現在のフェーズを判定する / Determine the Current Phase -以下のコマンドを実行して実装済みコマンドファイルを列挙してください: -Run bash to list all implemented command files: +### フェーズ1チェック: CmdDatas 残コマンドの確認 ```bash find SRC.Sharp/SRCCore/CmdDatas/Commands -name "*.cs" | \ @@ -119,62 +125,170 @@ find SRC.Sharp/SRCCore/CmdDatas/Commands -name "*.cs" | \ sort ``` -コマンドクラス名とファイル名の対応を把握してください。 -Identify the mapping between command class names and their file names. +既知の残コマンドは以下の 4 件です(既にテスト済みなら次フェーズへ): +- `ABGMCmd` (抽象基底, PlayMIDICmd/StartBGMCmd の親) +- `AIfCmd` (非同期 If) +- `ATalkCmd` (非同期 Talk) +- `FontCmd` (フォント設定) + +これら 4 件のいずれかが未テストであれば **フェーズ1** として Step 2-8 を実行してください。 + +### フェーズ2チェック: Commands/ のカバレッジ確認 + +フェーズ1 が完了している場合は以下を確認してください: + +```bash +ls SRC.Sharp/SRCCoreTests/Commands/ +wc -l SRC.Sharp/SRCCore/Commands/Command.*.cs +``` + +テスト済みファイル (CommandPropsTests.cs, SelectedStateTests.cs, UiCommandTests.cs) のみが存在し、 +`Command.attack.cs` (1546行), `Command.process.cs` (1617行), `Command.unitability.cs` (742行) 等に +対応するテストがなければ **フェーズ2** として Step 2-8 を実行してください。 + +### フェーズ3チェック: Intermissions/ のカバレッジ確認 + +フェーズ2 が完了している場合は以下を確認してください: + +```bash +ls SRC.Sharp/SRCCoreTests/Intermissions/ 2>/dev/null || echo "テストなし" +wc -l SRC.Sharp/SRCCore/Intermissions/Intermission.cs +``` + +`SRCCoreTests/Intermissions/` が存在しない、またはテストが少なければ **フェーズ3** として Step 2-8 を実行してください。 ## Step 2: 既存テストの確認 / Check Existing Test Coverage -以下のコマンドで既存テストファイルを確認してください: -Check existing test files: +現在のフェーズに応じて既存テストを確認してください: + +### フェーズ1 の場合 ```bash ls SRC.Sharp/SRCCoreTests/CmdDatas/ ``` 既存テストファイルの内容を読んで、どのコマンドがテスト済みかを把握してください。 -特に以下のファイルを参照してテストパターンを確認: -Read existing test files to understand which commands are already tested. -Refer to these files for test patterns: +テストパターンの参照先: +- `SRC.Sharp/SRCCoreTests/CmdDatas/SwitchDoLoopCmdTests.cs` - `SRC.Sharp/SRCCoreTests/CmdDatas/VariableCmdTests.cs` - `SRC.Sharp/SRCCoreTests/CmdDatas/ControlCmdTests.cs` -- `SRC.Sharp/SRCCoreTests/CmdDatas/SwitchDoLoopCmdTests.cs` + +### フェーズ2 の場合 + +```bash +ls SRC.Sharp/SRCCoreTests/Commands/ +``` + +既存テストは `CommandPropsTests.cs`, `SelectedStateTests.cs`, `UiCommandTests.cs` のみ。 +対象ファイル一覧と対応するソースを確認してください: +- `Command.launch.cs` / `Command.mapcommend.cs` / `Command.state.cs` +- `Command.unitcommand.cs` / `Command.unitmove.cs` +- `Command.unitsp.cs` / `Command.unitsupply.cs` / `Command.unitxxx.cs` +- `Command.attack.cs` / `Command.process.cs` (複雑なため後回し) + +テストパターンの参照先: +- `SRC.Sharp/SRCCoreTests/Commands/CommandPropsTests.cs` + +### フェーズ3 の場合 + +```bash +ls SRC.Sharp/SRCCoreTests/Intermissions/ 2>/dev/null || echo "テストなし" +``` + +`SRC.Sharp/SRCCore/Intermissions/Intermission.cs` を読んで public メソッドを把握してください。 ## Step 3: カバレッジマトリクスの構築 / Build Coverage Matrix -Step 1 で列挙したコマンドと Step 2 で確認した既存テストを比較して、 -未テストのコマンドリストを作成してください。 -以下はテスト不要のため除外: -- `NopCmd`, `NotImplementedCmd`, `NotSupportedCmd`(ロジックなし) +現在のフェーズに応じて未テスト対象リストを作成してください: + +### フェーズ1 の場合 + +Step 1 で確認した CmdDatas コマンドと Step 2 で確認した既存テストを比較し、 +未テストコマンドリストを作成してください。以下はテスト不要のため除外: +- `NopCmd`, `NotImplementedCmd`, `NotSupportedCmd` (ロジックなし) + +### フェーズ2 の場合 + +`SRC.Sharp/SRCCore/Commands/Command.*.cs` の各ファイルについて、 +対応するテストが存在しないものをリストアップしてください。 +以下の優先順位で対象を選んでください(1回の実行では PR 1000行以内に収まる量だけ): +1. `Command.state.cs` (51行) — 状態定数のテスト +2. `Command.launch.cs` (179行) — 発進・帰投ロジック +3. `Command.unitmove.cs` (467行) — ユニット移動 +4. `Command.unitxxx.cs` (346行) — ユニットその他コマンド +5. `Command.unitsupply.cs` (279行) — 補給 +6. `Command.unitsp.cs` (485行) — スペシャルパワー +7. `Command.unitcommand.cs` (498行) — ユニットコマンド +8. `Command.mapcommend.cs` (637行) — マップコマンド +9. `Command.unitability.cs` (742行) — アビリティ +10. `Command.preview.cs` (759行) — プレビュー +11. `Command.unitform.cs` (840行) — ユニットフォーム +12. `Command.attack.cs` / `Command.process.cs` (各1500行超, GUI依存が強いため最後) -Compare commands from Step 1 with existing tests from Step 2 to build -a list of untested commands. Exclude: -- `NopCmd`, `NotImplementedCmd`, `NotSupportedCmd` (no logic to test) +### フェーズ3 の場合 -## Step 4: ヘルプドキュメントの参照 / Read Help Documentation +`SRC.Sharp/SRCCore/Intermissions/Intermission.cs` の public メソッド一覧を作成し、 +テストが存在しないものをすべてリストアップしてください。 + +## Step 4: 仕様の確認 / Read Specifications + +現在のフェーズに応じて、テスト作成の根拠となる情報を収集してください: + +### フェーズ1 の場合 (CmdDatas — ヘルプドキュメント参照) 各未テストコマンドについて、対応するヘルプファイルを確認してください: -For each untested command, find and read the corresponding help file: ```bash # ヘルプファイルの一覧 / List available help files ls SRC.Sharp.Help/src/ | grep "コマンド.md" # 特定のコマンドのヘルプを読む例 / Example: read specific command help -cat "SRC.Sharp.Help/src/ForEachコマンド.md" +cat "SRC.Sharp.Help/src/ABGMコマンド.md" +cat "SRC.Sharp.Help/src/AIfコマンド.md" +cat "SRC.Sharp.Help/src/ATalkコマンド.md" +cat "SRC.Sharp.Help/src/Fontコマンド.md" ``` 各ヘルプファイルから以下を抽出してください: -Extract the following from each help file: - **書式 (Format/Syntax)**: コマンドの構文 - **解説 (Description)**: コマンドの動作説明 - **例 (Examples)**: 具体的な使用例 +### フェーズ2 の場合 (Commands/ — ソースコード直接参照) + +ヘルプドキュメントが存在しないため、ソースコードを仕様の根拠とします: + +```bash +# 対象ファイルを読む +cat SRC.Sharp/SRCCore/Commands/Command.launch.cs +# または対象ファイルのメソッドシグネチャを一覧 +grep -n "public\|internal\|private.*void\|private.*bool\|private.*int\|private.*string" \ + SRC.Sharp/SRCCore/Commands/Command.launch.cs +``` + +各メソッドについて以下を理解してください: +- **メソッドの目的**: コメントや命名から推測 +- **入力条件**: 引数・前提となるゲーム状態 (SelectedUnit, Map, etc.) +- **期待される副作用**: ユニット状態変化、Map 変化、GUI 呼び出し + +MockGUI のハンドラを設定することで GUI 依存の部分もテスト可能です: +```bash +cat SRC.Sharp/SRCCore/TestLib/MockGUI.cs +``` + +### フェーズ3 の場合 (Intermissions/ — ソースコード直接参照) + +```bash +cat SRC.Sharp/SRCCore/Intermissions/Intermission.cs +``` + +public メソッドの仕様をソースコードから読み取り、テスト観点を整理してください。 + ## Step 5: テストの作成 / Write Tests -各未テストコマンドに対して、以下のガイドラインに従いテストを作成してください: -For each untested command, write tests following these guidelines: +現在のフェーズに応じたガイドラインに従いテストを作成してください: -### テストパターン / Test Patterns +### フェーズ1 テストパターン (CmdDatas コマンド) 既存テストのパターンに従ってください: Follow the existing test patterns from `SwitchDoLoopCmdTests.cs`: @@ -210,22 +324,91 @@ public class [CommandGroup]CmdTests } ``` -### 必須テストケース / Required Test Cases +### フェーズ2 テストパターン (Commands/ ゲームロジック) -各コマンドに対して: -For each command: -1. **正常動作テスト** (最低1件): ヘルプの「解説」に記載の主要ユースケース -2. **境界条件テスト** (最低1件): ヘルプに記載のエッジケース -3. **エラーハンドリングテスト**: 引数不足や無効な引数のケース -4. **特殊モードテスト**: オプションパラメータがある場合 +Commands/ は SRC の partial class で構成されています。テストには MockGUI を使い、 +GUI のハンドラを必要に応じてセットアップしてください: -### テストファイルの配置 / Test File Placement +```csharp +[TestClass] +public class Command[TargetFile]Tests +{ + private SRC CreateSrc() + { + var src = new SRC { GUI = new MockGUI() }; + // 必要に応じてゲーム状態を初期化 + return src; + } + + // プロパティ・定数のテスト例 + [TestMethod] + public void [ConstName]_HasExpectedValue() + { + // Command.define.cs の定数値が正しいことを確認 + Assert.AreEqual(4, Command.AttackCmdID); + } + + // 状態変化のテスト例 + [TestMethod] + public void [MethodName]_[Condition]_[ExpectedResult]() + { + // Arrange: ゲーム状態を初期化 + var src = CreateSrc(); + var mock = (MockGUI)src.GUI; + // MockGUI のハンドラを必要に応じて設定 + // mock.SomeHandler = (...) => { ... }; -- 既存テストファイルに関連コマンドがある場合: 既存ファイルに追記 -- 新規コマンドグループの場合: `SRC.Sharp/SRCCoreTests/CmdDatas/[CommandGroup]CmdTests.cs` を新規作成 + // Act + // src.Commands.SomeMethod(...) + + // Assert + // Assert.AreEqual(expected, actual); + } +} +``` + +テストファイルの配置 (Commands/ フェーズ): +- `SRC.Sharp/SRCCoreTests/Commands/Command[TargetFile]Tests.cs` +- 例: `SRC.Sharp/SRCCoreTests/Commands/CommandLaunchTests.cs` + +### フェーズ3 テストパターン (Intermissions/) + +```csharp +[TestClass] +public class IntermissionTests +{ + private SRC CreateSrc() + { + var src = new SRC { GUI = new MockGUI() }; + // 必要なゲーム状態を設定 + return src; + } + + [TestMethod] + public void [MethodName]_[Condition]_[ExpectedResult]() + { + // Arrange + // Act: src.InterMission.SomeMethod(...) + // Assert + } +} +``` + +テストファイルの配置 (Intermissions/ フェーズ): +- `SRC.Sharp/SRCCoreTests/Intermissions/IntermissionTests.cs` + +### 必須テストケース / Required Test Cases (全フェーズ共通) + +各対象に対して: +1. **正常動作テスト** (最低1件): 主要ユースケース +2. **境界条件テスト** (最低1件): エッジケース +3. **エラーハンドリングテスト**: 無効な引数や状態のケース (可能な場合) +4. **特殊モードテスト**: オプションパラメータがある場合 ## Step 6: 実装との齟齬の確認 / Check for Discrepancies +### フェーズ1 の場合 + 実装がヘルプドキュメントと異なる場合は、以下の方針に従ってください: If the implementation differs from the help documentation, follow this policy: @@ -244,6 +427,19 @@ Title: [unit-test] [CommandName]: Discrepancy from help documentation - 推奨対応(修正 or ヘルプ更新 or 現状維持) ``` +### フェーズ2・3 の場合 + +ソースコードを仕様の根拠とするため、実装と仕様の齟齬は原則として生じません。 +テスト作成中に以下の観点で問題を発見した場合は Issue を作成してください: +- メソッドの動作が不明確で仕様を決定できない場合 +- 明らかなバグ(コメントと実装が矛盾するなど) +- テスト不可能な設計(外部依存が強すぎるなど) + +``` +タイトル: [カバレッジ補強] [ClassName.MethodName]: テスト困難 +Title: [coverage] [ClassName.MethodName]: Hard to test +``` + ## Step 7: テストの実行と検証 / Run and Validate Tests ```bash @@ -263,52 +459,65 @@ After completing test additions: `create-pull-request` safe output を使って PR を作成: Use `create-pull-request` safe output to create a PR: -**PR タイトル**: "[unit-tests] ユニットテスト補完: [追加したコマンド名のリスト]" +**PR タイトル**: "[unit-tests] カバレッジ補強 フェーズN: [追加/対象のサマリー]" **PR 本文**: ``` -🧪 ユニットテスト補完 レポート (YYYY-MM-DD) +🧪 カバレッジ補強レポート (YYYY-MM-DD) + +## 現在のフェーズ / Current Phase +- フェーズN: [CmdDatas 残件完了 / Commands/ 拡充 / Intermissions/ 追加] ## 追加したテスト / Tests Added -- [CommandName]Cmd: N件追加 (ファイル名) +- [ClassName / FileName]: N件追加 (ファイル名) - ... 合計: N件追加 ## カバレッジサマリー / Coverage Summary -- テスト済み (既存): X コマンド -- 新規テスト追加: Y コマンド -- 未テスト (残り): Z コマンド [リスト] +- フェーズ1 (CmdDatas/Commands): X/Y コマンド完了 (残り: ABGMCmd, AIfCmd, ATalkCmd, FontCmd のうち残件) +- フェーズ2 (Commands/): テストファイル Z件 / ソースファイル W件 +- フェーズ3 (Intermissions/): テスト有 or なし ## 齟齬の報告 / Discrepancies Found -- [CommandName]: [概要] → Issue #XXX +- [対象]: [概要] → Issue #XXX - なし / None ## テスト結果 / Test Results Passed: N, Skipped: M, Failed: 0 -次のステップ: 次回実行で残りのコマンドをカバー -Next step: Cover remaining commands on next run +次のステップ: 次回実行で次のフェーズ/ファイルをカバー +Next step: Cover the next phase/file on the next run ``` ### 変更がない場合 / If no changes needed `noop` safe output を使用: Use `noop` safe output with message: -"All implemented commands already have sufficient test coverage." +"All target areas already have sufficient test coverage." ## 重要な注意事項 / Important Notes - **既存テストを削除しない** / Never delete existing tests - **テストは必ずパスさせる** / All tests must pass before creating PR -- **ヘルプファイルを期待値として使用** / Use help files as the source of truth +- **フェーズ1**: ヘルプファイルを期待値として使用 / Use help files as the source of truth +- **フェーズ2・3**: ソースコードを仕様の根拠として使用 / Use source code as the specification - **PR は 1000 行以内** / Keep PR diff under 1000 lines; split if needed -- **一度に全コマンドを対象にしない** / Don't try to cover all commands at once; prioritize by Epic order - - Epic 4 (Events/Commands) > Epic 1 (Combat) > Epic 2 (Unit/Pilot) > others +- **一度に全ファイルを対象にしない** / Don't try to cover all files at once; use the priority order in Step 3 +- **フェーズ2の複雑ファイル注意**: `Command.attack.cs` と `Command.process.cs` は GUI 依存が強く難易度が高いため、 + 他のファイルを先に完了させてから最後に取り組んでください + `Command.attack.cs` and `Command.process.cs` are GUI-heavy; tackle them last ## コンテキスト / Context - リポジトリ: `${{ github.repository }}` -- コマンド実装: `SRC.Sharp/SRCCore/CmdDatas/Commands/` -- テストファイル: `SRC.Sharp/SRCCoreTests/CmdDatas/` -- ヘルプドキュメント: `SRC.Sharp.Help/src/[コマンド名]コマンド.md` -- テストインフラ: `SRC.Sharp/SRCCoreTests/TestLib/` +- **フェーズ1 ターゲット** + - コマンド実装: `SRC.Sharp/SRCCore/CmdDatas/Commands/` + - テストファイル: `SRC.Sharp/SRCCoreTests/CmdDatas/` + - ヘルプドキュメント: `SRC.Sharp.Help/src/[コマンド名]コマンド.md` +- **フェーズ2 ターゲット** + - コマンド実装: `SRC.Sharp/SRCCore/Commands/Command.*.cs` + - テストファイル: `SRC.Sharp/SRCCoreTests/Commands/` +- **フェーズ3 ターゲット** + - ソース: `SRC.Sharp/SRCCore/Intermissions/Intermission.cs` + - テストファイル: `SRC.Sharp/SRCCoreTests/Intermissions/` +- テストインフラ: `SRC.Sharp/SRCCore/TestLib/` - 移植プロトコル: `.github/copilot/autonomous-agent.md` From 9a59abfa46f52d87a3ba13964c09268dcf270e45 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 20:06:49 +0000 Subject: [PATCH 2/4] refactor: address code review feedback on schedule description and PR size guidance Agent-Logs-Url: https://github.com/7474/SRC/sessions/b0a62599-173f-4e91-a6a8-22f475c567a3 Co-authored-by: 7474 <4744735+7474@users.noreply.github.com> --- .github/workflows/complete-unit-tests.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/complete-unit-tests.md b/.github/workflows/complete-unit-tests.md index b8c00f3f..9cab0ef9 100644 --- a/.github/workflows/complete-unit-tests.md +++ b/.github/workflows/complete-unit-tests.md @@ -4,13 +4,13 @@ description: | フェーズ1: SRC.Sharp/SRCCore/CmdDatas/Commands/ の残コマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を完了する。 フェーズ2: SRC.Sharp/SRCCore/Commands/ (戦闘・ゲーム操作ロジック) のテストを拡充する。 フェーズ3: SRC.Sharp/SRCCore/Intermissions/ のテストをゼロから追加する。 - 各フェーズを日次で反復し、PR 1件あたり 1000 行以内を目安に段階的にカバレッジを向上させる。 + 各フェーズをスケジュール実行(日次)や手動実行で反復し、PR 1件あたり 1000 行以内を目安に段階的にカバレッジを向上させる。 This workflow incrementally raises test coverage for the SRC# migration project. Phase 1: Finish remaining CmdDatas commands (ABGMCmd, AIfCmd, ATalkCmd, FontCmd). Phase 2: Expand coverage for Commands/ (battle/game-action logic; ~8700 lines, ~11% covered). Phase 3: Add tests for Intermissions/ (2200 lines, currently 0% covered). - Each phase iterates daily, targeting less than 1000 diff lines per PR. + Each phase iterates on schedule (daily) or on demand, targeting less than 1000 diff lines per PR. NOTE: This workflow runs on windows-latest because SRC.Sharp contains Windows-targeting projects (SRCSharpForm, SRCTestForm targeting net8.0-windows). Running on Windows avoids @@ -211,7 +211,8 @@ Step 1 で確認した CmdDatas コマンドと Step 2 で確認した既存テ `SRC.Sharp/SRCCore/Commands/Command.*.cs` の各ファイルについて、 対応するテストが存在しないものをリストアップしてください。 -以下の優先順位で対象を選んでください(1回の実行では PR 1000行以内に収まる量だけ): +以下の優先順位で対象を選んでください(1回の実行では PR 1000行以内に収まる量だけ)。 +**1000行を超えそうな場合は対象ファイルを減らし、次の実行に回してください**(例: `Command.unitmove.cs` だけで 300 行のテストになるなら、それ1ファイルで PR を作成する): 1. `Command.state.cs` (51行) — 状態定数のテスト 2. `Command.launch.cs` (179行) — 発進・帰投ロジック 3. `Command.unitmove.cs` (467行) — ユニット移動 From 6129febccf9460b612d19114a1315a107b09c7a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 20:10:59 +0000 Subject: [PATCH 3/4] refactor: remove PR size limit, maximize coverage per run iteration Agent-Logs-Url: https://github.com/7474/SRC/sessions/37bf41de-3966-49d7-804c-dd3fcd2510ed Co-authored-by: 7474 <4744735+7474@users.noreply.github.com> --- .github/workflows/complete-unit-tests.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/complete-unit-tests.md b/.github/workflows/complete-unit-tests.md index 9cab0ef9..5c169fa4 100644 --- a/.github/workflows/complete-unit-tests.md +++ b/.github/workflows/complete-unit-tests.md @@ -4,13 +4,13 @@ description: | フェーズ1: SRC.Sharp/SRCCore/CmdDatas/Commands/ の残コマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を完了する。 フェーズ2: SRC.Sharp/SRCCore/Commands/ (戦闘・ゲーム操作ロジック) のテストを拡充する。 フェーズ3: SRC.Sharp/SRCCore/Intermissions/ のテストをゼロから追加する。 - 各フェーズをスケジュール実行(日次)や手動実行で反復し、PR 1件あたり 1000 行以内を目安に段階的にカバレッジを向上させる。 + 各フェーズをスケジュール実行(日次)や手動実行で反復し、1回の実行でできるだけ多くのテストを追加してカバレッジを向上させる。 This workflow incrementally raises test coverage for the SRC# migration project. Phase 1: Finish remaining CmdDatas commands (ABGMCmd, AIfCmd, ATalkCmd, FontCmd). Phase 2: Expand coverage for Commands/ (battle/game-action logic; ~8700 lines, ~11% covered). Phase 3: Add tests for Intermissions/ (2200 lines, currently 0% covered). - Each phase iterates on schedule (daily) or on demand, targeting less than 1000 diff lines per PR. + Each phase iterates on schedule (daily) or on demand, maximizing the amount of tests added per run. NOTE: This workflow runs on windows-latest because SRC.Sharp contains Windows-targeting projects (SRCSharpForm, SRCTestForm targeting net8.0-windows). Running on Windows avoids @@ -84,11 +84,10 @@ engine: copilot あなたは SRC# 移植プロジェクト (`${{ github.repository }}`) の自動テストエンジニアです。 以下のフェーズ順に、テストが不足している領域を特定してテストを追加してください。 -1 回の実行では PR が 1000 行以内に収まる分量のみを対象にしてください。 +1 回の実行でできるだけ多くのテストを追加してください。 You are an automated test engineer for the SRC# migration project (`${{ github.repository }}`). -Identify under-tested areas in the priority order below and add tests. -Keep each PR under 1000 diff lines — do only one chunk per run. +Identify under-tested areas in the priority order below and add as many tests as possible per run. **フェーズ優先順位 / Phase Priority** 1. **フェーズ1 (CmdDatas 残件)**: `SRC.Sharp/SRCCore/CmdDatas/Commands/` に残るコマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を優先的に完了する。 @@ -211,8 +210,7 @@ Step 1 で確認した CmdDatas コマンドと Step 2 で確認した既存テ `SRC.Sharp/SRCCore/Commands/Command.*.cs` の各ファイルについて、 対応するテストが存在しないものをリストアップしてください。 -以下の優先順位で対象を選んでください(1回の実行では PR 1000行以内に収まる量だけ)。 -**1000行を超えそうな場合は対象ファイルを減らし、次の実行に回してください**(例: `Command.unitmove.cs` だけで 300 行のテストになるなら、それ1ファイルで PR を作成する): +以下の優先順位で、未テストのファイルをすべて一度に対象にしてテストを追加してください: 1. `Command.state.cs` (51行) — 状態定数のテスト 2. `Command.launch.cs` (179行) — 発進・帰投ロジック 3. `Command.unitmove.cs` (467行) — ユニット移動 @@ -501,8 +499,7 @@ Use `noop` safe output with message: - **テストは必ずパスさせる** / All tests must pass before creating PR - **フェーズ1**: ヘルプファイルを期待値として使用 / Use help files as the source of truth - **フェーズ2・3**: ソースコードを仕様の根拠として使用 / Use source code as the specification -- **PR は 1000 行以内** / Keep PR diff under 1000 lines; split if needed -- **一度に全ファイルを対象にしない** / Don't try to cover all files at once; use the priority order in Step 3 +- **1回の実行でできるだけ多く対象にする** / Cover as many untested targets as possible per run - **フェーズ2の複雑ファイル注意**: `Command.attack.cs` と `Command.process.cs` は GUI 依存が強く難易度が高いため、 他のファイルを先に完了させてから最後に取り組んでください `Command.attack.cs` and `Command.process.cs` are GUI-heavy; tackle them last From 0614cb24dc848c25cc64cd29ba038544b6dbc385 Mon Sep 17 00:00:00 2001 From: koudenpa Date: Sat, 4 Apr 2026 14:22:39 +0900 Subject: [PATCH 4/4] gh aw compile --- .gitattributes | 1 + .github/aw/actions-lock.json | 5 + .../workflows/complete-unit-tests.lock.yml | 441 ++++++++++-------- 3 files changed, 248 insertions(+), 199 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..c1965c21 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +.github/workflows/*.lock.yml linguist-generated=true merge=ours \ No newline at end of file diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index 18cf8a67..1360799f 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -20,6 +20,11 @@ "version": "v0.62.5", "sha": "dc50be57c94373431b49d3d0927f318ac2bb5c4c" }, + "github/gh-aw-actions/setup@v0.64.2": { + "repo": "github/gh-aw-actions/setup", + "version": "v0.64.2", + "sha": "c7a6a831a24a1273d2da068d5a612b6df00bb5e0" + }, "github/gh-aw/actions/setup@v0.48.1": { "repo": "github/gh-aw/actions/setup", "version": "v0.48.1", diff --git a/.github/workflows/complete-unit-tests.lock.yml b/.github/workflows/complete-unit-tests.lock.yml index 2826b2f5..3318a513 100644 --- a/.github/workflows/complete-unit-tests.lock.yml +++ b/.github/workflows/complete-unit-tests.lock.yml @@ -12,7 +12,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.62.5). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.64.2). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -20,35 +20,43 @@ # # For more information: https://github.github.com/gh-aw/introduction/overview/ # -# SRC# 移植プロジェクトのユニットテスト補完を自動実行するワークフロー。 -# SRC.Sharp/SRCCore/CmdDatas/Commands/ の実装済みコマンドのうち、 -# テストが不足しているものを特定し、SRC.Sharp.Help/src/ のヘルプドキュメントを -# 期待値として自動的にユニットテストを追加する。 +# SRC# 移植プロジェクトのカバレッジ補強を自動実行するワークフロー。 +# フェーズ1: SRC.Sharp/SRCCore/CmdDatas/Commands/ の残コマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を完了する。 +# フェーズ2: SRC.Sharp/SRCCore/Commands/ (戦闘・ゲーム操作ロジック) のテストを拡充する。 +# フェーズ3: SRC.Sharp/SRCCore/Intermissions/ のテストをゼロから追加する。 +# 各フェーズをスケジュール実行(日次)や手動実行で反復し、1回の実行でできるだけ多くのテストを追加してカバレッジを向上させる。 # -# This workflow automatically completes unit tests for the SRC# migration project. -# It identifies implemented commands under SRC.Sharp/SRCCore/CmdDatas/Commands/ -# that lack test coverage and adds unit tests using SRC.Sharp.Help/src/ help -# documentation as the expected behavior specification. +# This workflow incrementally raises test coverage for the SRC# migration project. +# Phase 1: Finish remaining CmdDatas commands (ABGMCmd, AIfCmd, ATalkCmd, FontCmd). +# Phase 2: Expand coverage for Commands/ (battle/game-action logic; ~8700 lines, ~11% covered). +# Phase 3: Add tests for Intermissions/ (2200 lines, currently 0% covered). +# Each phase iterates on schedule (daily) or on demand, maximizing the amount of tests added per run. # # NOTE: This workflow runs on windows-latest because SRC.Sharp contains Windows-targeting # projects (SRCSharpForm, SRCTestForm targeting net8.0-windows). Running on Windows avoids # the need for EnableWindowsTargeting workarounds and allows full solution build and test. # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"423dd098126900aedcfcaa5a4746e53b5c03eabf71cb0c2112030303e81a2792","compiler_version":"v0.62.5","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"76754ddc94a337029e921cd69c3c09d6ce1041b1feefa21f6261ebecc00f0bf5","compiler_version":"v0.64.2","strict":true,"agent_id":"copilot"} -name: "ユニットテスト補完エージェント / Unit Test Completion Agent" +name: "カバレッジ補強エージェント / Coverage Reinforcement Agent" "on": schedule: - - cron: "11 13 * * *" + - cron: "30 20 * * *" # Friendly format: daily (scattered) workflow_dispatch: + inputs: + aw_context: + default: "" + description: Agent caller context (used internally by Agentic Workflows). + required: false + type: string permissions: {} concurrency: group: "gh-aw-${{ github.workflow }}" -run-name: "ユニットテスト補完エージェント / Unit Test Completion Agent" +run-name: "カバレッジ補強エージェント / Coverage Reinforcement Agent" jobs: activation: @@ -63,7 +71,7 @@ jobs: secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5 + uses: github/gh-aw-actions/setup@c7a6a831a24a1273d2da068d5a612b6df00bb5e0 # v0.64.2 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Generate agentic run info @@ -71,17 +79,17 @@ jobs: env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} - GH_AW_INFO_VERSION: "" + GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} + GH_AW_INFO_VERSION: "latest" GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.62.5" - GH_AW_INFO_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_INFO_CLI_VERSION: "v0.64.2" + GH_AW_INFO_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","github"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.24.5" + GH_AW_INFO_AWF_VERSION: "v0.25.1" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "true" @@ -119,7 +127,7 @@ jobs: - name: Create prompt with built-in context env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} + GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} @@ -128,22 +136,23 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + # poutine:ignore untrusted_checkout_exec run: | bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh { - cat << 'GH_AW_PROMPT_EOF' + cat << 'GH_AW_PROMPT_0348df2b39ac92c9_EOF' - GH_AW_PROMPT_EOF + GH_AW_PROMPT_0348df2b39ac92c9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_EOF' + cat << 'GH_AW_PROMPT_0348df2b39ac92c9_EOF' - Tools: create_issue, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_EOF + Tools: create_issue(max:3), create_pull_request, missing_tool, missing_data, noop + GH_AW_PROMPT_0348df2b39ac92c9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_EOF' + cat << 'GH_AW_PROMPT_0348df2b39ac92c9_EOF' The following GitHub context information is available for this workflow: @@ -173,14 +182,14 @@ jobs: {{/if}} - GH_AW_PROMPT_EOF + GH_AW_PROMPT_0348df2b39ac92c9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_EOF' + cat << 'GH_AW_PROMPT_0348df2b39ac92c9_EOF' - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' + GH_AW_PROMPT_0348df2b39ac92c9_EOF + cat << 'GH_AW_PROMPT_0348df2b39ac92c9_EOF' {{#runtime-import .github/workflows/complete-unit-tests.md}} - GH_AW_PROMPT_EOF + GH_AW_PROMPT_0348df2b39ac92c9_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 @@ -229,14 +238,16 @@ jobs: - name: Validate prompt placeholders env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + # poutine:ignore untrusted_checkout_exec run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh - name: Print prompt env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + # poutine:ignore untrusted_checkout_exec run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh - name: Upload activation artifact if: success() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: name: activation path: | @@ -259,8 +270,6 @@ jobs: GH_AW_WORKFLOW_ID_SANITIZED: completeunittests outputs: checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} - detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }} - detection_success: ${{ steps.detection_conclusion.outputs.success }} has_patch: ${{ steps.collect_output.outputs.has_patch }} inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }} model: ${{ needs.activation.outputs.model }} @@ -268,14 +277,15 @@ jobs: output_types: ${{ steps.collect_output.outputs.output_types }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5 + uses: github/gh-aw-actions/setup@c7a6a831a24a1273d2da068d5a612b6df00bb5e0 # v0.64.2 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Set runtime paths + id: set-runtime-paths run: | - echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_ENV" - echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_ENV" - echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_ENV" + echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_OUTPUT" + echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_OUTPUT" + echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_OUTPUT" - name: Create gh-aw temp directory run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Configure gh CLI for GitHub Enterprise @@ -329,7 +339,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.24.5 + run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.1 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 @@ -341,18 +351,18 @@ jobs: const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine + run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.1 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.1 ghcr.io/github/gh-aw-firewall/squid:0.25.1 ghcr.io/github/gh-aw-mcpg:v0.2.6 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine - name: Write Safe Outputs Config run: | mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"create_issue":{"max":3},"create_pull_request":{"max":1,"title_prefix":"[unit-tests] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_EOF + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_15d1c031cf5d2338_EOF' + {"create_issue":{"labels":["automation","testing","bug"],"max":3},"create_pull_request":{"draft":false,"if_no_changes":"warn","labels":["automation","testing"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_path_prefixes":[".github/",".agents/"],"title_prefix":"[unit-tests] "},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"}} + GH_AW_SAFE_OUTPUTS_CONFIG_15d1c031cf5d2338_EOF - name: Write Safe Outputs Tools run: | - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF' + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_f8b997c72136d21b_EOF' { "description_suffixes": { "create_issue": " CONSTRAINTS: Maximum 3 issue(s) can be created. Labels [\"automation\" \"testing\" \"bug\"] will be automatically added.", @@ -361,8 +371,8 @@ jobs: "repo_params": {}, "dynamic_tools": [] } - GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF' + GH_AW_SAFE_OUTPUTS_TOOLS_META_f8b997c72136d21b_EOF + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_76031ab4fe2e7ab6_EOF' { "create_issue": { "defaultMax": 1, @@ -491,7 +501,7 @@ jobs: } } } - GH_AW_SAFE_OUTPUTS_VALIDATION_EOF + GH_AW_SAFE_OUTPUTS_VALIDATION_76031ab4fe2e7ab6_EOF node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs - name: Generate Safe Outputs MCP Server Config id: safe-outputs-config @@ -534,7 +544,7 @@ jobs: - name: Start MCP Gateway id: start-mcp-gateway env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} @@ -556,10 +566,10 @@ jobs: export DEBUG="*" export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.20' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.6' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh + cat << GH_AW_MCP_CONFIG_2bfa63ede783c9d1_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh { "mcpServers": { "github": { @@ -600,7 +610,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_EOF + GH_AW_MCP_CONFIG_2bfa63ede783c9d1_EOF - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -617,8 +627,8 @@ jobs: set -o pipefail touch /tmp/gh-aw/agent-step-summary.md # shellcheck disable=SC1003 - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --allow-domains "*.githubusercontent.com,*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,bun.sh,cdn.jsdelivr.net,codeload.github.com,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,jsr.io,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,www.npmjs.com,www.npmjs.org,yarnpkg.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --allow-domains '*.githubusercontent.com,*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,bun.sh,cdn.jsdelivr.net,codeload.github.com,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,jsr.io,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.1 --skip-pull --enable-api-proxy \ + -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} @@ -626,8 +636,8 @@ jobs: GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.62.5 + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + GH_AW_VERSION: v0.64.2 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -704,6 +714,8 @@ jobs: run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh - name: Copy Safe Outputs if: always() + env: + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} run: | mkdir -p /tmp/gh-aw cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true @@ -712,7 +724,7 @@ jobs: if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,bun.sh,cdn.jsdelivr.net,codeload.github.com,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,jsr.io,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,www.npmjs.com,www.npmjs.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} @@ -757,10 +769,16 @@ jobs: else echo 'AWF binary not installed, skipping firewall log summary' fi + - name: Write agent output placeholder if missing + if: always() + run: | + if [ ! -f /tmp/gh-aw/agent_output.json ]; then + echo '{"items":[]}' > /tmp/gh-aw/agent_output.json + fi - name: Upload agent artifacts if: always() continue-on-error: true - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: name: agent path: | @@ -768,142 +786,28 @@ jobs: /tmp/gh-aw/sandbox/agent/logs/ /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ - /tmp/gh-aw/sandbox/firewall/logs/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch if-no-files-found: ignore - # --- Threat Detection (inline) --- - - name: Check if detection needed - id: detection_guard + - name: Upload firewall audit logs if: always() - env: - OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }} - HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }} - run: | - if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then - echo "run_detection=true" >> "$GITHUB_OUTPUT" - echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH" - else - echo "run_detection=false" >> "$GITHUB_OUTPUT" - echo "Detection skipped: no agent outputs or patches to analyze" - fi - - name: Clear MCP configuration for detection - if: always() && steps.detection_guard.outputs.run_detection == 'true' - run: | - rm -f /tmp/gh-aw/mcp-config/mcp-servers.json - rm -f /home/runner/.copilot/mcp-config.json - rm -f "$GITHUB_WORKSPACE/.gemini/settings.json" - - name: Prepare threat detection files - if: always() && steps.detection_guard.outputs.run_detection == 'true' - run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true - - name: Setup threat detection - if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" - WORKFLOW_DESCRIPTION: "SRC# 移植プロジェクトのユニットテスト補完を自動実行するワークフロー。\nSRC.Sharp/SRCCore/CmdDatas/Commands/ の実装済みコマンドのうち、\nテストが不足しているものを特定し、SRC.Sharp.Help/src/ のヘルプドキュメントを\n期待値として自動的にユニットテストを追加する。\n\nThis workflow automatically completes unit tests for the SRC# migration project.\nIt identifies implemented commands under SRC.Sharp/SRCCore/CmdDatas/Commands/\nthat lack test coverage and adds unit tests using SRC.Sharp.Help/src/ help\ndocumentation as the expected behavior specification.\n\nNOTE: This workflow runs on windows-latest because SRC.Sharp contains Windows-targeting\nprojects (SRCSharpForm, SRCTestForm targeting net8.0-windows). Running on Windows avoids\nthe need for EnableWindowsTargeting workarounds and allows full solution build and test." - HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }} - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); - await main(); - - name: Ensure threat-detection directory and log - if: always() && steps.detection_guard.outputs.run_detection == 'true' - run: | - mkdir -p /tmp/gh-aw/threat-detection - touch /tmp/gh-aw/threat-detection/detection.log - - name: Execute GitHub Copilot CLI - if: always() && steps.detection_guard.outputs.run_detection == 'true' - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool shell(cat) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(tail) - # --allow-tool shell(wc) - timeout-minutes: 20 - run: | - set -o pipefail - touch /tmp/gh-aw/agent-step-summary.md - # shellcheck disable=SC1003 - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} - GH_AW_PHASE: detection - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.62.5 - GITHUB_API_URL: ${{ github.api_url }} - GITHUB_AW: true - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md - GITHUB_WORKSPACE: ${{ github.workspace }} - GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com - GIT_AUTHOR_NAME: github-actions[bot] - GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com - GIT_COMMITTER_NAME: github-actions[bot] - XDG_CONFIG_HOME: /home/runner - - name: Parse threat detection results - id: parse_detection_results - if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - - name: Upload threat detection log - if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + continue-on-error: true + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: - name: detection - path: /tmp/gh-aw/threat-detection/detection.log + name: firewall-audit-logs + path: | + /tmp/gh-aw/sandbox/firewall/logs/ + /tmp/gh-aw/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Set detection conclusion - id: detection_conclusion - if: always() - env: - RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} - DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }} - run: | - if [[ "$RUN_DETECTION" != "true" ]]; then - echo "conclusion=skipped" >> "$GITHUB_OUTPUT" - echo "success=true" >> "$GITHUB_OUTPUT" - echo "Detection was not needed, marking as skipped" - elif [[ "$DETECTION_SUCCESS" == "true" ]]; then - echo "conclusion=success" >> "$GITHUB_OUTPUT" - echo "success=true" >> "$GITHUB_OUTPUT" - echo "Detection passed successfully" - else - echo "conclusion=failure" >> "$GITHUB_OUTPUT" - echo "success=false" >> "$GITHUB_OUTPUT" - echo "Detection found issues" - fi conclusion: needs: - activation - agent + - detection - safe_outputs if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true') runs-on: ubuntu-slim @@ -920,7 +824,7 @@ jobs: total_count: ${{ steps.missing_tool.outputs.total_count }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5 + uses: github/gh-aw-actions/setup@c7a6a831a24a1273d2da068d5a612b6df00bb5e0 # v0.64.2 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -931,18 +835,19 @@ jobs: name: agent path: /tmp/gh-aw/ - name: Setup agent output environment variable + id: setup-agent-output-env if: steps.download-agent-output.outcome == 'success' run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV" + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - name: Process No-Op Messages id: noop uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_NOOP_MAX: "1" - GH_AW_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -954,8 +859,8 @@ jobs: id: missing_tool uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -968,8 +873,8 @@ jobs: if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} GH_AW_WORKFLOW_ID: "complete-unit-tests" @@ -993,8 +898,8 @@ jobs: id: handle_noop_message uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }} @@ -1010,8 +915,8 @@ jobs: id: handle_create_pr_error uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -1021,11 +926,146 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_create_pr_error.cjs'); await main(); + detection: + needs: agent + if: always() && needs.agent.result != 'skipped' + runs-on: ubuntu-latest + outputs: + detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }} + detection_success: ${{ steps.detection_conclusion.outputs.success }} + steps: + - name: Setup Scripts + uses: github/gh-aw-actions/setup@c7a6a831a24a1273d2da068d5a612b6df00bb5e0 # v0.64.2 + with: + destination: ${{ runner.temp }}/gh-aw/actions + - name: Download agent output artifact + id: download-agent-output + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: agent + path: /tmp/gh-aw/ + - name: Setup agent output environment variable + id: setup-agent-output-env + if: steps.download-agent-output.outcome == 'success' + run: | + mkdir -p /tmp/gh-aw/ + find "/tmp/gh-aw/" -type f -print + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + # --- Threat Detection --- + - name: Download container images + run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.1 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.1 ghcr.io/github/gh-aw-firewall/squid:0.25.1 + - name: Check if detection needed + id: detection_guard + if: always() + env: + OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }} + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + run: | + if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then + echo "run_detection=true" >> "$GITHUB_OUTPUT" + echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH" + else + echo "run_detection=false" >> "$GITHUB_OUTPUT" + echo "Detection skipped: no agent outputs or patches to analyze" + fi + - name: Clear MCP configuration for detection + if: always() && steps.detection_guard.outputs.run_detection == 'true' + run: | + rm -f /tmp/gh-aw/mcp-config/mcp-servers.json + rm -f /home/runner/.copilot/mcp-config.json + rm -f "$GITHUB_WORKSPACE/.gemini/settings.json" + - name: Prepare threat detection files + if: always() && steps.detection_guard.outputs.run_detection == 'true' + run: | + mkdir -p /tmp/gh-aw/threat-detection/aw-prompts + cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true + cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true + for f in /tmp/gh-aw/aw-*.patch; do + [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true + done + echo "Prepared threat detection files:" + ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + - name: Setup threat detection + if: always() && steps.detection_guard.outputs.run_detection == 'true' + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" + WORKFLOW_DESCRIPTION: "SRC# 移植プロジェクトのカバレッジ補強を自動実行するワークフロー。\nフェーズ1: SRC.Sharp/SRCCore/CmdDatas/Commands/ の残コマンド (ABGMCmd, AIfCmd, ATalkCmd, FontCmd) を完了する。\nフェーズ2: SRC.Sharp/SRCCore/Commands/ (戦闘・ゲーム操作ロジック) のテストを拡充する。\nフェーズ3: SRC.Sharp/SRCCore/Intermissions/ のテストをゼロから追加する。\n各フェーズをスケジュール実行(日次)や手動実行で反復し、1回の実行でできるだけ多くのテストを追加してカバレッジを向上させる。\n\nThis workflow incrementally raises test coverage for the SRC# migration project.\nPhase 1: Finish remaining CmdDatas commands (ABGMCmd, AIfCmd, ATalkCmd, FontCmd).\nPhase 2: Expand coverage for Commands/ (battle/game-action logic; ~8700 lines, ~11% covered).\nPhase 3: Add tests for Intermissions/ (2200 lines, currently 0% covered).\nEach phase iterates on schedule (daily) or on demand, maximizing the amount of tests added per run.\n\nNOTE: This workflow runs on windows-latest because SRC.Sharp contains Windows-targeting\nprojects (SRCSharpForm, SRCTestForm targeting net8.0-windows). Running on Windows avoids\nthe need for EnableWindowsTargeting workarounds and allows full solution build and test." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + await main(); + - name: Ensure threat-detection directory and log + if: always() && steps.detection_guard.outputs.run_detection == 'true' + run: | + mkdir -p /tmp/gh-aw/threat-detection + touch /tmp/gh-aw/threat-detection/detection.log + - name: Install GitHub Copilot CLI + run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + env: + GH_HOST: github.com + - name: Install AWF binary + run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.1 + - name: Execute GitHub Copilot CLI + if: always() && steps.detection_guard.outputs.run_detection == 'true' + id: detection_agentic_execution + # Copilot CLI tool arguments (sorted): + timeout-minutes: 20 + run: | + set -o pipefail + touch /tmp/gh-aw/agent-step-summary.md + # shellcheck disable=SC1003 + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.1 --skip-pull --enable-api-proxy \ + -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + env: + COPILOT_AGENT_RUNNER_TYPE: STANDALONE + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} + GH_AW_PHASE: detection + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_VERSION: v0.64.2 + GITHUB_API_URL: ${{ github.api_url }} + GITHUB_AW: true + GITHUB_HEAD_REF: ${{ github.head_ref }} + GITHUB_REF_NAME: ${{ github.ref_name }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md + GITHUB_WORKSPACE: ${{ github.workspace }} + GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com + GIT_AUTHOR_NAME: github-actions[bot] + GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com + GIT_COMMITTER_NAME: github-actions[bot] + XDG_CONFIG_HOME: /home/runner + - name: Upload threat detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 + with: + name: detection + path: /tmp/gh-aw/threat-detection/detection.log + if-no-files-found: ignore + - name: Parse and conclude threat detection + id: detection_conclusion + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); + await main(); + safe_outputs: needs: - activation - agent - if: (!cancelled()) && needs.agent.result != 'skipped' && needs.agent.outputs.detection_success == 'true' + - detection + if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success' runs-on: ubuntu-slim permissions: contents: write @@ -1035,8 +1075,9 @@ jobs: env: GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/complete-unit-tests" GH_AW_ENGINE_ID: "copilot" + GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }} GH_AW_WORKFLOW_ID: "complete-unit-tests" - GH_AW_WORKFLOW_NAME: "ユニットテスト補完エージェント / Unit Test Completion Agent" + GH_AW_WORKFLOW_NAME: "カバレッジ補強エージェント / Coverage Reinforcement Agent" outputs: code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }} code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }} @@ -1050,7 +1091,7 @@ jobs: process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5 + uses: github/gh-aw-actions/setup@c7a6a831a24a1273d2da068d5a612b6df00bb5e0 # v0.64.2 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -1061,11 +1102,12 @@ jobs: name: agent path: /tmp/gh-aw/ - name: Setup agent output environment variable + id: setup-agent-output-env if: steps.download-agent-output.outcome == 'success' run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV" + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1095,6 +1137,7 @@ jobs: git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" echo "Git configured with standard GitHub Actions identity" - name: Configure GH_HOST for enterprise compatibility + id: ghes-host-config shell: bash run: | # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct @@ -1106,11 +1149,11 @@ jobs: id: process_safe_outputs uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,bun.sh,cdn.jsdelivr.net,codeload.github.com,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,jsr.io,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,www.npmjs.com,www.npmjs.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"labels\":[\"automation\",\"testing\",\"bug\"],\"max\":3},\"create_pull_request\":{\"draft\":false,\"if_no_changes\":\"warn\",\"labels\":[\"automation\",\"testing\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[unit-tests] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"labels\":[\"automation\",\"testing\",\"bug\"],\"max\":3},\"create_pull_request\":{\"draft\":false,\"if_no_changes\":\"warn\",\"labels\":[\"automation\",\"testing\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[unit-tests] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -1119,9 +1162,9 @@ jobs: setupGlobals(core, github, context, exec, io); const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); await main(); - - name: Upload safe output items + - name: Upload Safe Output Items if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: name: safe-output-items path: /tmp/gh-aw/safe-output-items.jsonl