Try   HackMD

GitHub Actions for .Net Framework

tags: GitHub GitHubActions CICD .NetFramework Azure yml

用 GitHub Actions 將 .Net Framework web 自動部署至 Azure。

當時主要參考Calvin A. Allen的兩篇文章

Building .NET Framework Applications with Github Actions
Git Tag Based Released Process Using GitHub Actions

yml建置部署流程檔建立可由GitHub網站建立,或自行新增檔案。

由GitHub網站建立

直接至Repository後,上方點選Actions,可以看到有多個範本樣板

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

但找不到 .Net Framework的
沒關係,可以直接選底下的範本讓他自動建立需要的檔案(這邊我選"Deploy Node.js to Azure Web"),並直接在網頁上編輯。

他會在Repo下建立.github/workflows資料夾(如果沒有的話)裡面放yml檔。

要注意這邊還沒真的新增,需要Commit後才會真的加入Repository

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

這個yml檔就是列著我們要自動建置部署等等的步驟(Tasks)。所需相關步驟也是由右側Marketplace搜尋取得參數設定。

自行建立檔案

從上其實可以知道只要自行在你的Repository下新增.github/workflows資料夾,資料夾內新增yml檔就可以了。只是要知道個steps使用的參數。

yml內容

先給完整的yml檔內容,以及可以參考的GitHub Actions相關指令

name: Azure CI

on:
  push:
    tags: release/[1-9]+.[0-9]+.[0-9]+

env:
  AZURE_WEBAPP_NAME: appname
  AZURE_WEBAPP_PACKAGE_PATH: './_build'

jobs:
  build-and-deploy-azure:
    runs-on: [windows-latest]

    steps:
    - uses: actions/checkout@v2

    - name: Setup MSbuild
      uses: microsoft/setup-msbuild@v1.0.1
   
    - name: Setup NuGet
      uses: NuGet/setup-nuget@v1.0.2
      
    - name: Restore NuGet Packages
      run: nuget restore YourSolution.sln
    
    - name: Build the Solution
      run: msbuild YourSolution.sln /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:platform="Any CPU" /p:configuration="Release" /p:PublishUrl=.${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
      
    - name: Upload Artifact
      uses: actions/upload-artifact@v2.1.4
      with:
        name: AzureDepBundle
        path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
    
    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
    
    - name: Publish Artifacts to Azure
      uses: Azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
        slot-name: production

第一部分是這個workflow的名稱。

name: Azure CI

之後會在Actions workflows顯示的名稱。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

第二部分是觸發條件,這邊我是以特定tag名稱為觸發條件,也就是當我git push像是release/1.2.0的tag時就會觸發這個workflow。

on:
  push:
    tags: release/[1-9]+.[0-9]+.[0-9]+

也可以單純的以branch為觸發條件。

on:
  push:
    branches: master

第三部分是以map的形式設定參數,這邊主要是給後面jobs和steps使用。

env:
  AZURE_WEBAPP_NAME: appname
  AZURE_WEBAPP_PACKAGE_PATH: './_build'

第四部分可以設定多組jobs,預設為同時執行,這邊我只有一個job,job_id叫做build-and-deploy-azure(可以自行命名),並指定執行在最新版windows虛擬機上(GitHub-hosted),另外也有self-hosted但就沒有研究了。
接下來就是要做的steps。

jobs:
  build-and-deploy-azure:
    runs-on: [windows-latest]

    steps:
    - uses: actions/checkout@v2

因為是 .Net Framework 所以需要MSBuild和NuGet。

    - name: Setup MSbuild
      uses: microsoft/setup-msbuild@v1.0.1
   
    - name: Setup NuGet
      uses: NuGet/setup-nuget@v1.0.2

再來還原NuGet packages與建置專案。

    - name: Restore NuGet Packages
      run: nuget restore YourSolution.sln
    
    - name: Build the Solution
      run: msbuild YourSolution.sln /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:platform="Any CPU" /p:configuration="Release" /p:PublishUrl=.${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

這邊建置專案指定了一些參數,其中/p:PublishUrl=.${{ env.AZURE_WEBAPP_PACKAGE_PATH }}指定建置後在虛擬機上放的路徑,也就是上面設定的./_build

再來將建置好的檔案(Artifact)從路徑./_build上傳,取名AzureDepBundle

    - name: Upload Artifact
      uses: actions/upload-artifact@v2.1.4
      with:
        name: AzureDepBundle
        path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

這是選擇性,上傳會在GitHub上Build的那次紀錄存著一份。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

接著是登入Azure並上傳。

    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
    
    - name: Publish Artifacts to Azure
      uses: Azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
        slot-name: production

secrets.AZURE_CREDENTIALS是在Settings -> Secrets內設定,AZURE_CREDENTIALS 是我自訂的名稱,可以自行更換。
secrets內容請參考 https://github.com/Azure/actions/https://github.com/Azure/login 產生,應為json形式資料。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

app-name部分對應到Azure上App Service名稱。

以上檔案commite後就完成拉~