Skip to Content
デベロッパーガイドDevelopmentNPM

パッケージ概要

このモノレポには、@qwen-code/qwen-code@qwen-code/qwen-code-core の2つの主要パッケージが含まれています。

@qwen-code/qwen-code

これは Qwen Code のメインパッケージです。ユーザーインターフェース、コマンド解析、その他すべてのユーザー向け機能を担当します。

このパッケージは公開時に単一の実行可能ファイルにバンドルされます。このバンドルには、@qwen-code/qwen-code-core を含むパッケージのすべての依存関係が含まれています。つまり、ユーザーが npm install -g @qwen-code/qwen-code でインストールする場合でも、npx @qwen-code/qwen-code で直接実行する場合でも、この単一の自己完結型実行可能ファイルを使用することになります。

@qwen-code/qwen-code-core

このパッケージには CLI のコアロジックが含まれています。設定済みのプロバイダへの API リクエスト、認証処理、ローカルキャッシュの管理を担当します。

このパッケージはバンドルされません。公開時には、自身の依存関係を持つ標準の Node.js パッケージとして公開されます。これにより、必要に応じて他のプロジェクトでスタンドアロンパッケージとして使用できます。dist フォルダ内のすべてのトランスパイル済み JavaScript コードがパッケージに含まれます。

リリースプロセス

このプロジェクトは構造化されたリリースプロセスに従い、すべてのパッケージが正しくバージョン管理され公開されるようにします。プロセスは可能な限り自動化されています。

リリース方法

リリースは release.yml  GitHub Actions ワークフローを通じて管理されます。パッチやホットフィックスを手動でリリースするには:

  1. リポジトリの Actions タブに移動します。
  2. リストから Release ワークフローを選択します。
  3. Run workflow ドロップダウンボタンをクリックします。
  4. 必要な入力を入力します:
    • Version: リリースする正確なバージョン (例: v0.2.1)。
    • Ref: リリース元のブランチまたはコミット SHA (デフォルトは main)。
    • Dry Run: 公開せずにワークフローをテストする場合は true、実際のリリースを行う場合は false に設定します。
  5. Run workflow をクリックします。

リリースタイプ

このプロジェクトは複数のリリースタイプをサポートしています:

安定版リリース

本番環境向けの通常の安定版リリースです。

プレビューリリース

毎週火曜日 23:59 UTC に、今後の機能への早期アクセスを提供するプレビューリリースを行います。

ナイトリリリース

毎日 0:00 UTC に、最先端の開発テスト向けのナイトリリリースを行います。

自動リリーススケジュール

  • ナイトリー: 毎日 0:00 UTC
  • プレビュー: 毎週火曜日 23:59 UTC
  • 安定版: メンテナーによる手動リリース

異なるリリースタイプの使用方法

各タイプの最新バージョンをインストールするには:

# 安定版 (デフォルト) npm install -g @qwen-code/qwen-code # プレビュー npm install -g @qwen-code/qwen-code@preview # ナイトリー npm install -g @qwen-code/qwen-code@nightly

リリースプロセスの詳細

スケジュールされたリリースまたは手動リリースは、以下の手順で行われます:

  1. 指定されたコード (main ブランチの最新版または特定のコミット) をチェックアウトします。
  2. すべての依存関係をインストールします。
  3. preflight チェックと統合テストのフルスイートを実行します。
  4. すべてのテストが成功した場合、リリースタイプに基づいて適切なバージョン番号を計算します。
  5. 適切な dist-tag でパッケージをビルドし、npm に公開します。
  6. そのバージョンの GitHub Release を作成します。

失敗時の処理

リリースワークフローのいずれかのステップが失敗した場合、リポジトリに自動的に新しい Issue が作成され、bug ラベルとタイプ固有の失敗ラベル (例: nightly-failurepreview-failure) が付けられます。Issue には、デバッグを容易にするために失敗したワークフロー実行へのリンクが含まれます。

リリース検証

新しいリリースをプッシュした後は、パッケージが期待通りに動作することを確認するためにスモークテストを実行する必要があります。これは、パッケージをローカルにインストールし、正しく機能するかどうかを確認する一連のテストを実行することで行えます。

  • npx -y @qwen-code/qwen-code@latest --version で、プッシュが期待通りに動作したことを検証します (rc や dev タグを使用していない場合)。
  • npx -y @qwen-code/qwen-code@<リリースタグ> --version で、タグが適切にプッシュされたことを検証します。
  • これはローカル環境を破壊します npm uninstall @qwen-code/qwen-code && npm uninstall -g @qwen-code/qwen-code && npm cache clean --force && npm install @qwen-code/qwen-code@<バージョン>
  • いくつかの LLM コマンドとツールを実行する基本的なスモークテストを行い、パッケージが期待通りに動作することを確認することを推奨します。今後、これをより明確にコード化する予定です。

バージョン変更をマージすべきか、そうでないか?

現在のコミットまたは古いコミットからパッチやホットフィックスリリースを作成する上記のパターンは、リポジトリを以下の状態にします:

  1. タグ (vX.Y.Z-patch.1): このタグは、公開する安定版コードが含まれる main 上の元のコミットを正しく指します。これは非常に重要です。このタグをチェックアウトした人は誰でも、公開された正確なコードを取得できます。
  2. ブランチ (release-vX.Y.Z-patch.1): このブランチには、タグ付けされたコミットの上に1つの新しいコミットが含まれています。その新しいコミットには、package.json (および package-lock.json などの関連ファイル) のバージョン番号の変更のみが含まれます。

この分離は良い方法です。これにより、バージョンベースのリリース固有のコミットをマージするかどうかを決定するまで、main ブランチの履歴をクリーンに保つことができます。

これは重要な判断であり、リリースの性質に完全に依存します。

安定版パッチとホットフィックスではマージバックする

安定版パッチやホットフィックスのリリースでは、release-<タグ> ブランチを main にマージバックすることをほぼ常に行うべきです。

  • なぜか?主な理由は、main の package.json のバージョンを更新するためです。古いコミットから v1.2.1 をリリースしても、バージョンアップをマージバックしなければ、main ブランチの package.json は “version”: “1.2.0” のままになります。次の開発者が次の機能リリース (v1.3.0) の作業を開始するときに、誤った古いバージョン番号のコードベースからブランチを作成することになります。これにより混乱が生じ、後で手動でバージョンを更新する必要が生じます。
  • プロセス: release-v1.2.1 ブランチが作成され、パッケージが正常に公開された後、release-v1.2.1 を main にマージするプルリクエストを作成する必要があります。この PR には1つのコミット “chore: bump version to v1.2.1” のみが含まれます。これはクリーンでシンプルな統合であり、main ブランチを最新のリリースバージョンと同期させます。

プレリリース (RC、ベータ、Dev) ではマージバックしない

通常、プレリリースのリリースブランチは main にマージバックしません。

  • なぜか?プレリリースバージョン (例: v1.3.0-rc.1、v1.3.0-rc.2) は、定義上、安定版ではなく一時的なものです。リリース候補の一連のバージョンアップで main ブランチの履歴を汚したくはありません。main の package.json は最新の安定版リリースバージョンを反映すべきであり、RC を反映すべきではありません。
  • プロセス: release-v1.3.0-rc.1 ブランチが作成され、npm publish --tag rc が実行され、その後… ブランチはその役割を終えます。単に削除できます。RC のコードは既に main (または機能ブランチ) にあるため、機能コードは失われません。リリースブランチはバージョン番号の一時的な手段に過ぎませんでした。

ローカルテストと検証: パッケージングおよび公開プロセスの変更

NPM に実際に公開したり、公開 GitHub リリースを作成したりせずにリリースプロセスをテストする必要がある場合は、GitHub UI からワークフローを手動でトリガーできます。

  1. リポジトリの Actions タブ  に移動します。
  2. “Run workflow” ドロップダウンをクリックします。
  3. dry_run オプションをチェックしたまま (true) にします。
  4. “Run workflow” ボタンをクリックします。

これにより、リリースプロセス全体が実行されますが、npm publishgh release create の手順はスキップされます。ワークフローログを確認して、すべてが期待通りに動作することを確認できます。

パッケージングおよび公開プロセスに変更を加えた場合は、コミットする前にローカルでテストすることが重要です。これにより、パッケージが正しく公開され、ユーザーがインストールしたときに期待通りに動作することを確認できます。

変更を検証するには、公開プロセスのドライランを実行できます。これにより、npm レジストリに実際にパッケージを公開せずに、公開プロセスをシミュレートします。

npm_package_version=9.9.9 SANDBOX_IMAGE_REGISTRY="registry" SANDBOX_IMAGE_NAME="thename" npm run publish:npm --dry-run

このコマンドは次のことを行います:

  1. すべてのパッケージをビルドします。
  2. すべての prepublish スクリプトを実行します。
  3. npm に公開されるパッケージの tarball を作成します。
  4. 公開されるパッケージのサマリーを表示します。

生成された tarball を確認して、正しいファイルが含まれていること、package.json ファイルが正しく更新されていることを確認できます。tarball は各パッケージのディレクトリのルートに作成されます (例: packages/cli/qwen-code-0.1.6.tgz)。

ドライランを実行することで、パッケージングプロセスへの変更が正しく、パッケージが正常に公開されることを確信できます。

リリースの詳細

リリースプロセスの主な目的は、packages/ ディレクトリのソースコードを取得し、ビルドして、プロジェクトのルートにある一時的な dist ディレクトリにクリーンで自己完結型のパッケージをアセンブルすることです。この dist ディレクトリが実際に NPM に公開されるものです。

主要なステージは次のとおりです:

ステージ 1: リリース前の健全性チェックとバージョン管理

  • 処理内容: ファイルが移動される前に、プロジェクトが良好な状態にあることを確認します。テスト、リンティング、型チェック (npm run preflight) が実行されます。ルートの package.json および packages/cli/package.json のバージョン番号が新しいリリースバージョンに更新されます。
  • 理由: 高品質で動作するコードのみがリリースされることを保証します。バージョン管理は新しいリリースを示す最初のステップです。

ステージ 2: ソースコードのビルド

  • 処理内容: packages/core/src および packages/cli/src の TypeScript ソースコードが JavaScript にコンパイルされます。
  • ファイルの移動:
    • packages/core/src/*/.ts -> コンパイル -> packages/core/dist/
    • packages/cli/src/*/.ts -> コンパイル -> packages/cli/dist/
  • 理由: 開発中に記述された TypeScript コードは、Node.js で実行できるプレーンな JavaScript に変換する必要があります。cli パッケージは core パッケージに依存するため、最初に core パッケージがビルドされます。

ステージ 3: 公開可能な最終パッケージのバンドルとアセンブル

これは、ファイルが最終的な公開状態に移動および変換される最も重要なステージです。このプロセスでは、最新のバンドル技術を使用して最終パッケージを作成します。

  1. バンドルの作成:

    • 処理内容: prepare-package.js スクリプトが dist ディレクトリにクリーンな配布パッケージを作成します。
    • 主な変換:
      • README.md と LICENSE を dist/ にコピー
      • 国際化のために locales フォルダをコピー
      • 配布用にクリーンな package.json を作成 (必要な依存関係のみ)
      • 配布用依存関係を最小限に維持 (バンドルされたランタイム依存関係は含めない)
      • node-pty のオプションの依存関係を維持
  2. JavaScript バンドルの作成:

    • 処理内容: packages/core/dist と packages/cli/dist の両方からビルドされた JavaScript が、esbuild を使用して単一の実行可能な JavaScript ファイルにバンドルされます。
    • ファイルの場所: dist/cli.js
    • 理由: これにより、必要なすべてのアプリケーションコードを含む単一の最適化されたファイルが作成されます。インストール時に複雑な依存関係解決が不要になるため、パッケージが簡素化されます。
  3. 静的ファイルおよびサポートファイルのコピー:

    • 処理内容: ソースコードの一部ではないが、パッケージが正しく機能したり、適切に説明されたりするために必要な重要なファイルが dist ディレクトリにコピーされます。
    • ファイルの移動:
      • README.md -> dist/README.md
      • LICENSE -> dist/LICENSE
      • locales/ -> dist/locales/
      • ベンダーファイル -> dist/vendor/
    • 理由:
      • README.md と LICENSE は、どの NPM パッケージにも含めるべき標準ファイルです。
      • Locales は国際化機能をサポートします。
      • ベンダーファイルには必要なランタイム依存関係が含まれます。

ステージ 4: NPM への公開

  • 処理内容: ルートの dist ディレクトリ内から npm publish コマンドが実行されます。
  • 理由: dist ディレクトリ内から npm publish を実行することで、ステージ 3 で慎重にアセンブルしたファイルのみが NPM レジストリにアップロードされます。これにより、ソースコード、テストファイル、開発設定が誤って公開されるのを防ぎ、ユーザーにとってクリーンで最小限のパッケージが実現します。

このプロセスにより、最終的に公開される成果物は、開発ワークスペースの直接コピーではなく、プロジェクトの目的に特化した、クリーンで効率的な表現となります。

NPM Workspaces

このプロジェクトは NPM Workspaces  を使用して、このモノレポ内のパッケージを管理しています。これにより、プロジェクトのルートから複数のパッケージにわたる依存関係の管理やスクリプトの実行が容易になります。

仕組み

ルートの package.json ファイルで、このプロジェクトのワークスペースを定義します:

{ "workspaces": ["packages/*"] }

これにより、packages ディレクトリ内のすべてのフォルダが個別のパッケージとして扱われ、ワークスペースの一部として管理されるようになります。

ワークスペースの利点

  • 依存関係管理の簡素化: プロジェクトのルートで npm install を実行すると、ワークスペース内のすべてのパッケージの依存関係がインストールされ、それらがリンクされます。つまり、各パッケージのディレクトリで npm install を実行する必要はありません。
  • 自動リンク: ワークスペース内のパッケージは相互に依存できます。npm install を実行すると、NPM は自動的にパッケージ間のシンボリックリンクを作成します。つまり、1つのパッケージに変更を加えると、その変更は依存している他のパッケージですぐに利用可能になります。
  • スクリプト実行の簡素化: --workspace フラグを使用して、プロジェクトのルートから任意のパッケージのスクリプトを実行できます。たとえば、cli パッケージの build スクリプトを実行するには、npm run build --workspace @qwen-code/qwen-code を実行します。
Last updated on