mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-29 03:25:41 +00:00
Compare commits
186
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50d5281424 | ||
|
|
87327fdfb4 | ||
|
|
e32461361c | ||
|
|
537a18e6e8 | ||
|
|
73ad823a41 | ||
|
|
3eaf1ebf0a | ||
|
|
3ef689b7b4 | ||
|
|
60b34e93a1 | ||
|
|
b09b114aa4 | ||
|
|
2dd89afd30 | ||
|
|
7f916d72ad | ||
|
|
cdfb2b1902 | ||
|
|
6676b808f1 | ||
|
|
4685aff0b1 | ||
|
|
02ede68108 | ||
|
|
5e1a5bb6de | ||
|
|
06dec7b1fd | ||
|
|
0a8991d828 | ||
|
|
0e080d0a20 | ||
|
|
bbde4eb00c | ||
|
|
212ad4a72d | ||
|
|
4f1827e75b | ||
|
|
54f0b5442a | ||
|
|
6bf9867be3 | ||
|
|
b8ac4d7515 | ||
|
|
12cc9682fd | ||
|
|
da49e18b36 | ||
|
|
2522a42021 | ||
|
|
dc73fa12b0 | ||
|
|
af1057e7b0 | ||
|
|
e80abb24d1 | ||
|
|
4e4704174e | ||
|
|
bd51acb6a2 | ||
|
|
a319460f01 | ||
|
|
e9e7fd1d61 | ||
|
|
a600086709 | ||
|
|
176ec1b03c | ||
|
|
edf3d7596f | ||
|
|
593f515c46 | ||
|
|
3452f906c4 | ||
|
|
a3c64a504e | ||
|
|
9487f83053 | ||
|
|
689b7a166a | ||
|
|
ae3b3b2872 | ||
|
|
489ddd0723 | ||
|
|
65cda21c5f | ||
|
|
8c5dddfacb | ||
|
|
87e7a17035 | ||
|
|
d40835e9ff | ||
|
|
e4c04401e1 | ||
|
|
6f7fb78b07 | ||
|
|
fbfaf19c52 | ||
|
|
7f9e46314d | ||
|
|
885fbab556 | ||
|
|
1099afbbf9 | ||
|
|
9607e1da0b | ||
|
|
9be23e7ab9 | ||
|
|
4f4a23ecd3 | ||
|
|
8a918f7027 | ||
|
|
c5eb8df481 | ||
|
|
c10724de53 | ||
|
|
1bbb50877d | ||
|
|
3bd3965372 | ||
|
|
c39a20636c | ||
|
|
19c262e28b | ||
|
|
a7d9ed77b1 | ||
|
|
9228e21762 | ||
|
|
77fff06a1d | ||
|
|
4c04964e4d | ||
|
|
db81a280d5 | ||
|
|
b6f3a536aa | ||
|
|
45565f9544 | ||
|
|
2d1135eb5a | ||
|
|
8794e3c1b7 | ||
|
|
8d59800f37 | ||
|
|
aa44a894bf | ||
|
|
c240e295ed | ||
|
|
db1a105d78 | ||
|
|
55b478702a | ||
|
|
f8ce8075e5 | ||
|
|
4aeb8a66f9 | ||
|
|
52aea8ab81 | ||
|
|
004e5725ce | ||
|
|
df790953f0 | ||
|
|
e3f99c9649 | ||
|
|
f0ae726510 | ||
|
|
0e63e98d38 | ||
|
|
815ab5ff0b | ||
|
|
0177030c42 | ||
|
|
8d08bbb70f | ||
|
|
8996fdd62c | ||
|
|
e7cad6a498 | ||
|
|
33e0054422 | ||
|
|
279ed07811 | ||
|
|
0756135fcd | ||
|
|
73cdc8d948 | ||
|
|
0f03b77de4 | ||
|
|
93b7301ee0 | ||
|
|
63feec92f4 | ||
|
|
b104038221 | ||
|
|
d0a6527446 | ||
|
|
7379208c91 | ||
|
|
7df3482798 | ||
|
|
1f73167221 | ||
|
|
ccc6953cc2 | ||
|
|
043486f890 | ||
|
|
c9105b5eaf | ||
|
|
03c053372e | ||
|
|
37838350fa | ||
|
|
0afc0754c1 | ||
|
|
4f92065e0f | ||
|
|
71f0f47da2 | ||
|
|
2c5512cd4a | ||
|
|
55691a0515 | ||
|
|
c06a5a9533 | ||
|
|
c4ad4529d8 | ||
|
|
44e87fbe49 | ||
|
|
4b5897210c | ||
|
|
d1191cf494 | ||
|
|
f4250d2b82 | ||
|
|
1a4656992c | ||
|
|
8b67adbe00 | ||
|
|
6e8c683d9f | ||
|
|
fb5ed2365f | ||
|
|
44ae2f36a7 | ||
|
|
41407d4ad0 | ||
|
|
78d92fee37 | ||
|
|
4e32bd7c51 | ||
|
|
2227cce8a6 | ||
|
|
3e618b1e6f | ||
|
|
c392895e12 | ||
|
|
f86fb86870 | ||
|
|
3cacfc5225 | ||
|
|
6e94c82098 | ||
|
|
1a3d0a82a6 | ||
|
|
ea083c8c6c | ||
|
|
dd4ba80a2b | ||
|
|
aea5bc614b | ||
|
|
e006d9e5a0 | ||
|
|
2daf624538 | ||
|
|
7d6d8f3606 | ||
|
|
0bac3ab38f | ||
|
|
7486af58b8 | ||
|
|
475321a86e | ||
|
|
690ae25c88 | ||
|
|
e1e714a818 | ||
|
|
27cd673038 | ||
|
|
1da9fe3405 | ||
|
|
401fdd26cd | ||
|
|
ad142c6f65 | ||
|
|
96d6d64f77 | ||
|
|
5e80ef41d6 | ||
|
|
58553a4de1 | ||
|
|
dc237d6e8f | ||
|
|
42fa4831f0 | ||
|
|
cdab19e920 | ||
|
|
05de5fd007 | ||
|
|
f1429b9560 | ||
|
|
d9452bd763 | ||
|
|
8f24ef1fa7 | ||
|
|
e9a9475deb | ||
|
|
21b56b8098 | ||
|
|
de04afc47f | ||
|
|
1573fc4a82 | ||
|
|
e4a6edf7d7 | ||
|
|
df781f5643 | ||
|
|
6401db7043 | ||
|
|
9cb3a60501 | ||
|
|
0f8880353b | ||
|
|
f1b89de5b3 | ||
|
|
d99d2f5a53 | ||
|
|
72efdff6bc | ||
|
|
9e8a506601 | ||
|
|
77e1dd41cc | ||
|
|
aeb89e265e | ||
|
|
9046e3d7ce | ||
|
|
fc6b48793e | ||
|
|
7d2050db5e | ||
|
|
7e0d8360c4 | ||
|
|
a0912bbc9e | ||
|
|
987390b244 | ||
|
|
e1c7036780 | ||
|
|
da1a1a64c7 | ||
|
|
138c0fcfa9 | ||
|
|
8e7acdfd97 | ||
|
|
e1d8fd7031 |
@@ -3,18 +3,9 @@
|
||||
# for now: filter out annoying TASTY warnings
|
||||
common --ui_event_filters=-INFO
|
||||
|
||||
common --enable_bzlmod
|
||||
|
||||
# Use pre-built protoc binary instead of compiling from source
|
||||
common --incompatible_enable_proto_toolchain_resolution
|
||||
common --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=true
|
||||
|
||||
# Don't use toolchains_llvm for the swift app build
|
||||
common:mactools --ignore_dev_dependency
|
||||
|
||||
# Try to speed up sandboxes
|
||||
common --experimental_reuse_sandbox_directories
|
||||
|
||||
common --enable_platform_specific_config
|
||||
|
||||
common --strategy=Scalac=worker
|
||||
@@ -25,10 +16,18 @@ common --jobs=64
|
||||
|
||||
common --cxxopt="--std=c++23"
|
||||
common --cxxopt="-Wno-deprecated-non-prototype"
|
||||
common --per_file_copt=src/test/cpp/.*@-Wno-character-conversion
|
||||
common --per_file_copt=src/test/cpp/.*@-Wno-deprecated-enum-compare
|
||||
common --per_file_copt=src/test/cpp/.*@-Wno-sign-compare
|
||||
common --per_file_copt=src/test/cpp/.*@-Wno-unknown-warning-option
|
||||
common --host_cxxopt="--std=c++23"
|
||||
|
||||
common --javacopt="-Xlint:-options"
|
||||
|
||||
# Prefer protobuf's prebuilt protoc toolchain instead of building protoc from
|
||||
# source when compatible binaries are available.
|
||||
common --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc
|
||||
|
||||
# std::filesystem and other modern C++ deps require macOS 10.15+.
|
||||
common:macos --macos_minimum_os=10.15
|
||||
common:macos --host_macos_minimum_os=10.15
|
||||
@@ -37,13 +36,8 @@ common:macos --host_macos_minimum_os=10.15
|
||||
# Use host_linkopt for macOS-specific flags to avoid passing them to Linux cross-compilation
|
||||
common:macos --host_linkopt=-Wl,-no_warn_duplicate_libraries
|
||||
|
||||
# Workaround for grpc cf_event_engine build error on macOS with Bazel 7.x
|
||||
# See: https://github.com/grpc/grpc/issues/37619
|
||||
common:macos --features=-module_maps
|
||||
|
||||
# Pin DEVELOPER_DIR so Apple repo rules use full Xcode instead of Command Line
|
||||
# Tools. The sync script writes .bazelrc.xcode with an Xcode build-version
|
||||
# marker so in-place Xcode updates refresh Bazel's generated Apple toolchains.
|
||||
# Pin default DEVELOPER_DIR so Apple repo rules use full Xcode instead of
|
||||
# Command Line Tools when they are needed.
|
||||
common:macos --repo_env=DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
|
||||
|
||||
# Local machine or CI overrides. This lets Bazel-only runners use Command Line
|
||||
@@ -51,8 +45,9 @@ common:macos --repo_env=DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
|
||||
# generated Xcode settings win when both files exist.
|
||||
try-import %workspace%/.bazelrc.local
|
||||
|
||||
# Xcode config for macOS builds. Generated by scripts/sync_bazel_xcode.sh.
|
||||
# Bakes the Xcode build version into action cache keys and sets DEVELOPER_DIR.
|
||||
# Xcode config for Apple tool builds. Generated by scripts/sync_bazel_xcode.sh.
|
||||
# Bakes the Xcode build version into mactools action cache keys without making
|
||||
# ordinary macOS Bazel builds depend on the installed Xcode build number.
|
||||
try-import %workspace%/.bazelrc.xcode
|
||||
|
||||
common --java_language_version=25
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
8.5.1
|
||||
9.1.1
|
||||
|
||||
@@ -31,12 +31,26 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build-auth:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
outputs:
|
||||
image_tag: ${{ steps.push-auth.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Prepare non-LFS checkout
|
||||
env:
|
||||
GIT_CONFIG_GLOBAL: ${{ runner.temp }}/gitconfig-no-lfs
|
||||
GIT_CONFIG_NOSYSTEM: "1"
|
||||
run: |
|
||||
git config --global --unset-all filter.lfs.process || true
|
||||
git config --global filter.lfs.smudge "cat"
|
||||
git config --global filter.lfs.clean "cat"
|
||||
git config --global filter.lfs.required false
|
||||
rm -f .git/hooks/post-checkout .git/hooks/post-merge .git/hooks/pre-push
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_CONFIG_GLOBAL: ${{ runner.temp }}/gitconfig-no-lfs
|
||||
GIT_CONFIG_NOSYSTEM: "1"
|
||||
with:
|
||||
persist-credentials: false
|
||||
lfs: false
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
name: Bazel Cache Parity
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '17 11 * * *'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
warm-cache:
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- name: Clean workspace
|
||||
run: |
|
||||
git sparse-checkout disable 2>/dev/null || true
|
||||
git config --local core.sparseCheckout false 2>/dev/null || true
|
||||
git config --local --unset extensions.worktreeConfig 2>/dev/null || true
|
||||
rm -f .git/info/sparse-checkout .git/config.worktree 2>/dev/null || true
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS=(/opt/homebrew/bin /usr/local/bin)
|
||||
for path in "${COMMON_PATHS[@]}"; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
export PATH="$path:$PATH"
|
||||
fi
|
||||
done
|
||||
|
||||
if command -v git-lfs >/dev/null 2>&1; then
|
||||
git-lfs version
|
||||
exit 0
|
||||
fi
|
||||
|
||||
brew install git-lfs
|
||||
git-lfs version
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
lfs: false
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
- name: Warm remote cache
|
||||
run: ./scripts/check_bazel_remote_cache_parity.sh warm
|
||||
|
||||
verify-cache:
|
||||
needs: warm-cache
|
||||
runs-on: [self-hosted, bazel]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
probe: [a, b]
|
||||
|
||||
steps:
|
||||
- name: Clean workspace
|
||||
run: |
|
||||
git sparse-checkout disable 2>/dev/null || true
|
||||
git config --local core.sparseCheckout false 2>/dev/null || true
|
||||
git config --local --unset extensions.worktreeConfig 2>/dev/null || true
|
||||
rm -f .git/info/sparse-checkout .git/config.worktree 2>/dev/null || true
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS=(/opt/homebrew/bin /usr/local/bin)
|
||||
for path in "${COMMON_PATHS[@]}"; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
export PATH="$path:$PATH"
|
||||
fi
|
||||
done
|
||||
|
||||
if command -v git-lfs >/dev/null 2>&1; then
|
||||
git-lfs version
|
||||
exit 0
|
||||
fi
|
||||
|
||||
brew install git-lfs
|
||||
git-lfs version
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
lfs: false
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
- name: Verify remote cache parity
|
||||
run: ./scripts/check_bazel_remote_cache_parity.sh verify
|
||||
@@ -7,9 +7,11 @@ on:
|
||||
- 'src/**'
|
||||
- 'WORKSPACE'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- 'BUILD.bazel'
|
||||
- '.bazelrc'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'ci/github_actions/summarize_bazel_bep.py'
|
||||
- '.github/workflows/bazel_test.yml'
|
||||
- '!src/main/csharp/**'
|
||||
- '!src/test/csharp/**'
|
||||
@@ -18,9 +20,11 @@ on:
|
||||
- 'src/**'
|
||||
- 'WORKSPACE'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- 'BUILD.bazel'
|
||||
- '.bazelrc'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'ci/github_actions/summarize_bazel_bep.py'
|
||||
- '.github/workflows/bazel_test.yml'
|
||||
- '!src/main/csharp/**'
|
||||
- '!src/test/csharp/**'
|
||||
@@ -108,6 +112,9 @@ jobs:
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
- name: Run tests
|
||||
run: bazel test --build_event_json_file=test.json //src/test/... //src/main/go/...
|
||||
- name: Summarize Bazel build metrics
|
||||
if: always()
|
||||
run: python3 ci/github_actions/summarize_bazel_bep.py test.json
|
||||
- name: Collect failed test logs
|
||||
if: always()
|
||||
run: |
|
||||
|
||||
@@ -11,7 +11,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
@@ -20,6 +20,7 @@ on:
|
||||
- 'ci/BUILD.bazel'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- '.bazelrc'
|
||||
- 'docker-compose.prod.yml'
|
||||
- 'nginx/**'
|
||||
@@ -48,7 +49,7 @@ jobs:
|
||||
# This uses 1 runner slot instead of 4, and Bazel parallelizes internally
|
||||
# NOTE: Must run on a runner with the bazel label to ensure consistent Bazel cache
|
||||
build-all:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
outputs:
|
||||
eagle_image_tag: ${{ steps.push-images.outputs.eagle_image_tag }}
|
||||
admin_image_tag: ${{ steps.push-images.outputs.admin_image_tag }}
|
||||
@@ -116,7 +117,7 @@ jobs:
|
||||
bazel build \
|
||||
--stamp \
|
||||
--platforms=//:linux_x86_64 \
|
||||
--extra_toolchains=@llvm_toolchain_linux//:all \
|
||||
--extra_toolchains=@llvm_toolchain_linux//:cc-toolchain-x86_64-linux \
|
||||
//ci:eagle_server_image \
|
||||
//ci:admin_server_image \
|
||||
//ci:jfr_sidecar_image \
|
||||
@@ -227,7 +228,7 @@ jobs:
|
||||
echo "=== All images pushed successfully ==="
|
||||
|
||||
deploy:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
needs: [build-all]
|
||||
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
|
||||
environment: production
|
||||
@@ -319,7 +320,7 @@ jobs:
|
||||
./ci/github_actions/ensure_bazel_installed.sh
|
||||
bazel build \
|
||||
--platforms=//:linux_x86_64 \
|
||||
--extra_toolchains=@llvm_toolchain_linux//:all \
|
||||
--extra_toolchains=@llvm_toolchain_linux//:cc-toolchain-x86_64-linux \
|
||||
//ci:warmup_tar
|
||||
mkdir -p scripts/bin
|
||||
tar -xf bazel-bin/ci/warmup_tar.tar -C scripts/bin --strip-components=1
|
||||
|
||||
@@ -7,11 +7,16 @@ on:
|
||||
- 'src/main/scala/**'
|
||||
- 'src/main/protobuf/net/eagle0/eagle/**'
|
||||
- 'src/main/protobuf/net/eagle0/common/**'
|
||||
- 'src/main/go/net/eagle0/build/**'
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'WORKSPACE'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- 'BUILD.bazel'
|
||||
- '.bazelrc'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'scripts/build_eagle_ci.sh'
|
||||
- '.github/workflows/eagle_build.yml'
|
||||
|
||||
concurrency:
|
||||
@@ -51,4 +56,4 @@ jobs:
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
- name: Build Eagle server
|
||||
run: bazel build //src/main/scala/net/eagle0/eagle:eagle_server
|
||||
run: ./scripts/build_eagle_ci.sh
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
name: Go Services Build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/main/go/net/eagle0/admin_server/**'
|
||||
- 'src/main/go/net/eagle0/authcli/**'
|
||||
- 'src/main/go/net/eagle0/authservice/**'
|
||||
- 'src/main/go/net/eagle0/common/**'
|
||||
- 'src/main/go/net/eagle0/util/**'
|
||||
- 'src/main/protobuf/net/eagle0/eagle/api/auth.proto'
|
||||
- 'src/main/protobuf/net/eagle0/eagle/api/admin/**'
|
||||
- 'src/main/protobuf/net/eagle0/eagle/internal/auth_internal.proto'
|
||||
- 'src/main/resources/net/eagle0/attributions.json'
|
||||
- 'ci/BUILD.bazel'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'ci/github_actions/fetch_lfs.sh'
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- '.bazelrc'
|
||||
- '.github/workflows/go_services_build.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- name: Prepare non-LFS checkout
|
||||
env:
|
||||
GIT_CONFIG_GLOBAL: ${{ runner.temp }}/gitconfig-no-lfs
|
||||
GIT_CONFIG_NOSYSTEM: "1"
|
||||
run: |
|
||||
git config --global --unset-all filter.lfs.process || true
|
||||
git config --global filter.lfs.smudge "cat"
|
||||
git config --global filter.lfs.clean "cat"
|
||||
git config --global filter.lfs.required false
|
||||
rm -f .git/hooks/post-checkout .git/hooks/post-merge .git/hooks/pre-push
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_CONFIG_GLOBAL: ${{ runner.temp }}/gitconfig-no-lfs
|
||||
GIT_CONFIG_NOSYSTEM: "1"
|
||||
with:
|
||||
persist-credentials: false
|
||||
lfs: false
|
||||
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
|
||||
- name: Fetch LFS files needed for admin server
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: ./ci/github_actions/fetch_lfs.sh --include="src/main/go/net/eagle0/admin_server/static/tiles/*"
|
||||
|
||||
- name: Build Go service Docker images
|
||||
run: bazel build --stamp //ci:admin_server_image //ci:auth_server_image
|
||||
@@ -6,11 +6,13 @@ on:
|
||||
paths:
|
||||
- ".github/workflows/installer_build.yml"
|
||||
- "ci/github_actions/ensure_bazel_installed.sh"
|
||||
- ".bazelrc"
|
||||
- "src/main/go/net/eagle0/clients/win/installer/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/installer_build.yml"
|
||||
- "ci/github_actions/ensure_bazel_installed.sh"
|
||||
- ".bazelrc"
|
||||
- "src/main/go/net/eagle0/clients/win/installer/**"
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
steps:
|
||||
- name: Check for relevant changes since last successful run
|
||||
id: check
|
||||
uses: actions/github-script@v8
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
if (context.eventName === 'workflow_dispatch') {
|
||||
@@ -74,6 +74,7 @@ jobs:
|
||||
'ci/', // CI scripts & workflows
|
||||
'.github/workflows/ios_testflight.yml',
|
||||
'MODULE.bazel',
|
||||
'MODULE.bazel.lock',
|
||||
'.bazelrc',
|
||||
];
|
||||
|
||||
@@ -108,7 +109,7 @@ jobs:
|
||||
build-unity:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.should_build == 'true'
|
||||
runs-on: [self-hosted, macOS, testflight, halfdan]
|
||||
runs-on: [self-hosted, macOS, testflight]
|
||||
|
||||
steps:
|
||||
- name: Prune stale PR refs
|
||||
@@ -209,7 +210,7 @@ jobs:
|
||||
|
||||
archive-and-upload:
|
||||
needs: build-unity
|
||||
runs-on: [self-hosted, macOS, testflight, halfdan]
|
||||
runs-on: [self-hosted, macOS, testflight]
|
||||
|
||||
steps:
|
||||
- name: Ensure Git LFS available for checkout
|
||||
|
||||
+163
-153
@@ -24,6 +24,7 @@ on:
|
||||
- "ci/github_actions/upload_addressables.sh"
|
||||
- "ci/github_actions/ensure_unity_installed.sh"
|
||||
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
|
||||
- ".bazelrc"
|
||||
- "ci/mac/**"
|
||||
pull_request:
|
||||
# On PRs, only build Mac when Mac-specific files change. Shared C#/proto
|
||||
@@ -41,6 +42,7 @@ on:
|
||||
- "ci/github_actions/build_mac.sh"
|
||||
- "ci/github_actions/build_unity_mac.sh"
|
||||
- "ci/github_actions/ensure_bazel_installed.sh"
|
||||
- ".bazelrc"
|
||||
- "ci/mac/**"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
@@ -50,10 +52,6 @@ on:
|
||||
default: 'false'
|
||||
type: boolean
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write # Required to delete artifacts after deploy
|
||||
@@ -65,10 +63,12 @@ env:
|
||||
KEYCHAIN_NAME: build-${{ github.run_id }}.keychain
|
||||
|
||||
jobs:
|
||||
build-and-sign:
|
||||
runs-on: [self-hosted, macOS, unity-mac, halfdan]
|
||||
build-mac:
|
||||
runs-on: [self-hosted, macOS, unity-mac]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
outputs:
|
||||
submission_id: ${{ steps.notarize-submit.outputs.submission_id }}
|
||||
should_deploy: ${{ steps.check-deploy.outputs.should_deploy }}
|
||||
|
||||
steps:
|
||||
@@ -151,21 +151,6 @@ jobs:
|
||||
mkdir -p src/main/csharp/net/eagle0/clients/unity/eagle0/Library
|
||||
git rev-parse HEAD > src/main/csharp/net/eagle0/clients/unity/eagle0/Library/.last_built_sha
|
||||
|
||||
- name: Upload Addressables to CDN
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
env:
|
||||
ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
run: ./ci/github_actions/upload_addressables.sh StandaloneOSX
|
||||
|
||||
- name: Inject Sparkle Framework
|
||||
if: success()
|
||||
env:
|
||||
SPARKLE_EDDSA_PUBLIC_KEY: ${{ secrets.SPARKLE_EDDSA_PUBLIC_KEY }}
|
||||
run: |
|
||||
chmod +x ./scripts/inject_sparkle.sh
|
||||
./scripts/inject_sparkle.sh "${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app"
|
||||
|
||||
- name: Check if should deploy
|
||||
id: check-deploy
|
||||
run: |
|
||||
@@ -179,8 +164,137 @@ jobs:
|
||||
echo "should_deploy=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Import Code Signing Certificate
|
||||
- name: Zip unsigned app for deploy
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
run: |
|
||||
cd ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
ditto -c -k --keepParent eagle0.app eagle0.app.zip
|
||||
|
||||
- name: Upload unsigned app
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: unsigned-mac-app-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app.zip
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload Mac Addressables for deploy
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: mac-addressables-${{ github.run_id }}
|
||||
path: src/main/csharp/net/eagle0/clients/unity/eagle0/ServerData/StandaloneOSX
|
||||
if-no-files-found: ignore
|
||||
retention-days: 1
|
||||
|
||||
- name: Archive Build Log
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: editor_mac.log
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/editor_mac.log
|
||||
retention-days: 3
|
||||
- name: Cleanup build directory
|
||||
if: always()
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"
|
||||
|
||||
deploy-mac:
|
||||
needs: build-mac
|
||||
if: needs.build-mac.outputs.should_deploy == 'true'
|
||||
runs-on: [self-hosted, macOS, notarize]
|
||||
outputs:
|
||||
deployed_version: ${{ steps.deploy-mac.outputs.deployed_version }}
|
||||
concurrency:
|
||||
group: mac-deploy-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
steps:
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
export PATH="${COMMON_PATHS}:${PATH}"
|
||||
for path in /opt/homebrew/bin /usr/local/bin; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
fi
|
||||
done
|
||||
if ! command -v git-lfs >/dev/null 2>&1; then
|
||||
brew install git-lfs
|
||||
fi
|
||||
git-lfs --version
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_LFS_SKIP_SMUDGE: 1
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0 # For version numbering
|
||||
|
||||
- name: Check if run is still latest main
|
||||
id: check-latest
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/main" ]]; then
|
||||
LATEST_SHA=$(curl -fsSL \
|
||||
-H "Authorization: Bearer ${{ github.token }}" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/commits/main" \
|
||||
| python3 -c 'import json, sys; print(json.load(sys.stdin)["sha"])')
|
||||
if [[ "$LATEST_SHA" != "${{ github.sha }}" ]]; then
|
||||
echo "Skipping deploy because ${{ github.sha }} is no longer latest main ($LATEST_SHA is latest)"
|
||||
echo "should_deploy=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
echo "should_deploy=true" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Clean download directory
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: rm -rf ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
|
||||
- name: Download unsigned app
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: unsigned-mac-app-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
|
||||
- name: Unzip unsigned app
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: |
|
||||
cd ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
ditto -x -k eagle0.app.zip .
|
||||
rm eagle0.app.zip
|
||||
ls -la ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app/
|
||||
|
||||
- name: Clean Addressables directory
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: rm -rf src/main/csharp/net/eagle0/clients/unity/eagle0/ServerData/StandaloneOSX
|
||||
|
||||
- name: Download Mac Addressables
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
uses: actions/download-artifact@v8
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: mac-addressables-${{ github.run_id }}
|
||||
path: src/main/csharp/net/eagle0/clients/unity/eagle0/ServerData/StandaloneOSX
|
||||
|
||||
- name: Upload Addressables to CDN
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
run: ./ci/github_actions/upload_addressables.sh StandaloneOSX
|
||||
|
||||
- name: Inject Sparkle Framework
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
SPARKLE_EDDSA_PUBLIC_KEY: ${{ secrets.SPARKLE_EDDSA_PUBLIC_KEY }}
|
||||
run: |
|
||||
chmod +x ./scripts/inject_sparkle.sh
|
||||
./scripts/inject_sparkle.sh "${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app"
|
||||
|
||||
- name: Import Code Signing Certificate
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
||||
@@ -223,7 +337,7 @@ jobs:
|
||||
rm certificate.p12
|
||||
|
||||
- name: Code Sign App
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }}
|
||||
run: |
|
||||
@@ -232,7 +346,7 @@ jobs:
|
||||
|
||||
- name: Submit for Notarization
|
||||
id: notarize-submit
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
|
||||
@@ -241,156 +355,47 @@ jobs:
|
||||
chmod +x ./scripts/notarize_submit.sh
|
||||
./scripts/notarize_submit.sh "${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cleanup Keychain
|
||||
if: always()
|
||||
run: |
|
||||
security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
|
||||
|
||||
- name: Zip signed app for artifact
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
run: |
|
||||
cd ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
ditto -c -k --keepParent eagle0.app eagle0.app.zip
|
||||
|
||||
- name: Upload signed app
|
||||
if: success() && steps.check-deploy.outputs.should_deploy == 'true'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: signed-mac-app-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app.zip
|
||||
retention-days: 1
|
||||
|
||||
- name: Archive Build Log
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: editor_mac.log
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/editor_mac.log
|
||||
retention-days: 3
|
||||
- name: Cleanup build directory
|
||||
if: always()
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"
|
||||
|
||||
wait-notarization:
|
||||
needs: build-and-sign
|
||||
if: needs.build-and-sign.outputs.should_deploy == 'true'
|
||||
runs-on: [self-hosted, macOS, notarize, halfdan]
|
||||
|
||||
steps:
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
export PATH="${COMMON_PATHS}:${PATH}"
|
||||
for path in /opt/homebrew/bin /usr/local/bin; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
fi
|
||||
done
|
||||
if ! command -v git-lfs >/dev/null 2>&1; then
|
||||
brew install git-lfs
|
||||
fi
|
||||
git-lfs --version
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_LFS_SKIP_SMUDGE: 1
|
||||
with:
|
||||
persist-credentials: false
|
||||
sparse-checkout: scripts
|
||||
|
||||
- name: Clean download directory
|
||||
run: rm -rf ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
|
||||
- name: Download signed app
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: signed-mac-app-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
|
||||
- name: Unzip signed app
|
||||
run: |
|
||||
cd ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
ditto -x -k eagle0.app.zip .
|
||||
rm eagle0.app.zip
|
||||
ls -la ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app/
|
||||
|
||||
- name: Wait for Notarization and Staple
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
|
||||
TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
run: |
|
||||
chmod +x ./scripts/notarize_wait.sh
|
||||
./scripts/notarize_wait.sh "${{ needs.build-and-sign.outputs.submission_id }}" "${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app"
|
||||
./scripts/notarize_wait.sh "${{ steps.notarize-submit.outputs.submission_id }}" "${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app"
|
||||
|
||||
- name: Cleanup Keychain
|
||||
if: always()
|
||||
run: |
|
||||
security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
|
||||
|
||||
- name: Zip notarized app for artifact
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: |
|
||||
cd ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
rm -f eagle0.app.zip
|
||||
ditto -c -k --keepParent eagle0.app eagle0.app.zip
|
||||
|
||||
- name: Upload notarized app
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: notarized-mac-app-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC/eagle0.app.zip
|
||||
retention-days: 1
|
||||
- name: Cleanup build directory
|
||||
if: always()
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"
|
||||
|
||||
deploy:
|
||||
needs: [build-and-sign, wait-notarization]
|
||||
if: needs.build-and-sign.outputs.should_deploy == 'true'
|
||||
runs-on: [self-hosted, macOS, notarize, halfdan]
|
||||
outputs:
|
||||
deployed_version: ${{ steps.deploy-mac.outputs.deployed_version }}
|
||||
|
||||
steps:
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
export PATH="${COMMON_PATHS}:${PATH}"
|
||||
for path in /opt/homebrew/bin /usr/local/bin; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
fi
|
||||
done
|
||||
if ! command -v git-lfs >/dev/null 2>&1; then
|
||||
brew install git-lfs
|
||||
fi
|
||||
git-lfs --version
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_LFS_SKIP_SMUDGE: 1
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0 # For version numbering
|
||||
|
||||
- name: Clean download directory
|
||||
run: rm -rf ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
|
||||
- name: Download notarized app
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: notarized-mac-app-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
|
||||
- name: Unzip notarized app
|
||||
run: |
|
||||
cd ${{ env.EAGLE0_BUILD_DIR }}/eagle0MAC
|
||||
ditto -x -k eagle0.app.zip .
|
||||
rm eagle0.app.zip
|
||||
|
||||
- name: Ensure Bazel installed
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
|
||||
- name: Sync Bazel Xcode config
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: ./scripts/sync_bazel_xcode.sh
|
||||
|
||||
- name: Deploy Mac Build
|
||||
id: deploy-mac
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
@@ -401,8 +406,13 @@ jobs:
|
||||
echo "$SPARKLE_EDDSA_PRIVATE_KEY" > "$SPARKLE_PRIVATE_KEY_PATH"
|
||||
chmod 600 "$SPARKLE_PRIVATE_KEY_PATH"
|
||||
|
||||
# Install dmgbuild (creates .DS_Store programmatically, no AppleScript needed)
|
||||
pip3 install dmgbuild
|
||||
# Install dmgbuild in an isolated venv. Homebrew Python rejects system
|
||||
# installs under PEP 668, and mac_build_handler shells out to dmgbuild.
|
||||
DMGBUILD_VENV="${{ env.EAGLE0_BUILD_DIR }}/dmgbuild-venv"
|
||||
python3 -m venv "$DMGBUILD_VENV"
|
||||
"$DMGBUILD_VENV/bin/python" -m pip install --upgrade pip
|
||||
"$DMGBUILD_VENV/bin/python" -m pip install dmgbuild
|
||||
export PATH="$DMGBUILD_VENV/bin:$PATH"
|
||||
|
||||
# Background image for styled DMG
|
||||
BACKGROUND_PATH="$(pwd)/ci/mac/dmg/background.png"
|
||||
@@ -429,8 +439,8 @@ jobs:
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"
|
||||
|
||||
notify-mac:
|
||||
needs: deploy
|
||||
if: needs.deploy.outputs.deployed_version != ''
|
||||
needs: deploy-mac
|
||||
if: needs.deploy-mac.outputs.deployed_version != ''
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Purge CDN cache and notify clients
|
||||
@@ -445,13 +455,13 @@ jobs:
|
||||
-d '{"files": ["mac/*", "addressables/StandaloneOSX/*"]}' \
|
||||
--fail || echo "Warning: CDN purge failed (non-fatal)"
|
||||
|
||||
curl -X POST "https://admin.eagle0.net/notify-update?platform=mac&version=${{ needs.deploy.outputs.deployed_version }}&required=false" \
|
||||
curl -X POST "https://admin.eagle0.net/notify-update?platform=mac&version=${{ needs.deploy-mac.outputs.deployed_version }}&required=false" \
|
||||
-H "X-Notify-Secret: $NOTIFY_SECRET" \
|
||||
--fail --silent --show-error || echo "Warning: Failed to notify clients (non-fatal)"
|
||||
|
||||
# Cleanup job runs regardless of success/failure to prevent artifact accumulation
|
||||
cleanup:
|
||||
needs: [build-and-sign, wait-notarization, deploy, notify-mac]
|
||||
needs: [build-mac, deploy-mac, notify-mac]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -461,7 +471,7 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
# Delete this run's artifacts (names include run ID to avoid conflicts)
|
||||
for artifact_name in signed-mac-app-${{ github.run_id }} notarized-mac-app-${{ github.run_id }}; do
|
||||
for artifact_name in unsigned-mac-app-${{ github.run_id }} notarized-mac-app-${{ github.run_id }} mac-addressables-${{ github.run_id }}; do
|
||||
echo "Deleting artifact: $artifact_name"
|
||||
artifact_id=$(gh api "repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" \
|
||||
-q ".artifacts[] | select(.name == \"$artifact_name\") | .id")
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
name: Renovate Bazel Lockfile
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize, ready_for_review]
|
||||
paths:
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- 'maven_install.json'
|
||||
- 'renovate.json'
|
||||
- '.github/workflows/renovate_bazel_lockfile.yml'
|
||||
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize, ready_for_review]
|
||||
paths:
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- 'maven_install.json'
|
||||
- 'renovate.json'
|
||||
- '.github/workflows/renovate_bazel_lockfile.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.head.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
check-lockfile:
|
||||
if: >-
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.user.login != 'renovate[bot]'
|
||||
runs-on: [self-hosted, bazel]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
lfs: false
|
||||
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
|
||||
- name: Update Maven lockfile
|
||||
env:
|
||||
REPIN: "1"
|
||||
run: bazel run @maven//:pin
|
||||
|
||||
- name: Refresh Bazel lockfile
|
||||
run: bazel build --nobuild //src/main/scala/net/eagle0/eagle:eagle_server //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
|
||||
- name: Verify generated lockfiles are current
|
||||
run: |
|
||||
if git diff --quiet -- MODULE.bazel.lock maven_install.json; then
|
||||
echo "Generated dependency lockfiles are current"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Generated dependency lockfiles are stale. Run the lockfile update commands and commit the result:"
|
||||
echo " REPIN=1 bazel run @maven//:pin"
|
||||
echo " bazel build --nobuild //src/main/scala/net/eagle0/eagle:eagle_server //src/main/cpp/net/eagle0/shardok:shardok-server"
|
||||
git diff -- MODULE.bazel.lock maven_install.json
|
||||
exit 1
|
||||
|
||||
update-lockfile:
|
||||
if: >-
|
||||
github.event.pull_request.user.login == 'renovate[bot]' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository &&
|
||||
startsWith(github.event.pull_request.head.ref, 'renovate/')
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS=(/opt/homebrew/bin /usr/local/bin)
|
||||
for path in "${COMMON_PATHS[@]}"; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
export PATH="$path:$PATH"
|
||||
fi
|
||||
done
|
||||
|
||||
if command -v git-lfs >/dev/null 2>&1; then
|
||||
git-lfs version
|
||||
exit 0
|
||||
fi
|
||||
|
||||
brew install git-lfs
|
||||
git-lfs version
|
||||
|
||||
- name: Checkout Renovate branch
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
token: ${{ secrets.RENOVATE_LOCKFILE_TOKEN || github.token }}
|
||||
lfs: false
|
||||
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
|
||||
- name: Update Maven lockfile
|
||||
env:
|
||||
REPIN: "1"
|
||||
run: bazel run @maven//:pin
|
||||
|
||||
- name: Refresh Bazel lockfile
|
||||
run: bazel build --nobuild //src/main/scala/net/eagle0/eagle:eagle_server //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
|
||||
- name: Commit generated lockfile updates
|
||||
run: |
|
||||
if git diff --quiet -- MODULE.bazel.lock maven_install.json; then
|
||||
echo "Generated dependency lockfiles are already up to date"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add MODULE.bazel.lock maven_install.json
|
||||
git commit -m "Update generated dependency lockfiles"
|
||||
git push origin "HEAD:${{ github.event.pull_request.head.ref }}"
|
||||
@@ -0,0 +1,75 @@
|
||||
name: Renovate Go Artifacts
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize, ready_for_review]
|
||||
paths:
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'renovate.json'
|
||||
- '.github/workflows/renovate_go_artifacts.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
update-go-artifacts:
|
||||
if: >-
|
||||
github.event.pull_request.user.login == 'renovate[bot]' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository &&
|
||||
startsWith(github.event.pull_request.head.ref, 'renovate/')
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS=(/opt/homebrew/bin /usr/local/bin)
|
||||
for path in "${COMMON_PATHS[@]}"; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
export PATH="$path:$PATH"
|
||||
fi
|
||||
done
|
||||
|
||||
if command -v git-lfs >/dev/null 2>&1; then
|
||||
git-lfs version
|
||||
exit 0
|
||||
fi
|
||||
|
||||
brew install git-lfs
|
||||
git-lfs version
|
||||
|
||||
- name: Checkout Renovate branch
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
token: ${{ secrets.RENOVATE_LOCKFILE_TOKEN || github.token }}
|
||||
lfs: false
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache: false
|
||||
|
||||
- name: Update Go module sums
|
||||
run: go mod download all
|
||||
|
||||
- name: Commit generated Go artifact updates
|
||||
run: |
|
||||
if git diff --quiet -- go.sum; then
|
||||
echo "Go artifacts are already up to date"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add go.sum
|
||||
git commit -m "Update generated Go artifacts"
|
||||
git push origin "HEAD:${{ github.event.pull_request.head.ref }}"
|
||||
@@ -11,7 +11,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
|
||||
steps:
|
||||
- name: Ensure AWS CLI is available
|
||||
|
||||
@@ -7,10 +7,14 @@ on:
|
||||
- 'src/main/cpp/**'
|
||||
- 'src/main/protobuf/net/eagle0/shardok/**'
|
||||
- 'src/main/protobuf/net/eagle0/common/**'
|
||||
- 'src/main/go/net/eagle0/build/**'
|
||||
- 'src/main/resources/net/eagle0/shardok/**'
|
||||
- 'ci/BUILD.bazel'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- '.bazelrc'
|
||||
- '.github/workflows/shardok_arm64_build.yml'
|
||||
workflow_dispatch:
|
||||
@@ -30,12 +34,26 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build-shardok-arm64:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
outputs:
|
||||
image_tag: ${{ steps.push-shardok.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Prepare non-LFS checkout
|
||||
env:
|
||||
GIT_CONFIG_GLOBAL: ${{ runner.temp }}/gitconfig-no-lfs
|
||||
GIT_CONFIG_NOSYSTEM: "1"
|
||||
run: |
|
||||
git config --global --unset-all filter.lfs.process || true
|
||||
git config --global filter.lfs.smudge "cat"
|
||||
git config --global filter.lfs.clean "cat"
|
||||
git config --global filter.lfs.required false
|
||||
rm -f .git/hooks/post-checkout .git/hooks/post-merge .git/hooks/pre-push
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_CONFIG_GLOBAL: ${{ runner.temp }}/gitconfig-no-lfs
|
||||
GIT_CONFIG_NOSYSTEM: "1"
|
||||
with:
|
||||
persist-credentials: false
|
||||
lfs: false
|
||||
@@ -50,7 +68,7 @@ jobs:
|
||||
echo "=== Building shardok-server binary for linux-aarch64 ==="
|
||||
bazel build \
|
||||
--platforms=//:linux_arm64 \
|
||||
--extra_toolchains=@llvm_toolchain_linux_arm64//:all \
|
||||
--extra_toolchains=@llvm_toolchain_linux_arm64//:cc-toolchain-aarch64-linux \
|
||||
//src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
|
||||
LINUX_BIN="bazel-bin/src/main/cpp/net/eagle0/shardok/shardok-server"
|
||||
@@ -91,9 +109,10 @@ jobs:
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
# Keep this in sync with the standalone binary build above.
|
||||
bazel build \
|
||||
--platforms=//:linux_arm64 \
|
||||
--extra_toolchains=@llvm_toolchain_linux_arm64//:all \
|
||||
--extra_toolchains=@llvm_toolchain_linux_arm64//:cc-toolchain-aarch64-linux \
|
||||
//ci:shardok_server_image_arm64
|
||||
|
||||
IMAGE_PATH=$(readlink -f bazel-bin/ci/shardok_server_image_arm64)
|
||||
@@ -170,7 +189,7 @@ jobs:
|
||||
echo "Also tagged as: registry.digitalocean.com/eagle0/shardok-server:arm64-latest"
|
||||
|
||||
deploy-hetzner:
|
||||
runs-on: [self-hosted, bazel, halfdan]
|
||||
runs-on: [self-hosted, bazel]
|
||||
needs: [build-shardok-arm64]
|
||||
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
|
||||
environment: production
|
||||
|
||||
@@ -8,11 +8,15 @@ on:
|
||||
- 'src/main/protobuf/net/eagle0/shardok/**'
|
||||
- 'src/main/protobuf/net/eagle0/common/**'
|
||||
- 'src/main/go/net/eagle0/build/**'
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'WORKSPACE'
|
||||
- 'MODULE.bazel'
|
||||
- 'MODULE.bazel.lock'
|
||||
- 'BUILD.bazel'
|
||||
- '.bazelrc'
|
||||
- 'ci/github_actions/ensure_bazel_installed.sh'
|
||||
- 'scripts/build_shardok_ci.sh'
|
||||
- '.github/workflows/shardok_build.yml'
|
||||
|
||||
concurrency:
|
||||
@@ -52,4 +56,4 @@ jobs:
|
||||
- name: Ensure Bazel installed
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
- name: Build Shardok server
|
||||
run: bazel build -c opt //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
run: ./scripts/build_shardok_ci.sh
|
||||
|
||||
@@ -21,6 +21,8 @@ on:
|
||||
- "ci/github_actions/ensure_unity_installed.sh"
|
||||
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
|
||||
- "MODULE.bazel"
|
||||
- "MODULE.bazel.lock"
|
||||
- ".bazelrc"
|
||||
- "WORKSPACE"
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
@@ -42,13 +44,12 @@ on:
|
||||
- "ci/github_actions/ensure_unity_installed.sh"
|
||||
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
|
||||
- "MODULE.bazel"
|
||||
- "MODULE.bazel.lock"
|
||||
- ".bazelrc"
|
||||
- "WORKSPACE"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
|
||||
env:
|
||||
@@ -57,9 +58,12 @@ env:
|
||||
|
||||
jobs:
|
||||
windows-unity:
|
||||
runs-on: [self-hosted, macOS, unity-windows, halfdan]
|
||||
runs-on: [self-hosted, macOS, unity-windows]
|
||||
outputs:
|
||||
deployed_version: ${{ steps.get-version.outputs.deployed_version }}
|
||||
addressables_changed: ${{ steps.addressables.outputs.changed }}
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
steps:
|
||||
- name: Prune stale PR refs
|
||||
@@ -95,6 +99,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
lfs: false # Fetch LFS after checkout to avoid stale ref issues
|
||||
clean: false # Library/ persists between runs on self-hosted runners
|
||||
fetch-depth: 2 # Keep the previous main commit available for Addressables change detection
|
||||
|
||||
- name: Clean stale files
|
||||
run: |
|
||||
@@ -156,21 +161,209 @@ jobs:
|
||||
mkdir -p src/main/csharp/net/eagle0/clients/unity/eagle0/Library
|
||||
grep "m_EditorVersion:" src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt | head -1 | sed 's/m_EditorVersion: //' > src/main/csharp/net/eagle0/clients/unity/eagle0/Library/.last_unity_version
|
||||
|
||||
- name: Upload Addressables to CDN
|
||||
- name: Detect Addressables changes
|
||||
id: addressables
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
BASE_SHA="${{ github.event.before }}"
|
||||
HEAD_SHA="${{ github.sha }}"
|
||||
|
||||
if [ -z "$BASE_SHA" ] || [[ "$BASE_SHA" =~ ^0+$ ]]; then
|
||||
echo "No usable base SHA for this run; uploading Addressables as a safe default."
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! git cat-file -e "$BASE_SHA^{commit}"; then
|
||||
echo "Base SHA $BASE_SHA is not available locally; uploading Addressables as a safe default."
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
UNITY_PROJECT="src/main/csharp/net/eagle0/clients/unity/eagle0"
|
||||
ADDRESSABLE_PREFIXES=(
|
||||
"$UNITY_PROJECT/Assets/AddressableAssetsData/"
|
||||
"$UNITY_PROJECT/Assets/Eagle/Effects/"
|
||||
"$UNITY_PROJECT/Assets/Hex Tiles/"
|
||||
"$UNITY_PROJECT/Assets/TileableBridgePack/"
|
||||
"$UNITY_PROJECT/Assets/Shardok/LargeFlames.prefab"
|
||||
"$UNITY_PROJECT/Assets/Shardok/soundEffects/"
|
||||
"$UNITY_PROJECT/Assets/Shardok/Sounds/"
|
||||
"$UNITY_PROJECT/Assets/Medieval Combat Sounds/"
|
||||
"$UNITY_PROJECT/Assets/Magic Spells Sound Effects LITE/"
|
||||
"$UNITY_PROJECT/Assets/Fantasy Interface Sounds/"
|
||||
"$UNITY_PROJECT/Assets/AustraliaAnimalsPackv1/"
|
||||
"$UNITY_PROJECT/Assets/Editor/BuildScript.cs"
|
||||
"ci/github_actions/upload_addressables.sh"
|
||||
)
|
||||
|
||||
changed=false
|
||||
while IFS= read -r file; do
|
||||
for prefix in "${ADDRESSABLE_PREFIXES[@]}"; do
|
||||
if [[ "$file" == "$prefix"* ]]; then
|
||||
echo "Addressables-impacting change: $file"
|
||||
changed=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$changed" = "true" ]; then
|
||||
break
|
||||
fi
|
||||
done < <(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
|
||||
|
||||
if [ "$changed" = "true" ]; then
|
||||
echo "Uploading Addressables because their inputs changed."
|
||||
else
|
||||
echo "Skipping Addressables upload; no Addressables inputs changed."
|
||||
fi
|
||||
|
||||
echo "changed=$changed" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload Windows player for deploy
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: windows-unity-player-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0WIN
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload Windows Addressables for deploy
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request' && steps.addressables.outputs.changed == 'true'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: windows-addressables-${{ github.run_id }}
|
||||
path: src/main/csharp/net/eagle0/clients/unity/eagle0/ServerData/StandaloneWindows64
|
||||
if-no-files-found: ignore
|
||||
retention-days: 1
|
||||
|
||||
- name: Archive build log
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: editor_win.log
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/editor_win.log
|
||||
retention-days: 3
|
||||
- name: Archive EditMode test artifacts
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: unity_editmode_tests
|
||||
path: |
|
||||
${{ env.EAGLE0_BUILD_DIR }}/editor_editmode_tests.log
|
||||
${{ env.EAGLE0_BUILD_DIR }}/editmode-test-results.xml
|
||||
retention-days: 3
|
||||
- name: Cleanup build directory
|
||||
if: always()
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"
|
||||
|
||||
deploy-windows:
|
||||
needs: windows-unity
|
||||
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
runs-on: [self-hosted, macOS, bazel]
|
||||
outputs:
|
||||
deployed_version: ${{ steps.get-version.outputs.deployed_version }}
|
||||
concurrency:
|
||||
group: unity-windows-deploy-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
steps:
|
||||
- name: Prune stale PR refs
|
||||
run: |
|
||||
# Self-hosted runners persist .git between runs. When a PR is updated,
|
||||
# old local refs (refs/remotes/pull/*/merge) may point to commits whose
|
||||
# objects were never fetched or have been pruned. Remove these stale refs
|
||||
# before checkout to prevent "missing object" errors.
|
||||
if [ -d ".git" ]; then
|
||||
echo "Pruning stale PR refs..."
|
||||
git for-each-ref --format='%(refname)' refs/remotes/pull/ 2>/dev/null | \
|
||||
xargs -r git update-ref -d 2>/dev/null || true
|
||||
fi
|
||||
|
||||
- name: Ensure Git LFS available for checkout
|
||||
run: |
|
||||
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
export PATH="${COMMON_PATHS}:${PATH}"
|
||||
for path in /opt/homebrew/bin /usr/local/bin; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "$path" >> "$GITHUB_PATH"
|
||||
fi
|
||||
done
|
||||
if ! command -v git-lfs >/dev/null 2>&1; then
|
||||
brew install git-lfs
|
||||
fi
|
||||
git-lfs --version
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
env:
|
||||
GIT_LFS_SKIP_SMUDGE: 1
|
||||
with:
|
||||
persist-credentials: false
|
||||
lfs: false
|
||||
clean: false
|
||||
|
||||
- name: Check if run is still latest main
|
||||
id: check-latest
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/main" ]]; then
|
||||
LATEST_SHA=$(curl -fsSL \
|
||||
-H "Authorization: Bearer ${{ github.token }}" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/commits/main" \
|
||||
| python3 -c 'import json, sys; print(json.load(sys.stdin)["sha"])')
|
||||
if [[ "$LATEST_SHA" != "${{ github.sha }}" ]]; then
|
||||
echo "Skipping deploy because ${{ github.sha }} is no longer latest main ($LATEST_SHA is latest)"
|
||||
echo "should_deploy=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
echo "should_deploy=true" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Clean deploy directory
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}/eagle0WIN"
|
||||
|
||||
- name: Download Windows player
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: windows-unity-player-${{ github.run_id }}
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/eagle0WIN
|
||||
|
||||
- name: Clean Addressables directory
|
||||
if: steps.check-latest.outputs.should_deploy == 'true' && needs.windows-unity.outputs.addressables_changed == 'true'
|
||||
run: rm -rf src/main/csharp/net/eagle0/clients/unity/eagle0/ServerData/StandaloneWindows64
|
||||
|
||||
- name: Download Windows Addressables
|
||||
if: steps.check-latest.outputs.should_deploy == 'true' && needs.windows-unity.outputs.addressables_changed == 'true'
|
||||
uses: actions/download-artifact@v8
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: windows-addressables-${{ github.run_id }}
|
||||
path: src/main/csharp/net/eagle0/clients/unity/eagle0/ServerData/StandaloneWindows64
|
||||
|
||||
- name: Ensure Bazel installed
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: ./ci/github_actions/ensure_bazel_installed.sh
|
||||
|
||||
- name: Upload Addressables to CDN
|
||||
if: steps.check-latest.outputs.should_deploy == 'true' && needs.windows-unity.outputs.addressables_changed == 'true'
|
||||
env:
|
||||
ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
run: ./ci/github_actions/upload_addressables.sh StandaloneWindows64
|
||||
- name: Deploy Windows unity
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
run: bazel run //src/main/go/net/eagle0/build/unity3d_windows_build_handler:unity3d_windows_build_handler -- "${{ env.EAGLE0_BUILD_DIR }}/eagle0WIN" "/tmp/unity_manifest.txt"
|
||||
|
||||
- name: Update unified manifest
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
env:
|
||||
ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
@@ -195,40 +388,47 @@ jobs:
|
||||
|
||||
- name: Export deployed version
|
||||
id: get-version
|
||||
if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
if: steps.check-latest.outputs.should_deploy == 'true'
|
||||
run: |
|
||||
VERSION=$(grep "^version=" /tmp/unity_manifest.txt | cut -d= -f2 || date +%Y.%m.%d)
|
||||
echo "deployed_version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Archive build log
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: editor_win.log
|
||||
path: ${{ env.EAGLE0_BUILD_DIR }}/editor_win.log
|
||||
retention-days: 3
|
||||
- name: Archive EditMode test artifacts
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: unity_editmode_tests
|
||||
path: |
|
||||
${{ env.EAGLE0_BUILD_DIR }}/editor_editmode_tests.log
|
||||
${{ env.EAGLE0_BUILD_DIR }}/editmode-test-results.xml
|
||||
retention-days: 3
|
||||
- name: Cleanup build directory
|
||||
if: always()
|
||||
run: rm -rf "${{ env.EAGLE0_BUILD_DIR }}"
|
||||
|
||||
notify-windows:
|
||||
needs: windows-unity
|
||||
if: needs.windows-unity.outputs.deployed_version != ''
|
||||
needs: deploy-windows
|
||||
if: needs.deploy-windows.outputs.deployed_version != ''
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify clients of update
|
||||
env:
|
||||
NOTIFY_SECRET: ${{ secrets.EAGLE_NOTIFY_SECRET }}
|
||||
run: |
|
||||
curl -X POST "https://admin.eagle0.net/notify-update?platform=windows&version=${{ needs.windows-unity.outputs.deployed_version }}&required=false" \
|
||||
curl -X POST "https://admin.eagle0.net/notify-update?platform=windows&version=${{ needs.deploy-windows.outputs.deployed_version }}&required=false" \
|
||||
-H "X-Notify-Secret: $NOTIFY_SECRET" \
|
||||
--fail --silent --show-error || echo "Warning: Failed to notify clients (non-fatal)"
|
||||
|
||||
# Cleanup job runs regardless of success/failure to prevent artifact accumulation
|
||||
cleanup:
|
||||
needs: [windows-unity, deploy-windows, notify-windows]
|
||||
if: always() && github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Delete this run's Windows deploy artifacts
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
# Delete this run's artifacts (names include run ID to avoid conflicts)
|
||||
for artifact_name in windows-unity-player-${{ github.run_id }} windows-addressables-${{ github.run_id }}; do
|
||||
echo "Deleting artifact: $artifact_name"
|
||||
artifact_id=$(gh api "repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" \
|
||||
-q ".artifacts[] | select(.name == \"$artifact_name\") | .id")
|
||||
if [ -n "$artifact_id" ]; then
|
||||
echo "Deleting artifact ID: $artifact_id"
|
||||
gh api -X DELETE "repos/${{ github.repository }}/actions/artifacts/$artifact_id" || true
|
||||
fi
|
||||
done
|
||||
echo "Cleanup complete"
|
||||
|
||||
@@ -49,6 +49,21 @@ When code changes appear correct locally, create the PR promptly even if long-ru
|
||||
Opening the PR starts CI on the build machines, uploads results to the Bazel remote cache, and can speed up subsequent
|
||||
local validation. Continue monitoring any already-started local and CI validation after opening the PR.
|
||||
|
||||
For PRs expected to trigger substantial Bazel work in CI, run the relevant Bazel builds and tests locally too. This
|
||||
workstation is fast, and local Bazel runs can help hydrate the remote cache for the CI builders while still giving
|
||||
earlier signal on failures.
|
||||
|
||||
## GitHub CLI PR Bodies
|
||||
|
||||
When creating or editing PR descriptions with multiline bodies, write the body to a temporary markdown file and pass it
|
||||
with `gh pr create --body-file <path>` or `gh pr edit <number> --body-file <path>`. Do not use multiline `$'...'`
|
||||
shell quoting for PR bodies; Codex's permission matching may treat that as a complex shell command instead of a clean
|
||||
`gh pr` invocation, causing unnecessary approval prompts.
|
||||
|
||||
Write these temporary body files, and any other scratch files needed for commands, under a known writable location such
|
||||
as `/private/tmp`, `$TMPDIR`, or the current repository workspace. Do not use protected paths that require additional
|
||||
user permission just to create or edit temporary files.
|
||||
|
||||
---
|
||||
|
||||
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
|
||||
@@ -90,14 +105,14 @@ Unity Client ↔ Eagle (gRPC streaming) ↔ Shardok (internal gRPC)
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# Build Eagle server (Scala strategic layer)
|
||||
bazel build //src/main/scala/net/eagle0/eagle:eagle_server_deploy.jar
|
||||
# Build Eagle server using the same target as GitHub Actions
|
||||
./scripts/build_eagle_ci.sh
|
||||
|
||||
# Build Shardok server (C++ tactical layer)
|
||||
bazel build -c opt //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
# Build Shardok server using the same target and flags as GitHub Actions
|
||||
./scripts/build_shardok_ci.sh
|
||||
|
||||
# Shardok server includes both AI algorithms
|
||||
bazel build //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
# Warm the remote cache for the main GitHub Actions Bazel builds
|
||||
./scripts/hydrate_bazel_remote_cache.sh
|
||||
|
||||
# Build Unity/C# client
|
||||
./scripts/build_protos.sh # Protocol buffer generation for Unity
|
||||
@@ -150,6 +165,19 @@ bazel run gazelle # Update Go build files
|
||||
|
||||
The pre-commit hook runs gazelle but only checks if it succeeds - it does NOT verify the BUILD files are in canonical format. The `gazelle_test` will fail if deps are not alphabetically sorted. **Always run gazelle manually after BUILD file changes.**
|
||||
|
||||
### Bazel Cache Hydration
|
||||
|
||||
When making changes that will trigger GitHub Actions Bazel builds, run the matching CI script instead of hand-writing
|
||||
`bazel build` commands. The scripts keep local cache hydration aligned with CI targets, compilation modes, and flags:
|
||||
|
||||
```bash
|
||||
./scripts/build_eagle_ci.sh
|
||||
./scripts/build_shardok_ci.sh
|
||||
./scripts/hydrate_bazel_remote_cache.sh
|
||||
```
|
||||
|
||||
Use direct `bazel build` commands only for targeted debugging where CI cache hydration is not the goal.
|
||||
|
||||
### Code Formatting
|
||||
|
||||
```bash
|
||||
@@ -210,7 +238,7 @@ ShardokAIClient client(playerId, isDefender, hexMap, settings, AIAlgorithmType::
|
||||
|
||||
```bash
|
||||
# Build the server (includes both AI algorithms)
|
||||
bazel build //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
./scripts/build_shardok_ci.sh
|
||||
|
||||
# Test both algorithms
|
||||
bazel test //src/test/cpp/net/eagle0/shardok/ai:ai_iterative_deepening_test
|
||||
@@ -253,7 +281,7 @@ to be used for different players or game situations within the same server proce
|
||||
**C# (Unity Client):**
|
||||
|
||||
- Located in `/src/main/csharp/net/eagle0/clients/unity/eagle0/`
|
||||
- Uses Unity 6 (6000.4.9f1) with comprehensive protobuf integration (100+ .proto files)
|
||||
- Uses Unity 6 (6000.4.10f1) with comprehensive protobuf integration (100+ .proto files)
|
||||
- Key components: `EagleConnection.cs` (gRPC client), `EagleGameController.cs` (main game logic)
|
||||
- Real-time bidirectional streaming with server via `PersistentClientConnection.cs`
|
||||
- Strategic map UI in `Assets/Eagle/`, tactical battle UI in `Assets/Shardok/`
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "nogo")
|
||||
load("@rules_shell//shell:sh_test.bzl", "sh_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
@@ -10,6 +11,7 @@ platform(
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:x86_64",
|
||||
],
|
||||
missing_toolchain_error = "No Linux x86_64 toolchain matched. Docker/Eagle image builds should pass --platforms=//:linux_x86_64 and --extra_toolchains=@llvm_toolchain_linux//:cc-toolchain-x86_64-linux when compiling C++ code.",
|
||||
)
|
||||
|
||||
# Platform for cross-compiling to Linux ARM64
|
||||
@@ -19,6 +21,7 @@ platform(
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:aarch64",
|
||||
],
|
||||
missing_toolchain_error = "No Linux ARM64 toolchain matched. Shardok ARM64 builds should pass --platforms=//:linux_arm64 and --extra_toolchains=@llvm_toolchain_linux_arm64//:cc-toolchain-aarch64-linux.",
|
||||
)
|
||||
|
||||
gazelle(name = "gazelle")
|
||||
|
||||
@@ -228,7 +228,7 @@ to be used for different players or game situations within the same server proce
|
||||
**C# (Unity Client):**
|
||||
|
||||
- Located in `/src/main/csharp/net/eagle0/clients/unity/eagle0/`
|
||||
- Uses Unity 6 (6000.4.9f1) with comprehensive protobuf integration (100+ .proto files)
|
||||
- Uses Unity 6 (6000.4.10f1) with comprehensive protobuf integration (100+ .proto files)
|
||||
- Key components: `EagleConnection.cs` (gRPC client), `EagleGameController.cs` (main game logic)
|
||||
- Real-time bidirectional streaming with server via `PersistentClientConnection.cs`
|
||||
- Strategic map UI in `Assets/Eagle/`, tactical battle UI in `Assets/Shardok/`
|
||||
|
||||
+102
-64
@@ -3,25 +3,37 @@ module(name = "net_eagle0")
|
||||
# Version constants
|
||||
SCALA_VERSION = "3.7.4"
|
||||
|
||||
NETTY_VERSION = "4.1.127.Final"
|
||||
NETTY_VERSION = "4.1.135.Final"
|
||||
|
||||
SCALAPB_VERSION = "1.0.0-alpha.1"
|
||||
SCALAPB_VERSION = "1.0.0-alpha.5"
|
||||
|
||||
AWS_SDK_VERSION = "2.41.18"
|
||||
SCALAPB_JSON4S_VERSION = "1.0.0-alpha.1"
|
||||
|
||||
AWS_SDK_VERSION = "2.46.9"
|
||||
|
||||
SLF4J_VERSION = "2.0.18"
|
||||
|
||||
#
|
||||
# Core Build Tools
|
||||
#
|
||||
|
||||
bazel_dep(name = "bazel_skylib", version = "1.9.0")
|
||||
bazel_dep(name = "platforms", version = "1.0.0")
|
||||
bazel_dep(name = "aspect_rules_esbuild", version = "0.26.0")
|
||||
bazel_dep(name = "aspect_rules_js", version = "3.2.2")
|
||||
bazel_dep(name = "bazel_jar_jar", version = "0.1.15", repo_name = "bazel_jar_jar")
|
||||
bazel_dep(name = "platforms", version = "1.1.0")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.21.5")
|
||||
bazel_dep(name = "rules_foreign_cc", version = "0.15.1")
|
||||
bazel_dep(name = "rules_android", version = "0.7.3")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.7.4")
|
||||
bazel_dep(name = "rules_pkg", version = "1.2.0")
|
||||
bazel_dep(name = "rules_shell", version = "0.8.0")
|
||||
|
||||
#
|
||||
# Language Support - Scala
|
||||
#
|
||||
|
||||
bazel_dep(name = "rules_scala", version = "7.2.1")
|
||||
bazel_dep(name = "rules_scala", version = "7.2.6")
|
||||
|
||||
scala_config = use_extension(
|
||||
"@rules_scala//scala/extensions:config.bzl",
|
||||
@@ -41,21 +53,31 @@ scala_deps.scala_proto()
|
||||
# Language Support - C++
|
||||
#
|
||||
|
||||
bazel_dep(name = "toolchains_llvm", version = "1.6.0")
|
||||
bazel_dep(name = "toolchains_llvm", version = "1.7.0")
|
||||
|
||||
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
|
||||
|
||||
LLVM_VERSION = "22.1.7"
|
||||
|
||||
LLVM_DISTRIBUTIONS = {
|
||||
"LLVM-22.1.7-Linux-ARM64.tar.xz": "118ca2d3ad9da34367e05735317854e7977db45dc4c02a32af58da64c23b8789",
|
||||
"LLVM-22.1.7-Linux-X64.tar.xz": "edb0522b41e261819c06ea437d249f9b8acfa413d3805bc9920eec6fb76ff830",
|
||||
"LLVM-22.1.7-macOS-ARM64.tar.xz": "4177245188b0a30a6539c96b361dea56f253485756bfd8927a6a59e7301e7806",
|
||||
}
|
||||
|
||||
# Native toolchain (macOS -> macOS, Linux -> Linux)
|
||||
llvm.toolchain(
|
||||
name = "llvm_toolchain",
|
||||
llvm_version = "20.1.4",
|
||||
extra_llvm_distributions = LLVM_DISTRIBUTIONS,
|
||||
llvm_version = LLVM_VERSION,
|
||||
)
|
||||
|
||||
# Cross-compilation toolchain (macOS -> Linux x86_64)
|
||||
# Uses the same LLVM distribution but with a Linux sysroot
|
||||
llvm.toolchain(
|
||||
name = "llvm_toolchain_linux",
|
||||
llvm_version = "20.1.4",
|
||||
extra_llvm_distributions = LLVM_DISTRIBUTIONS,
|
||||
llvm_version = LLVM_VERSION,
|
||||
)
|
||||
|
||||
# Linux x86_64 sysroot for cross-compilation
|
||||
@@ -68,7 +90,8 @@ llvm.sysroot(
|
||||
# Cross-compilation toolchain (macOS -> Linux ARM64)
|
||||
llvm.toolchain(
|
||||
name = "llvm_toolchain_linux_arm64",
|
||||
llvm_version = "20.1.4",
|
||||
extra_llvm_distributions = LLVM_DISTRIBUTIONS,
|
||||
llvm_version = LLVM_VERSION,
|
||||
)
|
||||
|
||||
# Linux ARM64 sysroot for cross-compilation
|
||||
@@ -77,7 +100,6 @@ llvm.sysroot(
|
||||
label = "@linux_sysroot_arm64//sysroot",
|
||||
targets = ["linux-aarch64"],
|
||||
)
|
||||
|
||||
use_repo(llvm, "llvm_toolchain", "llvm_toolchain_linux", "llvm_toolchain_linux_arm64")
|
||||
|
||||
# Download the Linux sysroots (Ubuntu 24.04 Noble for C++23 support)
|
||||
@@ -103,11 +125,11 @@ sysroot(
|
||||
# Language Support - Go
|
||||
#
|
||||
|
||||
bazel_dep(name = "rules_go", version = "0.59.0", repo_name = "io_bazel_rules_go")
|
||||
bazel_dep(name = "gazelle", version = "0.47.0", repo_name = "bazel_gazelle")
|
||||
bazel_dep(name = "rules_go", version = "0.61.1", repo_name = "io_bazel_rules_go")
|
||||
bazel_dep(name = "gazelle", version = "0.51.3", repo_name = "bazel_gazelle")
|
||||
|
||||
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.23.3")
|
||||
go_sdk.download(version = "1.25.11")
|
||||
use_repo(go_sdk, "go_default_sdk")
|
||||
|
||||
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
|
||||
@@ -130,7 +152,7 @@ use_repo(
|
||||
# Language Support - Rust
|
||||
#
|
||||
|
||||
bazel_dep(name = "rules_rust", version = "0.68.1")
|
||||
bazel_dep(name = "rules_rust", version = "0.70.0")
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
rust.toolchain(edition = "2021")
|
||||
@@ -150,8 +172,16 @@ use_repo(crate, "map_generator_crates")
|
||||
# Platform Support - Apple/iOS
|
||||
#
|
||||
|
||||
bazel_dep(name = "apple_support", version = "1.24.1", repo_name = "build_bazel_apple_support")
|
||||
bazel_dep(name = "rules_apple", version = "4.3.3", repo_name = "build_bazel_rules_apple")
|
||||
bazel_dep(name = "apple_support", version = "2.6.1", repo_name = "build_bazel_apple_support")
|
||||
bazel_dep(name = "rules_apple", version = "4.5.3", repo_name = "build_bazel_rules_apple")
|
||||
|
||||
multiple_version_override(
|
||||
module_name = "rules_swift",
|
||||
versions = [
|
||||
"2.1.1",
|
||||
"3.5.0",
|
||||
],
|
||||
)
|
||||
|
||||
# Register Apple CC toolchain for Objective-C compilation
|
||||
apple_cc_configure = use_extension(
|
||||
@@ -164,11 +194,15 @@ use_repo(apple_cc_configure, "local_config_apple_cc", "local_config_apple_cc_too
|
||||
# Protocol Buffers & RPC
|
||||
#
|
||||
|
||||
bazel_dep(name = "protobuf", version = "33.5", repo_name = "com_google_protobuf")
|
||||
bazel_dep(name = "protobuf", version = "35.1", repo_name = "com_google_protobuf")
|
||||
single_version_override(
|
||||
module_name = "protobuf",
|
||||
version = "35.1",
|
||||
)
|
||||
|
||||
# Use pre-built protoc binaries instead of compiling from source.
|
||||
# See: https://protobuf.dev/reference/cpp/cpp-generated/#invocation
|
||||
prebuilt_protoc = use_extension("@com_google_protobuf//bazel/private:prebuilt_protoc_extension.bzl", "protoc")
|
||||
prebuilt_protoc = use_extension("@com_google_protobuf//bazel/private/oss/toolchains/prebuilt:protoc_extension.bzl", "protoc")
|
||||
use_repo(
|
||||
prebuilt_protoc,
|
||||
"prebuilt_protoc.linux_aarch_64",
|
||||
@@ -183,21 +217,18 @@ use_repo(
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_proto", version = "7.1.0")
|
||||
bazel_dep(name = "rules_cc", version = "0.2.14")
|
||||
bazel_dep(name = "grpc", version = "1.78.0")
|
||||
bazel_dep(name = "rules_cc", version = "0.2.19")
|
||||
bazel_dep(name = "grpc", version = "1.81.1")
|
||||
|
||||
# Patch grpc 1.78.0 to fix rules_python incompatibility: grpc requests Python
|
||||
# 3.14.0b2 toolchain but rules_python >= 1.6.0 removed it in favor of 3.14.
|
||||
# Upstream fix: https://github.com/grpc/grpc/commit/459279b
|
||||
# TODO: Remove this override once a fixed grpc version is published to BCR.
|
||||
# gRPC 1.81.1's generated upb module map trips Clang's layering check in the
|
||||
# Linux ARM64 cross-toolchain even though the normal Bazel deps are present.
|
||||
single_version_override(
|
||||
module_name = "grpc",
|
||||
patch_strip = 1,
|
||||
patches = ["//third_party/patches:grpc_fix_python_version.patch"],
|
||||
version = "1.78.0",
|
||||
patches = ["//third_party/grpc/patches:disable_xds_client_layering_check.patch"],
|
||||
)
|
||||
|
||||
bazel_dep(name = "grpc-java", version = "1.78.0")
|
||||
bazel_dep(name = "grpc-java", version = "1.78.0.bcr.1")
|
||||
bazel_dep(name = "rules_proto_grpc_csharp", version = "5.8.0")
|
||||
bazel_dep(name = "flatbuffers", version = "25.12.19")
|
||||
|
||||
@@ -205,13 +236,13 @@ bazel_dep(name = "flatbuffers", version = "25.12.19")
|
||||
# Testing
|
||||
#
|
||||
|
||||
bazel_dep(name = "googletest", version = "1.17.0")
|
||||
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
|
||||
|
||||
#
|
||||
# Container Images (OCI)
|
||||
#
|
||||
|
||||
bazel_dep(name = "rules_oci", version = "2.2.7")
|
||||
bazel_dep(name = "rules_oci", version = "2.3.0")
|
||||
bazel_dep(name = "aspect_bazel_lib", version = "2.22.5")
|
||||
|
||||
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
|
||||
@@ -222,19 +253,19 @@ oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
|
||||
# curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json" "https://registry-1.docker.io/v2/library/eclipse-temurin/manifests/25-jre" | python3 -c "import json,sys; m=json.load(sys.stdin); [print(p['digest']) for p in m.get('manifests',[]) if p['platform']['architecture']=='amd64']"
|
||||
oci.pull(
|
||||
name = "eclipse_temurin_25_jre",
|
||||
digest = "sha256:98236ffdfb61cff3fc4f8e40e5b80460a5a4c35a0f56a5b4182a926844a7db49",
|
||||
digest = "sha256:0beb258e10ad28d2bae0f74349a170bdfa67da0ef87c028cbf3d95c3e1170120",
|
||||
image = "docker.io/library/eclipse-temurin",
|
||||
platforms = ["linux/amd64"],
|
||||
tag = "25-jre",
|
||||
tag = "26-jre",
|
||||
)
|
||||
|
||||
# Base image for JFR sidecar (Java 25 JDK - includes jcmd for JFR dumps)
|
||||
oci.pull(
|
||||
name = "eclipse_temurin_25_jdk",
|
||||
digest = "sha256:bc2d562355813350f47bc472b9721b0b84761866671ad95d9a9f1151fa69da6e",
|
||||
digest = "sha256:41c3a5b8a607d226c73e81538cd94d0e66f746f41f057561447eb47b40a91a65",
|
||||
image = "docker.io/library/eclipse-temurin",
|
||||
platforms = ["linux/amd64"],
|
||||
tag = "25-jdk",
|
||||
tag = "26-jdk",
|
||||
)
|
||||
|
||||
# Base image for Shardok (Ubuntu 24.04 for C++ runtime)
|
||||
@@ -245,15 +276,16 @@ oci.pull(
|
||||
"linux/amd64",
|
||||
"linux/arm64/v8",
|
||||
],
|
||||
tag = "24.04",
|
||||
tag = "26.04",
|
||||
)
|
||||
|
||||
# Base image for Admin Server (Alpine for lightweight Go binary)
|
||||
oci.pull(
|
||||
name = "alpine_linux",
|
||||
digest = "sha256:a2d49ea686c2adfe3c992e47dc3b5e7fa6e6b5055609400dc2acaeb241c829f4",
|
||||
image = "docker.io/library/alpine",
|
||||
platforms = ["linux/amd64"],
|
||||
tag = "3.21",
|
||||
tag = "3.24",
|
||||
)
|
||||
use_repo(oci, "alpine_linux", "alpine_linux_linux_amd64", "eclipse_temurin_25_jdk", "eclipse_temurin_25_jdk_linux_amd64", "eclipse_temurin_25_jre", "eclipse_temurin_25_jre_linux_amd64", "ubuntu_24_04", "ubuntu_24_04_linux_amd64", "ubuntu_24_04_linux_arm64_v8")
|
||||
|
||||
@@ -261,8 +293,8 @@ use_repo(oci, "alpine_linux", "alpine_linux_linux_amd64", "eclipse_temurin_25_jd
|
||||
# Java/Scala Dependencies
|
||||
#
|
||||
|
||||
bazel_dep(name = "rules_java", version = "9.3.0")
|
||||
bazel_dep(name = "rules_jvm_external", version = "6.10")
|
||||
bazel_dep(name = "rules_java", version = "9.6.1")
|
||||
bazel_dep(name = "rules_jvm_external", version = "7.0")
|
||||
|
||||
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
|
||||
maven.install(
|
||||
@@ -281,7 +313,7 @@ maven.install(
|
||||
|
||||
# ScalaPB
|
||||
"com.thesamet.scalapb:lenses_3:%s" % SCALAPB_VERSION,
|
||||
"com.thesamet.scalapb:scalapb-json4s_3:%s" % SCALAPB_VERSION,
|
||||
"com.thesamet.scalapb:scalapb-json4s_3:%s" % SCALAPB_JSON4S_VERSION,
|
||||
"com.thesamet.scalapb:scalapb-runtime_3:%s" % SCALAPB_VERSION,
|
||||
"com.thesamet.scalapb:scalapb-runtime-grpc_3:%s" % SCALAPB_VERSION,
|
||||
"com.thesamet.scalapb:compilerplugin_3:%s" % SCALAPB_VERSION,
|
||||
@@ -293,10 +325,10 @@ maven.install(
|
||||
"org.json4s:json4s-native_3:4.1.0-M8",
|
||||
|
||||
# Testing
|
||||
"org.scalamock:scalamock_3:7.4.1",
|
||||
"org.scalamock:scalamock_3:7.5.5",
|
||||
|
||||
# Developer tools
|
||||
"org.scalameta:scalafmt-cli_2.13:3.9.9",
|
||||
"org.scalameta:scalafmt-cli_2.13:3.11.1",
|
||||
|
||||
# AWS SDK
|
||||
"software.amazon.awssdk:s3-transfer-manager:%s" % AWS_SDK_VERSION,
|
||||
@@ -308,38 +340,42 @@ maven.install(
|
||||
"software.amazon.awssdk:http-client-spi:%s" % AWS_SDK_VERSION,
|
||||
|
||||
# AWS Lambda
|
||||
"com.amazonaws:aws-lambda-java-core:1.2.3",
|
||||
"com.amazonaws:aws-lambda-java-events:3.13.0",
|
||||
"com.amazonaws:aws-lambda-java-core:1.4.0",
|
||||
"com.amazonaws:aws-lambda-java-events:3.16.1",
|
||||
|
||||
# Logging
|
||||
"org.slf4j:slf4j-api:2.0.16",
|
||||
"org.slf4j:slf4j-simple:2.0.16",
|
||||
"org.slf4j:slf4j-api:%s" % SLF4J_VERSION,
|
||||
"org.slf4j:slf4j-simple:%s" % SLF4J_VERSION,
|
||||
|
||||
# Other
|
||||
"org.reactivestreams:reactive-streams:1.0.4",
|
||||
"javax.xml.bind:jaxb-api:2.3.1",
|
||||
|
||||
# OkHttp (for SSE with read timeout support, OAuth HTTP calls)
|
||||
"com.squareup.okhttp3:okhttp:4.12.0",
|
||||
"com.squareup.okhttp3:okhttp-sse:4.12.0",
|
||||
"com.squareup.okhttp3:okhttp-jvm:5.4.0",
|
||||
"com.squareup.okhttp3:okhttp-sse:5.4.0",
|
||||
|
||||
# JWT (for OAuth token handling)
|
||||
"com.nimbusds:nimbus-jose-jwt:9.37.3",
|
||||
"com.nimbusds:nimbus-jose-jwt:10.9.1",
|
||||
|
||||
# Error tracking
|
||||
"io.sentry:sentry:8.31.0",
|
||||
"io.sentry:sentry:8.43.2",
|
||||
|
||||
# SQLite for client text storage
|
||||
"org.xerial:sqlite-jdbc:3.46.1.0",
|
||||
"org.xerial:sqlite-jdbc:3.53.2.0",
|
||||
|
||||
# Postgres for production history benchmarking and migration work
|
||||
"org.postgresql:postgresql:42.7.4",
|
||||
"org.postgresql:postgresql:42.7.11",
|
||||
],
|
||||
duplicate_version_warning = "error",
|
||||
fail_if_repin_required = True,
|
||||
known_contributing_modules = [
|
||||
"grpc-java",
|
||||
"protobuf",
|
||||
],
|
||||
lock_file = "//:maven_install.json",
|
||||
repositories = [
|
||||
"https://repo1.maven.org/maven2",
|
||||
"https://repo.maven.apache.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -349,7 +385,7 @@ maven.artifact(
|
||||
artifact = "scala3-staging_3",
|
||||
exclusions = ["org.scala-lang:scala3-compiler_3"],
|
||||
group = "org.scala-lang",
|
||||
version = "3.3.6",
|
||||
version = SCALA_VERSION,
|
||||
)
|
||||
|
||||
# Force specific versions for dependencies with conflicts between grpc-java and protobuf
|
||||
@@ -357,21 +393,20 @@ maven.artifact(
|
||||
artifact = "gson",
|
||||
force_version = True,
|
||||
group = "com.google.code.gson",
|
||||
version = "2.11.0",
|
||||
version = "2.14.0",
|
||||
)
|
||||
maven.artifact(
|
||||
artifact = "error_prone_annotations",
|
||||
force_version = True,
|
||||
group = "com.google.errorprone",
|
||||
version = "2.30.0",
|
||||
version = "2.50.0",
|
||||
)
|
||||
maven.artifact(
|
||||
artifact = "guava",
|
||||
force_version = True,
|
||||
group = "com.google.guava",
|
||||
version = "33.3.1-android",
|
||||
version = "33.6.0-jre",
|
||||
)
|
||||
|
||||
use_repo(maven, "maven", "unpinned_maven")
|
||||
|
||||
#
|
||||
@@ -379,6 +414,7 @@ use_repo(maven, "maven", "unpinned_maven")
|
||||
#
|
||||
|
||||
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
|
||||
|
||||
# GTL (for parallel_hashmap)
|
||||
@@ -389,6 +425,8 @@ GTL_SHA = "1969c45dd76eac0dd87e9e2b65cffe358617f4fe1bcd203f72f427742537913a"
|
||||
http_archive(
|
||||
name = "gtl",
|
||||
build_file_content = """
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
|
||||
cc_library(
|
||||
name = "gtl",
|
||||
hdrs = glob(["include/gtl/*.hpp"]),
|
||||
@@ -416,12 +454,12 @@ http_archive(
|
||||
)
|
||||
|
||||
# Sparkle framework for macOS auto-updates
|
||||
SPARKLE_VERSION = "2.6.4"
|
||||
SPARKLE_VERSION = "2.9.3"
|
||||
|
||||
http_archive(
|
||||
name = "sparkle",
|
||||
build_file = "//src/main/objc/net/eagle0/clients/unity/sparkle/external:BUILD.sparkle",
|
||||
sha256 = "50612a06038abc931f16011d7903b8326a362c1074dabccb718404ce8e585f0b",
|
||||
sha256 = "74a07da821f92b79310009954c0e15f350173374a3abe39095b4fc5096916be6",
|
||||
strip_prefix = "",
|
||||
url = "https://github.com/sparkle-project/Sparkle/releases/download/%s/Sparkle-%s.tar.xz" % (SPARKLE_VERSION, SPARKLE_VERSION),
|
||||
)
|
||||
@@ -431,24 +469,24 @@ http_archive(
|
||||
# Fallback: busybox.net (can be unreliable/slow)
|
||||
http_file(
|
||||
name = "busybox_x86_64",
|
||||
downloaded_file_path = "busybox",
|
||||
executable = True,
|
||||
sha256 = "6e123e7f3202a8c1e9b1f94d8941580a25135382b99e8d3e34fb858bba311348",
|
||||
urls = [
|
||||
"https://eagle0-sysroot.sfo3.digitaloceanspaces.com/busybox/busybox-1.35.0-x86_64-linux-musl",
|
||||
"https://busybox.net/downloads/binaries/1.35.0-x86_64-linux-musl/busybox",
|
||||
],
|
||||
downloaded_file_path = "busybox",
|
||||
executable = True,
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "busybox_aarch64",
|
||||
downloaded_file_path = "busybox",
|
||||
executable = True,
|
||||
sha256 = "141adb1b625a6f44c4b114f76b4387b4ea4f7ab802b88eb40e0d2f6adcccb1c3",
|
||||
urls = [
|
||||
# TODO: Upload aarch64 binary to GitHub release when needed
|
||||
"https://busybox.net/downloads/binaries/1.35.0-aarch64-linux-musl/busybox",
|
||||
],
|
||||
downloaded_file_path = "busybox",
|
||||
executable = True,
|
||||
)
|
||||
|
||||
# LLVM MinGW toolchain for Windows cross-compilation from macOS
|
||||
@@ -522,7 +560,7 @@ register_toolchains("@local_config_apple_cc_toolchains//:all")
|
||||
# Set dev_dependency so we can turn this off for swift MacOS builds
|
||||
register_toolchains(
|
||||
"@llvm_toolchain//:all",
|
||||
"@llvm_toolchain_linux//:all",
|
||||
"@llvm_toolchain_linux_arm64//:all",
|
||||
"@llvm_toolchain_linux//:cc-toolchain-x86_64-linux",
|
||||
"@llvm_toolchain_linux_arm64//:cc-toolchain-aarch64-linux",
|
||||
dev_dependency = True,
|
||||
)
|
||||
|
||||
Generated
+1916
-2456
File diff suppressed because one or more lines are too long
+1
-1
@@ -214,7 +214,7 @@ oci_push(
|
||||
#
|
||||
# Shardok Server ARM64 Docker Image (for Hetzner on-demand compute)
|
||||
#
|
||||
# Build: bazel build //ci:shardok_server_image_arm64 --platforms=//:linux_arm64 --extra_toolchains=@llvm_toolchain_linux_arm64//:all
|
||||
# Build: bazel build //ci:shardok_server_image_arm64 --platforms=//:linux_arm64 --extra_toolchains=@llvm_toolchain_linux_arm64//:cc-toolchain-aarch64-linux
|
||||
# Load: bazel run //ci:shardok_server_load_arm64
|
||||
# Push: bazel run //ci:shardok_server_push_arm64
|
||||
#
|
||||
|
||||
@@ -5,8 +5,26 @@ set -euo pipefail
|
||||
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
export PATH="${COMMON_PATHS}:${PATH}"
|
||||
|
||||
write_developer_dir_override() {
|
||||
repo_contents_cache_dir() {
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
printf '%s\n' "${HOME}/Library/Caches/eagle0-bazel-repo-contents"
|
||||
else
|
||||
printf '%s\n' "${XDG_CACHE_HOME:-${HOME}/.cache}/eagle0-bazel-repo-contents"
|
||||
fi
|
||||
}
|
||||
|
||||
write_bazel_local_config() {
|
||||
local repo_contents_cache
|
||||
repo_contents_cache="$(repo_contents_cache_dir)"
|
||||
|
||||
if [ "$(uname -s)" != "Darwin" ]; then
|
||||
if [ -n "${CI:-}" ]; then
|
||||
mkdir -p "$repo_contents_cache"
|
||||
{
|
||||
echo "# Generated by ci/github_actions/ensure_bazel_installed.sh; do not edit."
|
||||
printf 'common --repo_contents_cache=%s\n' "$repo_contents_cache"
|
||||
} > .bazelrc.local
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -30,8 +48,10 @@ write_developer_dir_override() {
|
||||
if [ -f .bazelrc.local ] && [ -z "${CI:-}" ]; then
|
||||
echo "Keeping existing .bazelrc.local outside CI"
|
||||
else
|
||||
mkdir -p "$repo_contents_cache"
|
||||
{
|
||||
echo "# Generated by ci/github_actions/ensure_bazel_installed.sh; do not edit."
|
||||
printf 'common --repo_contents_cache=%s\n' "$repo_contents_cache"
|
||||
printf 'common:macos --repo_env=DEVELOPER_DIR=%s\n' "$developer_dir"
|
||||
} > .bazelrc.local
|
||||
fi
|
||||
@@ -43,7 +63,7 @@ write_developer_dir_override() {
|
||||
echo "Using Apple developer directory at $developer_dir"
|
||||
}
|
||||
|
||||
write_developer_dir_override
|
||||
write_bazel_local_config
|
||||
|
||||
if [ -n "${GITHUB_PATH:-}" ]; then
|
||||
for path in /opt/homebrew/bin /usr/local/bin; do
|
||||
|
||||
@@ -34,6 +34,7 @@ echo "Platform: ${PLATFORM}"
|
||||
# Check if Unity is installed and has required modules
|
||||
check_modules_installed() {
|
||||
local unity_path="${UNITY_INSTALL_PATH}/${UNITY_VERSION}"
|
||||
local unity_app_contents_path="${unity_path}/Unity.app/Contents"
|
||||
|
||||
if [ ! -d "$unity_path" ]; then
|
||||
return 1
|
||||
@@ -49,7 +50,8 @@ check_modules_installed() {
|
||||
;;
|
||||
mac)
|
||||
# Mac IL2CPP module
|
||||
if [ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport/Variations/macos_development_il2cpp" ] && \
|
||||
if [ ! -d "${unity_app_contents_path}/PlaybackEngines/MacStandaloneSupport/Source/Player/MacPlayer/GameAssembly.xcodeproj" ] && \
|
||||
[ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport/Variations/macos_development_il2cpp" ] && \
|
||||
[ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport" ]; then
|
||||
echo "✗ Mac IL2CPP module not installed for Unity ${UNITY_VERSION}"
|
||||
return 1
|
||||
@@ -69,7 +71,8 @@ check_modules_installed() {
|
||||
echo "✗ iOS module missing"
|
||||
missing=1
|
||||
fi
|
||||
if [ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport" ]; then
|
||||
if [ ! -d "${unity_app_contents_path}/PlaybackEngines/MacStandaloneSupport/Source/Player/MacPlayer/GameAssembly.xcodeproj" ] && \
|
||||
[ ! -d "${unity_path}/PlaybackEngines/MacStandaloneSupport" ]; then
|
||||
echo "✗ Mac module missing"
|
||||
missing=1
|
||||
fi
|
||||
@@ -191,8 +194,10 @@ echo "Running: ${INSTALL_CMD[*]}"
|
||||
echo ""
|
||||
|
||||
# Capture output to check for "already installed" messages
|
||||
OUTPUT=$("${INSTALL_CMD[@]}" 2>&1) || true
|
||||
set +e
|
||||
OUTPUT=$("${INSTALL_CMD[@]}" 2>&1)
|
||||
EXIT_CODE=$?
|
||||
set -e
|
||||
echo "$OUTPUT"
|
||||
|
||||
# Check if modules are already installed (Unity Hub returns error but modules are present)
|
||||
@@ -219,13 +224,13 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify installation
|
||||
# Verify installation and requested modules
|
||||
echo ""
|
||||
if [ -d "${UNITY_INSTALL_PATH}/${UNITY_VERSION}" ]; then
|
||||
echo "✓ Verified: Unity ${UNITY_VERSION} is now installed"
|
||||
if check_modules_installed; then
|
||||
echo "✓ Verified: Unity ${UNITY_VERSION} is now installed with ${PLATFORM} support"
|
||||
exit 0
|
||||
else
|
||||
echo "✗ Unity ${UNITY_VERSION} installation could not be verified"
|
||||
echo "✗ Unity ${UNITY_VERSION} installation with ${PLATFORM} support could not be verified"
|
||||
echo " Expected path: ${UNITY_INSTALL_PATH}/${UNITY_VERSION}"
|
||||
echo ""
|
||||
echo "The installation may still be in progress, or may require manual intervention."
|
||||
|
||||
@@ -38,7 +38,7 @@ fi
|
||||
echo "Using git-lfs at $(command -v git-lfs)"
|
||||
git lfs version
|
||||
|
||||
git lfs install
|
||||
git lfs install --force
|
||||
|
||||
echo "LFS objects before pull:"
|
||||
git lfs ls-files | wc -l
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Print a compact timing summary from a Bazel build event JSON file."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from collections import Counter, defaultdict
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
def duration_to_ms(value: Any) -> float | None:
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, (int, float)):
|
||||
return float(value)
|
||||
if isinstance(value, str):
|
||||
if value.endswith("s"):
|
||||
try:
|
||||
return float(value[:-1]) * 1000
|
||||
except ValueError:
|
||||
return None
|
||||
try:
|
||||
return float(value)
|
||||
except ValueError:
|
||||
return None
|
||||
if isinstance(value, dict):
|
||||
seconds = value.get("seconds", 0)
|
||||
nanos = value.get("nanos", 0)
|
||||
try:
|
||||
return float(seconds) * 1000 + float(nanos) / 1_000_000
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def format_ms(milliseconds: float | None) -> str | None:
|
||||
if milliseconds is None:
|
||||
return None
|
||||
if milliseconds >= 1000:
|
||||
return f"{milliseconds / 1000:.2f}s"
|
||||
return f"{milliseconds:.0f}ms"
|
||||
|
||||
|
||||
def nested_get(data: dict[str, Any], *keys: str) -> Any:
|
||||
current: Any = data
|
||||
for key in keys:
|
||||
if not isinstance(current, dict):
|
||||
return None
|
||||
current = current.get(key)
|
||||
return current
|
||||
|
||||
|
||||
def read_events(path: Path) -> list[dict[str, Any]]:
|
||||
events = []
|
||||
with path.open() as file:
|
||||
for line_number, line in enumerate(file, start=1):
|
||||
stripped = line.strip()
|
||||
if not stripped:
|
||||
continue
|
||||
try:
|
||||
event = json.loads(stripped)
|
||||
except json.JSONDecodeError as error:
|
||||
print(f"Ignoring malformed BEP line {line_number}: {error}")
|
||||
continue
|
||||
if isinstance(event, dict):
|
||||
events.append(event)
|
||||
return events
|
||||
|
||||
|
||||
def collect_metric_events(events: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
metric_events = []
|
||||
for event in events:
|
||||
if isinstance(event.get("buildMetrics"), dict):
|
||||
metric_events.append(event["buildMetrics"])
|
||||
return metric_events
|
||||
|
||||
|
||||
def first_present(data: dict[str, Any], keys: list[str]) -> Any:
|
||||
for key in keys:
|
||||
value = data.get(key)
|
||||
if value is not None:
|
||||
return value
|
||||
return None
|
||||
|
||||
|
||||
def summarize_timing(build_metrics: dict[str, Any]) -> list[str]:
|
||||
timing = build_metrics.get("timingMetrics")
|
||||
if not isinstance(timing, dict):
|
||||
return []
|
||||
|
||||
labels = [
|
||||
("Wall time", ["wallTimeInMs", "wallTime", "elapsedTime"]),
|
||||
("Loading phase", ["loadingPhaseTimeInMs", "loadingPhaseTime"]),
|
||||
("Analysis phase", ["analysisPhaseTimeInMs", "analysisPhaseTime"]),
|
||||
("Execution phase", ["executionPhaseTimeInMs", "executionPhaseTime"]),
|
||||
("Critical path", ["criticalPathTimeInMs", "criticalPathTime"]),
|
||||
]
|
||||
|
||||
lines = []
|
||||
for label, keys in labels:
|
||||
value = format_ms(duration_to_ms(first_present(timing, keys)))
|
||||
if value is not None:
|
||||
lines.append(f" {label}: {value}")
|
||||
return lines
|
||||
|
||||
|
||||
def summarize_counts(build_metrics: dict[str, Any]) -> list[str]:
|
||||
summaries: list[tuple[str, Any]] = []
|
||||
|
||||
action_summary = build_metrics.get("actionSummary")
|
||||
if isinstance(action_summary, dict):
|
||||
summaries.extend(
|
||||
[
|
||||
("Actions created", action_summary.get("actionsCreated")),
|
||||
("Actions executed", action_summary.get("actionsExecuted")),
|
||||
("Action cache hits", action_summary.get("actionCacheHits")),
|
||||
("Remote cache hits", action_summary.get("remoteCacheHits")),
|
||||
]
|
||||
)
|
||||
|
||||
target_metrics = build_metrics.get("targetMetrics")
|
||||
if isinstance(target_metrics, dict):
|
||||
summaries.extend(
|
||||
[
|
||||
("Targets configured", target_metrics.get("targetsConfigured")),
|
||||
("Targets loaded", target_metrics.get("targetsLoaded")),
|
||||
]
|
||||
)
|
||||
|
||||
package_metrics = build_metrics.get("packageMetrics")
|
||||
if isinstance(package_metrics, dict):
|
||||
summaries.extend(
|
||||
[
|
||||
("Packages loaded", package_metrics.get("packagesLoaded")),
|
||||
("Packages successfully loaded", package_metrics.get("packagesSuccessfullyLoaded")),
|
||||
]
|
||||
)
|
||||
|
||||
return [f" {label}: {value}" for label, value in summaries if value is not None]
|
||||
|
||||
|
||||
def worker_mnemonic(metric: dict[str, Any]) -> str:
|
||||
for path in [
|
||||
("mnemonic",),
|
||||
("workerKey", "mnemonic"),
|
||||
("workerKeyInfo", "mnemonic"),
|
||||
]:
|
||||
value = nested_get(metric, *path)
|
||||
if value:
|
||||
return str(value)
|
||||
return "unknown"
|
||||
|
||||
|
||||
def worker_actions(metric: dict[str, Any]) -> int | None:
|
||||
for key in ["actionsExecuted", "executedActionCount", "actionCount", "actions"]:
|
||||
value = metric.get(key)
|
||||
if isinstance(value, int):
|
||||
return value
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
return int(value)
|
||||
except ValueError:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def summarize_workers(build_metrics: dict[str, Any]) -> list[str]:
|
||||
worker_metrics = build_metrics.get("workerMetrics")
|
||||
if not isinstance(worker_metrics, list) or not worker_metrics:
|
||||
return []
|
||||
|
||||
counts = Counter()
|
||||
actions_by_mnemonic: defaultdict[str, int] = defaultdict(int)
|
||||
saw_action_counts = False
|
||||
|
||||
for metric in worker_metrics:
|
||||
if not isinstance(metric, dict):
|
||||
continue
|
||||
mnemonic = worker_mnemonic(metric)
|
||||
counts[mnemonic] += 1
|
||||
actions = worker_actions(metric)
|
||||
if actions is not None:
|
||||
saw_action_counts = True
|
||||
actions_by_mnemonic[mnemonic] += actions
|
||||
|
||||
if not counts:
|
||||
return []
|
||||
|
||||
lines = [" Worker metric entries:"]
|
||||
for mnemonic, count in counts.most_common():
|
||||
suffix = ""
|
||||
if saw_action_counts:
|
||||
suffix = f", actions={actions_by_mnemonic[mnemonic]}"
|
||||
lines.append(f" {mnemonic}: workers={count}{suffix}")
|
||||
return lines
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: summarize_bazel_bep.py <build_event_json_file>")
|
||||
return 0
|
||||
|
||||
path = Path(sys.argv[1])
|
||||
if not path.exists():
|
||||
print(f"Bazel BEP summary: {path} does not exist")
|
||||
return 0
|
||||
|
||||
events = read_events(path)
|
||||
metric_events = collect_metric_events(events)
|
||||
if not metric_events:
|
||||
print("Bazel BEP summary: no buildMetrics event found")
|
||||
return 0
|
||||
|
||||
build_metrics = metric_events[-1]
|
||||
sections = [
|
||||
summarize_timing(build_metrics),
|
||||
summarize_counts(build_metrics),
|
||||
summarize_workers(build_metrics),
|
||||
]
|
||||
lines = [line for section in sections for line in section]
|
||||
|
||||
if not lines:
|
||||
print("Bazel BEP summary: buildMetrics event had no recognized metrics")
|
||||
return 0
|
||||
|
||||
print("Bazel BEP summary:")
|
||||
for line in lines:
|
||||
print(line)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -19,6 +19,18 @@ SERVER_DATA="$UNITY_PROJECT/ServerData/$BUILD_TARGET"
|
||||
DO_ENDPOINT="https://sfo3.digitaloceanspaces.com"
|
||||
DO_BUCKET="eagle0-assets"
|
||||
|
||||
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
export PATH="${COMMON_PATHS}:${PATH}"
|
||||
|
||||
if ! command -v aws >/dev/null 2>&1; then
|
||||
if command -v brew >/dev/null 2>&1; then
|
||||
brew install awscli
|
||||
else
|
||||
echo "ERROR: aws CLI is unavailable, and Homebrew is not on PATH"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "$SERVER_DATA" ]; then
|
||||
echo "No Addressables bundles found at $SERVER_DATA"
|
||||
echo "Skipping upload (this is expected if Addressables are bundled locally)"
|
||||
@@ -32,13 +44,26 @@ echo "Target: s3://$DO_BUCKET/addressables/$BUILD_TARGET/"
|
||||
export AWS_ACCESS_KEY_ID="$ACCESS_KEY_ID"
|
||||
export AWS_SECRET_ACCESS_KEY="$SECRET_KEY"
|
||||
|
||||
# Sync bundles to Spaces
|
||||
# --delete removes files in destination that don't exist in source
|
||||
# --acl public-read makes files publicly accessible
|
||||
# Sync bundles to Spaces. Addressable bundle filenames include content hashes, so a
|
||||
# same-sized existing bundle is already the same content. Use --size-only to avoid
|
||||
# re-uploading every rebuilt bundle just because Unity gave it a fresh local mtime.
|
||||
# Metadata files keep stable names, so sync them again without --size-only below.
|
||||
#
|
||||
# --delete removes files in destination that don't exist in source.
|
||||
# --acl public-read makes files publicly accessible.
|
||||
aws s3 sync "$SERVER_DATA" "s3://$DO_BUCKET/addressables/$BUILD_TARGET/" \
|
||||
--endpoint-url "$DO_ENDPOINT" \
|
||||
--acl public-read \
|
||||
--size-only \
|
||||
--delete
|
||||
|
||||
aws s3 sync "$SERVER_DATA" "s3://$DO_BUCKET/addressables/$BUILD_TARGET/" \
|
||||
--endpoint-url "$DO_ENDPOINT" \
|
||||
--acl public-read \
|
||||
--exclude "*" \
|
||||
--include "*.bin" \
|
||||
--include "*.hash" \
|
||||
--include "*.json"
|
||||
|
||||
echo "Addressables upload complete"
|
||||
echo "Files available at: https://assets.eagle0.net/addressables/$BUILD_TARGET/"
|
||||
|
||||
@@ -5,6 +5,8 @@ lower OCI layer and frequently-changing first-party jars in a small top layer,
|
||||
so most pushes only re-upload the small layer.
|
||||
"""
|
||||
|
||||
load("@rules_java//java/common:java_info.bzl", "JavaInfo")
|
||||
|
||||
def _unique_name(jar):
|
||||
# short_path is unique per jar and stable across commits (it depends only on
|
||||
# the jar's own package/coordinate, not on unrelated targets), so the deps
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
|
||||
|
||||
#pkg_tar(
|
||||
# name = "eagle_servers",
|
||||
# strip_prefix = "/src/main/scala/net/eagle0",
|
||||
|
||||
@@ -532,7 +532,7 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/bazel
|
||||
key: bazel-linux-${{ hashFiles('MODULE.bazel', 'WORKSPACE') }}
|
||||
key: bazel-linux-${{ hashFiles('MODULE.bazel', 'MODULE.bazel.lock', 'WORKSPACE') }}
|
||||
|
||||
- name: Build Shardok server
|
||||
run: bazel build -c opt //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
# Unity Scene Separation Plan
|
||||
|
||||
## Current State
|
||||
|
||||
The Unity client now starts from the split-scene setup. The legacy scene remains only as a
|
||||
temporary reference snapshot.
|
||||
|
||||
- `Assets/Scenes/Main.unity` owns startup.
|
||||
- `Assets/Scenes/Shared.unity`, `Connection.unity`, `Eagle.unity`, and `Shardok.unity` are loaded additively for their application modes.
|
||||
- `ProjectSettings/EditorBuildSettings.asset` includes the split scenes only.
|
||||
- `Assets/Gameplay.unity` is no longer in build settings, but is still kept in the repo until the split-scene flow has gone through broader build and TestFlight validation.
|
||||
- Editor migration tooling that rebuilt split scenes from `Gameplay.unity` has been removed.
|
||||
|
||||
This means runtime no longer depends on the monolithic scene, but the legacy asset cleanup is
|
||||
intentionally deferred.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Finish the split-scene architecture. Keep one small bootstrap scene and load mode-specific UI scenes additively.
|
||||
|
||||
The target architecture should be:
|
||||
|
||||
- `Main`: startup/bootstrap only. Owns scene loading and truly persistent app services.
|
||||
- `Shared`: shared UI and app-wide interaction infrastructure, such as the event system, error panels, confirmation modals, connection status overlays, settings, and update notifications.
|
||||
- `Connection`: login, account selection, lobby, custom battle creation, and game-selection UI.
|
||||
- `Eagle`: strategic map, strategic command panels, province/hero/battalion UI, notifications, and Eagle-specific effects.
|
||||
- `Shardok`: tactical battle UI, hex grid, battle command UI, unit rows, tactical effects, and battle-only camera/input helpers.
|
||||
|
||||
Do not treat large prefabs as inherently bad. A large prefab is acceptable when it represents a coherent, reusable feature root. The problematic pattern is a large scene that owns unrelated application states and long-lived object references.
|
||||
|
||||
## Goals
|
||||
|
||||
- Reduce merge conflicts and accidental Unity serialization churn.
|
||||
- Make login/lobby, Eagle, and Shardok changes independently editable.
|
||||
- Make scene lifecycle explicit: load only the mode currently needed.
|
||||
- Avoid cross-scene inspector references that are hard to reason about.
|
||||
- Preserve `Gameplay.unity` as a reference snapshot until broader validation is complete.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not refactor gameplay logic and scene structure in the same change.
|
||||
- Do not delete `Gameplay.unity` until all migrated scenes are verified in Editor, local builds, and CI.
|
||||
- Do not move large vendor asset packs as part of this work.
|
||||
- Do not split every small widget into its own scene. Prefer prefabs for reusable UI components and scenes for application modes.
|
||||
|
||||
## Target Runtime Flow
|
||||
|
||||
```text
|
||||
Main
|
||||
Load Shared
|
||||
Load Connection
|
||||
|
||||
Connection -> Eagle
|
||||
Unload Connection
|
||||
Ensure Shared remains loaded
|
||||
Load Eagle
|
||||
|
||||
Eagle -> Shardok
|
||||
Keep Eagle loaded unless the battle UI must exclusively own the viewport
|
||||
Load Shardok additively
|
||||
|
||||
Shardok -> Eagle
|
||||
Unload Shardok
|
||||
Keep Eagle and Shared loaded
|
||||
|
||||
Eagle -> Connection
|
||||
Unload Shardok if loaded
|
||||
Unload Eagle
|
||||
Load Connection
|
||||
```
|
||||
|
||||
## Ownership Rules
|
||||
|
||||
Use these rules during migration to avoid ambiguous object lifetimes.
|
||||
|
||||
- `Main` owns `GameSceneManager`, app bootstrap, and any service object that must survive across login, lobby, Eagle, and Shardok.
|
||||
- `Shared` owns exactly one active `EventSystem` and shared modal/overlay UI.
|
||||
- `Connection` owns `ConnectionHandler` and connection/lobby panel instances.
|
||||
- `Eagle` owns `EagleGameController` and strategic-mode scene roots.
|
||||
- `Shardok` owns `ShardokGameController` and tactical-mode scene roots.
|
||||
- Cross-mode communication should happen through model/controller APIs, not direct serialized references to objects in another loadable scene.
|
||||
- If a scene needs an object from another scene, prefer resolving it during scene initialization and failing loudly when required dependencies are missing.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### Phase 1: Make Bootstrap Explicit
|
||||
|
||||
- Make `Main.unity` the intended startup scene.
|
||||
- Update `BootstrapManager` so the split-scene path is the default in development builds.
|
||||
- Ensure build settings order is intentional: `Main` first, then loadable scenes.
|
||||
- Add logging that states which startup path was chosen.
|
||||
|
||||
Validation:
|
||||
|
||||
- Enter Play Mode from `Main.unity`.
|
||||
- Confirm `Shared` and `Connection` load without duplicate `EventSystem` objects.
|
||||
- Confirm split-scene startup fails loudly if required scene infrastructure is missing.
|
||||
|
||||
### Phase 2: Migrate Shared Infrastructure
|
||||
|
||||
- Move shared error UI, update UI, settings UI, connection status overlays, and global modal roots into `Shared.unity`.
|
||||
- Keep only one event system active when additive scenes are loaded.
|
||||
- Remove duplicated shared UI from `Gameplay.unity` only after migrated UI is validated.
|
||||
|
||||
Validation:
|
||||
|
||||
- Trigger an error modal from Connection, Eagle, and Shardok flows.
|
||||
- Open/close settings from each mode that supports it.
|
||||
- Verify no duplicate event-system warnings.
|
||||
|
||||
### Phase 3: Migrate Connection and Lobby
|
||||
|
||||
- Move `ConnectionCanvas`, login controls, account selector, lobby, custom battle UI, and game-selection rows into `Connection.unity`.
|
||||
- Make `ConnectionHandler` initialize after the scene is loaded rather than assuming objects exist in `Gameplay.unity`.
|
||||
- Replace show/hide transitions that activate large inactive subtrees with scene transitions where appropriate.
|
||||
|
||||
Validation:
|
||||
|
||||
- Start unauthenticated, authenticate, list available games, create/drop a custom battle, and enter a game.
|
||||
- Return from an active game to the lobby.
|
||||
- Test stored account flows.
|
||||
|
||||
### Phase 4: Migrate Eagle Strategic UI
|
||||
|
||||
- Move strategic map, command panel roots, hero/battalion/province UI, Eagle notifications, and strategic effects into `Eagle.unity`.
|
||||
- Keep reusable row/panel widgets as prefabs under `Assets/Eagle/`.
|
||||
- Remove direct dependencies on connection-scene objects.
|
||||
|
||||
Validation:
|
||||
|
||||
- Load a game from the lobby.
|
||||
- Select provinces, heroes, battalions, command buttons, and notifications.
|
||||
- Issue at least one representative command from each major command-panel family.
|
||||
- Confirm generated/dynamic text listeners clean up when leaving the scene.
|
||||
|
||||
### Phase 5: Migrate Shardok Tactical UI
|
||||
|
||||
- Move Shardok canvas, hex grid, battle panels, tactical rows, battle effects, and battle-only input/camera roots into `Shardok.unity`.
|
||||
- Decide whether Eagle remains visible/loaded under Shardok. Prefer keeping Eagle loaded if returning from battle must preserve strategic UI state.
|
||||
- Ensure Shardok scene unload disposes generated text listeners, subscriptions, object pools, and pending animation state.
|
||||
|
||||
Validation:
|
||||
|
||||
- Enter battle from Eagle.
|
||||
- Select units, issue movement/attack/fire/extinguish/end-turn commands.
|
||||
- Resolve a battle and return to Eagle.
|
||||
- Start a second battle in the same session to catch stale singleton/listener state.
|
||||
|
||||
### Phase 6: Remove Legacy Scene Dependency
|
||||
|
||||
- Keep `Gameplay.unity` out of normal startup and build settings.
|
||||
- Keep `Gameplay.unity` in the repo temporarily as a reference snapshot if useful, then delete it in a separate cleanup PR.
|
||||
- Remove transitional helpers whose only purpose was loading, rebuilding, or testing the legacy scene.
|
||||
|
||||
Validation:
|
||||
|
||||
- Local Editor smoke test through login, Eagle, Shardok, and return flows.
|
||||
- Unity edit-mode test suite if available.
|
||||
- CI Unity build.
|
||||
- TestFlight build before deleting the legacy scene.
|
||||
|
||||
## Review Checklist For Each Migration PR
|
||||
|
||||
- The PR moves one coherent subsystem, not multiple unrelated UI areas.
|
||||
- Scene files remain small enough to review.
|
||||
- Prefab changes are limited to the migrated subsystem.
|
||||
- No required Inspector field is hidden behind a defensive null check.
|
||||
- No duplicate `EventSystem`, camera, global canvas, or singleton is active.
|
||||
- Leaving and re-entering the migrated scene works in one app session.
|
||||
- The old `Gameplay.unity` object is removed only after the new scene object is verified.
|
||||
|
||||
## Risks
|
||||
|
||||
- Serialized cross-scene references will break when objects move. Prefer runtime lookup/initialization through explicit scene controllers.
|
||||
- Singletons may survive scene unload and hold stale references. Audit `OnDestroy`, `Dispose`, and listener cleanup for every moved controller.
|
||||
- Additive scenes can accidentally create duplicate input/event/camera objects. Keep these centralized in `Shared` or `Main`.
|
||||
- Loading Shardok additively over Eagle can expose hidden assumptions about active canvases, cameras, and selected input targets.
|
||||
- Unity scene YAML changes are easy to corrupt manually. Prefer moving objects in the Unity Editor and reviewing diffs carefully.
|
||||
|
||||
## Open Decisions
|
||||
|
||||
- Whether Shardok should overlay Eagle additively or unload most Eagle UI while battle is active.
|
||||
- Whether the primary persistent game connection object belongs in `Main` or should be recreated per selected game.
|
||||
- Whether `Shared` should always load at startup or only after successful connection.
|
||||
- How long to keep `Gameplay.unity` after the split scene flow is fully validated.
|
||||
|
||||
## Completed Startup Work
|
||||
|
||||
The initial startup and scene migration work is complete:
|
||||
|
||||
1. `Main.unity` is the startup scene in build settings.
|
||||
2. The split-scene bootstrap path is explicit and logged.
|
||||
3. `Shared` plus `Connection` load by default.
|
||||
4. Eagle and Shardok scene transitions use the split scenes.
|
||||
5. The legacy `Gameplay.unity` fallback has been removed.
|
||||
6. Editor-only scene migration tooling has been removed.
|
||||
|
||||
That leaves broader build validation and eventual `Gameplay.unity` deletion as the remaining cleanup work.
|
||||
+272
-147
@@ -1,173 +1,298 @@
|
||||
# URP Migration Plan
|
||||
|
||||
## Why
|
||||
Last refreshed: 2026-06-12
|
||||
|
||||
Unity is removing Built-In Render Pipeline (BiRP) support after Unity 6.7. We're currently on Unity 6.4. Each Unity minor version ships roughly quarterly, giving us a few release cycles before BiRP is dropped. This document lays out the migration plan.
|
||||
## Why This Matters
|
||||
|
||||
## Strategy: Long-Lived Feature Branch
|
||||
Unity is steering projects away from the Built-in Render Pipeline (BiRP) toward the
|
||||
Universal Render Pipeline (URP). Eagle0 now runs on URP:
|
||||
|
||||
All URP conversion work happens on a **long-lived `urp-migration` branch**. Main stays fully functional on BiRP throughout the migration.
|
||||
- `ProjectSettings/GraphicsSettings.asset` points at
|
||||
`Assets/Settings/URP/Eagle0URPPipeline.asset`.
|
||||
- Every active quality level in `ProjectSettings/QualitySettings.asset` uses the
|
||||
same URP pipeline asset.
|
||||
- Legacy Post Processing Stack v2 has been removed from `Packages/manifest.json`;
|
||||
keep verifying it stays out with the migration inventory.
|
||||
|
||||
- **Main branch**: Continues using BiRP. All gameplay, AI, and server development proceeds normally.
|
||||
- **URP branch**: Accumulates rendering pipeline changes across all phases.
|
||||
- **Regular rebasing**: Periodically rebase/merge `main` into the URP branch to stay current. Shader and material changes rarely conflict with gameplay code, so merge conflicts should be manageable.
|
||||
- **Merge to main**: Only when everything renders correctly and visual QA passes.
|
||||
The migration should stay visible as a compatibility project, not a cosmetic cleanup.
|
||||
The remaining goal is to keep future rendering fixes small and well-baselined instead
|
||||
of rediscovering URP-specific failures late in a Unity upgrade.
|
||||
|
||||
This avoids the "everything is pink" problem of switching the pipeline on main before shaders are converted.
|
||||
## Current Recommendation
|
||||
|
||||
## Current State
|
||||
Keep URP enabled on main. For follow-up rendering work, use the baseline checklist
|
||||
and inventory tooling before changing shaders, materials, camera layering, or render
|
||||
pipeline settings.
|
||||
|
||||
| Category | Count | Notes |
|
||||
The next useful work is hardening:
|
||||
|
||||
1. Keep the visual baseline current for Connection, Eagle, Shardok, and Settings.
|
||||
2. Refresh the shader/material inventory after meaningful asset or scene changes.
|
||||
3. Remove or isolate unused rendering dependencies.
|
||||
4. Keep third-party beast/effect material compatibility covered by focused tests.
|
||||
5. Treat future pipeline experiments as separate branches with explicit findings.
|
||||
|
||||
This keeps normal gameplay work moving while making rendering regressions easier to
|
||||
localize.
|
||||
|
||||
## What We Can Do Right Now
|
||||
|
||||
### 1. Create Visual Baselines
|
||||
|
||||
Capture a small set of known-good views before any follow-up change to URP settings,
|
||||
custom shaders, render ordering, or third-party visual materials. These should be
|
||||
reproducible enough that a human can compare screenshots after each rendering change.
|
||||
|
||||
Minimum baseline scenes and states:
|
||||
|
||||
| Area | Required View |
|
||||
|---|---|
|
||||
| Connection | Connect panel, stored account list, running games list |
|
||||
| Eagle map | Normal province map with borders, faction highlights, selected province tooltip |
|
||||
| Eagle weather | Drought/heat shimmer, flood, blizzard/rain overlays |
|
||||
| Eagle beasts | Bird/animal/monster beast effects on map and notification panel |
|
||||
| Eagle UI | Command panel, notifications, settings panel, generated text |
|
||||
| Shardok | Terrain, grid lines, labels/icons, bridges, fires, overlays, command buttons |
|
||||
| Scene transitions | Connection -> Eagle -> Shardok -> Eagle |
|
||||
|
||||
Immediate deliverable: keep the manual checklist and editor-only capture tool working
|
||||
so each rendering PR can leave screenshots in an ignored directory.
|
||||
|
||||
Use `docs/URP_VISUAL_BASELINE_CHECKLIST.md` for the current manual baseline capture
|
||||
set.
|
||||
|
||||
### 2. Refresh The Shader And Material Inventory
|
||||
|
||||
The inventory is useful because scene split, URP, and recent visual fixes changed the
|
||||
project enough that we should regenerate it before significant rendering work.
|
||||
|
||||
Immediate deliverable: a report containing:
|
||||
|
||||
- all shaders under `Assets/`
|
||||
- all materials and the shader each material uses
|
||||
- all scenes/prefabs that reference custom shaders or Post Processing components
|
||||
- all usages of Built-in-only shader features:
|
||||
- `GrabPass`
|
||||
- `#pragma surface`
|
||||
- `UnityCG.cginc`
|
||||
- `UnityUI.cginc`
|
||||
- tessellation
|
||||
|
||||
This report can be generated by an editor script or a small external scanner. The
|
||||
important bit is making it repeatable so we can measure progress during migration.
|
||||
|
||||
Run `Eagle0 > Rendering > Generate URP Migration Inventory` in the Unity editor to
|
||||
generate the current report. The tool writes markdown and CSV files under Unity
|
||||
`Temp/urp_migration/`, so running it should not dirty project assets.
|
||||
|
||||
The generated CSVs include both the full material list and production material
|
||||
references, which helps separate game-path shader risk from unused package/demo
|
||||
assets.
|
||||
|
||||
`docs/URP_SHADER_DEBT_INVENTORY.md` records the current production-vs-package
|
||||
classification for remaining Built-in-style shader patterns.
|
||||
|
||||
Current inventory snapshot from June 12, 2026:
|
||||
|
||||
- Render pipeline settings are URP for both graphics default and active quality.
|
||||
- Post Processing Stack reference hits are still zero.
|
||||
- The all-material inventory is noisy: most material assets are `Standard`, and
|
||||
many Built-in-only shader hits are in third-party or package/demo assets.
|
||||
- The production material-reference report is the better starting point for the
|
||||
probe. Current production shader references are concentrated in TextMeshPro,
|
||||
Eagle custom map/effect shaders, Shardok grid/fire materials, and a small number
|
||||
of standard-material beast assets.
|
||||
- Highest production custom shader priorities remain `Eagle/ProvinceMap`,
|
||||
`Eagle/ProvinceWeatherMap`, `Eagle/ProvinceParticle`,
|
||||
`Eagle/ClipRectParticleUnlit`, `Shardok/Fire Overlay`, and the Shardok
|
||||
hex/overlay materials.
|
||||
|
||||
### 3. Verify Legacy Post Processing Usage
|
||||
|
||||
The project no longer depends on `com.unity.postprocessing`. The old references were
|
||||
limited to an unused Orc/Ogre sample scene profile and scene-template type metadata,
|
||||
not production scenes.
|
||||
|
||||
Immediate deliverable: keep the project free of Post Processing Stack v2 references
|
||||
and use the inventory report to catch regressions.
|
||||
|
||||
If references reappear:
|
||||
|
||||
- document the exact scene/camera/profile usage
|
||||
- either remove the stale dependency or plan the equivalent URP Volume settings
|
||||
|
||||
This is a good small PR because it either deletes a risky dependency now or precisely
|
||||
scopes the later migration work.
|
||||
|
||||
### 4. Keep Drought Effects URP-Friendly
|
||||
|
||||
The old `Eagle/HeatShimmer` shader used a Built-in-style `GrabPass`, but shimmer was
|
||||
already disabled in `DroughtEffect` because it did not work well with the UI Canvas.
|
||||
Drought now intentionally uses the animated sun overlay as its current visual signal.
|
||||
|
||||
Immediate deliverable: keep drought visuals free of `GrabPass` unless we intentionally
|
||||
add a new URP-friendly effect.
|
||||
|
||||
If stronger drought visuals are needed later, prefer:
|
||||
|
||||
- an animated transparent texture overlay clipped like the existing province particles
|
||||
- a small particle/sprite effect around the sun icon
|
||||
- a URP renderer feature only if screen-space distortion is truly worth the complexity
|
||||
|
||||
### 5. Check Third-Party URP Paths
|
||||
|
||||
The riskiest third-party shader set is Polytope Studio. The plan should not assume
|
||||
hand conversion until we know whether vendor URP variants exist or whether a current
|
||||
package update has already solved part of this.
|
||||
|
||||
Immediate deliverable: for each paid/third-party visual package, record:
|
||||
|
||||
- current installed version
|
||||
- whether a URP-compatible version exists
|
||||
- whether upgrading is license/account-accessible
|
||||
- whether the package is still used in production scenes
|
||||
|
||||
`docs/URP_THIRD_PARTY_ASSET_AUDIT.md` records the current production GUID-reference
|
||||
scan. The important result is that production assets use Polytope character prefabs
|
||||
for Eagle beast effects, but the Polytope environment/water assets that still contain
|
||||
`GrabPass` were not found on the production path.
|
||||
|
||||
Prioritize:
|
||||
|
||||
- Polytope Studio lowpoly character/environment shaders
|
||||
- GUI Pro Kit Fantasy RPG shaders
|
||||
- Modern UI Pack
|
||||
- RRFreelance Orc/Ogre shaders
|
||||
- DungeonMonsters2D sprite/animation shaders
|
||||
|
||||
### 6. Keep Probe Guidance For Future Pipeline Experiments
|
||||
|
||||
The original disposable probe has served its main purpose: URP is enabled on main and
|
||||
the biggest visual regressions were fixed in focused PRs. Keep the probe playbook as
|
||||
a template for future risky pipeline experiments, not as current migration guidance.
|
||||
|
||||
Use `docs/URP_PROBE_PLAYBOOK.md` when we need to measure a future Unity or render
|
||||
pipeline change cheaply before committing to a mergeable branch.
|
||||
|
||||
## Current Known Risks
|
||||
|
||||
| Risk | Why It Matters | Right-Now Action |
|
||||
|---|---|---|
|
||||
| Shaders | 47 | 7 custom Eagle, 1 hex mesh, 20 Polytope, 13 TextMesh Pro, 6 other third-party |
|
||||
| Materials | 325 | Mix of Standard shader, custom, and third-party |
|
||||
| ShaderGraph files | 4 | All TextMesh Pro (URP + HDRP variants already exist) |
|
||||
| Scenes with baked lighting | 6 | Gameplay, Connection, Eagle, Shardok, Shared, Map Editor |
|
||||
| Post-processing | 1 profile | PPP_Orc.asset (Post Processing Stack v2, FXAA/TAA, AO) |
|
||||
| C# rendering scripts | 16 | Material/shader property manipulation only |
|
||||
| Rendering path | Forward | Matches URP default |
|
||||
| `ProvinceMapShader` | Core Eagle map rendering: province IDs, borders, ocean animation, faction highlighting, clipping | Audit inputs/properties and baseline screenshots |
|
||||
| `UnityUI.cginc` usage | URP does not provide the same include path/semantics | Inventory exact shader uses; plan replacement clipping helpers |
|
||||
| `GrabPass` | No direct URP equivalent | Drought shimmer is removed/deferred; Polytope water shaders are present but not currently production-referenced |
|
||||
| Surface shaders | URP does not support Built-in surface shader generation | Inventory and convert or replace |
|
||||
| Polytope Studio shaders | Human-type Eagle beast effects use Polytope character prefabs with Built-in surface shaders | Check vendor URP availability before hand conversion; prioritize character materials over unused environment shaders |
|
||||
| Post Processing Stack v2 | Replaced by URP Volume system | Verify whether production scenes use it |
|
||||
| Scene lighting | URP lighting/shadow settings differ from BiRP | Baseline and rebake only after shader work is stable |
|
||||
| Render ordering | Recent Shardok fixes rely on careful labels/fire/bridge ordering | Include Shardok overlay cases in baseline |
|
||||
|
||||
### Positive Findings
|
||||
## Follow-Up Strategy
|
||||
|
||||
- **No OnRenderImage, Graphics.Blit, CommandBuffer, or GL.\* usage** in C# code
|
||||
- Forward rendering already in use (matches URP default)
|
||||
- TextMesh Pro already has URP ShaderGraph variants in the project
|
||||
- No custom render passes or ScriptableRenderFeatures
|
||||
- Shader property manipulation (SetTexture, SetFloat, SetColor) is URP-compatible
|
||||
Main now carries the URP switch. Future rendering work should be split by observable
|
||||
behavior:
|
||||
|
||||
### Known Risk Areas
|
||||
- **Compatibility fixes**: small PRs for specific pink/missing/dark assets.
|
||||
- **Render ordering fixes**: small PRs for Shardok/Eagle layer order regressions.
|
||||
- **Inventory/docs updates**: docs-only or editor-tool PRs that do not alter runtime
|
||||
visuals.
|
||||
- **Pipeline experiments**: isolated branches using the probe playbook, with findings
|
||||
copied into a mergeable follow-up.
|
||||
|
||||
- **GrabPass shaders** (HeatShimmerShader, PT_Water_Shader) have no direct URP equivalent
|
||||
- **ProvinceMapShader** is complex (province ID lookup, border rendering, ocean animation, faction highlighting, UI clipping)
|
||||
- **Surface shaders** (`#pragma surface surf Standard`) must be rewritten as HLSL or ShaderGraph
|
||||
- **Polytope Studio shaders** (20 shaders) have no vendor-provided URP variants
|
||||
- **Post Processing Stack v2** must be replaced with URP's integrated Volume system
|
||||
- **Tessellation** (PT_Water_Shader) is not natively supported in URP
|
||||
This keeps the project from accumulating another broad, hard-to-revert rendering PR.
|
||||
|
||||
## Shader Inventory
|
||||
## Long-Term Phases
|
||||
|
||||
### Custom Eagle Shaders (7) -- HIGH PRIORITY
|
||||
### Phase 0: Preparation And Switch
|
||||
|
||||
| Shader | Complexity | Key Issues |
|
||||
|---|---|---|
|
||||
| ProvinceMapShader | High | Province ID texture lookup, border rendering, ocean animation, faction highlighting, `UnityUI.cginc` dependency, stencil/clipping |
|
||||
| ProvinceWeatherMapShader | Medium | Weather overlay rendering |
|
||||
| ProvinceWeatherShader | Medium | Province weather effects |
|
||||
| ProvinceParticleShader | Low | Custom particle rendering |
|
||||
| HeatShimmerShader | High | **GrabPass** for screen distortion, province masking |
|
||||
| ClipRectParticleUnlit | Low | UI-clipped particle shader |
|
||||
| maskShader | Low | UI masking |
|
||||
- Visual baseline checklist/screenshots: complete, keep current
|
||||
- Repeatable shader/material inventory: complete, keep current
|
||||
- Post Processing Stack usage decision: complete, keep removed
|
||||
- Drought visual decision: complete, use non-GrabPass visual signal
|
||||
- Third-party URP availability check: documented
|
||||
- Disposable URP probe findings: superseded by the merged URP switch
|
||||
|
||||
### Hex Mesh Shader (1) -- MODERATE PRIORITY
|
||||
### Phase 1: Pipeline Setup
|
||||
|
||||
Uses `#pragma surface surf Standard` with GPU instancing. Straightforward conversion to URP Lit or ShaderGraph.
|
||||
- Install/configure URP: complete
|
||||
- Create URP Pipeline Asset and Renderer Asset: complete
|
||||
- Configure forward rendering, shadows, HDR, and renderer features: complete enough
|
||||
for current gameplay paths
|
||||
- Run Unity's Render Pipeline Converter: complete for the merged switch
|
||||
- Keep a record of every auto-converted material: use the inventory/audit tools
|
||||
|
||||
### Third-Party Shaders (39)
|
||||
### Phase 2: Core Custom Shaders
|
||||
|
||||
| Source | Count | Complexity | Notes |
|
||||
Highest priority:
|
||||
|
||||
- `ProvinceMapShader`
|
||||
- `ProvinceWeatherMapShader`
|
||||
- `ProvinceWeatherShader`
|
||||
- `ProvinceParticleShader`
|
||||
- `ClipRectParticleUnlit`
|
||||
- `maskShader`
|
||||
- `Hex Mesh Shader`
|
||||
|
||||
Conversion notes:
|
||||
|
||||
- Replace Built-in includes such as `UnityCG.cginc`.
|
||||
- Replace `UnityUI.cginc` clipping with URP-compatible code.
|
||||
- Preserve stencil operations, render queues, texture lookups, and property names.
|
||||
- Test map interactions, not just static rendering.
|
||||
|
||||
### Phase 3: GrabPass And Special Effects
|
||||
|
||||
- Keep drought visuals on the current animated sun overlay unless a new URP-friendly
|
||||
effect is intentionally added.
|
||||
- Reimplement or replace the Polytope `PT_Water_Shader` GrabPass shaders if they are
|
||||
ever become used by production assets.
|
||||
- Avoid leaving screen-space effects until the end; they are likely to drive renderer
|
||||
feature requirements.
|
||||
|
||||
### Phase 4: Third-Party Shaders
|
||||
|
||||
- Upgrade packages where vendor URP shaders exist.
|
||||
- Convert remaining PBR/toon/vegetation shaders manually.
|
||||
- Prefer replacement or deletion for unused demo-only assets.
|
||||
|
||||
### Phase 5: Materials, Lighting, And Post Processing
|
||||
|
||||
- Batch-update remaining materials.
|
||||
- Replace Post Processing Stack v2 with URP Volumes if still needed.
|
||||
- Rebake lighting for production scenes.
|
||||
- Tune shadow and HDR settings.
|
||||
|
||||
### Phase 6: Validation
|
||||
|
||||
Required visual QA:
|
||||
|
||||
- Connection lobby
|
||||
- Eagle map and command flows
|
||||
- Eagle weather/beasts/notifications
|
||||
- Shardok battle map overlays, unit text/icons, bridges, fires
|
||||
- Scene transitions
|
||||
- Mac and Windows builds
|
||||
- Performance sanity check
|
||||
|
||||
## Rough Effort
|
||||
|
||||
| Work | Best Case | Realistic | Worst Case |
|
||||
|---|---|---|---|
|
||||
| Polytope Studio | 20 | Moderate-High | PBR, Toon, vegetation (custom lighting), water (**GrabPass + tessellation**). No vendor URP pack available. |
|
||||
| TextMesh Pro | 13 | Low | URP ShaderGraph variants already exist in project |
|
||||
| RRFreelance | 3 | Low | Standard surface shaders, direct conversion |
|
||||
| Clown.fat | 2 | Moderate | Custom ToonRamp lighting model |
|
||||
| GUI Pro Kit | 1 | Low | Hidden particle shader |
|
||||
| Preparation/probe | 2-4 days | 1 week | 2 weeks |
|
||||
| Core custom shaders | 1.5 weeks | 2-3 weeks | 4 weeks |
|
||||
| GrabPass/special effects | 2-4 days | 1-2 weeks | 3 weeks |
|
||||
| Third-party shaders/materials | 1.5 weeks | 2-3 weeks | 4 weeks |
|
||||
| Lighting/post-processing | 3-5 days | 1-2 weeks | 2 weeks |
|
||||
| QA/polish | 1 week | 2 weeks | 3 weeks |
|
||||
| **Total** | **5-7 weeks** | **8-12 weeks** | **16+ weeks** |
|
||||
|
||||
### GrabPass Shaders (Require Special Handling)
|
||||
|
||||
GrabPass does not exist in URP. These must be reimplemented using `ScriptableRenderPass` + `Renderer Features` or Blit-based alternatives:
|
||||
|
||||
1. **HeatShimmerShader** -- Screen distortion effect (currently has a shimmer-disabled TODO, may be deprioritized)
|
||||
2. **PT_Water_Shader** -- Water refraction/transparency (PT_Water_Shader_WebGl exists without GrabPass as a reference)
|
||||
|
||||
## Phased Approach
|
||||
|
||||
### Phase 1: Pipeline Setup + Auto-Conversion (Days 1-3)
|
||||
|
||||
- Install URP package
|
||||
- Create URP Pipeline Asset and Renderer Asset
|
||||
- Configure basic pipeline settings (forward rendering, shadow settings)
|
||||
- Run Unity's **Render Pipeline Converter** (Edit > Rendering > Render Pipeline Converter)
|
||||
- Auto-converts Standard shader materials and some built-in shaders
|
||||
- Handles a significant portion of the 325 materials
|
||||
- Will NOT touch custom shaders
|
||||
- Create a test scene to validate basic rendering
|
||||
- Migrate viewport clipping system (`RendererViewportClipper`, `ViewportClipper`, `PopupClipper`) to use URP-compatible global shader properties
|
||||
|
||||
### Phase 2: Custom Eagle Shaders (Weeks 1-3)
|
||||
|
||||
This is the critical path. Without these, the game is unplayable.
|
||||
|
||||
**Week 1-2: ProvinceMapShader**
|
||||
- Convert from BiRP Cg/HLSL to URP HLSL
|
||||
- Replace `UnityCG.cginc` includes with `Core.hlsl` / `Common.hlsl`
|
||||
- Replace `UnityUI.cginc` with custom URP-compatible UI clipping
|
||||
- Preserve province ID texture lookup, border rendering, ocean animation, faction highlighting
|
||||
- Validate stencil operations and render queue ordering
|
||||
|
||||
**Week 2-3: Remaining Eagle shaders**
|
||||
- ProvinceWeatherMapShader + ProvinceWeatherShader
|
||||
- ProvinceParticleShader + ClipRectParticleUnlit
|
||||
- maskShader
|
||||
- Hex Mesh Shader (convert surface shader to URP Lit)
|
||||
- HeatShimmerShader (reimplement without GrabPass, or defer if shimmer remains disabled)
|
||||
|
||||
### Phase 3: Third-Party Shaders (Weeks 4-6)
|
||||
|
||||
**Polytope Studio (20 shaders)**
|
||||
- Convert PBR shaders (Armors, NPC, Weapons, Props, Rock) from surface shaders to URP Lit / ShaderGraph
|
||||
- Convert Toon shaders to custom URP shader or ShaderGraph with custom lighting
|
||||
- Convert vegetation shaders (custom `StandardCustom` lighting) to ShaderGraph
|
||||
- PT_Water_Shader: Reimplement without GrabPass and tessellation (use PT_Water_Shader_WebGl as reference for non-GrabPass approach)
|
||||
|
||||
**Other third-party**
|
||||
- Clown.fat ToonRamp shaders: Convert custom lighting model to ShaderGraph
|
||||
- RRFreelance shaders: Direct Standard-to-URP-Lit conversion
|
||||
- GUI Pro Kit particle shader: Convert to URP particle shader
|
||||
|
||||
### Phase 4: Materials, Lighting & Post-Processing (Weeks 7-8)
|
||||
|
||||
**Materials**
|
||||
- Batch-update any remaining materials not handled by the auto-converter
|
||||
- Verify all 325 materials render correctly
|
||||
- Fix any visual differences from lighting model changes
|
||||
|
||||
**Lighting**
|
||||
- Rebake lightmaps for all 6 scenes (Gameplay, Connection, Eagle, Shardok, Shared, Map Editor)
|
||||
- Configure URP shadow cascade settings to match current quality levels
|
||||
- Verify HDR rendering
|
||||
|
||||
**Post-Processing**
|
||||
- Remove Post Processing Stack v2 dependency (`com.unity.postprocessing: 3.5.1`)
|
||||
- Replace with URP integrated Volume system
|
||||
- Recreate PPP_Orc effects (FXAA/TAA, Ambient Occlusion) using URP Volume overrides
|
||||
|
||||
### Phase 5: Testing & Validation (Weeks 9-11)
|
||||
|
||||
- Visual QA across all 6 scenes
|
||||
- Verify beast/character rendering (vertex colors, animations)
|
||||
- Verify weather effects (blizzard, drought, flood)
|
||||
- Verify particle systems (fire & explosion effects, UI particles)
|
||||
- Verify UI rendering (GUI Pro Kit, Modern UI Pack, TextMesh Pro)
|
||||
- Performance profiling (URP has different performance characteristics)
|
||||
- Test on target platforms
|
||||
- Bug fixes and visual polish
|
||||
|
||||
## Effort Estimates
|
||||
|
||||
| Phase | Best Case | Realistic | Worst Case |
|
||||
|---|---|---|---|
|
||||
| 1. Pipeline Setup | 1-2 days | 2-3 days | 3-5 days |
|
||||
| 2. Custom Eagle Shaders | 1.5 weeks | 2-3 weeks | 3-4 weeks |
|
||||
| 3. Third-Party Shaders | 1.5 weeks | 2-3 weeks | 3-4 weeks |
|
||||
| 4. Materials & Lighting | 3-5 days | 1-1.5 weeks | 2 weeks |
|
||||
| 5. Testing & Validation | 1 week | 1.5-2 weeks | 2-3 weeks |
|
||||
| **Total** | **6-8 weeks** | **8-12 weeks** | **12-16 weeks** |
|
||||
|
||||
The biggest variable is Polytope Studio shader conversion. If vendor URP packs become available, Phase 3 shrinks significantly.
|
||||
The biggest variable is still third-party shader conversion. Vendor URP packages or
|
||||
asset deletion can shrink this significantly.
|
||||
|
||||
## Key Reminders
|
||||
|
||||
- **Don't leave GrabPass rewrites and ProvinceMapShader for the end** -- they're the riskiest pieces and should be tackled early.
|
||||
- The migration window (~1 year) is comfortable. Spreading the work across this window is fine, but front-load the hard shader work.
|
||||
- C# code changes should be minimal -- the codebase avoids direct rendering API usage.
|
||||
- `UnityUI.cginc` has no direct URP equivalent. Custom implementation will be needed for UI clipping in shaders.
|
||||
- Do not switch main to URP as a first step.
|
||||
- Do not leave `ProvinceMapShader`, `UnityUI.cginc`, or `GrabPass` work until the end.
|
||||
- Keep C# changes minimal; current rendering scripts mostly set material properties.
|
||||
- Preserve recent Shardok render-order behavior while changing pipelines.
|
||||
- Treat screenshots as migration tests; compilation alone is not meaningful here.
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
# URP Probe Playbook
|
||||
|
||||
Last refreshed: 2026-06-12
|
||||
|
||||
This playbook is historical reference for the disposable URP probe described in
|
||||
`docs/URP_MIGRATION_PLAN.md`. URP is now enabled on main; keep this as a template
|
||||
for future risky render-pipeline experiments. A probe branch is not a production
|
||||
branch and should not be merged as-is.
|
||||
|
||||
## Goals
|
||||
|
||||
- Use the already-installed URP package in an isolated branch.
|
||||
- Create the minimum URP pipeline/renderer assets needed to enter Play Mode.
|
||||
- Run Unity's Render Pipeline Converter.
|
||||
- Record compile errors, pink materials, broken shaders, and visual regressions.
|
||||
- Preserve findings in docs, then discard or reset the probe branch.
|
||||
|
||||
## Branch Shape
|
||||
|
||||
Use two branches:
|
||||
|
||||
| Branch | Purpose | Mergeable |
|
||||
|---|---|---|
|
||||
| `codex/urp-probe` | Disposable package/settings/material conversion experiment | No |
|
||||
| `codex/urp-probe-findings` | Small docs-only summary copied from the probe | Yes |
|
||||
|
||||
Do not open a PR from `codex/urp-probe` unless it is clearly marked draft and
|
||||
experimental. Prefer opening the PR from `codex/urp-probe-findings`.
|
||||
|
||||
## Before Starting
|
||||
|
||||
1. Confirm `origin/main` is fresh.
|
||||
2. Confirm the worktree is clean.
|
||||
3. Capture or review the baseline checklist in
|
||||
`docs/URP_VISUAL_BASELINE_CHECKLIST.md`.
|
||||
4. Generate a current inventory with
|
||||
`Eagle0 > Rendering > Generate URP Migration Inventory`.
|
||||
5. Keep the inventory output under Unity `Temp/urp_migration/`; do not commit
|
||||
generated reports unless they are intentionally summarized.
|
||||
|
||||
## Probe Steps
|
||||
|
||||
1. Create `codex/urp-probe` from `origin/main`.
|
||||
2. Confirm `com.unity.render-pipelines.universal` is installed in
|
||||
`Packages/manifest.json`.
|
||||
3. If testing new pipeline settings, create alternate URP Pipeline/Renderer assets
|
||||
under a clearly named temporary folder.
|
||||
4. Assign the alternate URP pipeline asset in:
|
||||
- `ProjectSettings/GraphicsSettings.asset`
|
||||
- `ProjectSettings/QualitySettings.asset`
|
||||
5. Run Unity's Render Pipeline Converter only if the experiment intentionally tests
|
||||
material conversion.
|
||||
6. Enter Play Mode from `Assets/Scenes/Main.unity`.
|
||||
7. Exercise the baseline views:
|
||||
- Connection lobby
|
||||
- Eagle map
|
||||
- Eagle weather and beast effects
|
||||
- Shardok terrain, grid, labels, bridges, fires, overlays
|
||||
- Connection -> Eagle -> Shardok -> Eagle transitions
|
||||
8. Record the exact failure mode for every broken visual:
|
||||
- compile error
|
||||
- pink material
|
||||
- invisible mesh or sprite
|
||||
- wrong render order
|
||||
- lighting/shadow difference
|
||||
- input or scene-load regression
|
||||
|
||||
## Expected High-Risk Areas
|
||||
|
||||
- Eagle province map shaders:
|
||||
- `ProvinceMapShader`
|
||||
- `ProvinceWeatherMapShader`
|
||||
- `ProvinceWeatherShader`
|
||||
- `ProvinceParticleShader`
|
||||
- Shardok map and overlay shaders:
|
||||
- `Hex Mesh Shader`
|
||||
- `maskShader`
|
||||
- `ClipRectParticleUnlit`
|
||||
- Third-party 3D materials:
|
||||
- Polytope Studio character prefabs used by Eagle human-type beast effects
|
||||
- RRFreelance Orc/Ogre materials used by `OgreEffect`
|
||||
- Render ordering in Shardok:
|
||||
- unit text/icons versus fires
|
||||
- unit text/icons versus bridges
|
||||
- selection/command overlays versus labels
|
||||
|
||||
## Findings Template
|
||||
|
||||
Copy this template into the mergeable findings branch after the probe:
|
||||
|
||||
```markdown
|
||||
# URP Probe Findings
|
||||
|
||||
Date:
|
||||
Unity version:
|
||||
URP package version:
|
||||
Probe branch commit:
|
||||
|
||||
## Summary
|
||||
|
||||
- Entered Play Mode:
|
||||
- Connection usable:
|
||||
- Eagle usable:
|
||||
- Shardok usable:
|
||||
- Build attempted:
|
||||
|
||||
## Converter Results
|
||||
|
||||
- Materials converted:
|
||||
- Materials left pink:
|
||||
- Shader compile errors:
|
||||
|
||||
## Visual Regressions
|
||||
|
||||
| Area | Expected | Actual | Likely Cause | Next Action |
|
||||
|---|---|---|---|---|
|
||||
|
||||
## Required Migration PRs
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## Notes
|
||||
|
||||
-
|
||||
```
|
||||
|
||||
## After The Probe
|
||||
|
||||
1. Copy findings into a docs-only branch.
|
||||
2. Delete or abandon `codex/urp-probe`.
|
||||
3. Do not merge probe-generated package/settings/material churn into main until the
|
||||
findings have been reviewed and broken visuals have owner PRs.
|
||||
@@ -0,0 +1,106 @@
|
||||
# URP Shader Debt Inventory
|
||||
|
||||
Last refreshed: 2026-06-12
|
||||
|
||||
This inventory classifies remaining Built-in Render Pipeline shader patterns after
|
||||
the URP switch. The project is running URP, but some shader source files still use
|
||||
Built-in-era helpers or features. That is shader debt, not evidence that the old
|
||||
pipeline is active.
|
||||
|
||||
## Scan Method
|
||||
|
||||
The scan looked for these patterns in Unity shader-like assets:
|
||||
|
||||
- `GrabPass`
|
||||
- `#pragma surface`
|
||||
- `UnityCG.cginc`
|
||||
- `UnityUI.cginc`
|
||||
- `UNITY_MATRIX_`
|
||||
- `sampler2D _GrabTexture`
|
||||
- `tessell`
|
||||
- `Tessellation`
|
||||
|
||||
It then mapped every matching shader asset to its Unity GUID and scanned production
|
||||
serialized assets under:
|
||||
|
||||
- `Assets/Scenes/`
|
||||
- `Assets/Eagle/`
|
||||
- `Assets/Shardok/`
|
||||
- `Assets/ConnectionHandler/`
|
||||
- `Assets/UI/`
|
||||
- `Assets/common/`
|
||||
- `Assets/Tutorial/`
|
||||
- `Assets/Resources/`
|
||||
- `Assets/Materials/`
|
||||
|
||||
This catches serialized production references. It does not prove runtime code never
|
||||
loads an asset by path, but it separates game-path shader debt from package/demo
|
||||
noise well enough to prioritize follow-up PRs.
|
||||
|
||||
## Summary
|
||||
|
||||
| Bucket | Shader Assets With Built-in Patterns | Serialized Production References |
|
||||
|---|---:|---:|
|
||||
| Project-owned production shaders | 9 | 7 referenced |
|
||||
| TextMeshPro package shaders | 17 | 1 referenced |
|
||||
| Third-party/package shaders | 25 | 0 referenced |
|
||||
|
||||
## Highest Priority: Referenced Project-Owned Shaders
|
||||
|
||||
These are the URP hardening targets that are actually referenced by production
|
||||
assets.
|
||||
|
||||
| Shader | Patterns | Production References | Recommended Action |
|
||||
|---|---|---|---|
|
||||
| `Assets/Eagle/Shaders/ProvinceMapShader.shader` | `UnityCG.cginc`, `UnityUI.cginc` | `Assets/Eagle/Materials/ProvinceMapMaterial.mat` | Convert includes/clipping to URP-compatible code, then baseline Eagle province colors, borders, ocean, faction highlights, and selected province state. |
|
||||
| `Assets/Eagle/Shaders/ProvinceWeatherMapShader.shader` | `UnityCG.cginc`, `UnityUI.cginc` | `Assets/Eagle/Materials/ProvinceWeatherMapMaterial.mat` | Convert with province map shader; baseline weather map overlay alignment and clipping. |
|
||||
| `Assets/Eagle/Shaders/ProvinceWeatherShader.shader` | `UnityCG.cginc`, `UnityUI.cginc` | `Assets/Eagle/Weather/BlizzardEffect.mat`, `Assets/Eagle/Weather/DroughtEffect.mat`, `Assets/Eagle/Weather/FloodEffect.mat` | Convert weather effect shader; baseline drought, flood, and blizzard/rain overlays. |
|
||||
| `Assets/Eagle/Shaders/ProvinceParticleShader.shader` | `UnityCG.cginc` | `Assets/Eagle/Effects/ProvinceParticleMaterial.mat` | Convert after map/weather shaders; baseline province particles and popup clipping. |
|
||||
| `Assets/Eagle/Shaders/ClipRectParticleUnlit.shader` | `UnityCG.cginc` | `Assets/Eagle/Effects/Fireworks.prefab`, `Assets/Eagle/Effects/ParticleAlphaBlendMaterial.mat`, `Assets/Eagle/Effects/ParticleStandardUnlitMaterial.mat` | Convert particle helper shader; baseline Eagle one-shot effects and popup clipping. |
|
||||
| `Assets/Eagle/maskShader.shader` | `UnityCG.cginc`, `UnityUI.cginc` | `Assets/Eagle/Materials/map_color_nolabels.mat`, `Assets/Eagle/Materials/map_color_whitened.mat` | Confirm whether these materials are still used at runtime; convert or delete stale material path. |
|
||||
| `Assets/Shardok/ShardokFireOverlay.shader` | `UnityCG.cginc` | `Assets/Shardok/ShardokFireOverlay.mat` | Convert separately from Eagle; baseline terrain < bridge < fire < grid < labels/icons < animations ordering. |
|
||||
|
||||
## Referenced Package Shader
|
||||
|
||||
| Shader | Patterns | Production References | Recommended Action |
|
||||
|---|---|---|---|
|
||||
| `Assets/TextMesh Pro/Resources/Shaders/TMP_Sprite.shader` | `UnityCG.cginc`, `UnityUI.cginc`, `UNITY_MATRIX_` | 16 tutorial sprite assets under `Assets/Tutorial/Sprite Assets/` | Leave alone unless Unity/URP surfaces a visible TextMeshPro sprite regression. Prefer package/vendor updates over hand-editing TMP package shaders. |
|
||||
|
||||
## Project-Owned Hits Without Serialized Production References
|
||||
|
||||
| Shader | Patterns | Recommended Action |
|
||||
|---|---|---|
|
||||
| `Assets/Hex Mesh Shader.shader` | `#pragma surface` | Candidate for deletion or archival if no runtime path uses it. Current Shardok scene uses the newer layered render stack, not this serialized shader path. |
|
||||
| `Assets/Shardok/Shaders/ForegroundUIOverlay.shader` | `UnityCG.cginc`, `UnityUI.cginc` | Confirm whether runtime code loads it by path; if not, delete or leave as low-priority debt. |
|
||||
|
||||
## Third-Party And Package Hits Without Serialized Production References
|
||||
|
||||
These files still contain Built-in-only shader patterns, but the current GUID scan
|
||||
did not find serialized production references. Treat them as package/demo cleanup,
|
||||
not as urgent game-path blockers.
|
||||
|
||||
| Package Area | Examples | Patterns | Recommended Action |
|
||||
|---|---|---|---|
|
||||
| Polytope Studio characters/weapons/props | Modular NPC, armor, weapons, props shaders | `#pragma surface`, `UnityCG.cginc` | Keep runtime beast material compatibility in place; only import/replace vendor URP materials if we intentionally remove the compatibility shim. |
|
||||
| Polytope Studio environment/water | Water, vegetation, rock shaders | `GrabPass`, `#pragma surface`, `UnityCG.cginc`, tessellation | Ignore unless production starts referencing these assets. Water shaders are the only remaining `GrabPass` hits. |
|
||||
| RRFreelance Orc/Ogre | Ogre, armor, weapon shaders | `#pragma surface`, `UnityCG.cginc` | Current production references are handled by compatibility/material fixes; do not hand-convert unless a visible ogre regression returns. |
|
||||
| TextMeshPro package shaders | TMP SDF/bitmap/surface shaders | `UnityCG.cginc`, `UnityUI.cginc`, `UNITY_MATRIX_`, surface shader variants | Prefer package updates. Avoid editing package shaders unless a concrete TMP visual regression exists. |
|
||||
| Clown.fat and TileableBridgePack | Toony shaders, bridge cutout shader | `#pragma surface`, `UnityCG.cginc`, `UNITY_MATRIX_` | Leave as low priority unless a production reference appears. |
|
||||
|
||||
## Suggested Follow-Up PR Order
|
||||
|
||||
1. Convert `ProvinceMapShader` and `ProvinceWeatherMapShader` together. They share
|
||||
map/clipping concerns and should be tested with the same Eagle map baselines.
|
||||
2. Convert `ProvinceWeatherShader`. Test drought, flood, blizzard/rain, and popup
|
||||
clipping.
|
||||
3. Convert Eagle particle shaders: `ProvinceParticleShader` and
|
||||
`ClipRectParticleUnlit`.
|
||||
4. Investigate `maskShader` usage. Delete stale materials if unused; convert only
|
||||
if still on the runtime path.
|
||||
5. Convert `ShardokFireOverlay.shader` in its own PR with Shardok layering
|
||||
screenshots.
|
||||
6. Leave unreferenced third-party/package shaders alone until they have a visible
|
||||
regression or production reference.
|
||||
|
||||
Each conversion PR should use `docs/URP_VISUAL_BASELINE_CHECKLIST.md` and include
|
||||
the affected screenshots in an ignored local directory, not in git.
|
||||
@@ -0,0 +1,114 @@
|
||||
# URP Third-Party Asset Audit
|
||||
|
||||
Last refreshed: 2026-06-11
|
||||
|
||||
This audit scopes third-party visual packages for the URP migration. It is based on
|
||||
a GUID reference scan from production Unity assets under:
|
||||
|
||||
- `Assets/Scenes`
|
||||
- `Assets/Eagle`
|
||||
- `Assets/Shardok`
|
||||
- `Assets/ConnectionHandler`
|
||||
- `Assets/UI`
|
||||
- `Assets/common`
|
||||
- `Assets/Tutorial`
|
||||
- `Assets/Resources`
|
||||
- `Assets/Materials`
|
||||
|
||||
The scan maps GUIDs from each package folder, then finds production scenes,
|
||||
prefabs, materials, controllers, assets, and scripts that reference those GUIDs.
|
||||
It does not prove runtime code never loads assets by path, but it catches the
|
||||
serialized references that matter most for a render-pipeline migration.
|
||||
|
||||
## Summary
|
||||
|
||||
| Package | Production Use | URP Risk | Notes |
|
||||
|---|---:|---|---|
|
||||
| Polytope Studio | 20 refs / 18 assets | High | Used by Eagle human-type beast effects. Production refs are character prefabs, not environment/water assets. |
|
||||
| GUI Pro Kit Fantasy RPG | 138 refs / 58 assets | Low | Production use is UI sprites/icons. No package shader dependency found in production refs. |
|
||||
| Modern UI Pack v4.2.0 | 23 refs / 6 assets | Low | Production use is UI textures/icons. |
|
||||
| RRFreelance Orc/Ogre | 2 refs / 2 assets | High | Ogre effect uses custom Built-in surface shaders. |
|
||||
| DungeonMonsters2D | 12 refs / 12 assets | Medium | 2D monster prefabs for Eagle beast effects. Expected to be mostly SpriteRenderer/Animator; keep covered in beast-effect visual checks. |
|
||||
| Animal pack deluxe v2 | 7 refs / 7 assets | Medium | Elephant effect and controller refs. Verify lit-material conversion. |
|
||||
| Animal pack deluxe | 24 refs / 24 assets | Medium | Multiple Eagle animal beast effects. Verify lit-material conversion. |
|
||||
| AfricaAnimalsPackLowPoly V2 | 10 refs / 10 assets | Medium | Eagle beast effects and controllers. Verify lit-material conversion. |
|
||||
| AfricaAnimalsPackv1 | 8 refs / 8 assets | Medium | Eagle beast effects and controllers. Verify lit-material conversion. |
|
||||
| AustraliaAnimalsPackv1 | 6 refs / 6 assets | Medium | Eagle beast effects and controllers. Verify lit-material conversion. |
|
||||
| DinoPackLowPolyV1 | 3 refs / 3 assets | Medium | Velociraptor effect and controller. Verify lit-material conversion. |
|
||||
| HEROIC FANTASY CREATURES FULL PACK Vol 2 | 12 refs / 12 assets | Medium | Hippogryph effect and controller. Verify lit-material conversion. |
|
||||
| TileableBridgePack | 0 refs | Low | No production serialized refs found. Shardok bridge visuals appear to use project-owned/runtime assets instead. |
|
||||
| Stylize Water Texture | 1 ref / 1 asset | Low | Eagle province map material uses one water texture, not a shader. |
|
||||
| Terrain Hexes | 2 refs / 1 asset | Low | Shardok scene/container use one rock texture. |
|
||||
| Hex Tiles | 0 refs | Low | No production serialized refs found. |
|
||||
| 4000_Fantasy_Icons | 273 refs / 117 assets | Low | Sprite/icon assets only. |
|
||||
| StrategyGameIcons | 21 refs / 12 assets | Low | Sprite/icon assets only. |
|
||||
| Clown.fat | 14 refs / 10 assets | Medium | Clown effects and animation clips; also retargeted by Polytope human effects. |
|
||||
| Dragon | 2 refs / 1 asset | Medium | Dragon effect mesh/animation. Verify material conversion. |
|
||||
| HoneyBadger | 2 refs / 1 asset | Medium | Honey badger effect mesh/animation. Verify material conversion. |
|
||||
| Raccoon | 2 refs / 1 asset | Medium | Raccoon effect mesh/animation. Verify material conversion. |
|
||||
|
||||
## Highest-Risk Findings
|
||||
|
||||
### Polytope Studio
|
||||
|
||||
Production assets reference Polytope character prefabs for Eagle map effects:
|
||||
|
||||
- `Assets/Eagle/Effects/ArcherEffect.prefab`
|
||||
- `Assets/Eagle/Effects/GiantEffect.prefab`
|
||||
- `Assets/Eagle/Effects/KnightEffect.prefab`
|
||||
- `Assets/Eagle/Effects/MilitiaEffect.prefab`
|
||||
- `Assets/Eagle/Effects/PeasantEffect.prefab`
|
||||
- `Assets/Eagle/Effects/SoldierEffect.prefab`
|
||||
|
||||
These prefabs ultimately use `PT_NPC_Mat`, which references
|
||||
`Polytope Studio/Lowpoly_Characters/Sources/Modular_NPC/Shaders/PT_Modular_NPC_Shader_PBR.shader`.
|
||||
That shader uses Built-in surface shader generation and is not URP-ready as-is.
|
||||
|
||||
Polytope environment and water shaders still exist in the project and include
|
||||
Built-in-only features such as `GrabPass`, `UnityCG.cginc`, surface shaders, and
|
||||
tessellation. However, this scan found no production serialized references to the
|
||||
Polytope environment or water assets. Treat them as demo/package risk, not current
|
||||
runtime risk, unless a later inventory run finds production references.
|
||||
|
||||
### RRFreelance Orc/Ogre
|
||||
|
||||
Production assets reference the Orc/Ogre package from:
|
||||
|
||||
- `Assets/Eagle/Effects/OgreEffect.prefab`
|
||||
- `Assets/Eagle/Effects/OgreMapAnims.controller`
|
||||
|
||||
The custom materials reference package shaders that use Built-in surface shader
|
||||
generation:
|
||||
|
||||
- `RRFreelance-Characters/Orc-Ogre/Shaders/OgreShader.shader`
|
||||
- `RRFreelance-Characters/Orc-Ogre/Shaders/ArmorShader2sided.shader`
|
||||
- `RRFreelance-Characters/Orc-Ogre/Shaders/WeaponShader.shader`
|
||||
|
||||
This should be converted, replaced with URP/Lit-compatible materials, or swapped
|
||||
for standard materials during the URP migration.
|
||||
|
||||
## Recommended URP Order
|
||||
|
||||
1. Keep the runtime beast-effect compatibility path covered by visual checks before
|
||||
replacing it with vendor URP materials.
|
||||
2. If the converter leaves them pink or visually broken, replace the affected
|
||||
materials with URP/Lit materials before touching unused demo-only shader packs.
|
||||
3. Leave Polytope water/vegetation/environment conversion until a production
|
||||
reference appears. They are noisy in the shader inventory but not currently on
|
||||
the game path.
|
||||
4. Include Eagle beast effects in the visual baseline. They cover most third-party
|
||||
3D package risk in one place.
|
||||
5. Treat UI sprite packs as low pipeline risk. Their risk is texture import/render
|
||||
ordering, not shader conversion.
|
||||
|
||||
## Vendor Version / Access Notes
|
||||
|
||||
Known versions from existing repo docs:
|
||||
|
||||
- Modern UI Pack: `v4.2.0`
|
||||
|
||||
Most other package versions are not recorded in repo-local metadata. Before hand
|
||||
converting large third-party shader sets, check the Unity Asset Store or vendor
|
||||
account for URP-compatible updates. This especially matters for Polytope Studio,
|
||||
because the package contains many Built-in surface shaders even though only a
|
||||
small character subset is currently used by production assets.
|
||||
@@ -0,0 +1,60 @@
|
||||
# URP Visual Baseline Checklist
|
||||
|
||||
Use this checklist before any URP follow-up branch changes render-pipeline settings,
|
||||
custom shaders, materials, lighting, camera layering, or render order. The goal is
|
||||
not exhaustive gameplay QA; it is a stable set of visual states that can be compared
|
||||
by eye after rendering changes.
|
||||
|
||||
Save screenshots under:
|
||||
|
||||
`src/main/csharp/net/eagle0/clients/unity/eagle0/Temp/urp-baselines/`
|
||||
|
||||
That directory is ignored by git.
|
||||
|
||||
Use `Eagle0 > Rendering > Capture URP Baseline Screenshot` in the Unity editor to
|
||||
write a timestamped Game view capture to that directory.
|
||||
|
||||
## Capture Setup
|
||||
|
||||
- Use the same Unity version as the branch under test.
|
||||
- Start from `Assets/Scenes/Main.unity`.
|
||||
- Use the same Game view resolution for every capture in a comparison set.
|
||||
- Capture the full Game view, not cropped panels.
|
||||
- Name files with a stable prefix and short state name, for example
|
||||
`main_01_connection_accounts.png` and `branch_01_connection_accounts.png`.
|
||||
- If a view depends on server data or an account, write a short note next to the
|
||||
screenshot naming the game/account/state used.
|
||||
|
||||
## Required Captures
|
||||
|
||||
| ID | Area | State | Must Verify |
|
||||
|---|---|---|---|
|
||||
| 01 | Connection | Connect panel with stored accounts visible | Background color, panel layout, text contrast, profession icons |
|
||||
| 02 | Connection | Running games list visible | Row icons, timestamps, buttons, selected/hover states if practical |
|
||||
| 03 | Eagle map | Normal province map after joining a game | Province colors, borders, ocean animation frame, faction highlights |
|
||||
| 04 | Eagle map | Province hovered/selected | On-map province tooltip, selected outline, side-panel readability |
|
||||
| 05 | Eagle weather | Drought province | Heat shimmer/drought signal remains visible and does not obscure UI |
|
||||
| 06 | Eagle weather | Flood/rain or blizzard province | Weather overlay color, particle ordering, map readability |
|
||||
| 07 | Eagle beasts | Beast effect on map | Beast animation visible in Game view and positioned over province |
|
||||
| 08 | Eagle beasts | Beast notification open | Animated beast visible in notification and not hidden behind panel art |
|
||||
| 09 | Eagle UI | Command panel with generated text | Text glyphs, fallback glyphs, panel clipping, button states |
|
||||
| 10 | Eagle UI | Settings panel open | Top-right settings button, Escape behavior, modal layering |
|
||||
| 11 | Shardok setup | Initial placement | Terrain tiles, grid lines, unit labels/icons, placement overlays |
|
||||
| 12 | Shardok battle | Unit selected with destination overlays | Overlay labels/icons draw above terrain, bridges, fires, and highlights |
|
||||
| 13 | Shardok battle | Bridge and fire visible near units | Bridge/fire render order does not cover unit labels/icons |
|
||||
| 14 | Shardok battle | Command buttons visible | Right-side UX, disabled/enabled button states, tooltip readability |
|
||||
| 15 | Scene transition | Eagle to Shardok to Eagle | No black/blank frame persists, returning Eagle map is visually intact |
|
||||
|
||||
## Acceptance Notes
|
||||
|
||||
For each URP rendering follow-up, record:
|
||||
|
||||
- Unity version and branch name.
|
||||
- Screenshot directory.
|
||||
- Any pink/missing materials.
|
||||
- Any invisible UI, labels, particle effects, bridges, fires, or weather effects.
|
||||
- Any render-order differences, especially Shardok overlays and Eagle beast effects.
|
||||
- Whether the difference is acceptable, needs shader work, or needs asset/material work.
|
||||
|
||||
Do not merge a URP rendering branch until the affected Connection, Eagle, Shardok,
|
||||
or Settings baseline captures are visually acceptable.
|
||||
@@ -1,36 +1,40 @@
|
||||
module github.com/nolen777/eagle0
|
||||
|
||||
go 1.23.0
|
||||
go 1.25.0
|
||||
|
||||
toolchain go1.23.3
|
||||
toolchain go1.26.4
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.8
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.10
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.51
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.2
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/aws/aws-sdk-go-v2 v1.42.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.25
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.24
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.103.3
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6
|
||||
golang.org/x/sys v0.30.0
|
||||
google.golang.org/grpc v1.68.0
|
||||
google.golang.org/protobuf v1.36.3
|
||||
golang.org/x/sys v0.46.0
|
||||
google.golang.org/grpc v1.81.1
|
||||
google.golang.org/protobuf v1.36.11
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 // indirect
|
||||
github.com/aws/smithy-go v1.22.1 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.2.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.31.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.43.3 // indirect
|
||||
github.com/aws/smithy-go v1.27.2 // indirect
|
||||
golang.org/x/net v0.56.0 // indirect
|
||||
golang.org/x/text v0.38.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect
|
||||
)
|
||||
|
||||
@@ -1,56 +1,184 @@
|
||||
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
|
||||
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
|
||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.8 h1:cZV+NUS/eGxKXMtmyhtYPJ7Z4YLoI/V8bkTdRZfYhGo=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.8/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
|
||||
github.com/aws/aws-sdk-go-v2 v1.42.0 h1:XvXMJTkFQtpBKIWZnmr9ZEOc2InWM2yldjXEJ/bymhA=
|
||||
github.com/aws/aws-sdk-go-v2 v1.42.0/go.mod h1:27+ACypSLljLAEKsCYOmrjKh83vuTRkuAe9Uv/3A4bg=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.13 h1:p1BBrg/Hhp6uK7zpejeI8QFXHJeC/mynzi04Sl03k9g=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.13/go.mod h1:8cIfkE9MDhkRZGpQ22aV6/lkYeYSozpz16Smrs5x4Ls=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.10 h1:fKODZHfqQu06pCzR69KJ3GuttraRJkhlC8g80RZ0Dfg=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.10/go.mod h1:PvdxRYZ5Um9QMq9PQ0zHHNdtKK+he2NHtFCUFMXWXeg=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.25 h1:ACCejvStYoilgwrfegSt5ZntCbPrk52qfwyNcnl3omM=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.25/go.mod h1:LJyU8sDRbXUxFn8xMJIGP+v9QYYwveNLI8a/giAOiAs=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.51 h1:F/9Sm6Y6k4LqDesZDPJCLxQGXNNHd/ZtJiWd0lCZKRk=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.51/go.mod h1:TKbzCHm43AoPyA+iLGGcruXd4AFhF8tOmLex2R9jWNQ=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.24 h1:2hQqYCV9yqyePQ9o6dCrZc/zO8U3TwPr9mIKlZnPu/I=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.24/go.mod h1:IDwpACtwqHLISdzfwUUNq4P9DsB/h5BLg4FwJPNfqFY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 h1:IBAoD/1d8A8/1aA8g4MBVtTRHhXRiNAgwdbo/xRM2DI=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23/go.mod h1:vfENuCM7dofkgKpYzuzf1VT1UKkA/YL3qanfBn7HCaA=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29 h1:r6qZHbT+wxgWO/e9vYNUEtg7lv5+UN3pRqKhLXvnArg=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29/go.mod h1:QRnaRcTVGKPGRy8w78HMQtKUGRYcnMZAANATkeVA6Mo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 h1:jSJjSBzw8VDIbWv+mmvBSP8ezsztMYJGH+eKqi9AmNs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27/go.mod h1:/DAhLbFRgwhmvJdOfSm+WwikZrCuUJiA4WgJG0fTNSw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 h1:f3vKqSo13fhTYb+JEcXwXefZQE26I1FB5eTSniU67ko=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29/go.mod h1:MzoLFUArKGpGD+ukmPiTPG1X5x4o6M2kq4v2dr1FiEc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 h1:l+X4K77Dui85pIj5foXDhPlnqcNRG2QUyvca300lXh8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27/go.mod h1:KvZXSFEXm6x84yE8qffKvT3x8J5clWnVFXphpohhzJ8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 h1:RdwIf/CuUsvJX3RgJagbOyotl/cxoLY4xviKuE7p2GY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29/go.mod h1:71wt8W2EgswdZy9Mf9KNnzxZ3TiZlv4caKghPktDOkA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.27 h1:AmB5QxnD+fBFrg9LcqzkgF/CaYvMyU/BTlejG4t1S7Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.27/go.mod h1:Sai7P3xTiyv9ZUYO3IFxMnmiIP759/67iQbU4kdmkyU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 h1:VTGy885W5DKBxWRUJbym9hytNaYzsyaPkCHGRRMAOhU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30/go.mod h1:AS0HycUvJRFvTt613AYDOgO2jzw+00cVSMny8XB3yMY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 h1:ZD2+BSw9vFsNlKYIasSNt3uDbjqqXIBcM13UJv/Lx2k=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12/go.mod h1:Ms4zlcVBbXbiP7EVLhl+lgjvA/a7YphqQ3Ih3174EmI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.8 h1:iwYS40JnrBeA9e9aI5S6KKN4EB2zR4iUVYN0nwVivz4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.8/go.mod h1:Fm9Mi+ApqmFiknZtGpohVcBGvpTu542VC4XO9YudRi0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.22 h1:V51LGlOq/1VsDsHUdoklAQi7rMmx4qQubvFYAlP2254=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.22/go.mod h1:4Pzhyz8hJOm2bepgl+NjvRx8vlUFAIIvJnZ/MkcNPpU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 h1:cWno7lefSH6Pp+mSznagKCgfDGeZRin66UvYUqAkyeA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8/go.mod h1:tPD+VjU3ABTBoEJ3nctu5Nyg4P4yjqSH5bJGGkY4+XE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 h1:DRebniUGZ2MqiiIVmQJ04vIXr918hubdHMnarSLEWyU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29/go.mod h1:LfRkPCD8YHDM2E5eTkos2UpwYeZnBcVarTa8L59bJHA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.8 h1:/Mn7gTedG86nbpjT4QEKsN1D/fThiYe1qvq7WsBGNHg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.8/go.mod h1:Ae3va9LPmvjj231ukHB6UeT8nS7wTPfC3tMZSZMwNYg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.29 h1:hiME6pBzC7OTl9LMtlyTWBuEl1f4QBcUmFDKC7MLXtc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.29/go.mod h1:G7RP+uhagpKtKhd1BM9N6JQqjCcGEU47K5lBVZQyRQw=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.2 h1:a7aQ3RW+ug4IbhoQp29NZdc7vqrzKZZfWZSaQAXOZvQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.2/go.mod h1:xMekrnhmJ5aqmyxtmALs7mlvXw5xRh+eYjOjvrIIFJ4=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.103.3 h1:JRseEu/vIDMaWis4bSw0QbXL+cvIGc1XnX076H5ZXLE=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.103.3/go.mod h1:77ZAgynvx1txMvDG8gGWoWkO1augYDxkp9JElWFgjQU=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.2.0 h1:3nXpRcFwRCW8n7HgO2QGy0Dc20eQNfBuUemGQhpF8m8=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.2.0/go.mod h1:LxYujSTLPRlp2vTtcUO/+1ilrew8ytt6SvQyOgejzFQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.9 h1:YqtxripbjWb2QLyzRK9pByfEDvgg95gpC2AyDq4hFE8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.9/go.mod h1:lV8iQpg6OLOfBnqbGMBKYjilBlf633qwHnBEiMSPoHY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.31.3 h1:ey1XLTYXb9PcLt4535632o5kCGXNXEhNb620Dqwuylo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.31.3/go.mod h1:Lk7PlmoTYryQmyBG0EXqj5BcUbj3whXdU2s3yGI3EAc=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 h1:6dBT1Lz8fK11m22R+AqfRsFn8320K0T5DTGxxOQBSMw=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8/go.mod h1:/kiBvRQXBc6xeJTYzhSdGvJ5vm1tjaDEjH+MSeRJnlY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.6 h1:yLr03zQE/5Eu5l3QU0Si+xMbLMbSDF2YXsigqXngs6g=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.6/go.mod h1:Q5N6icH+KJZDLh+ESNwzdv6cZ6vLFF/egy3IOxWhmz4=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 h1:VwhTrsTuVn52an4mXx29PqRzs2Dvu921NpGk7y43tAM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6/go.mod h1:+8h7PZb3yY5ftmVLD7ocEoE98hdc8PoKS0H3wfx1dlc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.43.3 h1:VrIhKRCSK1umelSgB9RghvA9RTUYeQffyAS5ApXehNI=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.43.3/go.mod h1:r8wkDOuLaaMFqFiYAb8dGY2A3gJCOujMc6CFOVC4Zhc=
|
||||
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
|
||||
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/aws/smithy-go v1.27.1 h1:4T340VFndXtADGF52gYa1POyL7s9E4Z1OeZ1hCscIw8=
|
||||
github.com/aws/smithy-go v1.27.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
|
||||
github.com/aws/smithy-go v1.27.2 h1:y9NPmSE6am6LjEFPfqHqG/jJk7AauQvhCJONKh7kpzk=
|
||||
github.com/aws/smithy-go v1.27.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik=
|
||||
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=
|
||||
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
|
||||
github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I=
|
||||
github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo=
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs=
|
||||
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6 h1:VQpB2SpK88C6B5lPHTuSZKb2Qee1QWwiFlC5CKY4AW0=
|
||||
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6/go.mod h1:yE65LFCeWf4kyWD5re+h4XNvOHJEXOCOuJZ4v8l5sgk=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.42.0 h1:kpt2PEJuOuqYkPcktfJqWWDjTEd/FNgrxcniL7kQrXQ=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.42.0/go.mod h1:W9zQ439utxymRrXsUOzZbFX4JhLxXU4+ZnCt8GG7yA8=
|
||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
||||
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
|
||||
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
|
||||
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad h1:3iLyITS/sySRwbUKoC7ogfj2Yr1Cjs0pfaRKj5U5HEw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:KdNqO+rCIWgFumrNBSEDlDNrkrQnpkax7Tv1WxNY8V4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
|
||||
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
|
||||
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
|
||||
+1254
-704
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
],
|
||||
"dependencyDashboard": true,
|
||||
"enabledManagers": [
|
||||
"bazel-module",
|
||||
"cargo",
|
||||
"github-actions",
|
||||
"gomod",
|
||||
"swift"
|
||||
],
|
||||
"labels": [
|
||||
"dependencies"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Bazel module artifact updates run in GitHub Actions so hosted Renovate does not need unsafe bazel mod deps execution",
|
||||
"matchManagers": [
|
||||
"bazel-module"
|
||||
],
|
||||
"skipArtifactsUpdate": true
|
||||
},
|
||||
{
|
||||
"description": "Go packages import Bazel-generated protobuf packages, so Renovate's generic Go artifact updater cannot run ./...",
|
||||
"matchManagers": [
|
||||
"gomod"
|
||||
],
|
||||
"skipArtifactsUpdate": true
|
||||
}
|
||||
],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true,
|
||||
"schedule": [
|
||||
"before 6am on monday"
|
||||
]
|
||||
},
|
||||
"prConcurrentLimit": 3,
|
||||
"prHourlyLimit": 1,
|
||||
"rebaseWhen": "behind-base-branch",
|
||||
"schedule": [
|
||||
"before 6am on monday"
|
||||
],
|
||||
"separateMajorMinor": true,
|
||||
"timezone": "America/Los_Angeles"
|
||||
}
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
bazel_cmd=(bazel)
|
||||
if [ -n "${BAZEL_OUTPUT_USER_ROOT:-}" ]; then
|
||||
bazel_cmd+=("--output_user_root=${BAZEL_OUTPUT_USER_ROOT}")
|
||||
fi
|
||||
if [ -n "${BAZEL_OUTPUT_BASE:-}" ]; then
|
||||
bazel_cmd+=("--output_base=${BAZEL_OUTPUT_BASE}")
|
||||
fi
|
||||
|
||||
"${bazel_cmd[@]}" build "$@" //src/main/scala/net/eagle0/eagle:eagle_server
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
bazel_cmd=(bazel)
|
||||
if [ -n "${BAZEL_OUTPUT_USER_ROOT:-}" ]; then
|
||||
bazel_cmd+=("--output_user_root=${BAZEL_OUTPUT_USER_ROOT}")
|
||||
fi
|
||||
if [ -n "${BAZEL_OUTPUT_BASE:-}" ]; then
|
||||
bazel_cmd+=("--output_base=${BAZEL_OUTPUT_BASE}")
|
||||
fi
|
||||
|
||||
"${bazel_cmd[@]}" build -c opt "$@" //src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <warm|verify> [bazel targets...]"
|
||||
echo
|
||||
echo "warm: build targets normally so local results can upload to the remote cache"
|
||||
echo "verify: require all target actions to be available from remote cache"
|
||||
}
|
||||
|
||||
if [ "$#" -lt 1 ]; then
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
mode="$1"
|
||||
shift
|
||||
|
||||
case "$mode" in
|
||||
warm | verify)
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
tmp_root="${RUNNER_TEMP:-/private/tmp}"
|
||||
run_id="${GITHUB_RUN_ID:-local}-$$"
|
||||
output_user_root="${tmp_root%/}/eagle0-bazel-user-root-${run_id}"
|
||||
output_base="${tmp_root%/}/eagle0-cache-parity-${mode}-${run_id}"
|
||||
|
||||
echo "Mode: $mode"
|
||||
echo "Output user root: $output_user_root"
|
||||
echo "Output base: $output_base"
|
||||
|
||||
run_ci_build_script() {
|
||||
local script="$1"
|
||||
shift
|
||||
|
||||
echo "Build script: $script"
|
||||
echo "Build args:"
|
||||
printf ' %s\n' "$@"
|
||||
|
||||
BAZEL_OUTPUT_USER_ROOT="$output_user_root" BAZEL_OUTPUT_BASE="$output_base" "$script" "$@"
|
||||
}
|
||||
|
||||
cache_check_args() {
|
||||
local bazel_args=(
|
||||
"--remote_download_all"
|
||||
)
|
||||
|
||||
if [ "$mode" = "verify" ]; then
|
||||
bazel_args+=(
|
||||
"--remote_upload_local_results=false"
|
||||
"--experimental_remote_require_cached"
|
||||
"--disk_cache="
|
||||
)
|
||||
fi
|
||||
|
||||
printf '%s\n' "${bazel_args[@]}"
|
||||
}
|
||||
|
||||
run_bazel_targets() {
|
||||
bazel_args=()
|
||||
while IFS= read -r arg; do
|
||||
bazel_args+=("$arg")
|
||||
done < <(cache_check_args)
|
||||
|
||||
echo "Bazel args:"
|
||||
printf ' %s\n' "${bazel_args[@]}" "$@"
|
||||
|
||||
bazel "--output_user_root=$output_user_root" "--output_base=$output_base" build "${bazel_args[@]}" "$@"
|
||||
}
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
run_bazel_targets "$@"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
bazel_args=()
|
||||
while IFS= read -r arg; do
|
||||
bazel_args+=("$arg")
|
||||
done < <(cache_check_args)
|
||||
run_ci_build_script scripts/build_eagle_ci.sh "${bazel_args[@]}"
|
||||
run_ci_build_script scripts/build_shardok_ci.sh "${bazel_args[@]}"
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
scripts/build_eagle_ci.sh
|
||||
scripts/build_shardok_ci.sh
|
||||
@@ -8,12 +8,12 @@
|
||||
#
|
||||
# Optional environment variables:
|
||||
# SPARKLE_FEED_URL - Appcast URL (default: https://assets.eagle0.net/mac/appcast.xml)
|
||||
# SPARKLE_VERSION - Sparkle version to use (default: 2.6.4)
|
||||
# SPARKLE_VERSION - Sparkle version to use (default: 2.9.3)
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
APP_PATH="$1"
|
||||
SPARKLE_VERSION="${SPARKLE_VERSION:-2.6.4}"
|
||||
SPARKLE_VERSION="${SPARKLE_VERSION:-2.9.3}"
|
||||
SPARKLE_FEED_URL="${SPARKLE_FEED_URL:-https://assets.eagle0.net/mac/appcast.xml}"
|
||||
SPARKLE_CACHE_DIR="/tmp/sparkle-cache"
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
# Xcode version. If Xcode is upgraded in place, the DEVELOPER_DIR path stays the
|
||||
# same, so Bazel can otherwise keep using stale Xcode metadata.
|
||||
#
|
||||
# 1. Writes .bazelrc.xcode with macOS-scoped flags:
|
||||
# - action_env for remote cache key invalidation
|
||||
# - DEVELOPER_DIR pointing to the active Xcode
|
||||
# 1. Writes .bazelrc.xcode with mactools-scoped flags:
|
||||
# - action_env for Apple build remote cache key invalidation
|
||||
# - DEVELOPER_DIR pointing to the active Xcode for Apple builds
|
||||
#
|
||||
# 2. Runs `bazel clean --expunge` when the version actually changes, because
|
||||
# local_config_apple_cc (a cached repository rule) bakes in the old version
|
||||
@@ -35,7 +35,7 @@ if [ -z "$XCODE_BUILD_VERSION" ]; then
|
||||
fi
|
||||
|
||||
BAZELRC_XCODE=".bazelrc.xcode"
|
||||
EXPECTED_LINE="common:macos --action_env=XCODE_BUILD_VERSION=${XCODE_BUILD_VERSION}"
|
||||
EXPECTED_LINE="common:mactools --action_env=XCODE_BUILD_VERSION=${XCODE_BUILD_VERSION}"
|
||||
|
||||
# Check if the file already has the right version (first line is the version marker)
|
||||
if [ -f "$BAZELRC_XCODE" ]; then
|
||||
@@ -45,19 +45,19 @@ if [ -f "$BAZELRC_XCODE" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Xcode version changed (or first run) — expunge local cache to clear
|
||||
# Xcode Bazel config changed (or first run) — expunge local cache to clear
|
||||
# stale local_config_apple_cc, then write the new config
|
||||
OLD_VERSION="unknown"
|
||||
OLD_CONFIG="missing"
|
||||
if [ -f "$BAZELRC_XCODE" ]; then
|
||||
OLD_VERSION=$(sed -n 's/.*XCODE_BUILD_VERSION=//p' "$BAZELRC_XCODE" | head -1)
|
||||
OLD_CONFIG=$(head -1 "$BAZELRC_XCODE")
|
||||
fi
|
||||
echo "Xcode build version changed: ${OLD_VERSION} -> ${XCODE_BUILD_VERSION}"
|
||||
echo "Xcode Bazel config changed: ${OLD_CONFIG} -> ${EXPECTED_LINE}"
|
||||
echo "Running bazel clean --expunge to clear stale toolchain config..."
|
||||
bazel clean --expunge 2>/dev/null || true
|
||||
|
||||
cat > "$BAZELRC_XCODE" << EOF
|
||||
${EXPECTED_LINE}
|
||||
common:macos --repo_env=DEVELOPER_DIR=${DEVELOPER_DIR}
|
||||
common:mactools --repo_env=DEVELOPER_DIR=${DEVELOPER_DIR}
|
||||
EOF
|
||||
|
||||
if [ -n "${GITHUB_ENV:-}" ]; then
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo -ne "\033[0;32m"
|
||||
echo 'Updating bazel dependencies. This will take about five minutes.'
|
||||
echo -ne "\033[0m"
|
||||
set -e
|
||||
|
||||
if [ "$(uname -s)" == "Linux" ]; then
|
||||
BAZEL_DEPS_URL=https://github.com/johnynek/bazel-deps/releases/download/v0.1-9/bazel-deps-linux
|
||||
BAZEL_DEPS_SHA256=034ce4d8674a200d73d97aa60774786a3771c0f3871197858bf55fd930677b15
|
||||
elif [ "$(uname -s)" == "Darwin" ]; then
|
||||
BAZEL_DEPS_URL=https://github.com/johnynek/bazel-deps/releases/download/v0.1-9/bazel-deps-macos
|
||||
BAZEL_DEPS_SHA256=97e1b932cccc60e30475fc0ef56a538c6b8a732adbdf0eaec1988f0b4f1dc5dc
|
||||
else
|
||||
echo "Your platform '$(uname -s)' is unsupported, sorry"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# This is some bash snippet designed to find the location of the script.
|
||||
# we operate under the presumption this script is checked into the repo being operated on
|
||||
# so we goto the script location, then use git to find the repo root.
|
||||
SCRIPT_LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd $SCRIPT_LOCATION
|
||||
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
|
||||
BAZEL_DEPS_DIR="$HOME/.bazel-deps-cache"
|
||||
BAZEL_DEPS_PATH="${BAZEL_DEPS_DIR}/v0.1-9"
|
||||
|
||||
if [ ! -f ${BAZEL_DEPS_PATH} ]; then
|
||||
( # Opens a subshell
|
||||
set -e
|
||||
echo "Fetching bazel deps."
|
||||
curl -L -o /tmp/bazel-deps-bin $BAZEL_DEPS_URL
|
||||
|
||||
GENERATED_SHA_256=$(shasum -a 256 /tmp/bazel-deps-bin | awk '{print $1}')
|
||||
|
||||
if [ "$GENERATED_SHA_256" != "$BAZEL_DEPS_SHA256" ]; then
|
||||
echo "Sha 256 does not match, expected: $BAZEL_DEPS_SHA256"
|
||||
echo "But found $GENERATED_SHA_256"
|
||||
echo "You may need to update the sha in this script, or the download was corrupted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod +x /tmp/bazel-deps-bin
|
||||
mkdir -p ${BAZEL_DEPS_DIR}
|
||||
mv /tmp/bazel-deps-bin ${BAZEL_DEPS_PATH}
|
||||
)
|
||||
fi
|
||||
|
||||
cd $REPO_ROOT
|
||||
set +e
|
||||
$BAZEL_DEPS_PATH generate -r $REPO_ROOT -s 3rdparty/workspace.bzl -d dependencies.yaml --target-file 3rdparty/target_file.bzl --disable-3rdparty-in-repo
|
||||
RET_CODE=$?
|
||||
set -e
|
||||
|
||||
if [ $RET_CODE == 0 ]; then
|
||||
echo "Success, going to format files"
|
||||
else
|
||||
echo "Failure, checking out 3rdparty/jvm"
|
||||
cd $REPO_ROOT
|
||||
git checkout 3rdparty/jvm 3rdparty/workspace.bzl
|
||||
exit $RET_CODE
|
||||
fi
|
||||
|
||||
$BAZEL_DEPS_PATH format-deps -d $REPO_ROOT/dependencies.yaml -o
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
|
||||
#define SUPPRESS_PROTOBUF_WARNINGS \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpragmas\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") _Pragma( \
|
||||
"GCC diagnostic ignored \"-Wsign-conversion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") _Pragma( \
|
||||
"GCC diagnostic ignored \"-Wdocumentation-deprecated-sync\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdocumentation\"") _Pragma( \
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
# Abstract base class for score calculators
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_binary(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -392,7 +392,6 @@ void EagleInterfaceImpl::PopulateGameStatusResponse(
|
||||
controller->ResolvedPlayerInfos(),
|
||||
controller->EndGameUnits(),
|
||||
response->mutable_game_over_response());
|
||||
auto status = controller->GameOverStatus();
|
||||
// player resolution infos
|
||||
// response->mutable_game_over_response()->mutable_user_infos() ...
|
||||
}
|
||||
@@ -650,7 +649,9 @@ auto EagleInterfaceImpl::SubscribeToGame(
|
||||
|
||||
// Deserialize and restart the game from the original request
|
||||
NewGameRequest newGameRequest;
|
||||
newGameRequest.ParseFromString(savedRequest);
|
||||
if (!newGameRequest.ParseFromString(savedRequest)) {
|
||||
return Status(StatusCode::INTERNAL, "Failed to parse saved tutorial battle request");
|
||||
}
|
||||
StartGame(newGameRequest);
|
||||
|
||||
controller = gamesManager->GetController(gameId);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//tools:copts.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "MapLoader.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "src/main/cpp/net/eagle0/common/FilesystemUtils.hpp"
|
||||
|
||||
const std::string kShardokMapExtension = ".e0m";
|
||||
@@ -14,14 +16,18 @@ auto LoadMap(const string& mapName) -> HexMapProto {
|
||||
const byte_vector mapProtoBytes = byte_vector::FromPath(mapPath);
|
||||
|
||||
net::eagle0::shardok::common::HexMap mapProto{};
|
||||
mapProto.ParseFromArray(mapProtoBytes.data(), (int)mapProtoBytes.size());
|
||||
if (!mapProto.ParseFromArray(mapProtoBytes.data(), static_cast<int>(mapProtoBytes.size()))) {
|
||||
throw std::runtime_error("Failed to parse map proto from " + mapPath);
|
||||
}
|
||||
|
||||
return mapProto;
|
||||
}
|
||||
|
||||
auto LoadMapFromBytes(const string& mapBytes) -> HexMapProto {
|
||||
net::eagle0::shardok::common::HexMap mapProto{};
|
||||
mapProto.ParseFromString(mapBytes);
|
||||
if (!mapProto.ParseFromString(mapBytes)) {
|
||||
throw std::runtime_error("Failed to parse map proto from bytes");
|
||||
}
|
||||
|
||||
return mapProto;
|
||||
}
|
||||
|
||||
+340
-271
File diff suppressed because it is too large
Load Diff
+16
-13
@@ -24,34 +24,35 @@ public class MoveCamera : MonoBehaviour {
|
||||
|
||||
void Update() {
|
||||
// Get the left mouse button
|
||||
if (Input.GetMouseButtonDown(0)) {
|
||||
if (GameInput.PrimaryPointerPressedThisFrame()) {
|
||||
// Get mouse origin
|
||||
mouseOrigin = Input.mousePosition;
|
||||
mouseOrigin = GameInput.PointerPosition();
|
||||
isRotating = true;
|
||||
}
|
||||
|
||||
// Get the right mouse button
|
||||
if (Input.GetMouseButtonDown(1)) {
|
||||
if (GameInput.SecondaryPointerPressedThisFrame()) {
|
||||
// Get mouse origin
|
||||
mouseOrigin = Input.mousePosition;
|
||||
mouseOrigin = GameInput.PointerPosition();
|
||||
isPanning = true;
|
||||
}
|
||||
|
||||
// Get the middle mouse button
|
||||
if (Input.GetMouseButtonDown(2)) {
|
||||
if (GameInput.MiddlePointerPressedThisFrame()) {
|
||||
// Get mouse origin
|
||||
mouseOrigin = Input.mousePosition;
|
||||
mouseOrigin = GameInput.PointerPosition();
|
||||
isZooming = true;
|
||||
}
|
||||
|
||||
// Disable movements on button release
|
||||
if (!Input.GetMouseButton(0)) isRotating = false;
|
||||
if (!Input.GetMouseButton(1)) isPanning = false;
|
||||
if (!Input.GetMouseButton(2)) isZooming = false;
|
||||
if (!GameInput.PrimaryPointerPressed()) isRotating = false;
|
||||
if (!GameInput.SecondaryPointerPressed()) isPanning = false;
|
||||
if (!GameInput.MiddlePointerPressed()) isZooming = false;
|
||||
|
||||
// Rotate camera along X and Y axis
|
||||
if (isRotating) {
|
||||
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
|
||||
Vector3 pos = Camera.main.ScreenToViewportPoint(
|
||||
(Vector3)GameInput.PointerPosition() - mouseOrigin);
|
||||
|
||||
transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed);
|
||||
transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed);
|
||||
@@ -59,7 +60,8 @@ public class MoveCamera : MonoBehaviour {
|
||||
|
||||
// Move the camera on it's XY plane
|
||||
if (isPanning) {
|
||||
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
|
||||
Vector3 pos = Camera.main.ScreenToViewportPoint(
|
||||
(Vector3)GameInput.PointerPosition() - mouseOrigin);
|
||||
|
||||
Vector3 move = new Vector3(pos.x * panSpeed, pos.y * panSpeed, 0);
|
||||
transform.Translate(move, Space.Self);
|
||||
@@ -67,10 +69,11 @@ public class MoveCamera : MonoBehaviour {
|
||||
|
||||
// Move the camera linearly along Z axis
|
||||
if (isZooming) {
|
||||
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
|
||||
Vector3 pos = Camera.main.ScreenToViewportPoint(
|
||||
(Vector3)GameInput.PointerPosition() - mouseOrigin);
|
||||
|
||||
Vector3 move = pos.y * zoomSpeed * transform.forward;
|
||||
transform.Translate(move, Space.World);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d7fd9488000d3734a9e00ee676215985, type: 3}
|
||||
m_Name: DefaultVolumeProfile
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::UnityEngine.Rendering.VolumeProfile
|
||||
components: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 647146733c18f46648c2162493680a2e
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
LFS
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -133,6 +133,7 @@ namespace eagle {
|
||||
foreach (var renderer in instance.GetComponentsInChildren<Renderer>()) {
|
||||
renderer.sortingLayerName = BeastSortingLayerName;
|
||||
renderer.sortingOrder = BeastCreatureSortingOrder;
|
||||
BeastMaterialCompatibility.ConfigureRenderer(renderer);
|
||||
}
|
||||
foreach (var smr in instance.GetComponentsInChildren<SkinnedMeshRenderer>()) {
|
||||
smr.updateWhenOffscreen = true;
|
||||
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace eagle {
|
||||
internal static class BeastMaterialCompatibility {
|
||||
private const string UniversalLitShaderName = "Universal Render Pipeline/Lit";
|
||||
private const string UniversalParticleUnlitShaderName =
|
||||
"Universal Render Pipeline/Particles/Unlit";
|
||||
private const string BuiltInParticleStandardUnlitShaderName = "Particles/Standard Unlit";
|
||||
private static readonly string[] BaseTexturePropertyNames =
|
||||
{ "_MainTex", "_BaseMap", "_Albedo", "_TextureSample0" };
|
||||
private static readonly Dictionary<Material, Texture2D> BakedPaletteTextures = new();
|
||||
private static readonly PaletteEntry[] PolytopePaletteEntries = {
|
||||
new(new Color(0.4980392f, 1f, 1f), "_FEATHERS2COLOR", "_FEATHERS2COLOR1"),
|
||||
new(new Color(0.4980392f, 1f, 0.4980392f), "_FEATHERS1COLOR", "_FEATHERS1COLOR1"),
|
||||
new(new Color(0f, 0f, 1f), "_CLOTH4COLOR", "_CLOTH4COLOR1"),
|
||||
new(new Color(0f, 1f, 1f), "_CLOTH3COLOR", "_CLOTH3COLOR1"),
|
||||
new(new Color(0f, 1f, 0f), "_CLOTH2COLOR", "_CLOTH2COLOR1"),
|
||||
new(new Color(0f, 0.4980392f, 0f), "_CLOTH1COLOR", "_CLOTH1COLOR1"),
|
||||
new(new Color(1f, 0.4980392f, 0.4980392f), "_LEATHER4COLOR", "_LEATHER4COLOR1"),
|
||||
new(new Color(1f, 1f, 0.4980392f), "_LEATHER3COLOR", "_LEATHER3COLOR1"),
|
||||
new(new Color(1f, 0f, 1f), "_LEATHER2COLOR", "_LEATHER2COLOR1"),
|
||||
new(new Color(1f, 0.4980392f, 1f), "_LEATHER1COLOR", "_LEATHER1COLOR1"),
|
||||
new(new Color(0.4980392f, 0.4980392f, 1f), "_METAL4COLOR", "_METAL4COLOR1"),
|
||||
new(new Color(0f, 0.4980392f, 0.4980392f), "_METAL3COLOR", "_METAL3COLOR1"),
|
||||
new(new Color(0f, 0f, 0.4980392f), "_METAL2COLOR", "_METAL2COLOR1"),
|
||||
new(new Color(0.4980392f, 0f, 0.4980392f), "_METAL1COLOR", "_METAL1COLOR1"),
|
||||
new(new Color(1f, 1f, 0f), "_OTHERCOLOR", "_OTHERCOLOR1"),
|
||||
new(new Color(0.4980392f, 0.4980392f, 0f), "_LIPSCOLOR", "_LIPSCOLOR1"),
|
||||
new(new Color(0.4980392f, 0.4980392f, 0.4980392f), "_SCLERACOLOR", "_SCLERACOLOR1"),
|
||||
new(new Color(1f, 0f, 0f), "_EYESCOLOR", "_EYESCOLOR1"),
|
||||
new(new Color(1f, 0.4980392f, 0f), "_HAIRCOLOR", "_HAIRCOLOR1"),
|
||||
new(new Color(0.4980392f, 0f, 0f), "_SKINCOLOR", "_SKINCOLOR1")
|
||||
};
|
||||
|
||||
public static void ConfigureRenderer(Renderer renderer) {
|
||||
if (!IsUniversalRenderPipelineActive()) { return; }
|
||||
|
||||
var sourceMaterials = renderer.sharedMaterials;
|
||||
var materials = renderer.materials;
|
||||
var changed = false;
|
||||
for (var i = 0; i < materials.Length; i++) {
|
||||
if (!ShouldReplaceMaterial(materials[i])) { continue; }
|
||||
|
||||
var sourceMaterial = i < sourceMaterials.Length ? sourceMaterials[i] : materials[i];
|
||||
materials[i] = CreateUniversalLitMaterial(sourceMaterial);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) { renderer.materials = materials; }
|
||||
}
|
||||
|
||||
public static Material CreateParticleMaterial(Material source, Texture texture) {
|
||||
if (!IsUniversalRenderPipelineActive()) {
|
||||
var builtInMaterial =
|
||||
source != null ? new Material(source)
|
||||
: CreateMaterial(BuiltInParticleStandardUnlitShaderName);
|
||||
if (builtInMaterial != null && texture != null) {
|
||||
builtInMaterial.mainTexture = texture;
|
||||
}
|
||||
return builtInMaterial;
|
||||
}
|
||||
|
||||
var material = CreateMaterial(UniversalParticleUnlitShaderName) ??
|
||||
CreateMaterial("Universal Render Pipeline/Unlit");
|
||||
if (material == null) { return source != null ? new Material(source) : null; }
|
||||
|
||||
CopyBaseTextureAndColor(source, material, texture);
|
||||
material.SetFloat("_Surface", 1f);
|
||||
material.SetFloat("_Blend", 0f);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.SrcAlpha);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.SetInt("_ZWrite", 0);
|
||||
material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
|
||||
material.renderQueue = (int)RenderQueue.Transparent;
|
||||
return material;
|
||||
}
|
||||
|
||||
private static bool ShouldReplaceMaterial(Material material) {
|
||||
if (material == null || material.shader == null) { return false; }
|
||||
|
||||
var shaderName = material.shader.name;
|
||||
if (shaderName.StartsWith("Universal Render Pipeline/") ||
|
||||
shaderName.StartsWith("Sprites/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Material CreateUniversalLitMaterial(Material source) {
|
||||
var shader = Shader.Find(UniversalLitShaderName);
|
||||
if (shader == null) { return new Material(source); }
|
||||
|
||||
var material = new Material(shader);
|
||||
if (TryCreatePolytopePaletteTexture(source, out var paletteTexture)) {
|
||||
CopyBaseTextureAndColor(source, material, paletteTexture);
|
||||
} else {
|
||||
CopyBaseTextureAndColor(source, material, null);
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
private static Material CreateMaterial(string shaderName) {
|
||||
var shader = Shader.Find(shaderName);
|
||||
return shader != null ? new Material(shader) : null;
|
||||
}
|
||||
|
||||
private static void
|
||||
CopyBaseTextureAndColor(Material source, Material target, Texture overrideTexture) {
|
||||
var texture = overrideTexture;
|
||||
if (texture == null && source != null) {
|
||||
texture = FindFirstTexture(source, BaseTexturePropertyNames);
|
||||
}
|
||||
|
||||
if (texture != null) {
|
||||
if (target.HasProperty("_BaseMap")) { target.SetTexture("_BaseMap", texture); }
|
||||
if (target.HasProperty("_MainTex")) { target.SetTexture("_MainTex", texture); }
|
||||
}
|
||||
|
||||
var color = Color.white;
|
||||
if (source != null) {
|
||||
if (source.HasProperty("_Color")) {
|
||||
color = source.GetColor("_Color");
|
||||
} else if (source.HasProperty("_BaseColor")) {
|
||||
color = source.GetColor("_BaseColor");
|
||||
}
|
||||
}
|
||||
|
||||
if (target.HasProperty("_BaseColor")) { target.SetColor("_BaseColor", color); }
|
||||
if (target.HasProperty("_Color")) { target.SetColor("_Color", color); }
|
||||
}
|
||||
|
||||
private static Texture FindFirstTexture(Material source, string[] propertyNames) {
|
||||
foreach (var propertyName in propertyNames) {
|
||||
if (!source.HasProperty(propertyName)) { continue; }
|
||||
|
||||
var texture = source.GetTexture(propertyName);
|
||||
if (texture != null) { return texture; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool TryCreatePolytopePaletteTexture(
|
||||
Material source,
|
||||
out Texture2D texture) {
|
||||
texture = null;
|
||||
if (source == null || !HasAnyProperty(source, "_SKINCOLOR", "_SKINCOLOR1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var maskTexture =
|
||||
GetTexture(source, "_TextureSample0") ?? GetTexture(source, "_TextureSample1");
|
||||
var shadeTexture =
|
||||
GetTexture(source, "_TextureSample2") ?? GetTexture(source, "_TextureSample3");
|
||||
if (maskTexture == null || shadeTexture == null) { return false; }
|
||||
|
||||
if (BakedPaletteTextures.TryGetValue(source, out texture)) { return true; }
|
||||
|
||||
var maskPixels = ReadTexturePixels(maskTexture);
|
||||
var shadePixels = ReadTexturePixels(shadeTexture);
|
||||
var width = Mathf.Min(maskPixels.width, shadePixels.width);
|
||||
var height = Mathf.Min(maskPixels.height, shadePixels.height);
|
||||
texture = new Texture2D(width, height, TextureFormat.RGBA32, true);
|
||||
texture.name = $"{source.name}_URP_BakedPalette";
|
||||
texture.wrapMode = maskTexture.wrapMode;
|
||||
texture.filterMode = maskTexture.filterMode;
|
||||
|
||||
for (var y = 0; y < height; y++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
var maskColor = maskPixels.texture.GetPixel(x, y);
|
||||
var shadeColor = shadePixels.texture.GetPixel(x, y);
|
||||
var paletteColor = ResolvePolytopePaletteColor(source, maskColor);
|
||||
texture.SetPixel(x, y, Multiply(shadeColor, paletteColor));
|
||||
}
|
||||
}
|
||||
|
||||
texture.Apply(updateMipmaps: true, makeNoLongerReadable: false);
|
||||
BakedPaletteTextures[source] = texture;
|
||||
DestroyIfTemporary(maskPixels.texture, maskTexture);
|
||||
DestroyIfTemporary(shadePixels.texture, shadeTexture);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Color ResolvePolytopePaletteColor(Material source, Color maskColor) {
|
||||
var bestDistance = float.MaxValue;
|
||||
var bestColor = Color.white;
|
||||
foreach (var entry in PolytopePaletteEntries) {
|
||||
var distance = ColorDistance(maskColor, entry.MaskColor);
|
||||
if (distance >= bestDistance) { continue; }
|
||||
|
||||
bestDistance = distance;
|
||||
bestColor = GetColor(source, entry.PropertyName, entry.AlternatePropertyName);
|
||||
}
|
||||
|
||||
return bestDistance <= 0.12f ? bestColor : Color.white;
|
||||
}
|
||||
|
||||
private static Color
|
||||
GetColor(Material source, string propertyName, string alternatePropertyName) {
|
||||
if (source.HasProperty(propertyName)) { return source.GetColor(propertyName); }
|
||||
if (source.HasProperty(alternatePropertyName)) {
|
||||
return source.GetColor(alternatePropertyName);
|
||||
}
|
||||
|
||||
return Color.white;
|
||||
}
|
||||
|
||||
private static Texture GetTexture(Material source, string propertyName) {
|
||||
return source.HasProperty(propertyName) ? source.GetTexture(propertyName) : null;
|
||||
}
|
||||
|
||||
private static bool HasAnyProperty(Material source, params string[] propertyNames) {
|
||||
foreach (var propertyName in propertyNames) {
|
||||
if (source.HasProperty(propertyName)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static TexturePixels ReadTexturePixels(Texture source) {
|
||||
var renderTexture = RenderTexture.GetTemporary(
|
||||
source.width,
|
||||
source.height,
|
||||
0,
|
||||
RenderTextureFormat.ARGB32,
|
||||
RenderTextureReadWrite.Default);
|
||||
var previous = RenderTexture.active;
|
||||
Graphics.Blit(source, renderTexture);
|
||||
RenderTexture.active = renderTexture;
|
||||
|
||||
var texture = new Texture2D(source.width, source.height, TextureFormat.RGBA32, false);
|
||||
texture.ReadPixels(new Rect(0, 0, source.width, source.height), 0, 0);
|
||||
texture.Apply();
|
||||
|
||||
RenderTexture.active = previous;
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
return new TexturePixels(texture);
|
||||
}
|
||||
|
||||
private static Color Multiply(Color a, Color b) {
|
||||
return new Color(a.r * b.r, a.g * b.g, a.b * b.b, a.a);
|
||||
}
|
||||
|
||||
private static float ColorDistance(Color a, Color b) {
|
||||
var r = a.r - b.r;
|
||||
var g = a.g - b.g;
|
||||
var blue = a.b - b.b;
|
||||
return Mathf.Sqrt(r * r + g * g + blue * blue);
|
||||
}
|
||||
|
||||
private static void DestroyIfTemporary(Texture2D texture, Texture original) {
|
||||
if (texture != original) { Object.Destroy(texture); }
|
||||
}
|
||||
|
||||
private static bool IsUniversalRenderPipelineActive() {
|
||||
var pipeline = GraphicsSettings.currentRenderPipeline;
|
||||
return pipeline != null && pipeline.GetType().Name.Contains("UniversalRenderPipeline");
|
||||
}
|
||||
|
||||
private readonly struct PaletteEntry {
|
||||
public readonly Color MaskColor;
|
||||
public readonly string PropertyName;
|
||||
public readonly string AlternatePropertyName;
|
||||
|
||||
public PaletteEntry(
|
||||
Color maskColor,
|
||||
string propertyName,
|
||||
string alternatePropertyName) {
|
||||
MaskColor = maskColor;
|
||||
PropertyName = propertyName;
|
||||
AlternatePropertyName = alternatePropertyName;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct TexturePixels {
|
||||
public readonly Texture2D texture;
|
||||
public readonly int width;
|
||||
public readonly int height;
|
||||
|
||||
public TexturePixels(Texture2D texture) {
|
||||
this.texture = texture;
|
||||
width = texture.width;
|
||||
height = texture.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29170b447ee24e68818c3554d0feeb32
|
||||
@@ -119,28 +119,15 @@ namespace eagle {
|
||||
|
||||
// Use provided material if available (ensures shader is in build)
|
||||
if (birdMaterial != null) {
|
||||
_materialInstance = new Material(birdMaterial);
|
||||
if (birdTexture != null) { _materialInstance.mainTexture = birdTexture; }
|
||||
_materialInstance = BeastMaterialCompatibility.CreateParticleMaterial(
|
||||
birdMaterial,
|
||||
birdTexture);
|
||||
renderer.material = _materialInstance;
|
||||
} else {
|
||||
// Fallback for editor testing
|
||||
var particleShader = Shader.Find("Particles/Standard Unlit");
|
||||
if (particleShader != null) {
|
||||
_materialInstance = new Material(particleShader);
|
||||
_materialInstance.SetFloat("_ColorMode", 1);
|
||||
_materialInstance.SetFloat("_Surface", 1);
|
||||
_materialInstance.SetFloat("_Blend", 0);
|
||||
_materialInstance.SetInt(
|
||||
"_SrcBlend",
|
||||
(int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
_materialInstance.SetInt(
|
||||
"_DstBlend",
|
||||
(int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
_materialInstance.EnableKeyword("_ALPHABLEND_ON");
|
||||
_materialInstance.renderQueue = 3000;
|
||||
if (birdTexture != null) { _materialInstance.mainTexture = birdTexture; }
|
||||
renderer.material = _materialInstance;
|
||||
}
|
||||
_materialInstance =
|
||||
BeastMaterialCompatibility.CreateParticleMaterial(null, birdTexture);
|
||||
if (_materialInstance != null) { renderer.material = _materialInstance; }
|
||||
}
|
||||
renderer.sortingLayerName = BeastSortingLayerName;
|
||||
renderer.sortingOrder = BeastBirdSortingOrder;
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace eagle {
|
||||
public static class ClientTextDiskCache {
|
||||
private const int MaxDirtyEntriesBeforeFlush = 50;
|
||||
private static readonly TimeSpan MaxTimeBetweenFlushes = TimeSpan.FromSeconds(1);
|
||||
|
||||
[Serializable]
|
||||
private class CacheEntry {
|
||||
public string llmId;
|
||||
public string text;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class CacheFile {
|
||||
public List<CacheEntry> entries = new();
|
||||
}
|
||||
|
||||
private class GameCache {
|
||||
public Dictionary<string, string> entries = new();
|
||||
public int dirtyEntries;
|
||||
public DateTime lastFlushUtc = DateTime.MinValue;
|
||||
public bool loaded;
|
||||
}
|
||||
|
||||
private static readonly object Lock = new();
|
||||
private static readonly Dictionary<long, GameCache> Caches = new();
|
||||
private static string _cacheDirectory;
|
||||
|
||||
public static Dictionary<string, string> LoadCompletedTexts(long gameId) {
|
||||
EnsureCacheDirectoryInitialized();
|
||||
|
||||
lock (Lock) {
|
||||
var cache = CacheFor(gameId);
|
||||
EnsureLoaded(gameId, cache);
|
||||
return new Dictionary<string, string>(cache.entries);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveCompletedText(long gameId, string llmId, string text) {
|
||||
if (String.IsNullOrEmpty(llmId)) { return; }
|
||||
|
||||
lock (Lock) {
|
||||
if (_cacheDirectory == null) {
|
||||
Debug.LogWarning(
|
||||
"Cannot save client text cache before the cache directory has " +
|
||||
"been initialized on the main thread.");
|
||||
return;
|
||||
}
|
||||
|
||||
var cache = CacheFor(gameId);
|
||||
EnsureLoaded(gameId, cache);
|
||||
|
||||
var normalizedText = text ?? "";
|
||||
if (cache.entries.TryGetValue(llmId, out var existing) &&
|
||||
existing == normalizedText) {
|
||||
return;
|
||||
}
|
||||
|
||||
cache.entries[llmId] = normalizedText;
|
||||
cache.dirtyEntries++;
|
||||
if (ShouldFlush(cache)) { FlushLocked(gameId, cache); }
|
||||
}
|
||||
}
|
||||
|
||||
private static void FlushAll() {
|
||||
lock (Lock) {
|
||||
if (_cacheDirectory == null) { return; }
|
||||
|
||||
foreach (var (gameId, cache) in Caches) {
|
||||
if (cache.dirtyEntries > 0) { FlushLocked(gameId, cache); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GameCache CacheFor(long gameId) {
|
||||
if (!Caches.TryGetValue(gameId, out var cache)) {
|
||||
cache = new GameCache();
|
||||
Caches[gameId] = cache;
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
private static void EnsureLoaded(long gameId, GameCache gameCache) {
|
||||
if (gameCache.loaded) { return; }
|
||||
|
||||
gameCache.loaded = true;
|
||||
var path = CachePath(gameId);
|
||||
if (!File.Exists(path)) { return; }
|
||||
|
||||
try {
|
||||
var cache = JsonUtility.FromJson<CacheFile>(File.ReadAllText(path));
|
||||
if (cache?.entries == null) { return; }
|
||||
|
||||
foreach (var entry in cache.entries) {
|
||||
if (!String.IsNullOrEmpty(entry.llmId)) {
|
||||
gameCache.entries[entry.llmId] = entry.text ?? "";
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Debug.LogWarning($"Failed to load client text cache for game {gameId}: {e}");
|
||||
gameCache.entries.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureCacheDirectoryInitialized() {
|
||||
if (_cacheDirectory != null) { return; }
|
||||
|
||||
_cacheDirectory = Path.Combine(Application.persistentDataPath, "eagle0", "client_text");
|
||||
Application.quitting -= FlushAll;
|
||||
Application.quitting += FlushAll;
|
||||
}
|
||||
|
||||
private static bool ShouldFlush(GameCache cache) => cache.dirtyEntries
|
||||
>= MaxDirtyEntriesBeforeFlush
|
||||
|| DateTime.UtcNow - cache.lastFlushUtc
|
||||
>= MaxTimeBetweenFlushes;
|
||||
|
||||
private static void FlushLocked(long gameId, GameCache gameCache) {
|
||||
try {
|
||||
Directory.CreateDirectory(CacheDirectory);
|
||||
var cache = new CacheFile();
|
||||
foreach (var (id, cachedText) in gameCache.entries) {
|
||||
cache.entries.Add(new CacheEntry { llmId = id, text = cachedText });
|
||||
}
|
||||
|
||||
File.WriteAllText(CachePath(gameId), JsonUtility.ToJson(cache));
|
||||
gameCache.dirtyEntries = 0;
|
||||
gameCache.lastFlushUtc = DateTime.UtcNow;
|
||||
} catch (Exception e) {
|
||||
Debug.LogWarning($"Failed to save client text cache for game {gameId}: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
private static string CacheDirectory => _cacheDirectory;
|
||||
|
||||
private static string CachePath(long gameId) =>
|
||||
Path.Combine(CacheDirectory, $"{gameId:X}.json");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f2c53e67d8043d492e8d3277c6e5794
|
||||
guid: 3a7621b5f8514e8d8b2d4d8cbb8ee5d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user