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
Here's the 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
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:
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
)
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
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.
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