コードを使用して Dataverse を Git リポジトリに接続して切断する

ConnectToGit API とDisconnectFromGit API を使用して、Microsoft Dataverse 環境を Git ソース管理とプログラムで統合します。 これらの API を使用すると、個々のソリューションまたは環境全体をサポートされている Git リポジトリに接続し、コードを使用してそれらの接続を管理できます。

前提条件

これらの API を使用する前に、次のことを確認してください。

  • Microsoft Dataverse 環境へのアクセス
  • システム管理者のアクセス許可
  • Git リポジトリへの読み取りと書き込みアクセス

ConnectToGit API

Dataverse ソリューションまたは環境と Git リポジトリの間の接続を作成します。 この接続を使用すると、Dataverse コンポーネントのソース管理を管理できます。

Parameters

ConnectToGit API は、次のパラメーターを受け入れます。

パラメーター タイプ 必須 Description
GitFolder String Yes ソリューションまたは環境をバインドするフォルダーの名前。
Branch String Yes 接続先のブランチの名前。
ConnectionType Integer No 接続先を指定します。 ConnectionType パラメーターを参照してください。
GitProvider Integer No Git プロバイダー。 GitProvider パラメーターを参照してください。
Organization String No 接続する組織の名前。
Project String No 接続するプロジェクトの名前。
Repository String No 接続先のリポジトリの名前。
RootFolder String No すべてのソリューションがソリューション スコープ内に存在するルート フォルダーの名前。
SolutionUniqueName String No Git に接続するソリューションの一意の名前。
UpstreamBranch String No 接続先のアップストリーム ブランチの名前。 既定値はリポジトリの既定のブランチです。
GitHubConnectionId String No Power Platform GitHub接続の接続 ID。 GitHubPATを指定しない限り、GitProvider1場合は必須です。 Dataverse 環境で仮想ネットワーク (VNET) のサポートが有効になっている場合は使用できません。
GitHubPAT String No 対象リポジトリにアクセスできる GitHub の個人用アクセストークン GitHubConnectionIdを指定しない限り、GitProvider1場合は必須です。 Dataverse 環境で仮想ネットワーク (VNET) のサポートが有効になっている場合に必要です。
GitHubAppConfigId String No GitHub アプリ構成レコードへの参照。 GitProvider1 の場合に必要です。 「githubappconfigs(<recordId>)」の形式を使用します。

ConnectionType パラメーター

ConnectionType パラメーターは、Dataverse 環境全体に接続するか、特定のソリューションに接続するかを制御します。

価値 Label Description
0 解決策 特定の Dataverse ソリューションを Git に接続します。
1 Environment Dataverse 環境全体を Git に接続します。

GitProvider パラメーター

GitProvider パラメーターを使用して、使用している Git プロバイダーの種類 (Azure DevOps または GitHub) を指定します。

価値 Label Description
0 Azure DevOps Azure DevOps でホストされているリポジトリに使用する
1 GitHub GitHub でホストされているリポジトリに使用する

DisconnectFromGit API

Dataverse ソリューションまたは環境から Git 接続を削除し、ソース管理の統合を無効にします。

パラメーター

DisconnectFromGit API にはパラメーターが 1 つだけ含まれています。

パラメーター タイプ 必須 Description
SolutionUniqueName String No Git から切断するソリューションの一意の名前。 すべてのソリューションまたは環境の接続を解除しないようにするために省略します。

追加情報

DisconnectFromGitを呼び出すときに指定するパラメーター値のオプションをいくつか次に示します。

  • 1 つのソリューションを切断する: 特定のソリューションを切断するための SolutionUniqueName を提供します。
  • すべてのソリューションを切断する: すべてのソリューション レベルの接続を切断するためのパラメーターを指定しません。
  • 環境の切断: 環境レベルの接続を切断するためのパラメーターを指定しません。

例示

次の例では、 ConnectToGit API と DisconnectFromGit API を使用するシナリオについて説明します。

Dataverse 環境全体を Azure DevOps リポジトリに接続する

この接続により、すべての環境レベルの構成とコンポーネントのソース管理が可能になります。

この接続では、次のパラメーターを使用しないでください。

  • RootFolder
  • SolutionUniqueName
  • UpstreamBranch

この例では、 ConnectToGit アクション を使用して Dataverse 環境全体を Azure DevOps リポジトリに接続する方法を示します。

申請

POST [Organization URI]/api/data/v9.2/ConnectToGit HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

{
   "GitFolder": "yourGitfolderName",
   "Branch": "yourBranchName",
   "ConnectionType": 1,
   "GitProvider": 0,
   "Organization": "yourOrganizationName",
   "Project": "yourProjectName",
   "Repository": "yourRepositoryName"
}

応答

HTTP/1.1 204 No Content
OData-Version: 4.0

Web API アクションを呼び出す方法について説明します

GitHub リポジトリに接続する

API を使用してGitHubに接続する前に、GitHub アプリの作成、ターゲット リポジトリへのインストール、Azure Key Vaultへの秘密キーのインポート、Power Platform GitHub接続の作成を行うセットアップ手順を完了します。 詳細については、「GitHubへの接続」を参照してください。

Web API を使用してGitHubアプリ構成レコードを作成する

Dataverse OData Web API を使用して、 githubappconfig レコードを作成します。 GitHub アプリ クライアント ID、Key Vault URI、キー名を使用して POST 要求を送信します。

これらの呼び出しには、不眠症、Visual Studio Code REST クライアント、curl などの任意の HTTP クライアントを使用できます。 認証にはベアラー トークンが必要です。 詳細については、「Microsoft Dataverse Web API の使用」を参照してください。

POST {{DataverseOrgUrl}}/api/data/v9.2/githubappconfigs
Authorization: Bearer {{token}}
Content-Type: application/json

{
    "githubappid": "Iv23liBWoH9sf7xDrRe6",
    "keyvaulturi": "{{KeyVaultUri}}",
    "keyname": "demoGitHubKey"
}

Important

応答ヘッダーで返されるレコード ID をメモします。 マネージド ID を識別し、RBAC を構成し、 ConnectToGitを呼び出すには、この値が必要です。 レコード ID は、 13d565bb-4c22-f111-a546-7ced8d6e3e85などの形式を使用します。

GitHub App の構成レコードを作成した後、Key Vault のロールベースのアクセス制御 (RBAC) を構成する で説明されているように、Dataverse マネージド ID に Key Vault Crypto User ロールを割り当てます。

ConnectToGit API を呼び出す

githubappconfig レコードを作成し、KEY VAULT RBAC を構成したら、Dataverse Web API を使用して、ConnectToGit アクションを呼び出してソース管理接続を確立します。

POST {{DataverseOrgUrl}}/api/data/v9.2/ConnectToGit
Authorization: Bearer {{token}}
Content-Type: application/json

{
    "GitProvider": 1,
    "ConnectionType": 1,
    "Organization": "YourGitHubOrg",
    "Repository": "YourRepo",
    "Project": "placeholder",
    "Branch": "yourBranch",
    "UpstreamBranch": "main",
    "GitFolder": "YourFolder",
    "GitHubConnectionId": "<connectionId>",
    "GitHubAppConfigId": "githubappconfigs(<recordId>)"
}

Important

ブランチはリポジトリに既に存在している必要があります。 必要に応じて、最初にGitHubで作成します。 GitHubAppConfigId値には、githubappconfigs(<recordId>)形式を使用する必要があります。

GitHub パラメーターを含む ConnectToGit API の HTTP 要求本文のスクリーンショット。

正常な応答を受け取った場合、環境はGitHubに接続されます。

PowerShell を使用してGitHub リポジトリに接続する

次の PowerShell の例では、GitHubアプリ構成レコードを作成し、Dataverse マネージド ID がMicrosoft Entra IDに表示されるのを待ち、Key Vault Crypto User ロールをマネージド ID に割り当てて、ConnectToGit アクションを呼び出します。 GitHub App の構成レコードが既にある場合は、構成と Key Vault のロール割り当ての手順をスキップするために、GitHubAppConfigId を指定します。

例を実行する前に、powerShell モジュールの Az.AccountsAz.KeyVault、および Az.Resources をインストールしてインポートします。 Dataverse 環境にアクセスできるアカウントと、Key Vaultロールを割り当てるアクセス許可を持つアカウントを使用して、Connect-AzAccountでサインインします。

Dataverse 環境で仮想ネットワーク (VNET) のサポートが有効になっている場合は、 GitHubPATを指定します。 GitHub接続は、仮想ネットワークのサポートでは使用できません。

[CmdletBinding()]
param(
    [Parameter(Mandatory)]
    [string]$DataverseOrgUrl,

    [Parameter(Mandatory)]
    [string]$GitHubOrg,

    [Parameter(Mandatory)]
    [string]$GitHubRepo,

    [Parameter(Mandatory)]
    [string]$Branch,

    [Parameter(Mandatory)]
    [string]$GitFolder,

    [string]$GitHubAppClientId,

    [string]$KeyVaultName,

    [string]$KeyVaultKeyName,

    [string]$GitHubAppConfigId,

    [string]$GitHubConnectionId,

    [string]$GitHubPAT,

    [ValidateSet(0, 1)]
    [int]$ConnectionType = 1,

    [string]$UpstreamBranch,

    [string]$RootFolder,

    [string]$SolutionUniqueName
)

Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"

if (($GitHubConnectionId -and $GitHubPAT) -or (-not $GitHubConnectionId -and -not $GitHubPAT)) {
    throw "Specify either -GitHubConnectionId or -GitHubPAT, but not both."
}

if (-not $GitHubAppConfigId) {
    foreach ($name in @('GitHubAppClientId', 'KeyVaultName', 'KeyVaultKeyName')) {
        if ([string]::IsNullOrWhiteSpace((Get-Variable -Name $name -ValueOnly))) {
            throw "Specify -$name when -GitHubAppConfigId is not provided."
        }
    }
}

$dataverseResource = $DataverseOrgUrl.TrimEnd('/')
$tokenResult = Get-AzAccessToken -ResourceUrl $dataverseResource -AsSecureString
$dataverseToken = [System.Net.NetworkCredential]::new('', $tokenResult.Token).Password

function Invoke-DataverseApi {
    param(
        [Parameter(Mandatory)]
        [string]$Method,

        [Parameter(Mandatory)]
        [string]$Endpoint,

        [object]$Body,

        [switch]$ReturnHeaders
    )

    $headers = @{
        Authorization      = "Bearer $dataverseToken"
        "OData-MaxVersion" = "4.0"
        "OData-Version"    = "4.0"
    }

    $request = @{
        Method      = $Method
        Uri         = "$dataverseResource/api/data/v9.2/$Endpoint"
        Headers     = $headers
        ContentType = "application/json; charset=utf-8"
    }

    if ($Body) {
        $request.Body = $Body | ConvertTo-Json -Depth 10
    }

    if ($ReturnHeaders) {
        return (Invoke-WebRequest @request).Headers
    }

    Invoke-RestMethod @request
}

$appConfigRecordId = $GitHubAppConfigId

if (-not $appConfigRecordId) {
    $keyVault = Get-AzKeyVault -VaultName $KeyVaultName
    $keyVaultUri = 'https://' + $KeyVaultName + '.vault.azure.net/'

    $appConfigBody = @{
        githubappid = $GitHubAppClientId
        keyvaulturi = $keyVaultUri
        keyname     = $KeyVaultKeyName
    }

    $responseHeaders = Invoke-DataverseApi `
        -Method POST `
        -Endpoint "githubappconfigs" `
        -Body $appConfigBody `
        -ReturnHeaders

    $entityIdHeader = [string]$responseHeaders["OData-EntityId"]
    if ($entityIdHeader -notmatch '\(([0-9a-f-]+)\)') {
        throw "Could not read the GitHub App configuration record ID from the Dataverse response."
    }

    $appConfigRecordId = $Matches[1]
    $managedIdentityName = "PPMI-githubappconfigmanagedidentity-$appConfigRecordId"

    $servicePrincipal = $null
    for ($attempt = 1; $attempt -le 60; $attempt++) {
        $servicePrincipal = Get-AzADServicePrincipal -DisplayName $managedIdentityName -ErrorAction SilentlyContinue
        if ($servicePrincipal) {
            break
        }

        Start-Sleep -Seconds 1
    }

    if (-not $servicePrincipal) {
        throw "The Dataverse managed identity was not found in Microsoft Entra ID. Check Dataverse System Jobs for GitHub App configuration errors."
    }

    $keyVaultScope = $keyVault.ResourceId
    if (-not $keyVaultScope) {
        $subscriptionId = (Get-AzContext).Subscription.Id
        $keyVaultScope = "/subscriptions/$subscriptionId/resourceGroups/$($keyVault.ResourceGroupName)/providers/Microsoft.KeyVault/vaults/$KeyVaultName"
    }

    $keyVaultCryptoUserRoleId = "12338af0-0e69-4776-bea7-57ae8d297424"
    $existingAssignment = Get-AzRoleAssignment `
        -ObjectId $servicePrincipal.Id `
        -RoleDefinitionId $keyVaultCryptoUserRoleId `
        -Scope $keyVaultScope `
        -ErrorAction SilentlyContinue

    if (-not $existingAssignment) {
        New-AzRoleAssignment `
            -ObjectId $servicePrincipal.Id `
            -RoleDefinitionId $keyVaultCryptoUserRoleId `
            -Scope $keyVaultScope | Out-Null
    }
}

$connectBody = @{
    GitProvider          = 1
    ConnectionType       = $ConnectionType
    Organization         = $GitHubOrg
    Repository           = $GitHubRepo
    Project              = "placeholder"
    Branch               = $Branch
    GitFolder            = $GitFolder
    GitHubAppConfigId    = "githubappconfigs($appConfigRecordId)"
}

if ($GitHubConnectionId) { $connectBody.GitHubConnectionId = $GitHubConnectionId }
if ($GitHubPAT)          { $connectBody.GitHubPAT          = $GitHubPAT }
if ($UpstreamBranch)     { $connectBody.UpstreamBranch     = $UpstreamBranch }
if ($RootFolder)         { $connectBody.RootFolder         = $RootFolder }
if ($SolutionUniqueName) { $connectBody.SolutionUniqueName = $SolutionUniqueName }

Invoke-DataverseApi -Method POST -Endpoint "ConnectToGit" -Body $connectBody
Write-Host "Connected Dataverse Git integration to GitHub."

Dataverse 環境全体を Git ソース管理から切断する

このアクションにより、環境レベルの Git 接続が削除されます。 この操作には SolutionUniqueName パラメーターを使用しないでください。 Dataverse は、環境レベルの Git 接続を自動的に識別して削除します。

この例では、 DisconnectFromGit アクション を使用して、Dataverse 環境全体を Git ソース管理から切断する方法を示します。

申請

POST [Organization URI]/api/data/v9.2/DisconnectFromGit HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

応答

HTTP/1.1 204 No Content
OData-Version: 4.0

Web API アクションを呼び出す方法について説明します

最初のソリューションを Git リポジトリに接続する

この接続により、ソリューション レベルのソース管理のリポジトリ リンクとフォルダー構造が、環境内の最初のソリューションに確立されます。

ソリューションを指定するには、これらのパラメーターの値を含める必要があります。

  • RootFolder
  • SolutionUniqueName

この例では、 ConnectToGit アクション を使用して、最初のソリューションを Git リポジトリに接続する方法を示します。

申請

POST [Organization URI]/api/data/v9.2/ConnectToGit HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

{
   "GitFolder": "yourGitfolderName",
   "Branch": "yourBranchName",
   "ConnectionType": 1,
   "GitProvider": 0,
   "Organization": "yourOrganizationName",
   "Project": "yourProjectName",
   "Repository": "yourRepositoryName",
   "RootFolder": "yourRootFolderName",
   "SolutionUniqueName": "yourSolutionUniqueName"
}

応答

HTTP/1.1 204 No Content
OData-Version: 4.0

Web API アクションを呼び出す方法について説明します

初期ソリューションを接続した後、追加のソリューションを同じ Git リポジトリに接続する

最初のソリューションを接続した後は、ソリューション固有のパラメーターのみが必要になります。 最初の接続からリポジトリ接続の詳細を継承します。

次のパラメーターのみを設定します。

  • SolutionUniqueName
  • Branch
  • GitFolder

Important

これが機能する前に、最初のソリューションを最初に接続する必要があります。 最初のソリューションを Git リポジトリに接続するを参照してください。

この例では、 ConnectToGit アクション を使用して後続のソリューションを Git リポジトリに接続する方法を示します。

申請

POST [Organization URI]/api/data/v9.2/ConnectToGit HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

{
   "GitFolder": "yourGitfolderName",
   "Branch": "yourBranchName",
   "SolutionUniqueName": "yourSolutionUniqueName"
}

応答

HTTP/1.1 204 No Content
OData-Version: 4.0

Web API アクションを呼び出す方法について説明します

他のソリューションを接続したまま、特定のソリューションを Git ソース管理から切断する

このアプローチを使用して、他のソリューションに影響を与えずに 1 つのソリューションのソース管理を削除します。

この例では、 DisconnectFromGit アクション を使用して、他のソリューションに影響を与えずに 1 つのソリューションのソース管理を削除する方法を示します。

申請

POST [Organization URI]/api/data/v9.2/DisconnectFromGit HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0

{
   "SolutionUniqueName": "yourSolutionUniqueName"
}

応答

HTTP/1.1 204 No Content
OData-Version: 4.0

Web API アクションを呼び出す方法について説明します

エラー処理

正常に完了したときに、 ConnectToGitDisconnectFromGit API のどちらも値を返しません。 API が失敗すると、エラーが返されます。

一般的なエラーのシナリオは次のとおりです。

  • 無効な資格情報: Git プロバイダーに対する有効な認証があることを確認します。
  • リポジトリが見つかりません: 組織、プロジェクト、リポジトリの名前を確認します。
  • アクセス許可が拒否されました: Dataverse アカウントにソース管理の管理アクセス許可があることを確認します。
  • 解決策が見つかりません: SolutionUniqueName が環境内に存在するかどうかを確認します。
  • ブランチが存在しない: 指定したブランチがリポジトリに存在するかどうかを確認します。

サポートとその他のリソース

Dataverse とのソース管理の統合の詳細については、以下を参照してください。