Giteaを使用してCI/CDパイプラインを構築する③

構築も大詰め、Gitea用の自動ビルド、デプロイ用のスクリプトを記述します。

目次

リポジトリにWorkflowを追加する

①「.git」フォルダと同じ階層に「.gitea」フォルダを作成

ドット始まりのフォルダのためPowerShellで作成します。配下のworkflowsフォルダも作成しましょう。

cd C:\・・・・\SampleWeb
mkdir .gitea/workflows

②「deploy.yml」ファイルを作成する

「workflows」フォルダ配下に「deploy.yml」ファイルをUTF8で作成します。

ファイル名は任意ですが、拡張子はymlにしておきます。ファイル名はGitea上に表示されますので識別しやすい名前にしておくといいでしょう。以下にファイル内容のサンプルを記載します。

name: Build and Deploy SampleWeb

on:
  push:
    branches: #mainブランチにプッシュされたら実行するように設定
      - main
  workflow_dispatch: #手動実行(giteaのランナー管理から)可能に設定

jobs:
  build-deploy:
    runs-on: windows #config.ymlのラベル設定と同じ(- windows:hostの前部分)にする

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Restore NuGet packages
        shell: powershell
        run: |
          & "C:\Tools\nuget\NuGet.exe" restore .\TestWebApp\TestWebApp.sln #要インターネット接続

      - name: Build
        shell: powershell
        run: |
          $ErrorActionPreference = "Stop"

          $msbuild = "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\MSBuild.exe" #Build Tools for Visual Studioインストール済み
          $project = ".\TestWebApp\TestWebApp\TestWebApp.csproj" #プロジェクトの場所(チェックアウト場所からの相対パス)を指定
          $publishDir = "C:\Build\publish\" #発行場所を指定もここは無視されてしまう
          $packageTmp = ".\TestWebApp\TestWebApp\obj\Release\Package\PackageTmp\" #実際に発行される場所を指定(act_runnerの仕様なのでパスは参考に)

          New-Item -ItemType Directory -Force $publishDir | Out-Null

          & $msbuild $project `
            /p:Configuration=Release `
            /p:Platform="AnyCPU" `
            /p:DeployOnBuild=true `
            /p:WebPublishMethod=FileSystem `
            /p:PublishProvider=FileSystem `
            /p:PublishUrl="$publishDir" `
            /p:DeleteExistingFiles=true 

          if ($LASTEXITCODE -ne 0) {
            throw "MSBuild failed with exit code $LASTEXITCODE"
          }

          if (!(Test-Path $packageTmp)) {
            throw "PackageTmp not found: $packageTmp"
          }

          robocopy $packageTmp $publishDir /E /PURGE #実際に出力された場所から、指定発行場所へファイルをコピーしている(このstepが終わると一時フォルダが削除されてしまうため、step終了前にコピーしている
          $copyCode = $LASTEXITCODE

          if ($copyCode -ge 8) {
            throw "robocopy failed with exit code $copyCode"
          }

          exit 0 #問題ない場合は0を返しておく。0以外だとGiteaがエラーありと判定する

      - name: Deploy to local IIS #IISへのデプロイ
        shell: powershell
        run: |
          $ErrorActionPreference = "Stop"

          $publishDir = "C:\Build\publish"
          $deployDir = "C:\inetpub\wwwroot\DeployTest" #deployDirは同サーバーのIIS公開フォルダ

          if (!(Test-Path $publishDir)) {
            throw "Publish directory not found: $publishDir"
          }

          New-Item -ItemType Directory -Force $deployDir | Out-Null

          "maintenance" | Out-File "$deployDir\app_offline.htm" -Encoding utf8

          robocopy "$publishDir" "$deployDir" /MIR /XD App_Data /XF Web.config app_offline.htm
          $code = $LASTEXITCODE
          if ($code -ge 8) {
            throw "robocopy deploy failed with exit code $code"
          }

          Remove-Item "$deployDir\app_offline.htm" -ErrorAction SilentlyContinue
          exit 0

ビルド実行後のファイル出力場所が指定場所ではなく、実行ユーザーフォルダ内の一時フォルダになります。前回記事でact_runnerを実行するアカウントはログインさせておく必要があると書いたのはこのためです。
またステップを抜けると一時フォルダが削除されてしまうため、削除前に指定フォルダへ出力ファイル群をコピーしています。
最終的には指定フォルダからIIS公開フォルダへファイルをコピーしてデプロイ終了となります。

③Gitリポジトリに「.gitea」フォルダをプッシュする

フォルダをプッシュすることで、Giteaが「deploy.yml」をもとにact_runnerに実行処理を依頼するようになります。

動作するか確認する

Giteaのリポジトリに対して、何かしら更新したファイルをmainブランチにマージしてみましょう。
設定が正しく行われていれば、自動でビルド、デプロイが行われます。実行結果や問題点についてはGiteaのメニューにあるActionsから確認することができます。エラーになっていた場合は詳細を確認し修正していってください。
(手動でも実行できますので、まずは手動実行で最後までパイプラインが通るか確認するといいです)

まとめ

これでGiteaによるパイプライン構築は終了です。
実運用ではイシューの記録、開発者が修正してプルリクエスト、承認によりmainブランチへマージの流れになると思いますが、このあたりは各プロジェクトによりけりですね。

上記サンプルのymlファイルを掲載しましたが、実際はファイル上書きだけでなく、削除するファイル、ログファイルなど残すものも多々あると思います。テストを重ねトラブルのないスクリプトに仕上げてもらえればと思います。

また今回はGiteaとIISが同じサーバーのためデプロイも簡単でしたが、他のサーバーへデプロイする、クラウド上のサーバーにデプロイするとなると多くの工夫や仕組みが必要になってくるかと思います。
難易度もぐっと上がってしまうと考えますが、当記事が構築の一助になれば幸いです。

  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次