# バッチ設計書 4-installer_wheel.sh

## 概要

本ドキュメントは、TensorFlowのCI/CDパイプラインにおけるプラットフォーム固有タグ付きインストーラーwheel生成バッチ `installer_wheel.sh` の設計仕様を記述する。

### 本バッチの処理概要

本バッチは、TensorFlowのPure Python wheelを生成した後、プラットフォーム固有のタグ（例：cp38-cp38-win_amd64）を付与してPyPIアップロード互換形式のインストーラーwheelを生成する処理を行う。

**業務上の目的・背景**：PyPIへのアップロード時、同一ファイル名のwheelは一度しかアップロードできない。プラットフォーム固有のwheelタグを付与することで、同一バージョンでも複数プラットフォーム向けのwheelをPyPIに登録可能にする。これはTensorFlowの「コラボレーターwheel」配布方式を実現するために必要な処理である。

**バッチの実行タイミング**：CI/CDパイプラインのリリースビルドまたはNightlyビルド時に実行される。

**主要な処理内容**：
1. TFCI環境の初期化（setup.sh の読み込み）
2. Nightlyビルドの場合、バージョン番号の更新
3. Bazel run によるPure Python wheel（py3-none-any）の生成
4. wheelのアンパック
5. 各プラットフォームタグに対するWHEELメタデータの書き換えと再パック
6. GCSステージングが有効な場合、gsutil による成果物のアップロード

**前後の処理との関連**：前段として `setup.sh` による環境初期化が行われる。後続として `upload.sh` によるPyPIアップロードが想定される。

**影響範囲**：インストーラーwheelファイルの生成、`$TFCI_OUTPUT_DIR` 配下のファイル、GCSステージング領域。

## バッチ種別

ビルド・パッケージング

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（CI/CDトリガーに依存） |
| 実行時刻 | CI/CDパイプラインによる |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | CI/CDパイプライン（Kokoro等）からの呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| TFCI環境変数の設定 | `$TFCI` 環境変数が適切に設定されていること |
| Python 3.13 | Bazel runでPython 3.13が使用される |
| wheelパッケージ | Python `wheel` パッケージがインストールされていること |
| TFCI_INSTALLER_WHL_TAGS | プラットフォームタグが定義されていること |

### 実行可否判定

`setup.sh` による環境初期化が正常に完了し、`$TFCI_INSTALLER_WHL_TAGS` が設定されていること。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| TFCI | string | Yes | なし | 環境設定ファイルのカンマ区切りパス |
| TFCI_NIGHTLY_UPDATE_VERSION_ENABLE | string | No | 0 | Nightlyバージョン更新の有効/無効 |
| TFCI_OUTPUT_DIR | string | Yes | なし | 出力ディレクトリパス |
| TFCI_INSTALLER_WHL_TAGS | string | Yes | なし | スペース区切りのプラットフォームタグリスト |
| TFCI_ARTIFACT_STAGING_GCS_ENABLE | string | No | 0 | GCSステージングの有効/無効 |
| TFCI_ARTIFACT_STAGING_GCS_URI | string | No | なし | GCSステージングURI |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| TensorFlowソースコード | ソースファイル | setup.py ベースのwheelビルド対象 |
| TFCI環境設定ファイル | シェルスクリプト | `ci/official/envs/` 配下の環境変数定義ファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| $TFCI_OUTPUT_DIR/*.whl | wheel | プラットフォーム固有タグ付きインストーラーwheel |
| $TFCI_ARTIFACT_STAGING_GCS_URI | GCS | GCSステージング領域へのアップロード |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | `tensorflow-{version}-{platform_tag}.whl` または `tf_nightly-{version}-{platform_tag}.whl` |
| 出力先 | `$TFCI_OUTPUT_DIR` |
| 文字コード | バイナリ |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. 環境初期化
   └─ setup.sh を source し、TFCI環境変数を設定
2. Nightlyバージョン更新（条件付き）
   └─ TFCI_NIGHTLY_UPDATE_VERSION_ENABLE=1 の場合、update_version.py --nightly を実行
3. Pure Python wheelビルド
   └─ bazel run //tensorflow/tools/pip_package:setup_py_binary -- bdist_wheel で生成
4. wheelアンパック
   └─ python3 -m wheel unpack でwheelを展開
5. 元のPure Python wheel削除
   └─ py3-none-any.whl ファイルを削除
6. プラットフォームタグ別wheel生成（ループ）
   └─ TFCI_INSTALLER_WHL_TAGS の各タグについて:
      a. .dist-info/WHEEL ファイル内の Tag: 行を書き換え
      b. python3 -m wheel pack で再パック
7. GCSアップロード（条件付き）
   └─ TFCI_ARTIFACT_STAGING_GCS_ENABLE=1 の場合、gsutil cp -n でアップロード
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[setup.sh による環境初期化]
    B --> C{Nightly更新有効?}
    C -->|Yes| D[バージョン番号更新]
    C -->|No| E[Pure Python wheelビルド]
    D --> E
    E --> F[wheelアンパック]
    F --> G[元のPure Python wheel削除]
    G --> H[各プラットフォームタグでループ]
    H --> I[WHEELメタデータのTag書き換え]
    I --> J[wheel再パック]
    J --> K{次のタグあり?}
    K -->|Yes| H
    K -->|No| L{GCSステージング有効?}
    L -->|Yes| M[gsutil cp -n でGCSにアップロード]
    L -->|No| N[バッチ終了]
    M --> N
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 非ゼロ終了 | Bazel runエラー | setup.py ビルド失敗 | ビルドログ・setup.py設定を確認 |
| 非ゼロ終了 | wheelアンパックエラー | wheelファイルの不正 | 生成されたwheelファイルを確認 |
| 非ゼロ終了 | wheel再パックエラー | メタデータ不整合 | WHEELファイルの内容を確認 |
| 非ゼロ終了 | GCSアップロードエラー | 認証/ネットワークエラー | 認証情報・接続を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | スクリプト自体にリトライ機能なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

`set -exo pipefail` により障害発生時にスクリプトが終了する。EXITトラップによりクリーンアップが実行される。`pushd`/`popd` によりディレクトリ移動が管理されているため、エラー時も元のディレクトリ復帰が保証される。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし |
| コミットタイミング | 該当なし |
| ロールバック条件 | GCSアップロードは `-n` フラグにより既存ファイルの上書きを防止 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | TFCI_INSTALLER_WHL_TAGS で定義されたタグ数分のwheel生成 |
| 目標処理時間 | wheel再パックは軽量処理のため数分以内 |
| メモリ使用量上限 | 通常のPythonプロセス程度 |

## 排他制御

CI/CDパイプラインの1ジョブとして実行される。同一出力ディレクトリに対する並行実行は想定されていない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | setup.sh 実行時 | TFCI環境変数の一覧 |
| 進捗ログ | 各タグ処理時 | "Generating a PyPI upload compatible wheel for {tag}" メッセージ |
| 終了ログ | 全タグ処理完了時 | "Following installer wheels were generated:" と生成ファイル一覧 |
| エラーログ | エラー発生時 | エラー発生コマンドの出力 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ジョブ実行結果 | 非ゼロ終了コード | CI/CDシステムの通知機能 |

## 備考

- `--HERMETIC_PYTHON_VERSION=3.13` によりPython 3.13がBazel runで使用される
- wheelのタグ書き換えは `sed` による `.dist-info/WHEEL` ファイルの直接編集で行われる
- 再パック時にRECORDファイル（ハッシュ情報）が自動再生成される
- `pushd`/`popd` によりカレントディレクトリの一時変更と復帰が管理される
