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
53 changes: 53 additions & 0 deletions .github/scripts/validate-unity-distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
import re
import subprocess
import sys
from pathlib import Path

Expand All @@ -10,6 +11,11 @@
DEMO = ROOT / "examples/demo"
BOOTSTRAP = ROOT / "examples/demo/Assets/OneSignal"
SAMPLE = ROOT / "com.onesignal.unity.core/Samples~"
PACKAGES = (
"com.onesignal.unity.android",
"com.onesignal.unity.core",
"com.onesignal.unity.ios",
)
INVENTORY = BOOTSTRAP / "Editor/Resources/OneSignalFileInventory.asset"

EXCLUDED_PREFIXES = (
Expand Down Expand Up @@ -64,6 +70,52 @@ def validate_inventory() -> None:
)


def is_unity_hidden(part: str) -> bool:
return part.startswith(".") or part.endswith("~")


def packed_files(package: str) -> list[str]:
output = subprocess.run(
["npm", "pack", "--dry-run", "--json", "--ignore-scripts"],
cwd=ROOT / package,
check=True,
capture_output=True,
text=True,
).stdout
return [entry["path"] for entry in json.loads(output)[0]["files"]]


def validate_package_metas() -> None:
# UPM packages are immutable, so Unity ignores any asset that ships without a valid .meta.
guids: dict[str, str] = {}
for package in PACKAGES:
packed = set(packed_files(package))

assets = set()
for path in packed:
if path.endswith(".meta"):
continue
parts = path.split("/")
if any(is_unity_hidden(part) for part in parts):
continue
assets.add(path)
assets.update("/".join(parts[:i]) for i in range(1, len(parts)))

missing = sorted(f"{package}/{asset}.meta" for asset in assets if f"{asset}.meta" not in packed)
if missing:
fail(f"packed assets are missing .meta files: {', '.join(missing)}")

for meta in sorted(f"{asset}.meta" for asset in assets):
path = f"{package}/{meta}"
match = re.search(r"^guid:\s*([0-9a-f]{32})\s*$", (ROOT / path).read_text(), re.MULTILINE)
if match is None:
fail(f"{path} has no valid guid")
guid = match.group(1)
if guid in guids:
fail(f"{path} reuses guid {guid} from {guids[guid]}")
guids[guid] = path


def validate_sample() -> None:
for filename, expected_guid in REQUIRED_SAMPLE_GUIDS.items():
path = SAMPLE / filename
Expand Down Expand Up @@ -111,6 +163,7 @@ def main() -> None:
if not (BOOTSTRAP / "Documentation").is_dir():
fail("exportable bootstrap documentation is missing")
validate_inventory()
validate_package_metas()
validate_sample()
print("Unity distribution layout is valid.")

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
run: |
echo "Tag from output: [${{ steps.npm-tag.outputs.tag }}]"

- name: Validate Unity distribution layout
run: python3 .github/scripts/validate-unity-distribution.py

- name: Publish packages
run: |
publish_pkg() {
Expand Down
2 changes: 2 additions & 0 deletions com.onesignal.unity.core/Runtime/InputGuard.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading