Skip to content

Instantly share code, notes, and snippets.

@houstonhaynes
Last active December 18, 2024 19:17
Show Gist options
  • Save houstonhaynes/510bb017074efd5b9090b9c550406ff9 to your computer and use it in GitHub Desktop.
Save houstonhaynes/510bb017074efd5b9090b9c550406ff9 to your computer and use it in GitHub Desktop.
Sample webhook and build/deploy script for .NET back end server
GITHUB_WEBHOOK_SECRET="[SOME_GUID_THAT_MUST_MATCH_GITHUB_SETTING]"
#!/usr/bin/env pwsh
param (
[Parameter(Mandatory = $true)]
[string]$refBranch
)
function Update-and-BuildProject {
param (
[string]$repoUrl,
[string]$localPath,
[string]$branch
)
try {
Write-Host "repoUrl: $repoUrl"
Write-Host "localPath: $localPath"
Write-Host "branch: $branch"
Write-Host "refBranch: $refBranch"
# Ensure we're in the correct directory
Set-Location $localPath
# Use existing git remote
Write-Host "Pulling and checking out branch: $refBranch"
git pull origin $refBranch
git checkout $refBranch
# Build and publish the project
dotnet run Publish
$publishExitCode = $LASTEXITCODE
if ($publishExitCode -eq 0) {
# Restart services only if the build was successful
sudo systemctl restart rex-server.service
sudo systemctl restart rex-app.service
Write-Host "Project updated and services restarted successfully."
} else {
Write-Error "Build failed with exit code $publishExitCode. Services were not restarted."
}
} catch {
Write-Error "An error occurred: $_"
}
}
# Setting up the HTTP listener
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://+:8081/")
$listener.Start()
Write-Host "Listening for connections on http://+:8081/..."
while ($listener.IsListening) {
$context = $listener.GetContext()
try {
$request = $context.Request
$response = $context.Response
$body = New-Object System.IO.StreamReader($request.InputStream)
$data = $body.ReadToEnd()
$body.Close()
# Log the received data
Write-Host "Received Data: $data"
$secret = [Environment]::GetEnvironmentVariable("GITHUB_WEBHOOK_SECRET")
$receivedSignature = $request.Headers["X-Hub-Signature"]
if (-not $receivedSignature) {
Write-Host "No signature provided"
$response.StatusCode = 400
$response.Close()
continue
}
# Compute HMAC hash on the raw data without any modifications
$hmac = New-Object System.Security.Cryptography.HMACSHA1
$hmac.Key = [Text.Encoding]::UTF8.GetBytes($secret)
$hashBytes = $hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($data))
$expectedSignature = "sha1=" + ([BitConverter]::ToString($hashBytes) -replace '-', '').ToLower()
if ($expectedSignature -eq $receivedSignature) {
Write-Host "Signatures match"
try {
# Extract the Content-Type header
$contentType = $request.Headers["Content-Type"]
# If the content type is application/x-www-form-urlencoded, extract and decode the payload
if ($contentType -eq "application/x-www-form-urlencoded") {
# Extract the 'payload' parameter
$formFields = [System.Web.HttpUtility]::ParseQueryString($data)
$payloadJson = $formFields["payload"]
} else {
# Assume the data is the raw JSON payload
$payloadJson = $data
}
# Parse the JSON payload
$payload = $payloadJson | ConvertFrom-Json
# Extract necessary information
$repoUrl = $payload.repository.clone_url
$branch = $payload.ref -replace 'refs/heads/', ''
$localPath = "/home/rexuser/Rex"
# Check if the branch is 'dev'
if ($branch -eq $refBranch) {
Update-and-BuildProject -repoUrl $repoUrl -localPath $localPath -branch $branch -refBranch $refBranch
} else {
Write-Output "No build triggered as the branch is not '{$refBranch}'."
}
} catch {
Write-Host "Failed to parse JSON payload. Error: $_"
$response.StatusCode = 400
$response.Close()
continue
}
} else {
Write-Host "Invalid secret"
$response.StatusCode = 403
$response.Close()
continue
}
$response.StatusCode = 200
$response.StatusDescription = "OK"
$response.Close()
} catch {
Write-Error "An error occurred: $_"
if ($response -and !$response.HasExited) {
$response.StatusCode = 500
$response.Close()
}
}
}
[Unit]
Description=GitHub Webhook Listener Service
After=network.target
[Service]
ExecStart=/opt/microsoft/powershell/7/pwsh -NoProfile -File /cicd/Update-and-BuildProject.ps1 -refBranch '*YOUR_BRANCH*'
WorkingDirectory=/cicd
Restart=on-failure
RestartSec=10
StartLimitInterval=0
StartLimitBurst=5
User=*YOUR_USER*
EnvironmentFile=/root/gatewaysettings.env
[Install]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment