mcpField
T
temporary-id-safe-output

temporary-id-safe-output

github.com/github開発5.5k50 回インストール今日更新
リポジトリ

temporary-id-safe-output について

safe output ジョブに一時 issue ID を導入するための開発スキルです。ID の生成、ワークフロージョブ間の対応表の受け渡し、参照解決、他の処理を止めない失敗処理を扱います。

主な機能

  1. 01一時 ID の生成と検証
  2. 02一時 ID と issue 番号の対応付け
  3. 03ワークフロー依存関係と環境変数の設定
  4. 04テキスト内の一時 ID 参照の置換
  5. 05警告による解決失敗の処理

活用シーン

  1. 01作成直後の親 issue にサブ issue をリンク
  2. 02safe output ジョブへの一時 ID 対応の追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/github/gh-aw --skill temporary-id-safe-output

インストール後、Claude Code で/temporary-id-safe-outputを入力して読み込まれたか確認します。

詳細

安全な出力ジョブへの一時 ID サポートの追加

安全な出力ジョブで一時 ID をサポートするには、この実装計画を使用してください。一時 ID を使用すると、実際の課題番号が確定する前に、エージェントが同じ実行内で新しく作成された課題を参照できます。

問題の説明

エージェントが親課題を作成し、同じ実行内ですぐにサブ課題をリンクする場合、create_issue が完了するまで実際の課題番号はわかりません。一時 ID を使うことで、実行時に解決されるプレースホルダーを通じてこの問題を解消できます。

一時 ID の形式

一時 ID は aw_[A-Za-z0-9]{3,8} のパターンに従います。

  • aw_ は、エージェント型ワークフローの一時 ID を示す固定プレフィックスです
  • XXXXXXXX は、3〜8 文字の英数字(A-Za-z0-9)です

例:aw_abc、aw_abc123、aw_Test123

実装コンポーネント

1. 共有モジュール:temporary_id.cjs

場所:pkg/workflow/js/temporary_id.cjs

このモジュールは、一時 ID を処理するための共有ユーティリティを提供します。

// Core functions
generateTemporaryId()           // Generate new temporary ID
isTemporaryId(value)            // Check if value is a temporary ID
normalizeTemporaryId(tempId)    // Normalize to lowercase for map lookups
loadTemporaryIdMap()            // Load map from GH_AW_TEMPORARY_ID_MAP env var
resolveIssueNumber(value, map)  // Resolve value to issue number (supports temp IDs)
replaceTemporaryIdReferences(text, map)  // Replace #aw_XXX references in text
2. 生成ジョブ:create_issue

create_issue ジョブは、他のジョブが利用できる一時 ID マップを出力します。

Go の変更(pkg/workflow/create_issue.go):

  • 変更不要です。すでに temporary_id_map を出力しています。

JavaScript の変更(pkg/workflow/js/create_issue.cjs):

  • 作成した各課題の一時 ID を生成します
  • temporary_id -> issue_number のマップを作成します
  • core.setOutput("temporary_id_map", JSON.stringify(map)) でマップを出力します
3. コンシューマージョブ:一時 ID サポートの追加

一時 ID の解決が必要な安全な出力ジョブごとに、以下を実施します。

ステップ 1:Go ジョブビルダーを更新する

pkg/workflow/<job_name>.go で:

  1. ビルド関数に createIssueJobName パラメーターを追加します。
func (c *Compiler) build<JobName>Job(data *WorkflowData, mainJobName string, createIssueJobName string) (*Job, error) {
  1. 一時 ID マップを渡す環境変数を追加します。
if createIssueJobName != "" {
    customEnvVars = append(customEnvVars, fmt.Sprintf("          GH_AW_TEMPORARY_ID_MAP: ${{ needs.%s.outputs.temporary_id_map }}\n", createIssueJobName))
}
  1. ジョブの needs 配列に create_issue を追加します。
needs := []string{mainJobName}
if createIssueJobName != "" {
    needs = append(needs, createIssueJobName)
}
  1. 動的な needs を使用するように SafeOutputJobConfig を更新します。
return c.buildSafeOutputJob(data, SafeOutputJobConfig{
    // ...
    Needs: needs,
    // ...
})
ステップ 2:コンパイラージョブを更新する

pkg/workflow/compiler_jobs.go で:

ジョブをビルドする際に createIssueJobName を渡します。

job, err := c.build<JobName>Job(data, mainJobName, createIssueJobName)
ステップ 3:JavaScript スクリプトを更新する

pkg/workflow/js/<job_name>.cjs で:

  1. 一時 ID ユーティリティをインポートします。
const { loadTemporaryIdMap, resolveIssueNumber } = require("./temporary_id.cjs");
  1. main() の冒頭で一時 ID マップを読み込みます。
const temporaryIdMap = loadTemporaryIdMap();
if (temporaryIdMap.size > 0) {
    core.info(`Loaded temporary ID map with ${temporaryIdMap.size} entries`);
}
  1. resolveIssueNumber() を使用して課題番号を解決します。
const resolved = resolveIssueNumber(item.issue_number, temporaryIdMap);
if (resolved.errorMessage) {
    core.warning(`Failed to resolve issue: ${resolved.errorMessage}`);
    continue;
}
const issueNumber = resolved.resolved;
if (resolved.wasTemporaryId) {
    core.info(`Resolved temporary ID '${item.issue_number}' to issue #${issueNumber}`);
}
ステップ 4:エージェント入力の検証を更新する

pkg/workflow/js/collect_ndjson_output.cjs で:

一時 ID を受け付けるフィールドに検証を追加します。

function isValidIssueNumberOrTemporaryId(value) {
    if (typeof value === "number" && Number.isInteger(value) && value > 0) {
        return true;
    }
    if (typeof value === "string" && /^aw_[0-9a-f]{12}$/i.test(value)) {
        return true;
    }
    return false;
}

この検証を parent_issue_number、sub_issue_number などのフィールドに使用します。

4. 失敗の処理

一時 ID の解決に失敗した場合、ジョブは以下のように動作する必要があります。

  • core.setFailed() で失敗させるのではなく、core.warning() で警告を記録します
  • 他の項目の処理を続行します
  • ステップのサマリーに失敗内容を含めます
  • 警告を伴って正常に完了します

これにより、以下が実現します。

  • 部分的な成功が可能になります(リンクの一部が成功し、他は失敗する場合があります)
  • 1 件の解決失敗によってワークフロー全体が致命的な失敗に陥るのを防ぎます
  • ユーザーがステップのサマリーで警告を確認できます

使用例

ワークフロー設定
safe-outputs:
  create-issue:
    title-prefix: "[Parent] "
    labels: [tracking]
    max: 3
  link-sub-issue:
    max: 10
エージェントの出力
{"type": "create_issue", "temporary_id": "aw_abc123", "title": "Parent: Feature X", "body": "..."}
{"type": "link_sub_issue", "parent_issue_number": "aw_abc123", "sub_issue_number": 42}
{"type": "link_sub_issue", "parent_issue_number": "aw_abc123", "sub_issue_number": 43}
実行フロー
  1. main ジョブ:エージェントが一時 ID aw_abc123 を含む出力を生成します
  2. create_issue ジョブ:課題 #100 を作成し、{"aw_abc123": 100} を出力します
  3. link_sub_issue ジョブ:
    • 一時 ID マップを読み込みます
    • aw_abc123 → 100 を解決します
    • 課題 #42 と #43 を #100 のサブ課題としてリンクします

一時 ID をサポートするジョブ

ジョブフィールドステータス
link_sub_issueparent_issue_number、sub_issue_number✅ 実装済み
add_commentissue_number(テキスト置換による)✅ 実装済み
update_issueissue_number🔄 追加可能
close_pull_request-N/A(PR 番号を使用)

テスト

単体テスト

pkg/workflow/js/temporary_id.test.cjs に以下のテストを追加します。

  • 有効な入力と無効な入力に対する isTemporaryId()
  • 一時 ID と通常の番号に対する resolveIssueNumber()
  • さまざまな JSON 入力に対する loadTemporaryIdMap()
統合テスト

pkg/workflow/<job_name>_dependencies_test.go に、以下を検証するテストを追加します。

  • 設定されている場合、ジョブの needs に create_issue が含まれる
  • GH_AW_TEMPORARY_ID_MAP 環境変数が正しく設定される
  • create_issue への依存関係がなくてもジョブが動作する

セキュリティに関する考慮事項

  1. 一時 ID は、単一のワークフロー実行内でのみ有効です
  2. マップは環境変数を介して渡されます(外部には公開されません)
  3. エージェントが一時 ID を偽造し、他のワークフローのイシューを参照することはできません
  4. 解決に失敗した場合はログに記録されますが、一時 ID マップの内容は公開されません

新しいジョブに対応するためのチェックリスト

  • Go ジョブビルダーが createIssueJobName パラメーターを受け取るように更新する
  • GH_AW_TEMPORARY_ID_MAP 環境変数を追加する
  • needs 配列に、条件付きで create_issue を含めるように更新する
  • compiler_jobs.go を更新し、createIssueJobName を渡す
  • JavaScript スクリプトに一時 ID ユーティリティをインポートする
  • イシュー番号のフィールドで resolveIssueNumber() を使用する
  • 必要に応じて collect_ndjson_output.cjs の検証を更新する
  • 解決ロジックの単体テストを追加する
  • ジョブの依存関係に関する統合テストを追加する
  • ドキュメントを更新する

コメント