Skip to content

Commit 0bfd82c

Browse files
committed
feat: add PercentileService, device-code auth endpoints, adaptive DOP in shared Core
- Add PercentileService: scrapes Epic V1 leaderboard population counts and posts results to FSTService via POST /api/leaderboard-population - Add PercentileService.Tests: 111 tests, 99%+ coverage - Add POST /api/auth/device-code endpoint to both services for manual Epic device_code grant re-authentication - Move AdaptiveConcurrencyLimiter to FortniteFestival.Core for shared use - Fix PercentileService Dockerfile to include FortniteFestival.Core dependency - CI workflow already builds/pushes both Docker images - Add leaderboard-population storage and personal DB refresh in FSTService - Add tools/v1lookup CLI utility - 709 FSTService tests (95%+ coverage), 111 PercentileService tests
1 parent 63bcb1f commit 0bfd82c

File tree

58 files changed

+6243
-170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+6243
-170
lines changed

.github/workflows/publish-image.yml

Lines changed: 101 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,25 @@ on:
88
- "FortniteFestival.Core/**"
99
- "FSTService.Tests/**"
1010
- "FSTService/Dockerfile"
11+
- "PercentileService/**"
12+
- "PercentileService.Tests/**"
13+
- "PercentileService/Dockerfile"
1114
- ".github/workflows/publish-image.yml"
1215
pull_request:
1316
branches: [master]
1417
paths:
1518
- "FSTService/**"
1619
- "FortniteFestival.Core/**"
1720
- "FSTService.Tests/**"
21+
- "PercentileService/**"
22+
- "PercentileService.Tests/**"
1823
- ".github/workflows/publish-image.yml"
1924
workflow_dispatch: # Allow manual trigger
2025

2126
env:
2227
REGISTRY: ghcr.io
23-
IMAGE_NAME: ${{ github.repository_owner }}/fstservice
28+
FST_IMAGE_NAME: ${{ github.repository_owner }}/fstservice
29+
PERCENTILE_IMAGE_NAME: ${{ github.repository_owner }}/percentileservice
2430

2531
jobs:
2632
test:
@@ -95,9 +101,78 @@ jobs:
95101
TestResults/*.trx
96102
TestResults/**/coverage.cobertura.xml
97103
104+
test-percentile:
105+
runs-on: ubuntu-latest
106+
107+
steps:
108+
- name: Checkout
109+
uses: actions/checkout@v4
110+
111+
- name: Setup .NET
112+
uses: actions/setup-dotnet@v4
113+
with:
114+
dotnet-version: "9.0.x"
115+
116+
- name: Restore dependencies
117+
run: dotnet restore PercentileService.Tests/PercentileService.Tests.csproj
118+
119+
- name: Build
120+
run: dotnet build PercentileService.Tests/PercentileService.Tests.csproj -c Release --no-restore
121+
122+
- name: Run tests with coverage
123+
run: >
124+
dotnet test PercentileService.Tests/PercentileService.Tests.csproj
125+
-c Release --no-build
126+
--logger trx --results-directory TestResults-Percentile
127+
--collect:"XPlat Code Coverage"
128+
-- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura
129+
DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="[PercentileService]*"
130+
DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Exclude="[PercentileService.Tests]*"
131+
132+
- name: Enforce minimum line coverage for PercentileService
133+
shell: bash
134+
env:
135+
COVERAGE_THRESHOLD: 95
136+
run: |
137+
REPORT=$(find TestResults-Percentile -name 'coverage.cobertura.xml' | head -1)
138+
if [ -z "$REPORT" ]; then
139+
echo "::error::No coverage report found"
140+
exit 1
141+
fi
142+
143+
LINE_RATE=$(sed -n 's/.*<package[^>]*name="PercentileService"[^>]*line-rate="\([^"]*\)".*/\1/p' "$REPORT" | head -1)
144+
145+
if [ -z "$LINE_RATE" ]; then
146+
LINE_RATE=$(sed -n 's/.*<coverage[^>]*line-rate="\([^"]*\)".*/\1/p' "$REPORT" | head -1)
147+
fi
148+
149+
if [ -z "$LINE_RATE" ]; then
150+
echo "::error::Could not parse line-rate from coverage report"
151+
exit 1
152+
fi
153+
154+
PERCENT=$(echo "$LINE_RATE * 100" | bc -l)
155+
PERCENT_FMT=$(printf "%.2f" "$PERCENT")
156+
echo "PercentileService line coverage: ${PERCENT_FMT}%"
157+
158+
PASS=$(echo "$PERCENT >= $COVERAGE_THRESHOLD" | bc -l)
159+
if [ "$PASS" -ne 1 ]; then
160+
echo "::error::Coverage ${PERCENT_FMT}% is below the ${COVERAGE_THRESHOLD}% threshold"
161+
exit 1
162+
fi
163+
164+
- name: Upload test results
165+
uses: actions/upload-artifact@v4
166+
if: always()
167+
with:
168+
name: test-results-percentile
169+
path: |
170+
TestResults-Percentile/*.trx
171+
TestResults-Percentile/**/coverage.cobertura.xml
172+
98173
build-and-push:
99174
runs-on: ubuntu-latest
100-
needs: test
175+
needs: [test, test-percentile]
101176
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
102177

103178
permissions:
@@ -115,20 +190,38 @@ jobs:
115190
username: ${{ github.actor }}
116191
password: ${{ secrets.GITHUB_TOKEN }}
117192

118-
- name: Extract metadata (tags, labels)
119-
id: meta
193+
- name: Extract FSTService metadata
194+
id: meta-fst
120195
uses: docker/metadata-action@v5
121196
with:
122-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
197+
images: ${{ env.REGISTRY }}/${{ env.FST_IMAGE_NAME }}
123198
tags: |
124199
type=sha
125200
type=raw,value=latest,enable={{is_default_branch}}
126201
127-
- name: Build and push
202+
- name: Build and push FSTService
128203
uses: docker/build-push-action@v6
129204
with:
130205
context: .
131206
file: FSTService/Dockerfile
132207
push: true
133-
tags: ${{ steps.meta.outputs.tags }}
134-
labels: ${{ steps.meta.outputs.labels }}
208+
tags: ${{ steps.meta-fst.outputs.tags }}
209+
labels: ${{ steps.meta-fst.outputs.labels }}
210+
211+
- name: Extract PercentileService metadata
212+
id: meta-percentile
213+
uses: docker/metadata-action@v5
214+
with:
215+
images: ${{ env.REGISTRY }}/${{ env.PERCENTILE_IMAGE_NAME }}
216+
tags: |
217+
type=sha
218+
type=raw,value=latest,enable={{is_default_branch}}
219+
220+
- name: Build and push PercentileService
221+
uses: docker/build-push-action@v6
222+
with:
223+
context: .
224+
file: PercentileService/Dockerfile
225+
push: true
226+
tags: ${{ steps.meta-percentile.outputs.tags }}
227+
labels: ${{ steps.meta-percentile.outputs.labels }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,5 @@ FodyWeavers.xsd
369369
FSTService/data/
370370

371371
# Local environment secrets (never commit real credentials)
372-
.env
372+
.env
373+
PercentileService/data/

FSTService.Tests/FSTService.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
<ItemGroup>
2121
<Using Include="Xunit" />
22+
<Using Include="FortniteFestival.Core.Scraping" />
2223
</ItemGroup>
2324

2425
<ItemGroup>

0 commit comments

Comments
 (0)