Bazel との日常的なやり取りは、主にいくつかのコマンドによって行われます。
build
、test
、run
。しかし、時には限界を感じることもあります。
パッケージをリポジトリに push する、エンドユーザー向けのドキュメントを公開する、
Kubernetes でアプリケーションをデプロイします。しかし、Bazel には publish
や
deploy
コマンド – これらのアクションの位置付け
bazel run コマンド
Bazel は密閉性、再現性、インクリメンタリティを重視しているため、
build
コマンドと test
コマンドは、上記のタスクには役立ちません。これらのアクション
ネットワーク アクセスが制限されたサンドボックスで実行されることがあり、セキュリティ リスクが
bazel build
ごとに再実行します。
代わりに、実行するタスクの主力である bazel run
に頼ってください。
防ぐことができます。Bazel ユーザーが、実行可能ファイルを作成するルールに慣れている
ルール作成者は、共通のパターン セットに従って、ルールを
"custom verbs"。
実際の環境: rules_k8s
たとえば rules_k8s
について考えてみましょう。
Bazel に関する Kubernetes のルールです。次のようなターゲットがあるとします。
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
k8s_object
ルールは、
staging
で bazel build
が使用されている場合の標準の Kubernetes YAML ファイル
あります。ただし、追加のターゲットも k8s_object
によって作成されます。
マクロを staging.apply
や :staging.delete
などの名前で使用することはできません。これらのビルドは、
これらのアクションを実行するスクリプトが用意されており、bazel run
staging.apply
で実行すると、これらは独自の bazel k8s-apply
コマンドや bazel
k8s-delete
コマンドのように動作します。
別の例: ts_api_guardian_test
このパターンは Angular プロジェクトでも見ることができます。「
ts_api_guardian_test
マクロ
2 つのターゲットが生成されます。1 つ目は標準の nodejs_test
ターゲットで、
「ゴールデン」パターンに対して生成された出力をファイル(つまり、このファイルに
出力)。これは、通常の bazel
test
呼び出しでビルドして実行できます。angular-cli
では、このような
ターゲット
bazel test //etc/api:angular_devkit_core_api
で。
時間が経つと、正当な理由でこのゴールデン ファイルの更新が必要になることがあります。
手動で更新するのは手間がかかり、エラーが発生しやすいため、
比較の代わりにゴールデン ファイルを更新する nodejs_binary
ターゲット
防ぐことができます。実質的には、同じテスト スクリプトを記述して「検証」で実行することもできます。
または「同意する」呼び出す方法によって異なります。これは同じパターンで
ネイティブの bazel test-accept
コマンドはありませんが、
同様の効果を
bazel run //etc/api:angular_devkit_core_api.accept
。
このパターンは非常に強力になり、 学習します。
独自のルールを調整する
このパターンの中核となるのがマクロです。マクロは 複数のターゲットを作成できます。通常は 指定された名前で、メインのビルド アクションを実行するターゲット(たとえば、 通常のバイナリ、Docker イメージ、またはソースコードのアーカイブをビルドします。イン このパターンに基づいて、追加のターゲットが作成されて、 公開など、プライマリ ターゲットの出力に基づいて、 テスト出力を更新したりできます。
わかりやすく説明するために、例としてウェブサイトを生成する架空のルールを Sphinx とマクロで別の行を作成 ターゲットにし、準備ができたらユーザーが公開できるようにします。次の点を考慮してください。 Sphinx でウェブサイトを生成する既存のルール:
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
次に、次のようなルールを検討します。このスクリプトは、実行時に 生成されたページを公開します。
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
最後に、次のマクロを定義して、上記両方のターゲットを作成します。 説明します。
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
BUILD
ファイルで、プライマリを作成するだけの場合と同様にマクロを使用します。
target:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
この例では、"docs"マクロが元のコマンドで
単一の Bazel ルールを適用します。ビルド時に、このルールによりいくつかの構成が生成されます。
Sphinx を実行して、手動検査が可能な HTML サイトを生成します。ただし、
追加の「docs.publish」作成されると、このファイルを使用して、
サイトを公開しています。プライマリ ターゲットの出力を確認したら、
以下と同様に、bazel run :docs.publish
を使用して一般公開用に公開します。
架空の bazel publish
コマンド。
_sphinx_publisher
の実装が何であるかは、すぐにはわかりません。
見てみましょう。多くの場合、このようなアクションではランチャー シェル スクリプトを作成します。
この方法では、通常、
ctx.actions.expand_template
非常にシンプルなシェル スクリプトを作成します。この例では、Publisher バイナリを呼び出します。
プライマリ ターゲットの出力へのパスに置き換えます。これによりパブリッシャーは
汎用的な実装にできますが、_sphinx_site
ルールによって生成されるのは
この小さなスクリプトだけで、この 2 つの
説明します。
rules_k8s
では、実際に .apply
はこのように動作します。
expand_template
基礎となる非常にシンプルな Bash スクリプトを
apply.sh.tpl
,
プライマリ ターゲットの出力を使用して kubectl
を実行します。このスクリプトは、
bazel run :staging.apply
を指定してビルドおよび実行することで、
k8s_object
ターゲットに対する k8s-apply
コマンド。