mirror of
https://github.com/sinbad/UEScripts.git
synced 2025-02-23 13:15:23 +00:00
Working on plugin packaging (for marketplace) script
This commit is contained in:
parent
9659b6b8aa
commit
c39b450f86
39
inc/pluginconfig.ps1
Normal file
39
inc/pluginconfig.ps1
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class PluginConfig {
|
||||||
|
[string]$OutputDir
|
||||||
|
|
||||||
|
PluginConfig([PSCustomObject]$obj) {
|
||||||
|
# Construct from JSON object
|
||||||
|
|
||||||
|
# Override just properties that are set
|
||||||
|
$obj.PSObject.Properties | ForEach-Object {
|
||||||
|
try {
|
||||||
|
# Nested array dealt with below
|
||||||
|
$this.$($_.Name) = $_.Value
|
||||||
|
} catch {
|
||||||
|
Write-Host "Invalid property in plugin config: $($_.Name) = $($_.Value)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read pluginconfig.json file from a source location and return PluginConfig instance
|
||||||
|
function Read-Plugin-Config {
|
||||||
|
param (
|
||||||
|
[string]$srcfolder
|
||||||
|
)
|
||||||
|
|
||||||
|
$configfile = Resolve-Path "$srcfolder\pluginconfig.json"
|
||||||
|
if (-not (Test-Path $configfile -PathType Leaf)) {
|
||||||
|
throw "$srcfolder\pluginconfig.json does not exist!"
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj = (Get-Content $configfile) | ConvertFrom-Json
|
||||||
|
|
||||||
|
return [PluginConfig]::New($obj)
|
||||||
|
|
||||||
|
}
|
64
inc/pluginversion.ps1
Normal file
64
inc/pluginversion.ps1
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
function Get-NextPluginVersion {
|
||||||
|
|
||||||
|
param (
|
||||||
|
[string]$currentVersion,
|
||||||
|
[bool]$major,
|
||||||
|
[bool]$minor,
|
||||||
|
[bool]$patch,
|
||||||
|
[bool]$hotfix
|
||||||
|
)
|
||||||
|
|
||||||
|
if (($major + $minor + $patch + $hotfix) -gt 1) {
|
||||||
|
throw "Can't set more than one of major/minor/patch/hotfix at the same time!"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Regex features:
|
||||||
|
# - Can read 2-4 version components but will pad with 0s up to 4 when writing
|
||||||
|
# - captures pre- and post-fix text and retains
|
||||||
|
$regex = "([^\d]*)(\d+)\.(\d+)(?:\.(\d+))?(?:\.(\d+))?(.*)"
|
||||||
|
$matches = $currentVersion | Select-String -Pattern $regex
|
||||||
|
# 1 = prefix
|
||||||
|
# 2-5 = version number components
|
||||||
|
# 6 = postfix
|
||||||
|
if (($matches.Matches.Count -gt 0) -and ($matches.Matches[0].Groups.Count -eq 7)) {
|
||||||
|
$prefix = $matches.Matches[0].Groups[1].Value
|
||||||
|
$postfix = $matches.Matches[0].Groups[6].Value
|
||||||
|
|
||||||
|
$intversions = $matches.Matches[0].Groups[2..5] | ForEach-Object {
|
||||||
|
if ($_.Value -ne "") {
|
||||||
|
[int]$_.Value
|
||||||
|
} else {
|
||||||
|
# We fill in the version numbers to 4 digits always
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$versionDigit = 2;
|
||||||
|
if ($major) {
|
||||||
|
$versionDigit = 0
|
||||||
|
} elseif ($minor) {
|
||||||
|
$versionDigit = 1
|
||||||
|
} elseif ($patch) {
|
||||||
|
$versionDigit = 2
|
||||||
|
} elseif ($hotfix) {
|
||||||
|
$versionDigit = 3
|
||||||
|
}
|
||||||
|
# increment then zero anything after
|
||||||
|
$intversions[$versionDigit]++
|
||||||
|
for ($d = $versionDigit + 1; $d -lt $intversions.Length; $d++) {
|
||||||
|
$intversions[$d] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
$newver = "$prefix$($intversions[0]).$($intversions[1]).$($intversions[2]).$($intversions[3])$postfix"
|
||||||
|
Write-Verbose "[version++] Bumping version to $newver"
|
||||||
|
|
||||||
|
return "$newver"
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw "[version++] Error: unable to read current version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
34
inc/uplugin.ps1
Normal file
34
inc/uplugin.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
. $PSScriptRoot\packageconfig.ps1
|
||||||
|
|
||||||
|
|
||||||
|
function Get-Uplugin-Filename {
|
||||||
|
param (
|
||||||
|
[string]$srcfolder,
|
||||||
|
[PluginConfig]$config
|
||||||
|
)
|
||||||
|
|
||||||
|
$projfile = ""
|
||||||
|
if ($config -and $config.ProjectFile) {
|
||||||
|
if (-not [System.IO.Path]::IsPathRooted($config.ProjectFile)) {
|
||||||
|
$projfile = Join-Path $srcfolder $config.ProjectFile
|
||||||
|
} else {
|
||||||
|
$projfile = Resolve-Path $config.ProjectFile
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $projfile)) {
|
||||||
|
throw "Invalid ProfileFile setting, $($config.ProjectFile) does not exist."
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
# can return multiple results, pick the first one
|
||||||
|
$matchedfile = @(Get-ChildItem -Path $srcfolder -Filter *.uplugin)[0]
|
||||||
|
$projfile = $matchedfile.FullName
|
||||||
|
}
|
||||||
|
|
||||||
|
# Resolve to absolute (do it here and not in join so missing file is friendlier error)
|
||||||
|
if ($projfile) {
|
||||||
|
return Resolve-Path $projfile
|
||||||
|
} else {
|
||||||
|
return $projfile
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,11 @@ function Get-Uproject-Filename {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Resolve to absolute (do it here and not in join so missing file is friendlier error)
|
# Resolve to absolute (do it here and not in join so missing file is friendlier error)
|
||||||
return Resolve-Path $projfile
|
if ($projfile) {
|
||||||
|
return Resolve-Path $projfile
|
||||||
|
} else {
|
||||||
|
return $projfile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read the uproject file and return as a PSCustomObject
|
# Read the uproject file and return as a PSCustomObject
|
||||||
|
8
pluginconfig_template.json
Normal file
8
pluginconfig_template.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"OutputDir": "/Path/To/Output/Parent/Dir",
|
||||||
|
|
||||||
|
"PluginFile": "OptionalPluginFilenameWillDetectInDirOtherwise.uplugin"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
203
ue-plugin-package.ps1
Normal file
203
ue-plugin-package.ps1
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
# Plugin packaging helper
|
||||||
|
# Bumps versions, zips for marketplace
|
||||||
|
# Put pluginconfig.json in your project folder to configure
|
||||||
|
# See pluginconfig_template.json
|
||||||
|
[CmdletBinding()] # Fail on unknown args
|
||||||
|
param (
|
||||||
|
[string]$src,
|
||||||
|
[switch]$major = $false,
|
||||||
|
[switch]$minor = $false,
|
||||||
|
[switch]$patch = $false,
|
||||||
|
[switch]$hotfix = $false,
|
||||||
|
# Don't incrememnt version
|
||||||
|
[switch]$keepversion = $false,
|
||||||
|
# Force move tag
|
||||||
|
[switch]$forcetag = $false,
|
||||||
|
# Testing mode; skips clean checks, tags
|
||||||
|
[switch]$test = $false,
|
||||||
|
# Browse the output directory in file explorer after packaging
|
||||||
|
[switch]$browse = $false,
|
||||||
|
# Dry-run; does nothing but report what *would* have happened
|
||||||
|
[switch]$dryrun = $false,
|
||||||
|
[switch]$help = $false
|
||||||
|
)
|
||||||
|
|
||||||
|
. $PSScriptRoot\inc\platform.ps1
|
||||||
|
. $PSScriptRoot\inc\pluginconfig.ps1
|
||||||
|
. $PSScriptRoot\inc\pluginversion.ps1
|
||||||
|
. $PSScriptRoot\inc\uproject.ps1
|
||||||
|
. $PSScriptRoot\inc\uplugin.ps1
|
||||||
|
. $PSScriptRoot\inc\filetools.ps1
|
||||||
|
|
||||||
|
|
||||||
|
function Write-Usage {
|
||||||
|
Write-Output "Steve's Unreal Plugin packaging tool"
|
||||||
|
Write-Output "Usage:"
|
||||||
|
Write-Output " ue-plugin-package.ps1 [-src:sourcefolder] [-major|-minor|-patch|-hotfix] [-keepversion] [-force] [-test] [-dryrun]"
|
||||||
|
Write-Output " "
|
||||||
|
Write-Output " -src : Source folder (current folder if omitted), must contain pluginconfig.json"
|
||||||
|
Write-Output " -major : Increment major version i.e. [x++].0.0.0"
|
||||||
|
Write-Output " -minor : Increment minor version i.e. x.[x++].0.0"
|
||||||
|
Write-Output " -patch : Increment patch version i.e. x.x.[x++].0 (default)"
|
||||||
|
Write-Output " -hotfix : Increment hotfix version i.e. x.x.x.[x++]"
|
||||||
|
Write-Output " -keepversion : Keep current version number, doesn't tag unless -forcetag"
|
||||||
|
Write-Output " -forcetag : Move any existing version tag"
|
||||||
|
Write-Output " -test : Testing mode, separate builds, allow dirty working copy"
|
||||||
|
Write-Output " -browse : After packaging, browse the output folder"
|
||||||
|
Write-Output " -dryrun : Don't perform any actual actions, just report on what you would do"
|
||||||
|
Write-Output " -help : Print this help"
|
||||||
|
Write-Output " "
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($src.Length -eq 0) {
|
||||||
|
$src = "."
|
||||||
|
Write-Verbose "-src not specified, assuming current directory"
|
||||||
|
}
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
if ($help) {
|
||||||
|
Write-Usage
|
||||||
|
Exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "~-~-~ Unreal Plugin Package Start ~-~-~"
|
||||||
|
|
||||||
|
if ($test) {
|
||||||
|
Write-Output "TEST MODE: No tagging, version bumping"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (([bool]$major + [bool]$minor + [bool]$patch + [bool]$hotfix) -gt 1) {
|
||||||
|
Write-Output "ERROR: Can't set more than one of major/minor/patch/hotfix at the same time!"
|
||||||
|
Print-Usage
|
||||||
|
Exit 5
|
||||||
|
}
|
||||||
|
if (($major -or $minor -or $patch -or $hotfix) -and $keepversion) {
|
||||||
|
Write-Output "ERROR: Can't set keepversion at the same time as major/minor/patch/hotfix!"
|
||||||
|
Print-Usage
|
||||||
|
Exit 5
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect Git
|
||||||
|
if ($src -ne ".") { Push-Location $src }
|
||||||
|
$isGit = Test-Path ".git"
|
||||||
|
if ($src -ne ".") { Pop-Location }
|
||||||
|
|
||||||
|
# Check working copy is clean (Git only)
|
||||||
|
if (-not $test -and $isGit) {
|
||||||
|
if ($src -ne ".") { Push-Location $src }
|
||||||
|
|
||||||
|
if (Test-Path ".git") {
|
||||||
|
git diff --no-patch --exit-code
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Output "Working copy is not clean (unstaged changes)"
|
||||||
|
if ($dryrun) {
|
||||||
|
Write-Output "dryrun: Continuing but this will fail without -dryrun"
|
||||||
|
} else {
|
||||||
|
Exit $LASTEXITCODE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
git diff --no-patch --cached --exit-code
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Output "Working copy is not clean (staged changes)"
|
||||||
|
if ($dryrun) {
|
||||||
|
Write-Output "dryrun: Continuing but this will fail without -dryrun"
|
||||||
|
} else {
|
||||||
|
Exit $LASTEXITCODE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($src -ne ".") { Pop-Location }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Import config & project settings
|
||||||
|
$config = Read-Plugin-Config -srcfolder:$src
|
||||||
|
|
||||||
|
$pluginfile = Get-Uplugin-Filename -srcfolder:$src -config:$config
|
||||||
|
if (-not $pluginfile) {
|
||||||
|
throw "Not in a uplugin dir!"
|
||||||
|
}
|
||||||
|
$proj = Read-Uproject $pluginfile
|
||||||
|
$pluginName = (Get-Item $pluginfile).Basename
|
||||||
|
|
||||||
|
Write-Output ""
|
||||||
|
Write-Output "Plugin File : $pluginfile"
|
||||||
|
Write-Output "Output Folder : $($config.OutputDir)"
|
||||||
|
Write-Output ""
|
||||||
|
|
||||||
|
if (([bool]$major + [bool]$minor + [bool]$patch + [bool]$hotfix) -eq 0) {
|
||||||
|
$patch = $true
|
||||||
|
}
|
||||||
|
$versionNumber = $proj.VersionName
|
||||||
|
if (-not $keepversion) {
|
||||||
|
# Bump up version, passthrough options
|
||||||
|
try {
|
||||||
|
$versionNumber = Get-NextPluginVersion -current:$versionNumber -major:$major -minor:$minor -patch:$patch -hotfix:$hotfix
|
||||||
|
# Save incremented version back to uplugin object (will be saved later)
|
||||||
|
$proj.VersionName = $versionNumber
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Output $_.Exception.Message
|
||||||
|
Exit 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Output "Next version will be: $versionNumber"
|
||||||
|
|
||||||
|
# For tagging release
|
||||||
|
# We only need to grab the main version once
|
||||||
|
if ((-not $keepversion) -or $forcetag) {
|
||||||
|
$forcearg = ""
|
||||||
|
if ($forcetag) {
|
||||||
|
$forcearg = "-f"
|
||||||
|
}
|
||||||
|
if (-not $test -and -not $dryrun -and $isGit) {
|
||||||
|
if ($src -ne ".") { Push-Location $src }
|
||||||
|
git tag $forcearg -a $versionNumber -m "Automated release tag"
|
||||||
|
if ($LASTEXITCODE -ne 0) { Exit $LASTEXITCODE }
|
||||||
|
if ($src -ne ".") { Pop-Location }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: Save .uplugin changes!
|
||||||
|
|
||||||
|
# Zip parent of the uplugin folder
|
||||||
|
$zipsrc = (Get-Item $pluginfile).Directory.FullName
|
||||||
|
$zipdst = Join-Path $config.OutputDir "$($pluginName)_$($versionNumber).zip"
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Path $config.OutputDir -Force > $null
|
||||||
|
Write-Output "Compressing to $zipdst"
|
||||||
|
|
||||||
|
$argList = [System.Collections.ArrayList]@()
|
||||||
|
$argList.Add("a") > $null
|
||||||
|
$argList.Add($zipdst) > $null
|
||||||
|
$argList.Add($zipsrc) > $null
|
||||||
|
|
||||||
|
if ($dryrun) {
|
||||||
|
Write-Output ""
|
||||||
|
Write-Output "Would have run:"
|
||||||
|
Write-Output "> 7z.exe $($argList -join " ")"
|
||||||
|
Write-Output ""
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$proc = Start-Process "7z.exe" $argList -Wait -PassThru -NoNewWindow
|
||||||
|
if ($proc.ExitCode -ne 0) {
|
||||||
|
throw "7-Zip failed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($browse -and -not $dryrun) {
|
||||||
|
Invoke-Item $config.OutputDir
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Output $_.Exception.Message
|
||||||
|
Write-Output "~-~-~ Unreal Plugin Package FAILED ~-~-~"
|
||||||
|
Exit 9
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "~-~-~ Unreal Plugin Package Completed OK ~-~-~"
|
Loading…
x
Reference in New Issue
Block a user