mirror of
https://github.com/sinbad/UEScripts.git
synced 2025-02-23 13:15:23 +00:00
Started work on packaging script, still WIP
This commit is contained in:
parent
f0bbab4c79
commit
8d78f7b225
24
ReadMe.md
24
ReadMe.md
@ -2,8 +2,15 @@
|
||||
|
||||
## Summary
|
||||
|
||||
These scripts are to help me set up Git / Subversion repositories for UE4 without
|
||||
having to remember everything.
|
||||
These scripts are to help me with various repetetive or easy-to-forget tasks
|
||||
related to [Unreal Engine 4](https://www.unrealengine.com).
|
||||
|
||||
* [Setting up a project for Git / Git-LFS](#git-setup)
|
||||
* [Packaging Builds](#packaging-builds)
|
||||
* [Releasing builds to Itch, Steam](#releasing-builds)
|
||||
|
||||
|
||||
## Git Setup
|
||||
|
||||
Initially we'd decided to go back to Subversion because of the importance of
|
||||
good locking workflow for uasset/umap files in UE4, to prevent binary merge errors.
|
||||
@ -26,7 +33,7 @@ We use a particular content workflow:
|
||||
|
||||
Together the scripts below configure everything so I don't have to remember.
|
||||
|
||||
## Steps to set up Git + LFS for a UE4 project
|
||||
### Steps to set up Git + LFS for a UE4 project
|
||||
|
||||
1. The script works for projects with no git repo yet, or those with an existing git repo
|
||||
1. For existing repos, ideally you will not have committed any large files to Git yet
|
||||
@ -39,7 +46,16 @@ Together the scripts below configure everything so I don't have to remember.
|
||||
1. Push ALL BRANCHES of this new repo to the host of your choice
|
||||
|
||||
|
||||
# Subversion Information (ignore below if using Git)
|
||||
## Packaging builds
|
||||
|
||||
.. TODO
|
||||
|
||||
## Releasing Builds
|
||||
|
||||
.. TODO
|
||||
|
||||
|
||||
# LEGACY: Subversion Information (ignore below if using Git)
|
||||
|
||||
## Steps to create a new SVN repo for a UE4 project
|
||||
|
||||
|
117
inc/packageconfig.ps1
Normal file
117
inc/packageconfig.ps1
Normal file
@ -0,0 +1,117 @@
|
||||
|
||||
class PackageVariant {
|
||||
# Name of the variant (can be anything)
|
||||
[string]$Name
|
||||
# Platform name (must be one supported by Unreal e.g. Win64)
|
||||
[string]$Platform
|
||||
# Configuration name i.e. Development, Shipping
|
||||
[string]$Configuration
|
||||
# Additional arguments to send to the build command line
|
||||
[string]$ExtraBuildArguments
|
||||
# Whether to create a zip of this package (default false)
|
||||
[bool]$Zip
|
||||
# The Steam application ID, if you intend to send this variant to Steam
|
||||
[string]$SteamAppId
|
||||
# The Steam depot ID, if you intend to send this variant to Steam
|
||||
[string]$SteamDepotId
|
||||
# Steam login to use to deploy to Steam (if you haven't cached your credential already you'll get a login prompt)
|
||||
[string]$SteamLogin
|
||||
# Itch application identifier e.g. your-account/game-name, if you intend to send this variant to Itch
|
||||
[string]$ItchAppId
|
||||
# Itch channel, if you intend to send this variant to Itch (usually a platform)
|
||||
[string]$ItchChannel
|
||||
|
||||
PackageVariant() {
|
||||
$this.Configuration = "Development"
|
||||
$this.Zip = $false
|
||||
}
|
||||
PackageVariant([PSCustomObject]$obj) {
|
||||
$this.Configuration = "Development"
|
||||
$this.Zip = $false
|
||||
|
||||
# Override just properties that are set
|
||||
$obj.PSObject.Properties | ForEach-Object {
|
||||
try {
|
||||
$this.$($_.Name) = $_.Value
|
||||
} catch {
|
||||
Write-Host "Invalid property for package variant: $($_.Name) = $($_.Value)"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
# Our config for both building and releasing
|
||||
# Note that environment variables also have an effect:
|
||||
# - UE4INSTALL: a specific UE install to use (default blank, find a version in UE4ROOT)
|
||||
# - UE4ROOT: Parent folder of all binary UE4 installs (default C:\Program Files\Epic Games)
|
||||
class PackageConfig {
|
||||
# The root of the folder structure which will contain packaged output
|
||||
# Will be structured $OutputDir/$version/$variant
|
||||
# If relative, will be considered relative to source folder
|
||||
[string]$OutputDir
|
||||
# Folder to place zipped releases (named $target_$platform_$variant_$version.zip)
|
||||
# If relative, will be considered relative to source folder
|
||||
[string]$ZipDir
|
||||
# Target name: this will usually be the name of your game
|
||||
[string]$Target
|
||||
# Whether to cook all maps (default true)
|
||||
[bool]$CookAllMaps
|
||||
# If CookAllMaps=false, list the map names you want to cook
|
||||
[array]$MapsIncluded
|
||||
# If CookAllMaps=true, list the map names you want to exclude from cooking
|
||||
[array]$MapsExcluded
|
||||
# Whether to combine assets into a pak file (default true)
|
||||
[bool]$UsePak
|
||||
# Whether to compress the pak file (default false since deployments often compress & can detect diffs better)
|
||||
[bool]$CompressPak
|
||||
# List of PackageVariant entries
|
||||
[array]$Variants
|
||||
# Names of the default variant(s) to package / release if unspecified
|
||||
[array]$DefaultVariants
|
||||
|
||||
PackageConfig([PSCustomObject]$obj) {
|
||||
# Construct from JSON object
|
||||
$this.CookAllMaps = $true
|
||||
$this.UsePak = $true
|
||||
$this.CompressPak = $false
|
||||
$this.Variants = @()
|
||||
|
||||
# Override just properties that are set
|
||||
$obj.PSObject.Properties | ForEach-Object {
|
||||
if ($_.Name -ne "Variants") {
|
||||
try {
|
||||
# Nested array dealt with below
|
||||
$this.$($_.Name) = $_.Value
|
||||
} catch {
|
||||
Write-Host "Invalid property in root package config: $($_.Name) = $($_.Value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this.Variants = $obj.Variants | ForEach-Object {
|
||||
[PackageVariant]::New($_)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
# Read packageconfig.json file from a source location and return PackageConfig instance
|
||||
function Read-Package-Config {
|
||||
param (
|
||||
[string]$srcfolder
|
||||
)
|
||||
|
||||
Write-Host "Hello!!!"
|
||||
|
||||
$configfile = Resolve-Path "$srcfolder\packageconfig.json"
|
||||
if (-not (Test-Path $configfile -PathType Leaf)) {
|
||||
throw "$srcfolder\packageconfig.json does not exist!"
|
||||
}
|
||||
|
||||
$obj = (Get-Content $configfile) | ConvertFrom-Json
|
||||
|
||||
return [PackageConfig]::New($obj)
|
||||
|
||||
}
|
96
inc/projectversion.ps1
Normal file
96
inc/projectversion.ps1
Normal file
@ -0,0 +1,96 @@
|
||||
Import-Module PsIni
|
||||
|
||||
function Get-Project-Version-Ini-Filename {
|
||||
return Join-Path $srcfolder "Config/DefaultGame.ini" -Resolve
|
||||
}
|
||||
|
||||
function Get-Project-Version {
|
||||
param (
|
||||
[string]$srcfolder
|
||||
)
|
||||
|
||||
$file = Get-Project-Version-Ini-Filename
|
||||
$gameIni = Get-IniContent $file
|
||||
|
||||
return $gameIni["/Script/EngineSettings.GeneralProjectSettings"].ProjectVersion
|
||||
|
||||
}
|
||||
function Increment-Project-Version {
|
||||
|
||||
param (
|
||||
[string]$srcfolder,
|
||||
[bool]$major,
|
||||
[bool]$minor,
|
||||
[bool]$patch,
|
||||
[bool]$hotfix,
|
||||
[bool]$dryrun = $false
|
||||
)
|
||||
|
||||
if (($major + $minor + $patch + $hotfix) -gt 1) {
|
||||
throw "Can't set more than one of major/minor/patch/hotfix at the same time!"
|
||||
}
|
||||
|
||||
$gameIniFile = Get-Project-Version-Ini-Filename
|
||||
$gameIni = Get-IniContent $gameIniFile
|
||||
|
||||
Write-Verbose "[version++] M:$major m:$minor p:$patch h:$hotfix"
|
||||
|
||||
# We have to use Write-Verbose now that we're using the return value, Write-Output
|
||||
# appends to the return value. Write-Verbose works but doesn't appear by default
|
||||
# Unless user sets $VerbosePreference="Continue"
|
||||
|
||||
# Bump the version number of the build
|
||||
Write-Verbose "[inc_version] Updating $gameIniFile"
|
||||
|
||||
$versionString = $gameIni["/Script/EngineSettings.GeneralProjectSettings"].ProjectVersion
|
||||
Write-Verbose "[version++] Current version is $versionString"
|
||||
|
||||
# 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 = $versionString | 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($major) {
|
||||
$intversions[0]++
|
||||
} elseif ($minor) {
|
||||
$intversions[1]++
|
||||
} elseif ($patch) {
|
||||
$intversions[2]++
|
||||
} else {
|
||||
$intversions[3]++
|
||||
}
|
||||
$newver = "$prefix$($intversions[0]).$($intversions[1]).$($intversions[2]).$($intversions[3])$postfix"
|
||||
Write-Verbose "[version++] Bumping version to $newver"
|
||||
|
||||
if ($dryrun) {
|
||||
Write-Verbose "[version++] dryrun: not changing $gameIniFile"
|
||||
} else {
|
||||
$gameIni["/Script/EngineSettings.GeneralProjectSettings"].ProjectVersion = $newver
|
||||
Out-IniFile -Force -InputObject $gameIni -FilePath $gameIniFile
|
||||
Write-Verbose "[version++] Success! Version is now $newver"
|
||||
}
|
||||
|
||||
return "$newver"
|
||||
|
||||
} else {
|
||||
throw "[version++] Error: unable to read current version"
|
||||
}
|
||||
}
|
||||
|
51
packageconfig_template.json
Normal file
51
packageconfig_template.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"OutputDir": "/Path/To/Output/Parent/Dir",
|
||||
"ZipDir": "/Path/To/Zipped/Releases/Folder",
|
||||
|
||||
"Target": "GameName",
|
||||
"CookAllMaps": true,
|
||||
"MapsIncluded": [
|
||||
],
|
||||
"MapsExcluded": [
|
||||
],
|
||||
"UsePak": true,
|
||||
"CompressPak": false,
|
||||
|
||||
|
||||
"Variants": [
|
||||
{
|
||||
"Name": "PublicWin64SteamBuild",
|
||||
"Platform": "Win64",
|
||||
"Configuration": "Shipping",
|
||||
"SteamAppId": "YourSteamAppId",
|
||||
"SteamDepotId": "YourWindowsDepotId",
|
||||
"Zip": false,
|
||||
"ExtraBuildArguments": "-EnableSteamworks"
|
||||
},
|
||||
{
|
||||
"Name": "PublicWin64Build",
|
||||
"Platform": "Win64",
|
||||
"Configuration": "Shipping",
|
||||
"ItchAppId": "itch-user/app-name",
|
||||
"ItchChannel": "win64",
|
||||
"Zip": false
|
||||
},
|
||||
{
|
||||
"Name": "PrivateWin64Build",
|
||||
"Platform": "Win64",
|
||||
"Configuration": "Development",
|
||||
"ItchAppId": "itch-user/private-app-name",
|
||||
"ItchChannel": "win64-dev",
|
||||
"Zip": true,
|
||||
"ExtraBuildArguments": "-Foo=Bar -Something"
|
||||
}
|
||||
],
|
||||
|
||||
"DefaultVariants": [
|
||||
"PrivateWin64Build"
|
||||
],
|
||||
|
||||
"SteamLogin": "YourSteamReleaseUser"
|
||||
}
|
||||
|
||||
|
170
ue4-package.ps1
Normal file
170
ue4-package.ps1
Normal file
@ -0,0 +1,170 @@
|
||||
[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]$noversionbump = $false,
|
||||
# Force move tag
|
||||
[switch]$forcetag = $false,
|
||||
# Name of variant to build (optional, uses DefaultVariants from packageconfig.json if unspecified)
|
||||
[array]$variant,
|
||||
# Testing mode; skips clean checks, tags
|
||||
[switch]$test = $false,
|
||||
# Dry-run; does nothing but report what *would* have happened
|
||||
[switch]$dryrun = $false,
|
||||
[switch]$help = $false
|
||||
)
|
||||
|
||||
. $PSScriptRoot\inc\packageconfig.ps1
|
||||
. $PSScriptRoot\inc\projectversion.ps1
|
||||
|
||||
|
||||
function Write-Usage {
|
||||
Write-Output "Steve's UE4 packaging tool"
|
||||
Write-Output "Usage:"
|
||||
Write-Output " ue4-package.ps1 [-src:sourcefolder] [-major|-minor|-patch|-hotfix] [-keepversion] [-force] [-variant=VariantName] [-test] [-dryrun]"
|
||||
Write-Output " "
|
||||
Write-Output " -src : Source folder (current folder if omitted), must contain buildconfig.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 " -variant=Name : Build only a named variant instead of DefaultVariants from packageconfig.json"
|
||||
Write-Output " -test : Testing mode, separate builds, allow dirty working copy"
|
||||
Write-Output " -dryrun : Don't perform any actual actions, just report on what you would do"
|
||||
Write-Output " -help : Print this help"
|
||||
}
|
||||
|
||||
if ($src.Length -eq 0) {
|
||||
$src = "."
|
||||
Write-Verbose "-src not specified, assuming current directory"
|
||||
}
|
||||
|
||||
# Import config
|
||||
$config = Read-Package-Config -srcfolder:$src
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Write-Output "~-~-~ UE4 Packaging Helper Start ~-~-~"
|
||||
|
||||
if ($help) {
|
||||
Write-Usage
|
||||
Exit 0
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
Write-Output "Package configuration:"
|
||||
Write-Output $config
|
||||
|
||||
try {
|
||||
if (([bool]$major + [bool]$minor + [bool]$patch + [bool]$hotfix) -eq 0) {
|
||||
$patch = $true
|
||||
}
|
||||
$mainver = $null
|
||||
if ($keepversion) {
|
||||
$mainver = Get-Project-Version $src
|
||||
} else {
|
||||
# Bump up version, passthrough options
|
||||
try {
|
||||
$mainver = Increment-Project-Version -srcfolder:$src -major:$major -minor:$minor -patch:$patch -hotfix:$hotfix -dryrun:$dryrun
|
||||
if (-not $dryrun -and $isGit) {
|
||||
if ($src -ne ".") { Push-Location $src }
|
||||
|
||||
$verIniFile = Get-Project-Version-Ini-Filename
|
||||
git add "$($verIniFile)"
|
||||
if ($LASTEXITCODE -ne 0) { Exit $LASTEXITCODE }
|
||||
git commit -m "Version bump to $mainver"
|
||||
if ($LASTEXITCODE -ne 0) { Exit $LASTEXITCODE }
|
||||
|
||||
if ($src -ne ".") { Pop-Location }
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Output $_.Exception.Message
|
||||
Exit 6
|
||||
}
|
||||
}
|
||||
# Keep test builds separate
|
||||
if ($test) {
|
||||
$mainver = "$mainver-test"
|
||||
}
|
||||
Write-Output "Next version will be: $mainver"
|
||||
|
||||
# For tagging release
|
||||
# We only need to grab the main version once
|
||||
$forcearg = ""
|
||||
if ($forcetag) {
|
||||
$forcearg = "-f"
|
||||
}
|
||||
if (-not $test -and -not $dryrun) {
|
||||
if ($src -ne ".") { Push-Location $src }
|
||||
git tag $forcearg -a $mainver -m "Automated release tag"
|
||||
if ($LASTEXITCODE -ne 0) { Exit $LASTEXITCODE }
|
||||
if ($src -ne ".") { Pop-Location }
|
||||
}
|
||||
|
||||
|
||||
# TODO: actually package something!
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Output $_.Exception.Message
|
||||
Exit 9
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Write-Output "~-~-~ UE4 Packaging Helper Completed OK ~-~-~"
|
Loading…
x
Reference in New Issue
Block a user