Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
140 commits
Select commit Hold shift + click to select a range
8b209d1
feat: forward remote login diagnostics to the client
Priveetee Sep 13, 2026
82d659d
feat: log remote login bridge and completion outcomes
Priveetee Sep 13, 2026
076634f
fix: recover cold SABR seeks
Priveetee Sep 16, 2026
d987fd2
feat: add presence access keys
Priveetee Sep 16, 2026
7593f94
feat: expose playback presence
Priveetee Sep 16, 2026
078e663
test: cover presence key lifecycle
Priveetee Sep 16, 2026
cc2183b
docs: document presence API
Priveetee Sep 16, 2026
604750b
feat: rotate home recommendations on refresh
Priveetee Sep 16, 2026
65d58d3
fix: clarify provider extraction errors
Priveetee Sep 16, 2026
21fd330
fix: batch portability history imports
Priveetee Sep 16, 2026
8751877
fix: support localized YouTube Takeout schemas
Priveetee Sep 16, 2026
8fe4962
perf: accelerate localized Takeout parsing
Priveetee Sep 16, 2026
0113723
test: cover localized Takeout imports
Priveetee Sep 16, 2026
e960ab1
feat: import YouTube Takeout activity JSON
Priveetee Sep 16, 2026
6d76325
test: cover YouTube Takeout JSON detection
Priveetee Sep 16, 2026
1b774ec
fix: parse localized Takeout day periods
Priveetee Sep 16, 2026
422df6b
fix: broaden localized Takeout imports and progress
Priveetee Sep 17, 2026
37333a5
fix: detect localized YouTube Takeout schemas
Priveetee Sep 17, 2026
ea9614e
fix: report invalid Takeout dates
Priveetee Sep 17, 2026
302b76e
fix: publish Takeout import progress
Priveetee Sep 17, 2026
426f458
fix: skip channel tabs without tab support
Priveetee Sep 17, 2026
e330e65
fix: associate localized playlist item files
Priveetee Sep 17, 2026
5e2c138
fix: parse one-digit takeout hours
Priveetee Sep 17, 2026
640540e
perf: anchor takeout history row matching
Priveetee Sep 17, 2026
74a07b2
feat: separate autoplay open setting
Priveetee Sep 17, 2026
2680d9a
docs: link AI transparency statement
Priveetee Sep 18, 2026
d74fb35
docs: move AI transparency notice
Priveetee Sep 18, 2026
4ad2488
refactor: extract server-cache Gradle module
Priveetee Sep 18, 2026
e6b048e
refactor: extract server-core models into Gradle module
Priveetee Sep 18, 2026
8e3a033
refactor: extract server-db into Gradle module
Priveetee Sep 18, 2026
784156b
refactor: extract server-sabr into Gradle module
Priveetee Sep 18, 2026
203b33f
refactor: extract server-downloader into Gradle module
Priveetee Sep 18, 2026
eed5c6e
refactor: move downloader and sabr tests to owning modules
Priveetee Sep 18, 2026
93451ab
refactor: extract server-auth into Gradle module
Priveetee Sep 18, 2026
8e3b660
refactor: extract server-token-gateway into Gradle module
Priveetee Sep 18, 2026
5957851
refactor: extract server-portability and server-domain modules
Priveetee Sep 18, 2026
2ee58cd
refactor: move portability glue into server-portability module
Priveetee Sep 18, 2026
bce7098
refactor: extract server-playback into Gradle module
Priveetee Sep 18, 2026
61e86cb
fix: relocate stray playback test files into source sets
Priveetee Sep 18, 2026
afff76c
refactor: extract server-services into Gradle module
Priveetee Sep 18, 2026
d34e242
refactor: extract server-http routes module and slim app to bootstrap
Priveetee Sep 18, 2026
4c6193f
refactor: extract server-admin into Gradle module
Priveetee Sep 18, 2026
ad8d0d8
refactor: co-locate tests with owning modules and add test-fixtures
Priveetee Sep 18, 2026
d2a9f1e
ci: route server workflows to CI stack
Priveetee Sep 19, 2026
d861cdf
fix: isolate optional subtitle failures
Priveetee Sep 19, 2026
d9e07ba
fix: bound nonstreaming proxy requests
Priveetee Sep 19, 2026
1e83eda
feat: persist autoplay countdown setting
Priveetee Sep 19, 2026
3c14a3a
feat: configure optional BiliBili cookies
Priveetee Sep 20, 2026
37e218a
fix: require HTTPS for BiliBili cookies
Priveetee Sep 20, 2026
2227216
feat: add BiliBili session lifecycle with QR login
Priveetee Sep 20, 2026
89756d7
feat: add health check and SESSDATA expiry detection for BiliBili
Priveetee Sep 20, 2026
5bf1654
feat: wire BiliBili session into stream extraction path
Priveetee Sep 20, 2026
46f2235
feat: add per-user rate limiting for BiliBili extraction
Priveetee Sep 20, 2026
a32f2c7
fix: keep BiliBili QR polling alive
Priveetee Sep 20, 2026
ca3daa0
chore: bump server to 1.8.2
Priveetee Sep 20, 2026
3ba47cf
refactor: integrate modular server architecture
Priveetee Sep 21, 2026
e8aad97
fix: copy Gradle modules in image build
Priveetee Sep 21, 2026
265837a
chore: update PipePipeExtractor dependency
Priveetee Sep 21, 2026
0249ea2
ci: build affected server modules
Priveetee Sep 21, 2026
cffb841
fix: align SABR duration with media end
Priveetee Sep 21, 2026
7c1fd0e
test: cover live session eviction and cache bounds
Priveetee Sep 21, 2026
a8cbd09
test: cover playback lookup by format
Priveetee Sep 21, 2026
e8aeeb6
fix: expose browser-compatible SABR audio
Priveetee Sep 21, 2026
8822eab
chore: update PipePipeExtractor dependency
Priveetee Sep 21, 2026
91d0197
ci: compile only affected server modules
Priveetee Sep 21, 2026
2f1dd25
fix: refresh SABR demand idle timestamp
Priveetee Sep 21, 2026
36c2dcd
fix: remove global BiliBili cookie configuration
Priveetee Sep 22, 2026
13ff6ad
fix: protect active live SABR sessions
Priveetee Sep 22, 2026
7aa81f4
style: keep SABR session store within line limit
Priveetee Sep 22, 2026
6c6fc0f
fix: widen live SABR read-ahead cushion
Priveetee Sep 22, 2026
87ff110
fix: track live SABR demand interruptions
Priveetee Sep 22, 2026
6f420ac
fix: requeue future live SABR demands
Priveetee Sep 22, 2026
ea5c398
test: cover live SABR demand continuity
Priveetee Sep 22, 2026
9ff2e09
fix: target retried live SABR demand
Priveetee Sep 22, 2026
afe3c50
fix: requeue recoverable live SABR demands
Priveetee Sep 22, 2026
576a024
feat: paginate subscription group memberships (#86)
kapdon Sep 23, 2026
4a85d92
perf: reduce live SABR startup latency
Priveetee Sep 23, 2026
ac4bbdb
test: cover low latency live SABR startup
Priveetee Sep 23, 2026
71d3892
fix: bypass cache for YouTube live HLS manifests
Priveetee Sep 23, 2026
919fc7e
refactor: split stream route helpers
Priveetee Sep 23, 2026
a1821af
fix: resolve live YouTube playback with HLS
Priveetee Sep 23, 2026
433d509
perf: retain live HLS manifest tokens longer
Priveetee Sep 23, 2026
c48e31e
fix: avoid caching live stream URLs
Priveetee Sep 24, 2026
8dc76a4
fix: use public live HLS for sessions
Priveetee Sep 24, 2026
8edb7a7
fix: prefer public live HLS for sessions
Priveetee Sep 24, 2026
92d5825
fix: prefer dedicated YouTube live HLS
Priveetee Sep 24, 2026
c3b1648
perf: add direct HLS route for known YouTube lives
Priveetee Sep 24, 2026
6dc140e
fix: fall back when direct live extraction fails
Priveetee Sep 24, 2026
92b33f8
perf: fetch live HLS without enumerating formats
Priveetee Sep 24, 2026
8f86660
test: cover fast PipePipe live HLS extraction
Priveetee Sep 24, 2026
73863fe
test: stub membership state in live service tests
Priveetee Sep 24, 2026
685c974
perf: log youtube live extraction stage timing
Priveetee Sep 24, 2026
f6b8a7e
perf: hedge YouTube live HLS resolution
Priveetee Sep 24, 2026
7c66c32
perf: gate SABR startup on readable media
Priveetee Sep 24, 2026
edc5e82
chore: pause automatic validation workflows
Priveetee Sep 24, 2026
aa115b8
perf: keep subtitle lookup off SABR startup path
Priveetee Sep 24, 2026
3fc97a1
perf: avoid blocking SABR extraction on redundant warmup
Priveetee Sep 24, 2026
3a15984
perf: trace SABR startup across services
Priveetee Sep 24, 2026
7be2893
docs: document playback startup tracing
Priveetee Sep 24, 2026
092bd14
perf: log selected SABR startup formats
Priveetee Sep 24, 2026
b62ad2a
perf: reuse prewarmed SABR playback sessions
Priveetee Sep 25, 2026
d596c98
fix: route playback trace through slf4j
Priveetee Sep 25, 2026
2562929
docs: record Beta playback startup measurements
Priveetee Sep 25, 2026
46ba92e
perf: trace playback extraction startup phases
Priveetee Sep 25, 2026
1596ce2
docs: document MSE playback trace events
Priveetee Sep 25, 2026
b25a632
docs: record traced browser startup samples
Priveetee Sep 25, 2026
4094231
perf: trace SABR initialization preload timing
Priveetee Sep 25, 2026
3869c18
docs: record latest Beta playback timings
Priveetee Sep 25, 2026
dca0cb5
perf: start SABR with a playable partial window
Priveetee Sep 25, 2026
c2e3a6f
test: verify token playback fallback
Priveetee Sep 25, 2026
23bc6b4
fix: skip arm64 Docker build on dev
Priveetee Sep 25, 2026
da342ad
feat: persist video layout preferences
Priveetee Sep 25, 2026
efdbbda
chore: restore automatic dev validation
Priveetee Sep 25, 2026
2ba474e
fix: end progressive SABR windows at stream end
Priveetee Sep 25, 2026
9843d78
fix: close SABR windows at indexed media end
Priveetee Sep 25, 2026
858cda8
fix: invalidate YouTube session on SABR timeout
Priveetee Sep 25, 2026
51b9d2d
fix: continue metadata repair across batches
Priveetee Sep 25, 2026
335313f
fix: keep metadata repair batches moving
Priveetee Sep 25, 2026
12b7bcf
feat: add progressive YouTube Takeout imports
Priveetee Sep 26, 2026
fe2e64c
chore: bump server to 1.9.0
Priveetee Sep 26, 2026
5a52dfd
fix: decode extractor responses with declared charset
tam1m Sep 26, 2026
395f9ab
fix: type YouTube extraction failures
Priveetee Sep 26, 2026
e1de8ba
fix: map YouTube extraction statuses
Priveetee Sep 26, 2026
af3fc81
test: expect gateway status for no YouTube stream
Priveetee Sep 26, 2026
f8ea89e
fix: preserve non-retriable restriction errors
Priveetee Sep 26, 2026
b8278c2
fix: ignore unrelated Takeout CSV metadata
Priveetee Sep 26, 2026
c2a7df2
fix: propagate imported subscription avatars
Priveetee Sep 26, 2026
3acf040
feat: expose opt-in channel notification settings
Priveetee Sep 26, 2026
08a0da5
fix: resolve history avatars from subscriptions
Priveetee Sep 26, 2026
ff2dc78
fix: repair imported subscription avatars
Priveetee Sep 26, 2026
da5ac6f
Merge pull request #87 from tam1m/fix/response-charset
Priveetee Sep 26, 2026
8823cbf
fix: stabilize playlist summaries and metadata repair
Priveetee Sep 26, 2026
bc07ddb
feat: resolve missing subscription avatars
Priveetee Sep 26, 2026
6ef40e5
feat: update provider support and playlist blocking
Priveetee Sep 26, 2026
6f80583
fix: allow BiliBili live HLS gateway
Priveetee Sep 26, 2026
9d9b45f
fix: update PipePipeExtractor live handling
Priveetee Sep 27, 2026
4381324
fix: stabilize DeArrow metadata and thumbnails
Priveetee Sep 27, 2026
b38db9f
fix: expire DeArrow thumbnail fallback quickly
Priveetee Sep 27, 2026
57a6f6f
chore: merge main for 1.9.0 release
Priveetee Sep 27, 2026
7cc91d6
style: trim trailing blank lines
Priveetee Sep 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
170 changes: 170 additions & 0 deletions .github/scripts/ci-affected-tasks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/usr/bin/env bash
set -euo pipefail

repo_root="$(git rev-parse --show-toplevel)"
cd "$repo_root"

event_name="${GITHUB_EVENT_NAME:-push}"
base_ref="${GITHUB_BASE_REF:-}"
before="${GITHUB_EVENT_BEFORE:-}"
zero_sha="0000000000000000000000000000000000000000"
sha="${GITHUB_SHA:-$(git rev-parse HEAD)}"
output_file="${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"
task_name="${AFFECTED_GRADLE_TASK:-build}"
case "$task_name" in
build|test) ;;
*) echo "Unsupported affected Gradle task: $task_name" >&2; exit 2 ;;
esac

emit_tasks() {
if [[ -z "$1" ]]; then
return
fi

{
echo "tasks<<EOF"
printf '%s\n' "$1"
echo "EOF"
} >>"$output_file"
}

if [[ "$event_name" != "push" && "$event_name" != "pull_request" ]]; then
emit_tasks "$task_name"
exit 0
fi

if [[ "$event_name" == "pull_request" ]]; then
if [[ -z "$base_ref" ]]; then
echo "Missing base ref for pull request" >&2
exit 1
fi

git fetch --no-tags origin "$base_ref"
base_commit="$(git rev-parse "origin/$base_ref")"
mapfile -d '' -t changed_files < <(
git diff --name-only -z "$base_commit...$sha"
)
elif [[ -n "$before" && "$before" != "$zero_sha" ]] &&
git cat-file -e "$before^{commit}" 2>/dev/null; then
mapfile -d '' -t changed_files < <(
git diff --name-only -z "$before...$sha"
)
elif git rev-parse --verify HEAD^ >/dev/null 2>&1; then
mapfile -d '' -t changed_files < <(
git diff --name-only -z "HEAD^...$sha"
)
else
emit_tasks "$task_name"
exit 0
fi

is_shared_change() {
case "$1" in
.github/scripts/* | .github/workflows/ci.yml | .github/workflows/coverage.yml)
return 0
;;
.github/workflows/openapi.yml)
return 0
;;
build.gradle.kts | settings.gradle.kts | gradle.properties | gradlew | gradle/*)
return 0
;;
openapi.yaml | openapi/* | src/*)
return 0
;;
Dockerfile)
return 0
;;
esac

return 1
}

is_ignored_change() {
case "$1" in
*.md | *.png | *.svg | .gitignore | .editorconfig | LICENSE*)
return 0
;;
docs/* | .github/ISSUE_TEMPLATE/*)
return 0
;;
esac

return 1
}

full_build=false
declare -A changed_modules=()

for file in "${changed_files[@]}"; do
if is_ignored_change "$file"; then
continue
fi

if is_shared_change "$file"; then
full_build=true
continue
fi

if [[ "$file" == server-*/* ]]; then
module="${file%%/*}"
changed_modules["$module"]=1
else
full_build=true
fi
done

if [[ "$full_build" == true ]]; then
emit_tasks "$task_name"
exit 0
fi

if [[ ${#changed_modules[@]} -eq 0 ]]; then
exit 0
fi

declare -A dependents_by_module=()
for build_file in server-*/build.gradle.kts; do
module="${build_file%/*}"
while IFS= read -r line; do
if [[ "$line" =~ project\(\":([A-Za-z0-9_-]+)\"\) ]]; then
dependency="${BASH_REMATCH[1]}"
dependents_by_module["$dependency"]+="$module "
fi
done <"$build_file"
done

declare -A affected_modules=()

mark_affected() {
local module="$1"

if [[ -n "${affected_modules[$module]:-}" ]]; then
return
fi

affected_modules["$module"]=1

local dependent
for dependent in ${dependents_by_module["$module"]:-}; do
mark_affected "$dependent"
done
}

for module in "${!changed_modules[@]}"; do
if [[ ! -f "$module/build.gradle.kts" ]]; then
echo "Changed module no longer exists: $module" >&2
emit_tasks "$task_name"
exit 0
fi

mark_affected "$module"
done

module_tasks="$(
for module in "${!affected_modules[@]}"; do
printf ':%s:%s\n' "$module" "$task_name"
done | sort
)"

emit_tasks "$module_tasks"
20 changes: 18 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04' || fromJSON('["self-hosted","Linux","X64","ci-stack"]') }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Isolate Gradle user home
run: echo "GRADLE_USER_HOME=${RUNNER_TEMP}/gradle-user-home" >> "$GITHUB_ENV"
Expand All @@ -29,5 +31,19 @@ jobs:

- uses: gradle/actions/setup-gradle@v6

- name: Build
run: ./gradlew build --max-workers=8
- name: Detect affected Gradle modules
id: affected
run: bash .github/scripts/ci-affected-tasks.sh

- name: Build affected modules
env:
TASKS: ${{ steps.affected.outputs.tasks }}
run: |
if [[ -z "$TASKS" ]]; then
echo "No Gradle compilation or tests are required."
exit 0
fi

readarray -t task_args <<<"$TASKS"
printf 'Running:\n%s\n' "$TASKS"
./gradlew "${task_args[@]}" --parallel --max-workers=32
27 changes: 23 additions & 4 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04' || fromJSON('["self-hosted","Linux","X64","ci-stack"]') }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Isolate Gradle user home
run: echo "GRADLE_USER_HOME=${RUNNER_TEMP}/gradle-user-home" >> "$GITHUB_ENV"
Expand All @@ -28,18 +30,35 @@ jobs:

- uses: gradle/actions/setup-gradle@v6

- name: Run tests and coverage report
run: ./gradlew test jacocoTestReport jacocoTestCoverageVerification
- name: Detect affected test modules
id: affected
env:
AFFECTED_GRADLE_TASK: test
run: bash .github/scripts/ci-affected-tasks.sh

- name: Run affected tests and coverage report
if: steps.affected.outputs.tasks != ''
env:
TASKS: ${{ steps.affected.outputs.tasks }}
run: |
readarray -t task_args <<<"$TASKS"
printf 'Running affected tests:\n%s\n' "$TASKS"
./gradlew "${task_args[@]}" --parallel --max-workers=32
./gradlew jacocoTestReport jacocoTestCoverageVerification --parallel --max-workers=32

- name: No coverage required
if: steps.affected.outputs.tasks == ''
run: echo "No source or build changes require coverage."

- name: Upload coverage HTML report
if: always()
if: always() && steps.affected.outputs.tasks != ''
uses: actions/upload-artifact@v7
with:
name: jacoco-html-report
path: build/reports/jacoco/test/html

- name: Upload coverage XML report
if: always()
if: always() && steps.affected.outputs.tasks != ''
uses: actions/upload-artifact@v7
with:
name: jacoco-xml-report
Expand Down
35 changes: 25 additions & 10 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
branches:
- main
- dev
paths-ignore:
- "**.md"
- "docs/**"
- ".github/ISSUE_TEMPLATE/**"
tags:
- "v*"
workflow_dispatch:
Expand All @@ -29,6 +33,7 @@ jobs:
image: ${{ steps.build-info.outputs.image }}
labels: ${{ steps.meta.outputs.labels }}
metadata-json: ${{ steps.meta.outputs.json }}
platform-matrix: ${{ steps.build-info.outputs.platform-matrix }}
version: ${{ steps.build-info.outputs.version }}

steps:
Expand All @@ -50,10 +55,16 @@ jobs:
else
image="${REGISTRY}/${GITHUB_REPOSITORY,,}"
fi
if [[ "$GITHUB_REF_NAME" == "dev" ]]; then
platform_matrix='{"include":[{"platform":"linux/amd64","arch":"amd64"}]}'
else
platform_matrix='{"include":[{"platform":"linux/amd64","arch":"amd64"},{"platform":"linux/arm64","arch":"arm64"}]}'
fi
{
echo "image=$image"
echo "version=$version"
echo "build-time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
echo "platform-matrix=$platform_matrix"
} >> "$GITHUB_OUTPUT"

- name: Extract metadata
Expand Down Expand Up @@ -83,12 +94,7 @@ jobs:
packages: write
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
arch: amd64
- platform: linux/arm64
arch: arm64
matrix: ${{ fromJSON(needs.prepare-image.outputs.platform-matrix) }}

steps:
- name: Checkout
Expand Down Expand Up @@ -191,8 +197,12 @@ jobs:
run: |
cd "$DIGEST_DIR"
mapfile -t digests < <(find . -maxdepth 1 -type f -printf '%f\n' | sort)
if [[ "${#digests[@]}" -ne 2 ]]; then
echo "Expected two platform digests, found ${#digests[@]}"
expected_digest_count=2
if [[ "$GITHUB_REF_NAME" == "dev" ]]; then
expected_digest_count=1
fi
if [[ "${#digests[@]}" -ne "$expected_digest_count" ]]; then
echo "Expected $expected_digest_count platform digest(s), found ${#digests[@]}"
exit 1
fi

Expand Down Expand Up @@ -227,8 +237,13 @@ jobs:
VERSION: ${{ needs.prepare-image.outputs.version }}
run: |
platforms="$(docker buildx imagetools inspect "$IMAGE:$VERSION" --format '{{json .Manifest}}' | jq -r '.manifests[].platform | "\(.os)/\(.architecture)"' | sort -u)"
if [[ "$platforms" != $'linux/amd64\nlinux/arm64' ]]; then
printf 'Unexpected manifest platforms:\n%s\n' "$platforms"
expected_platforms=$'linux/amd64\nlinux/arm64'
if [[ "$GITHUB_REF_NAME" == "dev" ]]; then
expected_platforms='linux/amd64'
fi
if [[ "$platforms" != "$expected_platforms" ]]; then
printf 'Unexpected manifest platforms:\n%s\nExpected:\n%s\n' \
"$platforms" "$expected_platforms"
exit 1
fi

Expand Down
19 changes: 17 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,31 @@ FROM --platform=$BUILDPLATFORM eclipse-temurin:25-jdk-alpine AS builder
ARG APP_VERSION=0.1.0
ARG GITHUB_SHA=unknown
ARG BUILD_TIME=unknown
ARG GRADLE_MAX_WORKERS=32
ENV GITHUB_SHA=$GITHUB_SHA
ENV BUILD_TIME=$BUILD_TIME
WORKDIR /app
COPY gradlew ./
COPY gradle/ ./gradle/
RUN ./gradlew --version --no-daemon -q
COPY build.gradle.kts gradle.properties settings.gradle.kts* ./
RUN ./gradlew dependencies --no-daemon -q || true
COPY src/ ./src/
RUN ./gradlew shadowJar --no-daemon -q -PappVersion="$APP_VERSION"
COPY server-admin/ ./server-admin/
COPY server-auth/ ./server-auth/
COPY server-cache/ ./server-cache/
COPY server-core/ ./server-core/
COPY server-db/ ./server-db/
COPY server-domain/ ./server-domain/
COPY server-downloader/ ./server-downloader/
COPY server-http/ ./server-http/
COPY server-playback/ ./server-playback/
COPY server-portability/ ./server-portability/
COPY server-sabr/ ./server-sabr/
COPY server-test-support/ ./server-test-support/
COPY server-services/ ./server-services/
COPY server-token-gateway/ ./server-token-gateway/
RUN ./gradlew dependencies --no-daemon --parallel --max-workers="$GRADLE_MAX_WORKERS" -q || true
RUN ./gradlew shadowJar --no-daemon --parallel --max-workers="$GRADLE_MAX_WORKERS" -q -PappVersion="$APP_VERSION"

FROM eclipse-temurin:25-jre-alpine AS runner
RUN apk upgrade --no-cache \
Expand Down
Loading