asp.net-coregithubcontinuous-deploymentpleskgithooks

Automatically deploy ASP.NET Core website to Plesk - Post-deploy script cut short


For the past days I've been trying to automate deployment of an ASP.NET Core website to a Plesk Obsidian for Windows environment. I've been struggling pretty bad with this.

In Plesk the Git extension is installed, which allows us to select a branch from which Plesk should pull files into the document root

Plesk admin panel

Here's the configuration panel

Plesk git configuration panel

I have to compile my source files before they can be deployed to the server. But the deploy actions script doesn't know dotnet. So I've setup following github action in my github repository:

name: create-release

on:
    push:
        branches:
            - 'master'
jobs:
    build:
        name: create-release
        runs-on: ubuntu-latest

        steps:
            - name: Setup SSH
              uses: webfactory/ssh-agent@v0.5.1
              with:
                ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
                
            - name: Setup Git Client
              run: |
                ssh-keyscan -H github.com >> ~/.ssh/known_hosts
                git config --global user.email "github-actions@doesnotmatter.dev"
                git config --global user.name "GitHub Actions"

            - name: Checkout
              uses: actions/checkout@v4
              
            - name: Setup .NET Core
              uses: actions/setup-dotnet@v3.0.3
              with:
                dotnet-version: 7.0.400
                # Authenticates packages to push to GPR
                source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
              env:
                NUGET_AUTH_TOKEN: '%NUGET_AUTH_TOKEN%'

            - name: Install dependencies
              run: dotnet restore
              env:
                NUGET_AUTH_TOKEN: ${{ github.token }}
                  
            - name: Build
              run: dotnet publish --configuration Release
                
            - name: Test
              run: dotnet test --no-restore --verbosity normal

            # Clone this repository (deploy branch) inside the "deploy" folder
            # Before clearing out, move .git folder out of the "deploy" folder
            # Recreate deploy folder, empty
            # Move .git folder back again
            # Move publish to deploy folder
            # Push files to the "deploy" branch
            - name: Deploy
              run: |
                git clone --depth 1 --single-branch -b deploy git@github.com:${{ github.repository }}.git deploy
                mv deploy/.git deploy-.git
                rm -rf deploy
                mkdir deploy
                mv deploy-.git deploy/.git
                cd deploy
                cp -R ../bin/Release/net7.0/publish .
                git add .
                git diff --staged --quiet || git commit -m "Update Artifacts"
                git push

This action does the following: When github receives a commit on the master branch, github will build the project and push a new commit with the build result to the deploy branch.

I've added this webhook to my github repository, along with the SSH private key as a secret

Trigger Plesk webhook from Github

So when Plesk receives the webhook, Plesk clones the repository commit in the document root, but DOES NOT stop the application pool. So the DLLs and EXEs are still locked at that point. This is why I put my build in a subfolder:

Deploy branch

Then, in Plesk, we can only specify a post-checkout script. Which at the moment looks like this:

# Create app_offline.htm.
# This effectively unlocks the exe and dll
echo "" > app_offline.htm
# Delete files from the document root. Don't ask for confirmation (Q)
DEL /F /Q *.exe *.dll *.pdb
# With the app-pool stopped, we can now move the files to the document root
copy publish . /y
# All commands below are never executed. So the app never gets online anymore
DEL /Q app_offline.htm
DEL /Q publish

For some reason all commands after the copy aren't executed anymore. Does anyone know why this is happening? I've tried COPY, MOVE, ROBOCOPY, XCOPY.

With xcopy it works at first, but stops again when there's already files in the target folder (xcopy publish . /v /s /y)

EDIT

The DELETE commands seems to work/not work in an alternating fashion.

I tried adding a TIMEOUT but then it doesn't work at all:

echo "" > app_offline.htm
DEL /F /Q *.exe *.dll *.pdb
xcopy publish . /v /s /y && TIMEOUT 2 && DEL /Q app_offline.htm && DEL /Q publish

EDIT 2

Tried this suggestion. Updated deploy script

echo "" > C:\Inetpub\example.com\app_offline.htm
DEL /F /Q *.exe *.dll *.pdb
xcopy C:\Inetpub\example.com\publish C:\Inetpub\example.com /v /s /y
DEL /Q C:\Inetpub\example.com\app_offline.htm
DEL /Q C:\Inetpub\example.com\publish

But same weird behavior here. One time it works, one time doesn't.


Solution

  • Solved it using the following post-deploy script

    echo "" > .\app_offline.htm
    PING -n 2 localhost
    DEL /F /Q *.exe *.dll *.pdb
    PING -n 2 localhost
    XCOPY .\publish . /C /Q /R /S /Y
    PING -n 2 localhost
    DEL /Q .\app_offline.htm
    DEL /Q .\publish
    

    I summarized all steps here