From b275fbacedc3648e43459f8ff9b60346b92a3167 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Mon, 31 Jan 2022 10:54:10 -0600 Subject: [PATCH] create update script for managing updates programatically ./UpdateIW4MAdmin.sh or ./UpdateIW4MAdmin.ps1 Co-authored-by: xerxes-at --- Application/BuildScripts/PostPublish.bat | 4 + DeploymentFiles/UpdateIW4MAdmin.ps1 | 118 +++++++++++++++++++++++ DeploymentFiles/UpdateIW4MAdmin.sh | 103 ++++++++++++++++++++ DeploymentFiles/deployment-pipeline.yml | 1 + IW4MAdmin.sln | 2 + README.md | 11 +++ 6 files changed, 239 insertions(+) create mode 100644 DeploymentFiles/UpdateIW4MAdmin.ps1 create mode 100644 DeploymentFiles/UpdateIW4MAdmin.sh diff --git a/Application/BuildScripts/PostPublish.bat b/Application/BuildScripts/PostPublish.bat index e6c5d036f..fec05fb72 100644 --- a/Application/BuildScripts/PostPublish.bat +++ b/Application/BuildScripts/PostPublish.bat @@ -47,6 +47,10 @@ echo making start scripts @(echo @echo off && echo @title IW4MAdmin && echo set DOTNET_CLI_TELEMETRY_OPTOUT=1 && echo dotnet Lib\IW4MAdmin.dll && echo pause) > "%PublishDir%\StartIW4MAdmin.cmd" @(echo #!/bin/bash&& echo export DOTNET_CLI_TELEMETRY_OPTOUT=1&& echo dotnet Lib/IW4MAdmin.dll) > "%PublishDir%\StartIW4MAdmin.sh" +echo copying update scripts +xcopy "%SourceDir%\UpdateIW4MAdmin.ps1" "%PublishDir%\UpdateIW4MAdmin.ps1" +xcopy "%SourceDir%\UpdateIW4MAdmin.sh" "%PublishDir%\UpdateIW4MAdmin.sh" + echo moving front-end library dependencies if not exist "%PublishDir%\wwwroot\font" mkdir "%PublishDir%\wwwroot\font" move "WebfrontCore\wwwroot\lib\open-iconic\font\fonts\*.*" "%PublishDir%\wwwroot\font\" diff --git a/DeploymentFiles/UpdateIW4MAdmin.ps1 b/DeploymentFiles/UpdateIW4MAdmin.ps1 new file mode 100644 index 000000000..a3964412b --- /dev/null +++ b/DeploymentFiles/UpdateIW4MAdmin.ps1 @@ -0,0 +1,118 @@ +param ( + [Parameter(HelpMessage = "Do not prompt for any user input")] + [switch]$Silent = $False, + + [Parameter(HelpMessage = "Clean unneeded files listed in _delete.txt after update")] + [switch]$Clean = $False, + + [Parameter(HelpMessage = "Only update releases in the verified stream")] + [switch]$Verified = $False, + + [Parameter(HelpMessage = "Directory to install to")] + [ValidateScript({ + if (-Not($_ | Test-Path)) + { + throw "File or folder does not exist" + } return $true + })] + [System.IO.FileInfo]$Directory +) + +Write-Output "=======================================" +Write-Output " IW4MAdmin Updater v1 " +Write-Output " by XERXES & RaidMax " +Write-Output "=======================================" + +$stopwatch = [system.diagnostics.stopwatch]::StartNew() +$repoName = "RaidMax/IW4M-Admin" +$assetPattern = "IW4MAdmin-20*.zip" + +if ($Verified) +{ + $releasesUri = "https://api.github.com/repos/$repoName/releases/latest" +} + +else +{ + $releasesUri = "https://api.github.com/repos/$repoName/releases" +} + +Write-Output "Retrieving latest version info..." + +$releaseInfo = (Invoke-WebRequest $releasesUri | ConvertFrom-Json) | Select -First 1 +$asset = $releaseInfo.assets | Where-Object name -like $assetPattern | Select -First 1 +$downloadUri = $asset.browser_download_url +$filename = Split-Path $downloadUri -leaf + +Write-Output "The latest version is $( $releaseInfo.tag_name ) released $( $releaseInfo.published_at )" + +if (!$Silent) +{ + $stopwatch.Stop() + Write-Warning "All IW4MAdmin files will be updated. Your database and configuration will not be modified. Are you sure you want to continue?" -WarningAction Inquire + $stopwatch.Start() +} + +Write-Output "Downloading update. This might take a moment..." + +$fileDownload = Invoke-WebRequest -Uri $downloadUri +if ($fileDownload.StatusDescription -ne "OK") +{ + throw "Could not update IW4MAdmin. ($fileDownload.StatusDescription)" +} + +$remoteHash = $fileDownload.Headers['Content-MD5'] +$decodedHash = [System.BitConverter]::ToString([System.Convert]::FromBase64String($remoteHash)).replace('-', '') +$directoryPath = Get-Location +$fullPath = "$directoryPath\$filename" +$outputFile = [System.IO.File]::Open($fullPath, 2) +$stream = [System.IO.BinaryWriter]::new($outputFile) + +if ($Directory) +{ + $outputDir = $Directory +} + +else +{ + $outputDir = Get-Location +} + +try +{ + $stream.Write($fileDownload.Content) +} +finally +{ + $stream.Dispose() + $outputFile.Dispose() +} + +$localHash = (Get-FileHash -Path $fullPath -Algorithm MD5).Hash + +if ($localHash -ne $decodedHash) +{ + throw "Failed to update. File hashes don't match!" +} + +Write-Output "Extracting $filename to $outputDir" +Expand-Archive -Path $fullPath -DestinationPath $outputDir -Force + +if ($Clean) +{ + Write-Output "Running post-update clean..." + $DeleteList = Get-Content -Path ./_delete.txt + ForEach ($file in $DeleteList) + { + Write-Output "Deleting $file" + Remove-Item -Path $file + } +} + +Write-Output "Removing temporary files..." +Remove-Item -Force $fullPath + +$stopwatch.Stop() +$executionTime = [math]::Round($stopwatch.Elapsed.TotalSeconds, 0) + +Write-Output "Update completed successfully in $executionTime seconds!" diff --git a/DeploymentFiles/UpdateIW4MAdmin.sh b/DeploymentFiles/UpdateIW4MAdmin.sh new file mode 100644 index 000000000..aa823fbf3 --- /dev/null +++ b/DeploymentFiles/UpdateIW4MAdmin.sh @@ -0,0 +1,103 @@ +#!/bin/bash +echo "=======================================" +echo " IW4MAdmin Updater v1 " +echo "=======================================" + +while getopts scvd: flag +do + case "${flag}" in + s) silent='true';; + c) clean='true';; + v) verified='true';; + d) directory=${OPTARG};; + *) exit 1;; + esac +done + +start=$SECONDS +repoName="RaidMax/IW4M-Admin" +releaseUri="https://api.github.com/repos/$repoName/releases" + +echo "Retrieving latest version info..." + +if [ ! "$directory" ] +then + directory=$(pwd) +else + if [ ! -d "$directory" ] + then + mkdir "$directory" + fi +fi + +if [ "$verified" ] +then + releaseUri="https://api.github.com/repos/$repoName/releases/latest" +fi + +releaseInfo=$(curl -s "${releaseUri}") +downloadUri=$(echo "$releaseInfo" | grep "browser_download_url" | cut -d '"' -f 4"" | head -n1) +publishDate=$(echo "$releaseInfo"| grep "published_at" | cut -d '"' -f 4"" | head -n1) +releaseTitle=$(echo "$releaseInfo" | grep "tag_name" | cut -d '"' -f 4"" | head -n1) +filename=$(basename $downloadUri) +fullpath="$directory/$filename" + +echo "The latest version is $releaseTitle released $publishDate" + +if [[ ! "$silent" ]] + then + echo -e "\033[33mAll IW4MAdmin files will be updated.\033[0m" + echo -e "\033[33mYour database and configuration will not be modified.\033[0m" + read -p "Are you sure you want to continue [Y/N]? " -n 1 -r + echo + if ! [[ $REPLY =~ ^[Yy]$ ]] + then + exit 0 + fi +fi + +echo "Downloading update. This might take a moment..." + +wget -q "$downloadUri" -O "$fullpath" + +if [[ $? -ne 0 ]] +then + echo "Could not download update files!" + exit 1 +fi + +echo "Extracting $filename to $directory" + +unzip -o -q "$fullpath" -d "$directory" + +if [[ $? -ne 0 ]] +then + echo "Could not extract update files!" + exit 1 +fi + +if [[ "$clean" ]] +then + echo "Running post-update clean..." + cat "_delete.txt" | while read -r line || [[ -n $line ]]; + do + rm -f "$directory/$line" + if [[ $? -ne 0 ]] + then + echo "Could not clean $directory/$line!" + exit 1 + fi + done +fi + +echo "Removing temporary files..." +rm -f "$fullpath" + +if [[ $? -ne 0 ]] +then + echo "Could not remove update files!" + exit 1 +fi + +executionTime=$(($SECONDS - start)) +echo "Update completed successfully in $executionTime seconds!" diff --git a/DeploymentFiles/deployment-pipeline.yml b/DeploymentFiles/deployment-pipeline.yml index ac5f3ac36..226a14f3b 100644 --- a/DeploymentFiles/deployment-pipeline.yml +++ b/DeploymentFiles/deployment-pipeline.yml @@ -121,6 +121,7 @@ steps: script: | echo changing to encoding for linux start script dos2unix $(outputFolder)\StartIW4MAdmin.sh + dos2unix $(outputFolder\UpdateIW4MAdmin.sh echo creating website version filename @echo IW4MAdmin-$(Build.BuildNumber) > $(Build.ArtifactStagingDirectory)\version_$(releaseType).txt workingDirectory: '$(Build.Repository.LocalPath)\Application\BuildScripts' diff --git a/IW4MAdmin.sln b/IW4MAdmin.sln index 087157f49..68c9e99ec 100644 --- a/IW4MAdmin.sln +++ b/IW4MAdmin.sln @@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution DeploymentFiles\PostPublish.ps1 = DeploymentFiles\PostPublish.ps1 README.md = README.md version.txt = version.txt + DeploymentFiles\UpdateIW4MAdmin.ps1 = DeploymentFiles\UpdateIW4MAdmin.ps1 + DeploymentFiles\UpdateIW4MAdmin.sh = DeploymentFiles\UpdateIW4MAdmin.sh EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedLibraryCore", "SharedLibraryCore\SharedLibraryCore.csproj", "{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}" diff --git a/README.md b/README.md index 59f85cc25..a231637f6 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,22 @@ Linux * You will need to retrieve your login credentials by typing `!rt` ingame ### Updating +**Manually** 1. Download the latest version of **IW4MAdmin** 2. Extract the newer version of **IW4MAdmin** into pre-existing **IW4MAdmin** folder and overwrite existing files _Your configuration and database will be saved_ +**OR** +Use the provided `UpdateIW4MAdmin` script to download and install automatically + +| Argument Windows (Linux) | Description | +|--------------------------|----------------------------------------------------------| +| -Silent (s) | Do not prompt for any user input | +| -Clean (c) | Clean unneeded files listed in `_dlete.txt` after update | +| -Verified (v) | Only update releases in the verified stream | + | -Directory (d) | Directory to install to | + ## Help Feel free to join the **IW4MAdmin** [Discord](https://discord.gg/ZZFK5p3) If you come across an issue, bug, or feature request please post an [issue](https://github.com/RaidMax/IW4M-Admin/issues)