使用 Visual Studio 所建立的 GitHub Actions 工作流程將應用程式部署至 Azure

從 Visual Studio 2019 16.11 版開始,您可為裝載於 GitHub.com 的 .NET 專案建立新的 GitHub Actions 工作流程。

必要條件

使用 GitHub Actions 將單一專案部署至 Azure

在 [方案總管] 中,以滑鼠右鍵按一下 GitHub.com 裝載的專案,然後選擇 [發佈]

以滑鼠右鍵按一下 > [發佈]

在下一個畫面上,選取 [Azure],然後選擇 [下一步]

選取 Azure

根據您的 [專案類型],您會取得不同的 Azure 服務清單以便挑選。 挑選其中一個符合您需求的支援的 Azure 服務

為專案選取適當的 Azure 服務

在精靈的最後一個步驟中,選取 [使用 GitHub Actions 工作流程 的 CI/CD (產生 YML 檔案)],然後選擇 [完成]

使用 GitHub Actions 工作流程的 CI/CD (產生 yml 檔案)

Visual Studio 會產生新的 GitHub Actions 工作流程,並要求您予以認可並推送至 GitHub.com。

認可並推送

如果您使用 內建 Git 工具來完成此步驟,Visual Studio 會偵測工作流程的執行。

工作流程正在執行

設定 GitHub 秘密

若要讓產生的工作流程順利部署至 Azure,則可能需要存取「發行設定檔」

一個 Github 祕密

成功的部署可能也需要存取「服務主體」

兩個 GitHub 祕密

在所有情況下,Visual Studio 會嘗試使用正確的值為您設定 GitHub 秘密。 如果失敗,它會讓您知道並讓您有機會再試一次。

GitHub 秘密遺漏

如果無法再次設定秘密,Visual Studio 會讓您有機會手動存取秘密,因此可在 GitHub.com 上透過存放庫的頁面完成程序。

設定遺漏的 GitHub 秘密

使用 GitHub Actions 將多個專案部署到 Azure 容器應用程式

如果您有一個以上的專案使用 Docker 容器,而且您想要將它們部署為多重專案應用程式,則這些步驟非常合適。 您可以部署多重專案應用程式,例如向 Azure 容器應用程式Azure Kubernetes Service (AKS) 實作微服務的應用程式。 本文涵蓋 Azure 容器應用程式。

  1. 在 [方案總管] 中,以滑鼠右鍵按一下 [GitHub Actions],然後選擇 [新工作流程]。 GitHub Actions 工作流程精靈隨即出現。

    GitHub Actions 節點功能表的螢幕擷取畫面。

  2. 在 [GitHub Actions 工作流程目標] 畫面上,選擇 [Azure]

  3. 針對特定目標,選擇 [Azure 容器應用程式]。 精靈會前進到 [容器應用程式] 畫面。

    螢幕擷取畫面顯示現有 Azure 容器應用程式。

  4. 選擇現有的 Azure 容器應用程式或選擇 [建立新的應用程式]

    螢幕擷取畫面顯示現有 Azure 容器應用程式。

    當您建立新的應用程式時,您會看到此畫面。 測試或學習時,最好建立新的資源群組,以便稍後刪除所有專案。 容器應用程式環境是容器應用程式群組的安全界限,這些容器應用程式會共用相同的虛擬網路,並將記錄寫入相同的記錄目的地。 請參閱 Azure 容器應用程式環境。 如果您之前不知道那是什麽,或尚未建立應用程式,請為此執行個體建立新的應用程式。

    螢幕擷取畫面顯示建立新的 Azure 容器應用程式執行個體。

    建立之後,會顯示新的 Azure 容器應用程式執行個體。

    螢幕擷取畫面顯示新建立的 Azure 容器應用程式執行個體。

  5. 選擇 [下一步] 以前進到 [登錄] 畫面。 選擇現有的 Azure Container Registry 或建立一個新的登錄。

    Azure Container Registry 畫面的螢幕擷取畫面。

    當您選擇建立新的登錄時,您會看到此畫面。 提供資源群組、SKU,並盡可能選擇與之前相同的區域。 如需 Azure Container Registry SKU 的相關資訊,請參閱 Azure Container Registry 服務層級

    螢幕擷取畫面顯示剛建立的新 Azure Container Registry。

    建立之後,新的登錄就會顯示在畫面上。

    螢幕擷取畫面顯示建立新的 Azure Container Registry。

  6. 解決方案中可部署的專案隨即顯示;選擇您想要在相同的 Azure 容器應用程式執行個體中一起部署的專案。

    螢幕擷取畫面顯示要部署的專案選擇。

  7. 選擇 [完成]。 您可以看到發出的命令以在 Azure 中建立資產,並設定驗證。 如果有任何失敗,請記下使用的命令列,因為您可以從 CLI 再試一次。 如果您在這個階段收到授權失敗,請別太擔心。 您也可以稍後在 Visual Studio 中設定驗證。

  8. 完成後,摘要畫面隨即出現。 摘要畫面會顯示認證,它會符合 Visual Studio 在 GitHub Actions 秘密下您的 GitHub 存放庫中建立的專案。 檢查是否有任何黃色警告標誌。 如果在建立流程期間有任何驗證步驟失敗,您可以按一下警告符號的連結,並遵循幾個步驟來更正。

  9. 開啟工作流程檔案,以檢查 Visual Studio 產生的內容。 雖然 Visual Studio 會盡最大努力為您的情況產生工作流程,但每個應用程式和存放庫都是唯一的,因此您通常必須手動編輯 Visual Studio 產生的工作流程 YML 檔案,才能順利執行。 若要開啟它,請展開 [方案總管] 中的 [GitHub Actions] 節點,以滑鼠右鍵按一下剛建立的工作流程,然後選擇 [編輯]

下列範例顯示 Visual Studio 針對具有兩個可部署專案、WebAPI 和 WebFrontEnd 的解決方案所建立的工作流程檔案範例。

on:
push:
  branches:
  - main
env:
CONTAINER_REGISTRY_LOGIN_SERVER: registry20230810121555.azurecr.io
CONTAINER_APP_NAME: containerapp20230810121017
CONTAINER_APP_RESOURCE_GROUP_NAME: webfrontend-container-app-1234
CONTAINER_APP_CONTAINER_NAME: containerapp
jobs:
WebApi_buildImageAndDeploy:
  runs-on: ubuntu-latest
  steps:
  - name: Checkout source code
    uses: actions/checkout@v3
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2
  - name: Login to Docker registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}
      username: ${{ secrets.registry20230810121555_USERNAME_6891 }}
      password: ${{ secrets.registry20230810121555_PASSWORD_6891 }}
  - name: Build and push Docker image to Azure container registry
    uses: docker/build-push-action@v4
    with:
      push: true
      tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webapi:${{ github.sha }}
      file: WebApi\Dockerfile
  - name: Azure login
    uses: azure/login@v1
    with:
      creds: ${{ secrets.containerapp20230810121017_SPN }}
  - name: Deploy to Azure container app
    uses: azure/CLI@v1
    with:
      inlineScript: >-
        az config set extension.use_dynamic_install=yes_without_prompt
        az containerapp registry set --name ${{ env.CONTAINER_APP_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --server ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }} --username ${{ secrets.registry20230810121555_USERNAME_2047 }} --password ${{ secrets.registry20230810121555_PASSWORD_2047 }}
        az containerapp update --name ${{ env.CONTAINER_APP_NAME }} --container-name ${{ env.CONTAINER_APP_CONTAINER_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --image ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webapi:${{ github.sha }}
  - name: Azure logout
    run: az logout
WebFrontEnd_buildImageAndDeploy:
  runs-on: ubuntu-latest
  needs: WebApi_buildImageAndDeploy
  steps:
  - name: Checkout source code
    uses: actions/checkout@v3
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2
  - name: Login to Docker registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}
      username: ${{ secrets.registry20230810121555_USERNAME_2047 }}
      password: ${{ secrets.registry20230810121555_PASSWORD_2047 }}
  - name: Build and push Docker image to Azure container registry
    uses: docker/build-push-action@v4
    with:
      push: true
      tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
      file: WebFrontEnd\Dockerfile
  - name: Azure login
    uses: azure/login@v1
    with:
      creds: ${{ secrets.containerapp20230810121017_SPN }}
  - name: Deploy to Azure container app
    uses: azure/CLI@v1
    with:
      inlineScript: >-
        az config set extension.use_dynamic_install=yes_without_prompt
        az containerapp registry set --name ${{ env.CONTAINER_APP_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --server ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }} --username ${{ secrets.registry20230810121555_USERNAME_2047 }} --password ${{ secrets.registry20230810121555_PASSWORD_2047 }}
        az containerapp update --name ${{ env.CONTAINER_APP_NAME }} --container-name ${{ env.CONTAINER_APP_CONTAINER_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --image ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
  - name: Azure logout
    run: az logout

工作流程的主要功能是使用正確的驗證登入 Azure 服務,並執行命令來建置和部署應用程式。

編輯和測試工作流程

上述程序會產生工作流程 YML 檔案,但您通常需要檢閱和自訂它,才能用於部署。 您可能需要參考 GitHub 撰寫工作流程動作的指導;請參閱 關於自訂動作。 工作流程檔案包含許多可設定的元素,例如環境變數的設定和秘密的名稱。 您可以看到 Dockerfiles 位置的參考、Azure 容器應用程式的名稱、您將用來觸發工作流程執行的存放庫分支,以及 GitHub 中秘密的參考。 秘密會使用語法 ${{ secrets.SECRET_NAME }} 來參考。 請參閲 GitHub Actions 秘密

如果您的專案不在存放庫的根目錄,您必須變更工作流程以指定路徑以尋找 Dockerfiles。 針對這兩個專案中 Dockerfile 的相對路徑新增環境變數。

DOCKER_FILEPATH_WEBAPI: docker/ComposeSample/WebApi/Dockerfile
DOCKER_FILEPATH_WEBFRONTEND: docker/ComposeSample/WebFrontend/Dockerfile

針對 file 參數使用這些環境變數的值,如下所示:

- name: Build and push Docker image to Azure container registry
  uses: docker/build-push-action@v4
  with:
    push: true
    tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
    file: ${{ env.DOCKER_FILEPATH_WEBFRONTEND }}

如果您需要變更 Dockerfile,請進行變更並儲存變更、提交和推送至遠端存放庫。 Visual Studio 產生的工作流程包含觸發程式,會在指定的分支上更新時執行它。 如果您要推送至 working 分支,它應該類似下列程式碼:

on:
  push:
  branches:
  - working

若要測試變更,請提交變更,並將其推送至觸發程式碼中指定的存放庫分支。 您不需要建立提取要求 (PR)。 只要 push 觸發程式設定為正確的分支,工作流程就會執行。

在 GitHub.com 您的存放庫的 [動作] 索引標籤中,尋找工作流程執行。 您可以在 Visual Studio 中使用 GitHub Actions 摘要索引標籤上的連結直接到達該處。 在 GitHub 中,您可以開啟工作流程執行來檢視記錄。

疑難排解

如果您的工作流程未成功執行,下列疑難排解秘訣可能會有幫助。

問題: 組建階段無法組建

Dockerfile 中可能會遇到的其中一個問題是,組建階段無法像 Visual Studio 中一樣運作。 Visual Studio 為專案產生的預設 Dockerfile 示範了此問題。 如果您有這類 Dockerfile,請考慮下列對組建階段的修改。 以下是在存放庫中專案位於 docker/ComposeSample/WebApi 的範例。 提供完整路徑是因為工作流程組建容器中的 Dockerfile 內容設定為存放庫的根目錄,但在 Visual Studio 中,它會設定為專案資料夾上方的資料夾。 會在此處附加後置詞 _build 來建立組建資料夾,而不只是複製專案檔,而是複製整個資料夾。 相較於 Visual Studio 所產生的預設 Dockerfile,已移除 COPY 命令第一個引數中路徑的檔案部分,以便我們複製整個資料夾,而不只是專案檔。 如果沒有這些變更,這個階段會產生 MSBuild 錯誤。

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["docker/ComposeSample/WebApi/", "WebApi_build/"]
RUN dotnet restore "WebApi_build/WebApi.csproj"
COPY . .
WORKDIR "/src/WebApi_build"
RUN dotnet build "WebApi.csproj" -c Release -o /app/build

問題: 驗證認證

工作流程需要為 Azure 存取設定正確的使用者名稱和密碼秘密。 當您在 Microsoft Visual Studio IDE 中或從 GitHub Actions 畫面建立 Azure 資產時,Visual Studio 會嘗試自動執行此動作。 您可以使用存放庫中的 [設定] 區段,檢查 GitHub 中的秘密,並確定其位於該位置,或重新產生秘密,然後再次新增至 GitHub。 根據工作流程每個區段中所參考的內容,檢查秘密識別碼。 如有必要,您可以移至 Azure 入口網站中的容器登錄,並取得容器登錄的使用者名稱和密碼,並使用這些值來更新 GitHub 中的秘密。

如果您執行 az ad sp create-for-rbac 命令來設定服務主體,並取得用戶端識別碼、用戶端密碼和租用戶識別碼,請在 GitHub 存放庫的 [GitHub Actions 秘密] 區段中,將用戶端識別碼和用戶端密碼新增為秘密。 您可以透過使用者名稱 (應用程式的用戶端識別碼) 和 Azure 容器應用程式驗證的密碼 (用戶端密碼) 的形式提供 Azure 登入認證。 若要這樣做,請將步驟 Azure login 取代為下列程式碼。 使用您為用戶端識別碼和用戶端密碼建立的專屬 GitHub 秘密名稱,並使用來自相同命令輸出的租用戶識別碼。

- name: Azure login
  uses: azure/CLI@v1
  with:
    inlineScript: |
      az login --service-principal -u ${{ secrets.GITHUB_SECRETID_FOR_USERNAME }} -p ${{ secrets.GITHUB_SECRETID_FOR_PASSWORD }} --tenant {your tenant ID}
      az account list

如果 Dockerfile 正常運作,且驗證正確,但您仍然看到工作流程的問題,請考慮下列資源:

支援哪些專案類型?

  • ASP.NET Core
  • ASP.NET 5 和更新版本
  • Azure Functions

支援哪些 Azure 服務?

  • Azure Web Apps
  • Azure Functions
  • Azure API 管理