Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 76 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@ jobs:
uses: actions/checkout@v6
with:
repository: metyatech/RuntimeAssetImportSample
ref: b4c78058993e68a62fc9c16b673aec65ee668573
path: RuntimeAssetImportSample
fetch-depth: 0
submodules: recursive

- name: Checkout Fab release tools
uses: actions/checkout@v6
with:
repository: metyatech/fab-plugin-release-tools
ref: de784111d9e88a3e13205494aa56ccb12a8740f3
path: fab-plugin-release-tools
fetch-depth: 1

- name: Link plugin into test project
shell: powershell
run: |
Expand Down Expand Up @@ -57,4 +66,70 @@ jobs:
- name: Validate Fab package
shell: powershell
working-directory: RuntimeAssetImportPlugin
run: pwsh -NoProfile -File .\PackageForFab.ps1 -EngineVersion 5.4
run: |
$releaseOutput = Join-Path $env:RUNNER_TEMP 'RuntimeAssetImport-Fab-UE5.4'
$runnerTempRoot = [System.IO.Path]::GetFullPath($env:RUNNER_TEMP).TrimEnd('\', '/')
$resolvedReleaseOutput = [System.IO.Path]::GetFullPath($releaseOutput).TrimEnd('\', '/')
if ($resolvedReleaseOutput.Equals($runnerTempRoot, [System.StringComparison]::OrdinalIgnoreCase) -or
-not $resolvedReleaseOutput.StartsWith($runnerTempRoot + [System.IO.Path]::DirectorySeparatorChar,
[System.StringComparison]::OrdinalIgnoreCase)) {
throw "Refusing to use release output outside RUNNER_TEMP: $resolvedReleaseOutput"
}
if ([System.IO.Directory]::Exists($resolvedReleaseOutput)) {
foreach ($file in [System.IO.Directory]::EnumerateFiles($resolvedReleaseOutput, '*',
[System.IO.SearchOption]::AllDirectories)) {
[System.IO.File]::SetAttributes($file, [System.IO.FileAttributes]::Normal)
}
[System.IO.Directory]::Delete($resolvedReleaseOutput, $true)
}
[void][System.IO.Directory]::CreateDirectory($resolvedReleaseOutput)

pwsh -NoProfile -File .\PackageForFab.ps1 `
-EngineVersion 5.4 `
-ReleaseToolsRoot (Join-Path $env:GITHUB_WORKSPACE 'fab-plugin-release-tools') `
-OutputDirectory $resolvedReleaseOutput
if ($LASTEXITCODE -ne 0) {
throw "PackageForFab.ps1 failed with exit code $LASTEXITCODE"
}

$zipFiles = @([System.IO.Directory]::GetFiles($resolvedReleaseOutput, '*.zip',
[System.IO.SearchOption]::TopDirectoryOnly))
$checksumFiles = @([System.IO.Directory]::GetFiles($resolvedReleaseOutput, '*.zip.sha256',
[System.IO.SearchOption]::TopDirectoryOnly))
$reportFiles = @([System.IO.Directory]::GetFiles($resolvedReleaseOutput, '*.zip.report.json',
[System.IO.SearchOption]::TopDirectoryOnly))
$logFiles = @([System.IO.Directory]::GetFiles($resolvedReleaseOutput, '*.zip.log',
[System.IO.SearchOption]::TopDirectoryOnly))
if ($zipFiles.Count -ne 1 -or $checksumFiles.Count -ne 1 -or
$reportFiles.Count -ne 1 -or $logFiles.Count -ne 1) {
throw 'Fab release output must contain exactly one ZIP and each of its three sidecars.'
}
$zipPath = $zipFiles[0]
$zipName = [System.IO.Path]::GetFileName($zipPath)
$pluginHead = (git -C (Join-Path $env:GITHUB_WORKSPACE 'RuntimeAssetImportPlugin') rev-parse HEAD).Trim()
if ($LASTEXITCODE -ne 0) { throw 'Could not read the CI plugin checkout HEAD.' }
$report = Get-Content -Raw -LiteralPath $reportFiles[0] | ConvertFrom-Json
if ($report.status -cne 'PASS' -or [string]$report.toolVersion -cne '0.3.1' -or
[string]$report.repositoryHead -cne $pluginHead -or
@($report.gates).Count -ne 12 -or
@($report.gates | Where-Object { $_.status -cne 'PASS' }).Count -ne 0) {
throw 'Fab release report failed the CI contract checks.'
}
$actualHash = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
$checksumText = [System.IO.File]::ReadAllText($checksumFiles[0]).TrimEnd("`r", "`n")
$checksumMatch = [System.Text.RegularExpressions.Regex]::Match(
$checksumText, '^(?<Hash>[0-9a-f]{64}) (?<Name>[^\r\n]+)$')
if (-not $checksumMatch.Success -or $checksumMatch.Groups['Hash'].Value -cne $actualHash -or
$checksumMatch.Groups['Name'].Value -cne $zipName) {
throw 'Fab release checksum sidecar does not match the generated ZIP.'
}
if ([System.IO.Path]::GetFileName([string]$report.outputZip) -cne $zipName) {
throw 'Fab release report outputZip does not match the generated ZIP.'
}

- name: Upload Fab release artifacts
uses: actions/upload-artifact@v7
with:
name: RuntimeAssetImport-Fab-UE5.4
path: ${{ runner.temp }}/RuntimeAssetImport-Fab-UE5.4/*
if-no-files-found: error
112 changes: 112 additions & 0 deletions FabPluginRelease.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"schemaVersion": 1,
"pluginName": "RuntimeAssetImport",
"descriptorFile": "RuntimeAssetImport.uplugin",
"engineVersions": [
"5.4",
"5.5",
"5.7",
"5.8"
],
"platforms": [
"Win64"
],
"distributionModules": [
"RuntimeAssetImport"
],
"enabledPluginDependencies": [
"ProceduralMeshComponent"
],
"publisher": {
"name": "metyatech",
"url": "https://github.com/metyatech",
"copyrightNotice": "// Copyright (c) 2026 metyatech. All rights reserved."
},
"sourceCopyrightOverrides": [
{
"path": "Source/RuntimeAssetImport/Private/RuntimeAssetImport.cpp",
"notices": [
"// Copyright Epic Games, Inc. All Rights Reserved.",
"// Copyright (c) 2026 metyatech. All rights reserved."
]
},
{
"path": "Source/RuntimeAssetImport/Public/RuntimeAssetImport.h",
"notices": [
"// Copyright Epic Games, Inc. All Rights Reserved.",
"// Copyright (c) 2026 metyatech. All rights reserved."
]
}
],
"listingId": "19cb2daa-b018-46ae-b28c-7bfe21075c4a",
"documentationUrl": "https://metyatech.github.io/unreal-plugin-docs/runtime-asset-import/",
"supportUrl": "https://github.com/metyatech/RuntimeAssetImportPlugin/issues",
"content": {
"mode": "plugin"
},
"includeDirectories": [
"Config",
"Content",
"Resources",
"Source/RuntimeAssetImport",
"Source/ThirdParty/assimp"
],
"includeFiles": [
"RuntimeAssetImport.uplugin",
"README.md",
"LICENSE",
"THIRD_PARTY_NOTICES.md"
],
"requiredPackageFiles": [
"RuntimeAssetImport.uplugin",
"Config/FilterPlugin.ini",
"Content/AssetImporterMeshMaterial.uasset",
"Resources/Icon128.png",
"Source/RuntimeAssetImport/RuntimeAssetImport.Build.cs",
"Source/ThirdParty/assimp/assimp.Build.cs",
"Source/ThirdParty/assimp/BUILD-INFO.json",
"Source/ThirdParty/assimp/LICENSE",
"Source/ThirdParty/assimp/Bin/Win64/assimp-vc143-mt.dll",
"Source/ThirdParty/assimp/Lib/Win64/assimp-vc143-mt.lib",
"README.md",
"LICENSE",
"THIRD_PARTY_NOTICES.md"
],
"customDistributionPaths": [
"README.md",
"LICENSE",
"THIRD_PARTY_NOTICES.md"
],
"thirdPartyLicenseSets": [
{
"root": "Source/ThirdParty/assimp/LICENSES",
"files": [
"assimp/LICENSE",
"contrib/Open3DGC/LICENSE.txt",
"contrib/clipper/License.txt",
"contrib/earcut-hpp/LICENSE",
"contrib/openddlparser/LICENSE",
"contrib/poly2tri/LICENSE",
"contrib/pugixml/LICENSE.md",
"contrib/rapidjson/license.txt",
"contrib/stb/LICENSE.txt",
"contrib/unzip/MiniZip64_info.txt",
"contrib/utf8cpp/doc/LICENSE",
"contrib/zlib/LICENSE"
]
}
],
"forbiddenPackagePatterns": [
"^Source/RuntimeAssetImportTest(?:/|$)",
"^(BuildAssimpForPlugin\\.ps1|PackageForFab\\.ps1|RunPackagedSmoke\\.ps1|MarketplaceListing\\.md|FabSubmissionChecklist\\.md|LICENSE-MIT-LEGACY)$",
"^Tests(?:/|$)",
"^Source/ThirdParty/assimp/LICENSES/contrib/draco(?:/|$)",
"^Source/ThirdParty/assimp/LICENSES/contrib/googletest(?:/|$)",
"^Source/ThirdParty/assimp/LICENSES/packaging(?:/|$)",
"^Source/ThirdParty/assimp/LICENSES/port(?:/|$)",
"^Source/ThirdParty/assimp/LICENSES/test(?:/|$)",
"^Source/ThirdParty/assimp/LICENSES/contrib/zlib/contrib/dotzlib(?:/|$)",
"(^|/)assimp\\.exe$"
],
"buildLogFailPatterns": []
}
12 changes: 8 additions & 4 deletions FabSubmissionChecklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,20 @@
- [x] Process-CWD-independent relative path resolution
- [x] Auxiliary hard-link rejection
- [x] Quaternion validity validation
- [x] FabPluginRelease.json validated by fab-plugin-release-tools 0.3.1
- [x] Repository-specific ZIP implementation replaced by pinned central release pipeline
- [x] Deterministic ZIP, SHA-256, JSON report, and release log generated
- [x] Direct ZIP inspection, safe extraction, and manifest comparison pass

## Unreal Engine Package Matrix

- [x] UE 5.4 Automation Tests
- [x] UE 5.4 `PackageForFab.ps1`
- [x] UE 5.4 central Fab release pipeline, Automation Tests, and `BuildPlugin`
- [x] UE 5.4 `BuildPlugin` Win64 Rocket build
- [x] UE 5.5 Automation Tests, Fab package validation, and `BuildPlugin`
- [x] UE 5.5 Automation Tests, central Fab package validation, and `BuildPlugin`
- [ ] UE 5.6 Automation Tests, Fab package validation, and `BuildPlugin` — Stock UE 5.6.1 verification failed; no engine files were modified.
- [x] UE 5.7 Automation Tests, Fab package validation, and `BuildPlugin`
- [x] UE 5.8 Automation Tests, Fab package validation, and `BuildPlugin`
- [x] UE 5.7 Automation Tests, central Fab package validation, and `BuildPlugin`
- [x] UE 5.8 Automation Tests, central Fab package validation, and `BuildPlugin`

## Packaged Shipping Smoke

Expand Down
Loading
Loading