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
73 changes: 73 additions & 0 deletions .github/scripts/audience/check-package-meta.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
#
# Guards the published shape of the com.immutable.audience package.
#
# When the package is installed from a git URL, Unity copies the folder into an
# immutable PackageCache verbatim. Every asset there must have a .meta companion
# or the asset is dropped, which turns into a fatal error on device builds.
# Non-Unity tooling files (csproj, props, sln) have no place in the package and
# trip the same failure because their .meta files are intentionally gitignored.
#
# This check fails the build if either problem is reintroduced.

set -euo pipefail

PKG="src/Packages/Audience"
status=0

# Files that should never ship inside the package.
forbidden=$(git ls-files "$PKG" \
| grep -E '\.(csproj|sln)$|/Directory\.Build\.(props|targets)$' || true)
if [ -n "$forbidden" ]; then
echo "ERROR: non-Unity tooling files tracked inside $PKG (move them out of the package):"
while IFS= read -r f; do
printf ' %s\n' "$f"
done <<< "$forbidden"
status=1
fi

# Every tracked asset must have a tracked .meta companion. Dotfiles and dot
# folders are ignored by Unity, so they are exempt.
missing=""
while IFS= read -r f; do
case "$f" in
*.meta) continue ;;
*/.*) continue ;;
.*) continue ;;
esac
if ! git ls-files --error-unmatch "$f.meta" >/dev/null 2>&1; then
missing="$missing $f"$'\n'
fi
done < <(git ls-files "$PKG")

if [ -n "$missing" ]; then
echo "ERROR: assets in $PKG are missing a committed .meta companion:"
printf '%s' "$missing"
status=1
fi

# Every tracked .meta must have a matching asset. The asset is either a tracked
# file or, for Unity folder metas, a directory that holds tracked files. An
# orphan meta left behind by `git rm`-ing an asset keeps a stale GUID around.
orphan=""
while IFS= read -r m; do
base="${m%.meta}"
if git ls-files --error-unmatch "$base" >/dev/null 2>&1; then
continue
fi
if [ -n "$(git ls-files "$base/")" ]; then
continue
fi
orphan="$orphan $m"$'\n'
done < <(git ls-files "$PKG" | grep -E '\.meta$' || true)

if [ -n "$orphan" ]; then
echo "ERROR: orphan .meta files in $PKG (no matching asset, stale GUID):"
printf '%s' "$orphan"
status=1
fi

if [ "$status" -eq 0 ]; then
echo "OK: $PKG is meta-complete and free of non-Unity tooling files."
fi
exit "$status"
30 changes: 17 additions & 13 deletions .github/workflows/test-audience-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@ on:
push:
branches: [main]
paths:
- 'src/Packages/Audience/Runtime/**'
- 'src/Packages/Audience/Tests/**'
- 'src/Packages/Audience/package.json'
- 'src/Packages/Audience/Directory.Build.props'
- 'src/Packages/Audience/link.xml'
- 'src/Packages/Audience/**'
- 'src/Audience.Build/**'
- '.github/workflows/test-audience-sdk.yml'
- '.github/scripts/audience/check-package-meta.sh'
pull_request:
paths:
- 'src/Packages/Audience/Runtime/**'
- 'src/Packages/Audience/Tests/**'
- 'src/Packages/Audience/package.json'
- 'src/Packages/Audience/Directory.Build.props'
- 'src/Packages/Audience/link.xml'
- 'src/Packages/Audience/**'
- 'src/Audience.Build/**'
- '.github/workflows/test-audience-sdk.yml'
- '.github/scripts/audience/check-package-meta.sh'

jobs:
package-shape:
name: Package shape (meta completeness)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check package meta files
run: ./.github/scripts/audience/check-package-meta.sh

test:
name: Unit Tests (.NET)
runs-on: ubuntu-latest
Expand All @@ -33,14 +37,14 @@ jobs:
dotnet-version: '8.0.x'

- name: Restore dependencies
run: dotnet restore src/Packages/Audience/Tests/Audience.Tests.csproj
run: dotnet restore src/Audience.Build/Audience.Tests/Audience.Tests.csproj

- name: Build
run: dotnet build src/Packages/Audience/Tests/Audience.Tests.csproj --no-restore --configuration Release
run: dotnet build src/Audience.Build/Audience.Tests/Audience.Tests.csproj --no-restore --configuration Release

- name: Run tests
run: >
dotnet test src/Packages/Audience/Tests/Audience.Tests.csproj
dotnet test src/Audience.Build/Audience.Tests/Audience.Tests.csproj
--no-build --configuration Release
--logger "trx;LogFileName=test-results.trx"
--logger "console;verbosity=normal"
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*.DotSettings.user.meta
Directory.Build.props.meta
Directory.Build.targets.meta
src/Packages/Audience/README.md.meta

# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
Expand Down Expand Up @@ -54,6 +53,11 @@ ExportedObj/
*.unityproj
*.sln
*.sln.meta

# Hand-maintained headless dotnet build projects for the Audience package.
# These live outside the Unity package so they never ship to consumers; keep
# them tracked despite the blanket *.csproj rule above.
!src/Audience.Build/**/*.csproj
*.suo
*.tmp
*.user
Expand Down
25 changes: 25 additions & 0 deletions src/Audience.Build/Audience.Runtime/Audience.Runtime.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>9.0</LangVersion>
<Nullable>disable</Nullable>
<!-- Match the Unity asmdef assembly name so InternalsVisibleTo works in both contexts -->
<AssemblyName>Immutable.Audience.Runtime</AssemblyName>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- Sources live in the package folder, not next to this project -->
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<PackageRoot>$(MSBuildThisFileDirectory)../../Packages/Audience</PackageRoot>
</PropertyGroup>
<!--
The Unity/ subtree belongs to the sibling Immutable.Audience.Unity asmdef.
It references UnityEngine, so it cannot build under the headless .NET SDK.
Excluding it here mirrors the noEngineReferences:true portability guard on
com.immutable.audience.asmdef, catching stray UnityEngine usage in Core/,
Events/, Transport/ and Utility/.
-->
<ItemGroup>
<Compile Include="$(PackageRoot)/Runtime/**/*.cs"
Exclude="$(PackageRoot)/Runtime/Unity/**/*.cs"
LinkBase="Runtime" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
<LangVersion>9.0</LangVersion>
<Nullable>disable</Nullable>
<IsPackable>false</IsPackable>
<!-- Match the Unity asmdef assembly name so InternalsVisibleTo("Immutable.Audience.Runtime.Tests") resolves correctly -->
<!-- Match the Unity asmdef assembly name so InternalsVisibleTo("Immutable.Audience.Runtime.Tests") resolves -->
<AssemblyName>Immutable.Audience.Runtime.Tests</AssemblyName>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<PackageRoot>$(MSBuildThisFileDirectory)../../Packages/Audience</PackageRoot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Runtime/Audience.Runtime.csproj" />
<ProjectReference Include="../Audience.Runtime/Audience.Runtime.csproj" />
</ItemGroup>
<!--
Exclude Tests/Editor/ from the headless dotnet build. Those tests reference
Unity-only types (MonoBehaviour, VisualElement, SampleApp MonoBehaviour)
and run inside the Unity Test Framework in-editor.
Editor/ and Runtime/Unity/ tests reference Unity-only types and run inside
the Unity Test Framework in-editor, so they are excluded from the headless
dotnet build.
-->
<ItemGroup>
<Compile Remove="Editor/**/*.cs" />
<!-- DeviceCollectorTests references Immutable.Audience.Unity which wraps
UnityEngine APIs unavailable in the headless dotnet build. These tests
run inside the Unity Test Framework via the asmdef instead. -->
<Compile Remove="Runtime/Unity/**/*.cs" />
<Compile Include="$(PackageRoot)/Tests/**/*.cs"
Exclude="$(PackageRoot)/Tests/Editor/**/*.cs;$(PackageRoot)/Tests/Runtime/Unity/**/*.cs"
LinkBase="Tests" />
</ItemGroup>
</Project>
17 changes: 17 additions & 0 deletions src/Audience.Build/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project>
<!--
Redirect dotnet build outputs to a repo-root artifacts/ folder.

These projects build the Audience package sources headlessly for unit tests.
They live outside src/Packages/Audience so they are never copied into a
consumer's PackageCache (git-URL installs ship the package folder verbatim,
and non-Unity files there break device builds when they lack .meta files).

$(MSBuildThisFileDirectory) = src/Audience.Build/
../../artifacts/ = <repo-root>/artifacts/
-->
<PropertyGroup>
<BaseOutputPath>$(MSBuildThisFileDirectory)../../artifacts/$(MSBuildProjectName)/bin/</BaseOutputPath>
<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)../../artifacts/$(MSBuildProjectName)/obj/</BaseIntermediateOutputPath>
</PropertyGroup>
</Project>
21 changes: 0 additions & 21 deletions src/Packages/Audience/Directory.Build.props

This file was deleted.

7 changes: 7 additions & 0 deletions src/Packages/Audience/README.md.meta

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

28 changes: 0 additions & 28 deletions src/Packages/Audience/Runtime/Audience.Runtime.csproj

This file was deleted.

Loading