forked from KaBooMa/S1API
-
-
Notifications
You must be signed in to change notification settings - Fork 28
399 lines (362 loc) · 16.9 KB
/
Copy pathdocs.yml
File metadata and controls
399 lines (362 loc) · 16.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
name: Build and Deploy Documentation
on:
push:
branches-ignore:
- 'agent/**'
- 'automation/**'
- 'dependabot/**'
- 'feat/**'
- 'fix/**'
- 'hotfix/**'
- 'release/**'
pull_request:
workflow_dispatch:
inputs:
assembly_branch:
description: 'Assembly branch to use (main or beta)'
required: false
default: 'main'
type: choice
options:
- main
- beta
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: ${{ github.event_name == 'pull_request' && format('docs-pr-{0}', github.event.pull_request.number) || 'pages' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
documentation:
name: documentation
runs-on: ubuntu-latest
steps:
- name: Checkout S1API
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
# Determine which assembly branch to use (beta or main) - MUST run before cache
- name: Determine Assembly Branch
id: assembly-branch
run: |
# Manual workflow dispatch takes precedence
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && [[ -n "${{ inputs.assembly_branch }}" ]]; then
echo "branch=${{ inputs.assembly_branch }}" >> $GITHUB_OUTPUT
echo "Using ${{ inputs.assembly_branch }} assemblies (manual trigger)"
elif [[ "${{ github.ref_name }}" == "beta" ]] || [[ "${{ github.base_ref }}" == "beta" ]]; then
echo "branch=beta" >> $GITHUB_OUTPUT
echo "Using beta assemblies for beta branch workflow"
elif [[ "${{ github.event_name }}" == "pull_request" ]] && [[ "${{ contains(github.event.pull_request.labels.*.name, 'beta') }}" == "true" ]]; then
echo "branch=beta" >> $GITHUB_OUTPUT
echo "Using beta assemblies for PR with beta label"
else
echo "branch=main" >> $GITHUB_OUTPUT
echo "Using main/stable assemblies"
fi
- name: Create Assembly Directory Structure
run: |
mkdir -p S1API/ScheduleOneAssemblies/Managed
mkdir -p S1API/ScheduleOneAssemblies/MelonLoader
# Try to restore assemblies from cache first (for external PRs)
# Cache key includes assembly branch to separate beta from main
# v4 includes Unity.Burst.dll, which the Mono test host needs while
# reflecting native test data.
# Only use cache for PR events to avoid stale assemblies after merges
- name: Restore Game Assemblies from Cache
id: cache-assemblies
if: github.event_name == 'pull_request'
uses: actions/cache/restore@v4
with:
path: S1API/ScheduleOneAssemblies
key: game-assemblies-v4-${{ steps.assembly-branch.outputs.branch }}-${{ hashFiles('S1API/S1API.csproj') }}
restore-keys: |
game-assemblies-v4-${{ steps.assembly-branch.outputs.branch }}-
# Only checkout game assemblies if cache miss AND we have access to secrets
- name: Checkout Game Assemblies
uses: actions/checkout@v4
with:
repository: ${{ secrets.GAME_ASSEMBLIES_REPO }}
token: ${{ secrets.GAME_ASSEMBLIES_TOKEN }}
ref: ${{ steps.assembly-branch.outputs.branch }}
path: game-assemblies
fetch-depth: 1
if: steps.cache-assemblies.outputs.cache-hit != 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
- name: Debug Game Assemblies Structure
run: |
echo "=== Game Assemblies Repository Structure ==="
find game-assemblies -type f -name "*.dll" | head -20
echo ""
echo "=== Looking for Assembly-CSharp.dll ==="
find game-assemblies -name "Assembly-CSharp.dll" -type f
if: steps.cache-assemblies.outputs.cache-hit != 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
- name: Copy Game Assemblies
run: |
# Copy Mono assemblies
if [ -d "game-assemblies/Managed" ]; then
cp -r game-assemblies/Managed/* S1API/ScheduleOneAssemblies/Managed/ || echo "Failed to copy Mono assemblies"
echo "Copied Mono assemblies from game-assemblies/Managed/"
else
echo "No game-assemblies/Managed directory found"
fi
# Copy mod loader assemblies
if [ -d "game-assemblies/MelonLoader" ]; then
cp -r game-assemblies/MelonLoader/* S1API/ScheduleOneAssemblies/MelonLoader/ || echo "Failed to copy MelonLoader assemblies"
echo "Copied MelonLoader assemblies"
else
echo "No game-assemblies/MelonLoader directory found"
fi
# Ensure Unity.TextMeshPro.dll is available
if [ ! -f "S1API/ScheduleOneAssemblies/Managed/Unity.TextMeshPro.dll" ]; then
echo "Unity.TextMeshPro.dll not found in Managed folder, searching for it..."
TMPRO_PATH=$(find game-assemblies -name "Unity.TextMeshPro.dll" -type f | head -1)
if [ -n "$TMPRO_PATH" ]; then
echo "Found Unity.TextMeshPro.dll at: $TMPRO_PATH"
cp "$TMPRO_PATH" S1API/ScheduleOneAssemblies/Managed/ || echo "Failed to copy Unity.TextMeshPro.dll"
echo "Copied Unity.TextMeshPro.dll to Managed folder"
else
echo "Warning: Unity.TextMeshPro.dll not found in game-assemblies repository"
echo "This may cause build failures for files that use TMPro"
fi
fi
if: steps.cache-assemblies.outputs.cache-hit != 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
- name: Verify Assembly Copies
run: |
echo "=== Verifying Assembly Structure ==="
ls -la S1API/ScheduleOneAssemblies/
echo ""
echo "=== Managed Assemblies ==="
ls -la S1API/ScheduleOneAssemblies/Managed/ | head -10
echo ""
echo "=== MelonLoader Assemblies ==="
ls -la S1API/ScheduleOneAssemblies/MelonLoader/ | head -10
echo ""
echo "=== Critical Assembly Check ==="
if [ -f S1API/ScheduleOneAssemblies/Managed/Assembly-CSharp.dll ]; then
echo "✓ Found Assembly-CSharp.dll"
ls -l S1API/ScheduleOneAssemblies/Managed/Assembly-CSharp.dll
else
echo "✗ Missing Assembly-CSharp.dll"
if [ -d "game-assemblies" ]; then
echo "Attempting auto-discovery..."
find game-assemblies -name "Assembly-CSharp.dll" -type f -exec ls -l {} \;
fi
fi
echo ""
echo "=== TextMeshPro Assembly Check ==="
if [ -f S1API/ScheduleOneAssemblies/Managed/Unity.TextMeshPro.dll ]; then
echo "✓ Found Unity.TextMeshPro.dll"
ls -l S1API/ScheduleOneAssemblies/Managed/Unity.TextMeshPro.dll
else
echo "✗ Missing Unity.TextMeshPro.dll"
if [ -d "game-assemblies" ]; then
echo "Attempting auto-discovery..."
find game-assemblies -name "Unity.TextMeshPro.dll" -type f -exec ls -l {} \;
echo "Searching for TextMeshPro assemblies..."
find game-assemblies -name "*TextMeshPro*" -type f -exec ls -l {} \;
fi
fi
echo ""
echo "=== Burst Assembly Check ==="
if [ -f S1API/ScheduleOneAssemblies/Managed/Unity.Burst.dll ]; then
echo "✓ Found Unity.Burst.dll"
ls -l S1API/ScheduleOneAssemblies/Managed/Unity.Burst.dll
else
echo "✗ Missing Unity.Burst.dll"
exit 1
fi
echo ""
echo "=== MelonLoader Assembly Check ==="
if [ -f S1API/ScheduleOneAssemblies/MelonLoader/0Harmony.dll ]; then
echo "✓ Found 0Harmony.dll"
ls -l S1API/ScheduleOneAssemblies/MelonLoader/0Harmony.dll
else
echo "✗ Missing 0Harmony.dll"
if [ -d "game-assemblies" ]; then
echo "Looking for MelonLoader assemblies..."
find game-assemblies -name "0Harmony.dll" -type f -exec ls -l {} \;
fi
fi
echo ""
if [ "${{ steps.cache-assemblies.outputs.cache-hit }}" == "true" ]; then
echo "✓ Using cached assemblies for build"
else
echo "✓ Using fresh assemblies from repository"
fi
# Save only verified non-empty assembly caches.
- name: Save Game Assemblies to Cache
uses: actions/cache/save@v4
if: always() && steps.cache-assemblies.outputs.cache-hit != 'true' && hashFiles('S1API/ScheduleOneAssemblies/Managed/Assembly-CSharp.dll') != '' && hashFiles('S1API/ScheduleOneAssemblies/Managed/Unity.Burst.dll') != '' && hashFiles('S1API/ScheduleOneAssemblies/MelonLoader/0Harmony.dll') != '' && ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/stable' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/npc-prefabs')))
with:
path: S1API/ScheduleOneAssemblies
key: game-assemblies-v4-${{ steps.assembly-branch.outputs.branch }}-${{ hashFiles('S1API/S1API.csproj') }}
- name: Create CI Build Properties
run: |
cat > ci.build.props << 'EOF'
<Project>
<PropertyGroup>
<AutomateLocalDeployment>false</AutomateLocalDeployment>
<!-- CI Assembly Paths (relative to S1API/S1API.csproj) -->
<MelonLoaderAssembliesPath>$(MSBuildThisFileDirectory)S1API/ScheduleOneAssemblies/MelonLoader</MelonLoaderAssembliesPath>
<MelonLoaderMonoAssembliesPath>$(MSBuildThisFileDirectory)S1API/ScheduleOneAssemblies/MelonLoader</MelonLoaderMonoAssembliesPath>
<!-- Mono Configuration -->
<LocalMonoDeploymentPath>null</LocalMonoDeploymentPath>
<MonoAssembliesPath>$(MSBuildThisFileDirectory)S1API/ScheduleOneAssemblies/Managed</MonoAssembliesPath>
</PropertyGroup>
</Project>
EOF
- name: Verify Build Properties
run: |
echo "=== CI Build Properties ==="
cat ci.build.props
echo ""
echo "=== MSBuild Property Resolution Test ==="
cd S1API
echo "Testing MonoAssembliesPath resolution (expect ./ScheduleOneAssemblies from project dir)..."
if [ -f "./ScheduleOneAssemblies/Managed/Assembly-CSharp.dll" ]; then
echo "✓ Assembly-CSharp.dll accessible from build context"
ls -l ./ScheduleOneAssemblies/Managed/Assembly-CSharp.dll
else
echo "✗ Assembly-CSharp.dll NOT accessible from build context"
echo "Current directory: $(pwd)"
echo "Looking for: ./ScheduleOneAssemblies/Managed/Assembly-CSharp.dll"
ls -la ./ScheduleOneAssemblies/Managed/ || echo "Directory doesn't exist"
fi
echo ""
echo "Testing MelonLoaderAssembliesPath resolution..."
if [ -f "./ScheduleOneAssemblies/MelonLoader/0Harmony.dll" ]; then
echo "✓ 0Harmony.dll accessible from build context"
ls -l ./ScheduleOneAssemblies/MelonLoader/0Harmony.dll
else
echo "✗ 0Harmony.dll NOT accessible from build context"
echo "Current directory: $(pwd)"
echo "Looking for: ./ScheduleOneAssemblies/MelonLoader/0Harmony.dll"
ls -la ./ScheduleOneAssemblies/MelonLoader/ || echo "Directory doesn't exist"
fi
- name: Restore dependencies
run: dotnet restore S1API.sln -p:Configuration=MonoMelon
- name: Build S1API
run: dotnet build S1API/S1API.csproj --no-restore -c MonoMelon -v normal
- name: Run Mono contract and compatibility tests
run: >-
dotnet test
S1API.Tests/S1API.Tests.csproj
--no-restore
--configuration MonoMelon
--verbosity normal
--property:AutomateLocalDeployment=false
- name: Upload S1API Mono Artifact
uses: actions/upload-artifact@v4
with:
name: S1API-Mono
path: S1API/bin/MonoMelon/netstandard2.1/S1API.dll
- name: Install DocFX
run: dotnet tool install -g docfx
- name: Build documentation
run: |
cd S1API
docfx docfx.json
- name: Check public API documentation coverage
run: >-
dotnet run
--project tools/S1APIDocumentationCoverage/S1APIDocumentationCoverage.csproj
--configuration Release
--
--api-directory S1API/api
--minimum 80
- name: Preserve pull request API assembly
if: github.event_name == 'pull_request'
run: |
mkdir -p "$RUNNER_TEMP/s1api-api-compat"
cp \
S1API/bin/MonoMelon/netstandard2.1/S1API.dll \
"$RUNNER_TEMP/s1api-api-compat/current.dll"
- name: Build target branch API baseline
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
git checkout --detach --force "$BASE_SHA"
baseline_tag="$(git describe --tags --abbrev=0 --match 'v[0-9]*' "$BASE_SHA" 2>/dev/null || true)"
if [[ -n "$baseline_tag" ]] && git diff --quiet "$baseline_tag" "$BASE_SHA" -- \
':(glob)S1API/**/*.cs' \
S1API/S1API.csproj \
S1API/Directory.Build.props \
Directory.Build.props; then
baseline_version="${baseline_tag#v}"
release_dir="$RUNNER_TEMP/s1api-api-compat/release"
release_zip="$release_dir/S1API-Forked-${baseline_version}.zip"
mkdir -p "$release_dir"
gh release download "$baseline_tag" \
--repo "$GITHUB_REPOSITORY" \
--pattern "S1API-Forked-${baseline_version}.zip" \
--dir "$release_dir"
unzip -p "$release_zip" \
Mods/S1API.Mono.MelonLoader.dll \
> "$RUNNER_TEMP/s1api-api-compat/baseline.dll"
echo "Using shipped ${baseline_tag} Mono assembly as the API baseline"
else
dotnet restore S1API/S1API.csproj -p:Configuration=MonoMelon
dotnet build \
S1API/S1API.csproj \
--no-restore \
--configuration MonoMelon \
--verbosity minimal \
--property:AutomateLocalDeployment=false
cp \
S1API/bin/MonoMelon/netstandard2.1/S1API.dll \
"$RUNNER_TEMP/s1api-api-compat/baseline.dll"
echo "Using target-branch source build as the API baseline"
fi
test -s "$RUNNER_TEMP/s1api-api-compat/baseline.dll"
git checkout --detach --force "$GITHUB_SHA"
- name: Restore ApiCompat tool cache
if: github.event_name == 'pull_request'
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/apicompat
key: apicompat-${{ runner.os }}-${{ runner.arch }}-10.0.302
- name: Install ApiCompat
if: github.event_name == 'pull_request'
run: |
if [ ! -x "$RUNNER_TEMP/apicompat/apicompat" ]; then
dotnet tool install \
Microsoft.DotNet.ApiCompat.Tool \
--tool-path "$RUNNER_TEMP/apicompat" \
--version 10.0.302
fi
- name: Check public API compatibility
if: github.event_name == 'pull_request'
run: |
"$RUNNER_TEMP/apicompat/apicompat" \
--left "$RUNNER_TEMP/s1api-api-compat/baseline.dll" \
--right "$RUNNER_TEMP/s1api-api-compat/current.dll" \
--suppression-file .github/api-compat-suppressions.xml \
--enable-rule-cannot-change-parameter-name \
--enable-rule-attributes-must-match
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./S1API/_site
if: github.event_name != 'pull_request' && github.ref != 'refs/heads/beta'
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: documentation
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/stable' || github.ref == 'refs/heads/npc-prefabs'
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4