git-integration-operations-cli について
Fabric ワークスペースと Git リポジトリの連携ライフサイクルを管理するコマンドラインスキルです。同期や自動化を担う運用担当者向けに、接続、コミット、更新、状態確認、切断と非同期処理の確認方法を扱います。
主な機能
- 01ワークスペースと Git リポジトリの接続
- 02ワークスペース内容のコミットと更新
- 03同期状態の確認と競合解決
- 04Git 連携の切断
- 05サービスプリンシパルと CI/CD の支援
活用シーン
- 01Fabric ワークスペースを Azure DevOps または GitHub に接続
- 02ワークスペース項目を Git にコミット
- 03Git からワークスペースを更新して同期を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ skills-for-fabric --skill git-integration-operations-cliインストール後、Claude Code で/git-integration-operations-cliを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
apm.ymlreferences/automation-templates.mdgit-integration-concepts.md詳細
テレメトリ — 必須。
api.fabric.microsoft.comへのすべての呼び出しには、x-ms-fabric-skill: git-integration-operations-cliを付与する必要があります (az restの場合は--headers "x-ms-fabric-skill=git-integration-operations-cli")。 すべての LRO ポーリング、fabric_lro、リトライにも適用されます。スニペットでは省略されていますが、必ず追加してください。
重要な注意事項
- ワークスペース名からワークスペース ID を取得するには、すべてのワークスペースを一覧表示してから、 JMESPath で
displayNameをフィルターします。アイテム ID を取得するには、ワークスペース内の該当する種類のアイテムを 一覧表示してから、displayNameをフィルターします。- すべての Git 操作は、
https://api.fabric.microsoft.comに対するコントロールプレーン呼び出しです。fab auth loginを一度実行すると、fab apiがベース URL と Fabric トークンのオーディエンスを自動的に設定します。az restによる代替手段では、一致する--resourceを自分で指定する必要があります。指定しないと 401 が返されます。commitToGit、updateFromGit、さらにはgit/statusも、同期レスポンスボディではなく、**HTTP 202 (長時間実行操作)**を返す場合があります。202の場合は、操作をポーリングします。fabでは、--show_headersからx-ms-operation-idを読み取り、statusがSucceededになるまでfab api operations/{id}をポーリングします。az restによる代替手段では、Location/x-ms-operation-idヘッダーをポーリングします (COMMON-CORE の長時間実行操作のポーリングを参照)。その後、git/statusを読み取り、workspaceHead == remoteCommitHashであることを確認します。完了の確認には、操作のポーリングを優先してください。 代わりにgit/statusをポーリングする場合は、処理中(202)のレスポンス、またはまだ同期されていないレスポンスを 「実行中」として扱い、ヘッドが一致するまではchangesに基づいて処理しないでください。 (参照:rest/api/fabric/core/git および fabric/cicd/git-integration/git-automation。)updateFromGitには、ワークスペースの現在のworkspaceHeadが必要です。古い値を指定すると400 WorkspaceHeadMismatchが返されます。必ず最初にgit/statusを読み取ってください。- すべての Git 操作の前提条件:ワークスペースが容量に割り当てられている必要があります (割り当てられていないワークスペースでは
WorkspaceHasNoCapacityAssignedが発生します)。また、呼び出し元 (ユーザーまたはサービスプリンシパル)には適切なワークスペースロールが必要です。接続と切断には Admin が必要です。 コミットと更新には、すべてのアイテムへの書き込み権限を持つ少なくとも Contributor が必要です。 ブランチの切り替えには Admin が必要です(ワークスペースのオプトイン設定 Allow users with at least Contributor role to change Git branch が有効な場合は Contributor でも可能です)。 1 つのワークスペースで同時に実行できる Git 操作は 1 つだけです。- テナント管理者の切り替え設定は Git 統合の可否を左右し、原因不明の失敗を引き起こすことがよくあります。 GitHub の同期設定は既定でオフです(GitHub への接続前に有効にしてください)。Azure DevOps の同期は既定でオンです。 ワークスペースと Azure リポジトリのリージョンが異なる場合は、クロスジオエクスポート設定が必要です (GitHub では適用されません)。references/git-integration-concepts.md § Tenant admin prerequisites を参照してください。
Git Integration Operations — CLI Skill
CLI 環境から Fabric の Git 統合ライフサイクル(接続、コミット、更新、ステータス確認、切断)を自動化します。 昇格後にワークスペース間のアイテム参照が再バインドされるかどうかは別の問題であり、Git ライフサイクル自体ではなく、 アイテム定義の形式(論理 ID かオブジェクト ID か)によって決まります。
前提知識
まず、次の共通リファレンスをお読みください(パスは、このスキルが skills-for-fabric 内の
skills/git-integration-operations-cli/ にあることを前提としています。リポジトリ外で作成する場合は調整してください)。
- COMMON-CLI.md § Fabric でワークスペースとアイテムを検索する — 名前からワークスペース/アイテム ID を特定するために必須です。
- COMMON-CORE.md § 認証とトークンの取得 — 対象ユーザーが誤っていると 401 が発生します。認証に関する問題がある場合は、まずお読みください。
- COMMON-CLI.md § 認証の手順 — CLI での
az loginのフローとトークン取得について説明しています。 - COMMON-CLI.md § az rest を使用した Fabric コントロールプレーン API —
az restを使用するフォールバック手順です(必ず--resourceを指定してください)。LRO のポーリングヘルパーも含まれています。 - COMMON-CORE.md § コアコントロールプレーン REST API — ページネーション、長時間実行操作のポーリング、レート制限について説明しています。
目次
| タスク | リファレンス |
|---|---|
| 接続前の事前確認 | SKILL.md § 接続前の事前確認 |
| ワークスペースを Git に接続する | SKILL.md § ワークスペースを Git に接続する |
| Git 接続を作成する(サービスプリンシパル) | SKILL.md § Git プロバイダー接続を作成する(サービスプリンシパル) |
| ワークスペースのアイテムを Git にコミットする | SKILL.md § Git にコミットする |
| Git からワークスペースを更新する | SKILL.md § Git から更新する |
| 同期状態を確認する | SKILL.md § 同期状態を確認する |
| 更新の競合を解決する | SKILL.md § 競合を解決する |
| Git との接続を解除する | SKILL.md § Git との接続を解除する |
| ブランチワークスペースをベースにリンクする(ワークスペースの関係) | SKILL.md § ブランチワークスペースをベースにリンクする(ワークスペースの関係) |
| Git 統合の概念(同期モデル、状態、アクセス許可) | references/git-integration-concepts.md § 概念 |
| テナント管理者の前提条件(スイッチ) | references/git-integration-concepts.md § テナント管理者の前提条件 |
| サポートされている Git プロバイダー | references/git-integration-concepts.md § サポートされている Git プロバイダー |
| サポートされているアイテムの種類 | references/git-integration-concepts.md § サポートされているアイテムの種類 |
| 書式のみの差分を避ける(末尾の改行/行末) | references/git-integration-concepts.md § 書式のみの差分を避ける |
| サービスプリンシパル/CI-CD パイプラインのテンプレート | references/automation-templates.md |
| 注意事項、ルール、トラブルシューティング | SKILL.md § 注意事項、ルール、トラブルシューティング |
必須/推奨/回避
必ず実施すること
git/statusを読み取り、現在のworkspaceHeadをすべてのcommitToGitおよびupdateFromGit呼び出しに渡してください。- 各非同期操作の後に
git/statusをポーリングし、workspaceHead == remoteCommitHashかつchanges配列が空になるまで続けてください。202/Succeededという状態だけでは、同期が正しく行われた証拠にはなりません。状態を検証してください。 - 論理 ID をターゲットワークスペース内で解決できるように、アイテムは参照先のアイテムと一緒に同じコミットでデプロイしてください。
絶対にしないこと
- 同じワークスペースで、2 つの Git 操作を同時に実行しないでください。1 つ目がまだ
Runningの間に 2 つ目のcommitToGit/updateFromGitを実行すると、HEAD の追跡が破損します。直列化してください。次の操作を始める前に、1 つ目の操作がSucceededになるまでポーリングします。 - 同じブランチ上で、ワークスペースを信頼できる情報源と CI/CD のプッシュ先の両方として扱わないでください。ブランチごとに書き込み元を 1 つ選びます。人がワークスペースからコミットするか、自動化が Git にプッシュするかのどちらか一方にしてください。同時に両方を行わないでください。
推奨事項
- 主な操作手段として、
fab auth loginの実行後にfab apiを使用してください。ベース URL と Fabric トークンのオーディエンスが自動的に設定され、オーディエンスの誤りによる 401 エラーを回避できます。fabを使用できない場合、またはヘッダーを細かく制御する必要がある場合は、--resource "https://api.fabric.microsoft.com"を指定してaz restを代替手段として使用してください。 - 下流/ターゲットワークスペースに Git の最新状態をきれいに取り込むには、競合解決に
PreferRemoteを使用してください。
避けること
- 古い
workspaceHeadを再利用しないでください(400 WorkspaceHeadMismatchの原因になります)。 - 標準入力でリクエストボディを
fab apiに渡さないでください(-i <file.json>または-i '<inline JSON>'を使用してください)。
CLI:fab を主に使用し、az rest を代替として使用
以下のすべての操作は fab api を使用しています。fab auth login は一度実行してください(自動化ではサービスプリンシパルもサポートしています)。その後は fab がベース URL とトークンのオーディエンスを処理します。az rest を代替として使用する場合は、同じ呼び出しを機械的に次のように変換します。
実行する ID で fab を認証します。
fab auth login # interactive user (SSO)
fab auth login -u <client-id> -p <client-secret> --tenant <tenant-id> # service principal (CI/CD)
fab auth login --identity # managed identity (Azure compute)
サービスプリンシパルまたはマネージド ID は、接続または切断を行うにはワークスペースの管理者である必要があります(コミット/更新には、すべてのアイテムに対する書き込み権限を持つコントリビューター以上で十分です)。また、ConfiguredConnection 経由の場合は、Git プロバイダーの認証情報を保持している必要があります。パイプラインスクリプトの全文は
references/automation-templates.md を参照してください。
fab api <endpoint>はaz rest --method GET --url "https://api.fabric.microsoft.com/v1/<endpoint>" --resource "https://api.fabric.microsoft.com"に相当します。fab api -X post <endpoint> -i body.jsonには--method POST --headers "Content-Type=application/json" --body @body.jsonを追加します。
fab api は -i を使用して、ファイルパスまたはインライン JSON 文字列(例:-i '{"displayName":"..."}')からリクエストボディを読み取ります。標準入力からは読み取りません。出力は
{"status_code": <code>, "text": <parsed body>} です(トップレベルの headers オブジェクトを表示するには --show_headers を追加します)。そのため、レスポンスフィールドは jq -r '.text.<field>' で、LRO ID は jq -r '.headers["x-ms-operation-id"]' で読み取ります。az rest の一連の操作例は
例 2 を参照してください。
接続前の確認
git/connect の前に、以下の Git 関連の確認を順番に実行します。各確認の失敗には個別の対処方法があります。事前に解決しておくと、接続時によく発生するエラーを防げます。
| 確認項目 | コマンド | 成功時は続行/失敗時は対処 |
|---|---|---|
| 認証と Fabric トークン | fab auth login の後に fab api workspaces | 401 → 再ログインします(fab が正しいオーディエンスを自動的に設定します) |
| 呼び出し元がワークスペースの Admin であること | fab api "workspaces/${WORKSPACE_ID}/roleAssignments" | 接続/切断には Admin ロールが必要です |
| ワークスペースに容量が割り当てられていること | fab api "workspaces/${WORKSPACE_ID}" → capacityId を確認します | WorkspaceHasNoCapacityAssigned → 容量を割り当てます(Git には容量が必要です) |
| SP パス用の Git 資格情報 | fab api connections(適合する接続がすでにあれば再利用します) | SP での接続には ConfiguredConnection が必要です。存在しない場合、このスキルは ADO の組織/プロジェクト/リポジトリと SP のテナント/クライアント/シークレットから接続を作成します。Git プロバイダー接続の作成を参照してください(テナント設定の「サービスプリンシパルによる接続の作成」が必要です)。対話型ユーザーの SSO パスでは Automatic を使用するため、接続は不要です。 |
対象の directoryName がブランチ上に存在すること | GitHub:curl -fsS -H "Authorization: Bearer $PAT" "https://api.github.com/repos/$OWNER/$REPO/contents/$DIR?ref=$BRANCH" — ADO:リポジトリの Items API | API は(ポータルとは異なり)存在しないフォルダーを作成しません。存在しない directoryName への接続は 404 GitProviderResourceNotFound で失敗します。フォルダーが新規の場合は、先に作成してください(ワークスペースを Git に接続の注記を参照)。 |
ワークスペースを Git に接続する
ワークスペースを Azure DevOps または GitHub のリポジトリに接続し、その後、同期の方向を確立するために接続を初期化します。
# 1. Connect (Azure DevOps example). Body goes in a file, passed with -i.
cat > connect.json <<'JSON'
{
"gitProviderDetails": {
"gitProviderType": "AzureDevOps",
"organizationName": "myorg",
"projectName": "MyProject",
"repositoryName": "fabric",
"branchName": "main",
"directoryName": "/workspace-a"
}
}
JSON
fab api -X post "workspaces/${WORKSPACE_ID}/git/connect" -i connect.json
# 2. Initialize the connection (choose which side wins on first sync)
printf '{"initializationStrategy":"PreferWorkspace"}' > init.json
fab api -X post "workspaces/${WORKSPACE_ID}/git/initializeConnection" -i init.json
ワークスペースにすでに正式な項目がある場合は PreferWorkspace を、Git ブランチが正式な状態である場合は PreferRemote を使用します。
対象の
directoryNameは、ブランチ上にすでに存在している必要があります。 Fabric ポータルでは、不足しているフォルダーをREADME.mdプレースホルダーとしてコミットして暗黙的に作成しますが、git/connectAPI はフォルダーを作成しません。 ブランチ上に存在しないdirectoryNameへの接続は、404 GitProviderResourceNotFoundで失敗します。リポジトリとブランチも存在している必要があります(接続によってブランチが作成されることはありません)。フォルダーが新しい場合は、接続する前に、Git プロバイダーの API を通じて(Fabric API ではなく)プレースホルダーファイルをブランチにコミットして作成してください。ポータルの慣例に合わせて、本文がThis is an auto-created file via Fabric skills for <workspace-name>のREADME.mdを使用します。# GitHub: <BRANCH> に <DIR>/README.md を作成します(Git 接続で使用する PAT を再利用) DIR="workspace-a"; WS_NAME="My Workspace" CONTENT=$(printf 'This is an auto-created file via Fabric skills for %s\n' "$WS_NAME" | base64) cat > mkfolder.json <<JSON { "message": "Create ${DIR} folder for Fabric Git connect", "branch": "${BRANCH}", "content": "${CONTENT}" } JSON curl -fsS -X PUT -H "Authorization: Bearer ${GITHUB_PAT}" \ "https://api.github.com/repos/${OWNER}/${REPO}/contents/${DIR}/README.md" -d @mkfolder.json # Azure DevOps の場合は同様に、refs/heads/${BRANCH} 上の "/${DIR}/README.md" に対する # "add" 変更を含めて POST .../_apis/git/repositories/${REPO}/pushes を実行します(本文は同じです)。
2 つの認証方式(どちらのプロバイダーでも自動化には
myGitCredentialsを使用します)。 ワークスペースは、次のいずれかの方法で Git に認証します。
- 自動 Git 資格情報(Azure DevOps のみ):ワークスペースの設定から確立される、接続ユーザーの SSO ID です。少なくとも Contributor 権限を持つ副次的なコントリビューターもこれを再利用できます。GitHub では利用できず、ヘッドレスまたはサービスプリンシパルによる自動化にも使用できません。
- 構成済み資格情報(Azure DevOps および GitHub):接続リクエスト本文で参照される Fabric クラウド接続です。これは、サービスプリンシパルまたは無人実行で必須となる方法です。
Azure DevOps では、接続の"myGitCredentials": { "source": "ConfiguredConnection", "connectionId": "<connection-guid>" }credentialTypeにServicePrincipal(ヘッドレス自動化)またはOAuth2(保存済みの委任ユーザートークン)のいずれかを指定できます。Create Connection API ではどちらも有効な ConfiguredConnection 資格情報として扱われ、どちらもマルチテナントシナリオに対応しています。 GitHub では、ワークスペースの接続に Personal Access Token(PAT) が必要です。クラウド接続には Contents Read(コミットには Write も必要)権限を持つきめ細かなトークン、またはrepoスコープを持つクラシックトークンを保存します。GitHub には自動資格情報モードがないため、対話型ユーザーの接続でも PAT が必須です。 違いは「GitHub には資格情報が必要だが、ADO には不要」ということではありません。サービスプリンシパルが接続を実行する場合、ADO でも ConfiguredConnection が必要です。自動モードが対応するのは、対話型ユーザーの SSO のみです。(詳細: fabric/cicd/git-integration/automate-git-integration-with-service-principal; rest/api/fabric/core/git/connect.)
初期化の応答を処理します。
initializeConnectionはrequiredAction(UpdateFromGit、CommitToGit、またはNone)とworkspaceHeadおよびremoteCommitHashを返します。また、202を返すこともあります。処理が完了したら、返されたハッシュを使用してrequiredActionで指定された同期操作を呼び出してください。そうしないと、ワークスペースは接続済みでも同期が完了しません。(詳細: rest/api/fabric/core/git/initialize-connection.)
Git プロバイダー接続を作成する(サービス プリンシパル)
自動化を無人で実行するには、まず Git プロバイダーの資格情報を保存する Fabric クラウド接続を作成し、その id を上記の myGitCredentials ブロックで connectionId として渡します。Create Connection API(POST /v1/connections、委任スコープ Connection.ReadWrite.All)を使用します。サービス プリンシパルが接続を作成するには、Fabric 管理者設定「サービス プリンシパルによるワークスペース、接続、デプロイ パイプラインの作成を許可する」が有効になっている必要があります。
指定が必要な情報(Azure DevOps):
- ADO の組織、プロジェクト、リポジトリ名を、1 つの
urlパラメーターにまとめたもの:https://dev.azure.com/<org>/<project>/_git/<repo>/ - サービス プリンシパルのテナント ID、クライアント(アプリケーション)ID、クライアント シークレット
- 接続の表示名(最大 200 文字、テナント内で一意である必要があります)
接続を使用するための前提条件:サービス プリンシパルに、(a)Azure DevOps 組織とプロジェクトへのアクセス権(Git のアクセス制御は Fabric だけでなく ADO 自体によって適用されます)、および(b)対象の Fabric ワークスペースの管理者権限を付与してください。
# Create an Azure DevOps source-control connection using a service principal.
# The body holds a cleartext SP secret, so restrict perms and delete it on exit
# (a leftover connection.json can be captured by a later CI step or artifact upload).
trap 'rm -f connection.json' EXIT
umask 077
cat > connection.json <<'JSON'
{
"displayName": "ado-sp-fabric-cicd",
"connectivityType": "ShareableCloud",
"connectionDetails": {
"type": "AzureDevOpsSourceControl",
"creationMethod": "AzureDevOpsSourceControl.Contents",
"parameters": [
{ "dataType": "Text", "name": "url",
"value": "https://dev.azure.com/<org>/<project>/_git/<repo>/" }
]
},
"credentialDetails": {
"credentials": {
"credentialType": "ServicePrincipal",
"tenantId": "<tenant-id>",
"servicePrincipalClientId": "<client-id>",
"servicePrincipalSecret": "<client-secret>"
}
}
}
JSON
fab api -X post "connections" -i connection.json
201 のレスポンスで接続の id が返されます。これを接続呼び出しの myGitCredentials ブロックで connectionId として使用します。シークレットを一切使わない方法として、本文をインラインで -i '{...}' と渡す(ディスク上にファイルを作成しない)か、未加工の servicePrincipalSecret の代わりに servicePrincipalSecretReference を使って Key Vault のシークレットを参照できます。上記の例では credentialType: "ServicePrincipal" を使用しています。Azure DevOps 接続では credentialType: "OAuth2"(保存された委任ユーザー トークン)も使用でき、どちらの資格情報タイプもマルチテナントのシナリオに対応しています。既存のユーザー接続ワークスペースをサービス プリンシパルに切り替えるには、SP をワークスペース管理者として追加し、この接続を共有または再作成してから、同じ ConfiguredConnection 本文で PATCH /workspaces/{id}/git/myGitCredentials を実行します。(詳細:
fabric/cicd/git-integration/automate-git-integration-with-service-principal;
rest/api/fabric/core/connections/create-connection。)
Git にコミットする
ワークスペースのアイテムを接続済みブランチにプッシュします。まずヘッドを読み取り、その後コミットします。
# Read current head. git/status can return 202 (LRO) with no body — capture the
# status code with --show_headers and poll before reading, or workspaceHead comes
# back as "null" and the commit below fails with a misleading 400.
RESP=$(fab api "workspaces/${WORKSPACE_ID}/git/status" --show_headers)
if [ "$(echo "$RESP" | jq -r '.status_code')" = "202" ]; then
OP=$(echo "$RESP" | jq -r '.headers["x-ms-operation-id"]')
until [ "$(fab api "operations/${OP}" | jq -r '.text.status')" = "Succeeded" ]; do sleep 5; done
RESP=$(fab api "workspaces/${WORKSPACE_ID}/git/status" --show_headers) # now 200 with body
fi
HEAD=$(echo "$RESP" | jq -r '.text.workspaceHead')
# Commit all pending changes. Build the body with jq so the comment is always
# valid JSON even if it contains a quote, backslash, or newline.
jq -n --arg head "$HEAD" --arg msg "Author items" \
'{mode:"All", workspaceHead:$head, comment:$msg}' > commit.json
RESP=$(fab api -X post "workspaces/${WORKSPACE_ID}/git/commitToGit" -i commit.json --show_headers)
# commitToGit may complete synchronously (200) or async (202). Only poll when async.
if [ "$(echo "$RESP" | jq -r '.status_code')" = "202" ]; then
OP=$(echo "$RESP" | jq -r '.headers["x-ms-operation-id"]')
until [ "$(fab api "operations/${OP}" | jq -r '.text.status')" = "Succeeded" ]; do sleep 5; done
fi
一部のアイテムをコミットするには、items 配列とともに "mode": "Selective" を使用します。commitToGit は同期的に完了する場合(200、すでに完了済み)と非同期的に完了する場合(202、ポーリング用の x-ms-operation-id 付き)があります。202 が返されると決めつけず、上記のように .status_code に応じて処理を分岐してください。
Git から更新する
コミット済みアイテムをワークスペースにプルします(たとえば、同じブランチ/フォルダーに接続された下流またはターゲットのワークスペース)。
# Read both hashes from the target workspace
STATUS=$(fab api "workspaces/${TARGET_WS}/git/status")
TH=$(echo "$STATUS" | jq -r '.text.workspaceHead')
REMOTE=$(echo "$STATUS" | jq -r '.text.remoteCommitHash')
cat > update.json <<JSON
{
"workspaceHead": "${TH}",
"remoteCommitHash": "${REMOTE}",
"conflictResolution": {
"conflictResolutionType": "Workspace",
"conflictResolutionPolicy": "PreferRemote"
},
"options": { "allowOverrideItems": true }
}
JSON
fab api -X post "workspaces/${TARGET_WS}/git/updateFromGit" -i update.json
同期ステータスを確認する
ワークスペースとリモートのヘッドが一致するまでポーリングします。commitToGit と updateFromGit はどちらも非同期なので、完了を確認するにはこのループを使用します。
for i in $(seq 1 30); do
S=$(fab api "workspaces/${WORKSPACE_ID}/git/status")
WH=$(echo "$S" | jq -r '.text.workspaceHead')
RC=$(echo "$S" | jq -r '.text.remoteCommitHash')
CH=$(echo "$S" | jq -r '.text.changes | length')
# Success = heads match AND no residual changes. Heads matching alone can still
# leave uncommitted/unapplied diffs; validate both before declaring "synced".
[ "$WH" = "$RC" ] && [ "$CH" = "0" ] && { echo "synced at $WH"; break; }
sleep 8
done
処理がまだ進行中の場合(commit/update から 202 が返された場合)は、ヘッドから推測するのではなく、LRO を直接ポーリングしてください。
# Capture x-ms-operation-id from the 202, then poll until Succeeded
OP_ID=$(fab api -X post "workspaces/${WORKSPACE_ID}/git/commitToGit" -i commit.json \
--show_headers | jq -r '.headers["x-ms-operation-id"]')
while :; do
ST=$(fab api "operations/${OP_ID}" | jq -r '.text.status')
case "$ST" in Succeeded) break ;; Failed) echo "op failed"; break ;; *) sleep 5 ;; esac
done
git/status は changes 配列も返します。配列が空でない場合、未コミット(ワークスペース側)または未適用(リモート側)の差分があることを意味します。
競合を解決する
実際の競合とは、両側で変更されている状態です。最後の同期後に、同じ項目がワークスペース(未コミットのローカル編集)とブランチ(新しいコミット)の両方で変更されています。git/status では、その項目が changes 配列に conflictType: "Conflict" として示されます(workspaceChange と remoteChange の両方が Modified です)。これは片側だけの差分とは異なり、片側だけの差分ではポリシーを指定せずに updateFromGit(リモート側のみの変更)または commitToGit(ワークスペース側のみの変更)を行います。
項目が両側で変更されている場合、updateFromGit には競合ポリシーが必須です。conflictResolution ブロックなしで呼び出すと、400 MissingWorkspaceConflictResolution が返されます。
conflictResolutionPolicy: "PreferRemote"— Git ブランチを優先します(ターゲットへのプルデプロイで一般的)。ローカル編集は破棄されます。conflictResolutionPolicy: "PreferWorkspace"— ライブワークスペースを優先します。代わりにワークスペースのバージョンを Git にプッシュするには、競合ポリシーを受け取らないcommitToGitを使用します。
options.allowOverrideItems: true を設定すると、ターゲットワークスペースにすでに存在する項目を更新で上書きできるようになります(競合する項目がすでにワークスペースに存在する場合は常に必要です。両側の競合では定義上、項目は存在しています)。
ポリシーの選び方:
| シナリオ | ポリシー |
|---|---|
| 下流/ターゲットのワークスペースで Git から最新の変更を取得する | PreferRemote |
| 作成元のワークスペースが信頼できる唯一の情報源である | PreferWorkspace(または、ワークスペースのバージョンを Git にプッシュするには commitToGit) |
| 同じ項目が両側で実際に編集されている | git/status の各 changes エントリの conflictType を確認し、項目ごとに意図的に解決する |
Git との接続を解除する
fab api -X post "workspaces/${WORKSPACE_ID}/git/disconnect"
ブランチワークスペースをベースにリンクする(ワークスペースの関係)
プレビュー。 Git ワークスペースの関係 API は Fabric Git サーフェスの一部であり、プレビュー段階です。ブランチワークスペースと、そこから分岐したベースワークスペースの系譜リンクを記録し、Fabric ポータルでベース↔ブランチの関係を確認できるようにします。組み込みの分岐機能がリリースされる前にブランチワークスペースが作成された場合や、独自の自動化(ポータルの分岐 UX ではない方法)でブランチワークスペースをプロビジョニングし、その系譜を UI に表示したい場合に使用します。関係を作成しても、どちらのワークスペースも Git に接続されず、項目が移動したり同期が開始されたりすることはありません。リンクが記録されるだけです。
前提条件 — 両方のワークスペースが同じ Git ルートを参照している必要があります。 ベースワークスペースとブランチワークスペースが、ブランチのみが異なる同じリポジトリルートに接続されていない場合、作成は WorkspaceRelationRootDirectoryMismatch で失敗します。
- Azure DevOps:
organizationName、projectName、repositoryName、directoryNameが同じで、branchNameのみが異なること。 - GitHub: リポジトリ URL と
directoryNameが同じで、branchNameのみが異なること。
そのため、まず両方のワークスペースを Git に接続(および初期化)してください。この関係によって、既存のブランチ/ベースの組み合わせが可視化されます。
リレーションを作成する(ブランチ ↔ ベースをリンクする)
リレーションは双方向なので、作成するのは一度だけです。本文をよく確認してください。POST するワークスペースと relationType は別のものです。
- URL のワークスペース(
workspaces/{workspaceId}/...)は、呼び出し元のワークスペースです。 relatedWorkspaceIdはもう一方のワークスペースです。relationTypeは、URL に指定されたワークスペースではなく、もう一方の(relatedWorkspaceIdの)ワークスペースの役割を表します。作成時に指定できる値はBaseとBranchのみです。
そのため、同じリンクを作成する方法は次の2通りです。
| 呼び出し元(URL のワークスペース) | relatedWorkspaceId | relationType |
|---|---|---|
| ブランチワークスペース | ベース | Base |
| ベースワークスペース | ブランチ | Branch |
両方の方法を実行しないでください。一方の方向でリレーションが作成されると、もう一方の作成は WorkspaceRelationBidirectionalExists エラーで失敗します。どちら側から呼び出す場合も、必要な権限は同じです。**ブランチワークスペースの Admin 権限と、ベースワークスペースの Contributor 権限(またはそれ以上)が必要です。**推奨される(最も直感的な)方法は、ブランチから呼び出してベースを指定することです。
# From the BRANCH workspace, declare that the related workspace is its Base.
printf '{"relatedWorkspaceId":"%s","relationType":"Base"}' "${BASE_WS}" > relation.json
fab api -X post "workspaces/${BRANCH_WS}/git/workspaceRelations" -i relation.json
201 が返されます。サービスプリンシパルとマネージド ID に対応しています。
リレーションを一覧表示する
Viewer 以上であれば、ワークスペースのリレーションを一覧表示できます(continuationToken を使ってページネーションできます)。レスポンスの relationType は Base、Branch、RelatedWorkspace のいずれかです。
fab api "workspaces/${WORKSPACE_ID}/git/workspaceRelations"
リレーションを削除する
削除されるのはリネージリンクのみです。ワークスペースやそのアイテムは削除されません。呼び出し元は、パスで指定されたワークスペース(ベース側またはブランチ側)の Admin である必要があります。削除できるのは Branch リレーションのみです。それ以外の場合、API は WorkspaceRelationTypeNotBranch を返します。
fab api -X delete "workspaces/${WORKSPACE_ID}/git/workspaceRelations/${RELATION_ID}"
(詳細:rest/api/fabric/core/workspace-relations。)
関連項目:ワークスペースをまたぐアイテムのバインド
同じブランチからターゲットワークスペースを更新すると、アイテムがそこに昇格されます。アイテム間の各参照が自動的に再バインドされるか(論理 ID)、切れるか(オブジェクト ID/ハードコードされたエンドポイント)は、Git のライフサイクルではなくアイテム定義形式の特性であり、fabric-cicd と Bulk Import API のどちらにも同様に当てはまります。特定の依存関係について判断するには、エビデンスタグ付きの互換性マトリックスを確認するか、不確かな参照を実際に検証してください。その場合は cross-workspace-item-binding スキルを使用します(このリポジトリではまだ利用できない、今後追加予定の関連スキルです)。これは、このスキルが扱う接続/コミット/更新のライフサイクルとは別の課題です。
関連項目:Terraform(Infrastructure as Code)
命令的な fab api 呼び出しではなく、宣言的に(Infrastructure as Code で)接続側を管理するには、git-integration-terraform スキルを使用します(このリポジトリではまだ利用できない、今後追加予定の関連スキルです)。このスキルでは、microsoft/fabric プロバイダーの fabric_connection リソースと fabric_workspace_git リソース(Azure DevOps のサービスプリンシパルまたは自動接続、GitHub PAT、初期化戦略、plan/apply/import)を扱います。この構成では Terraform が接続を管理し、このスキルの commit/update-from-git/status 操作は命令的なランタイムの手順として引き続き使用します。そのため、Terraform で接続を管理し、CLI の手順で update-from-git を実行する構成が一般的です。
関連項目:Variable Library(環境パラメーター化)
Git 統合でワークスペース間を移動するのはアイテムの定義ですが、それだけではステージ(dev/test/prod)ごとに異なる値(接続文字列、エンドポイント、容量 ID、機能フラグ)はパラメーター化されません。環境ごとのこのパラメーター化には Variable Library を使用します。変数を一度定義し、ステージごとに値セットを用意すると、アイテムはステージに応じた値を解決できます。Git 同期されたワークスペースで環境ごとに異なる値が必要な場合、このスキルでロジックをハードコードしたり重複させたりするのではなく、変数/値セットのモデリングには関連スキルの variable-library-cli を使用してください。このスキルはソース管理のライフサイクルを担当し、Variable Library スキルはそれに値を提供するパラメーター化を担当します。
注意点、ルール、トラブルシューティング
| 症状 | 原因 | 対処方法 |
|---|---|---|
400 WorkspaceHeadMismatch | workspaceHead が古い | git/status を再読み込みし、現在のヘッドを指定して再試行します |
400 MissingWorkspaceConflictResolution | 両方の側で同じ項目が変更されているのに、conflictResolution を指定せずに updateFromGit が送信された | conflictResolution(ポリシーは PreferRemote または PreferWorkspace)と options.allowOverrideItems: true を追加します。まず git/status で conflictType: "Conflict" を確認してください |
WorkspaceHasNoCapacityAssigned | ワークスペースに容量が割り当てられていない(Git には容量が必要) | ワークスペースに容量を割り当ててから、再試行します |
git/connect で 404 GitProviderResourceNotFound | プロバイダー上にリポジトリ、ブランチ、または directoryName が存在しません。API はポータルとは異なり、フォルダーを自動作成しません | リポジトリ名とブランチ名を確認します。フォルダーが新規の場合は、Git プロバイダー API を使ってブランチに README.md のプレースホルダーをコミットして事前に作成し(ワークスペースを Git に接続するを参照)、再試行します |
WorkspaceAlreadyConnectedToGit | ワークスペースはすでにリポジトリにリンクされています | まず接続を解除してから、新しいリポジトリに接続します |
InsufficientPrivileges / 403 | 呼び出し元に操作で必要なロールがありません(接続/接続解除には Admin が必要です。コミット/更新には、すべての項目への書き込み権限を持つ Contributor 以上が必要です) | 呼び出し元に必要なロールを付与します。接続/接続解除には Admin、コミット/更新にはすべての項目への書き込み権限を持つ Contributor を付与してください |
PrincipalTypeNotSupported | 自動資格情報(または GitHub)を使用するサービスプリンシパルです | myGitCredentials で ConfiguredConnection に切り替えます |
commitToGitRequest is required(fab api を使用) | stdin 経由で本文がパイプされています | 本文をファイルに書き込み、-i body.json を渡します |
操作が 202 を返した後、何も変化しない | 非同期処理がまだ完了していません | (--show_headers から取得した)operations/{id} をポーリングするか、ヘッドが一致するまで git/status をポーリングします |
操作が長時間 Running のままになる | ワークスペースが大きいか、2 つ目の Git 操作がキューに入っています | 適切なタイムアウト(約 10 分)を設定してポーリングを続けます。同時に 2 つ目の Git 操作を開始しないでください |
401 Unauthorized | トークンの対象者が間違っています | fab auth login を実行します(fab が対象者を自動設定します)。az rest を使う場合は、代替手段として --resource https://api.fabric.microsoft.com を渡します |
git/workspaceRelations で WorkspaceRelationRootDirectoryMismatch | ベースワークスペースとブランチワークスペースが異なる Git ルートに接続されています | 両方を同じリポジトリ/組織/プロジェクト/ディレクトリ(Azure DevOps の場合)、または同じリポジトリ URL/ディレクトリ(GitHub の場合)に接続します。違いは branchName のみにしてから、再試行してください |
WorkspaceRelationAlreadyExists / WorkspaceRelationBidirectionalExists | ベース↔ブランチのリレーションはすでに記録されています(双方向です) | 対応は不要です。GET git/workspaceRelations で確認してください。逆方向のリレーションも作成しないでください |
削除時に WorkspaceRelationTypeNotBranch | Branch ではないリレーションを削除しようとしました | 削除できるのは Branch リレーションのみです。正しい workspaceRelationId を使用し、ブランチ側から削除してください |
| 同期のたびに、自分では行っていない未コミットの変更が報告される(空行が 1 つ削除される、または CRLF/LF が切り替わる) | 影響を受けるワークスペースで、エディターまたは AI エージェントが項目のソース(notebook-content.py、pipeline-content.json、.platform)を末尾の改行または CRLF で作成し、その後 Fabric が確認済みのエクスポート形式(LF、末尾の改行なし)に再シリアル化しました | 代表的な往復処理で動作を確認してから、作成時に確認済みのエクスポート形式に合わせます。末尾の改行を付けず、改行コードを LF にします。同期対象のリポジトリで .editorconfig と .gitattributes を使って設定し、AI エージェントに末尾の改行を追加しないよう伝えてください。git-integration-concepts.md § 書式設定のみの差分を回避するを参照してください |
例
例 1:ソースをコミットしてから、ターゲットワークスペースにデプロイする
# Commit everything in the source workspace (jq builds a JSON-safe body)
SRC_HEAD=$(fab api "workspaces/${SRC_WS}/git/status" | jq -r '.text.workspaceHead')
jq -n --arg head "$SRC_HEAD" --arg msg "Deploy v1" \
'{mode:"All", workspaceHead:$head, comment:$msg}' > commit.json
fab api -X post "workspaces/${SRC_WS}/git/commitToGit" -i commit.json
# ...poll src status until synced, then updateFromGit into ${TARGET_WS} (see above)
例 2:az rest による代替手段
fab が利用できない場合は、同じ REST エンドポイントを az rest でも使用できます。必ず
--resource を指定してください。本文はインラインで指定する(--body '{...}')か、ファイルから
読み込めます(--body @file.json)。
# status
az rest --method GET \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WORKSPACE_ID}/git/status" \
--resource "https://api.fabric.microsoft.com"
# commit (body inline)
az rest --method POST \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WORKSPACE_ID}/git/commitToGit" \
--resource "https://api.fabric.microsoft.com" \
--headers "Content-Type=application/json" \
--body "{\"mode\":\"All\",\"workspaceHead\":\"${HEAD}\",\"comment\":\"Author items\"}"