Fix Android SIGSEGV at pc=0x0, merge upstream, add keystore upload to release workflow - #219
Conversation
…py#37429) Closes ppy#37406. I almost applied ```diff diff --git a/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Intro/StarRatingSequence.cs b/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Intro/StarRatingSequence.cs index 318572d..76719a7de8 100644 --- a/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Intro/StarRatingSequence.cs +++ b/osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Intro/StarRatingSequence.cs @@ -5,8 +5,10 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transforms; @@ -134,6 +136,14 @@ private void load(OsuColour colour, AudioManager audio) Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Colour = colour.ForStarDifficulty(Math.Max(difficulty, 0.1)), + EdgeEffect = difficulty < OsuColour.STAR_DIFFICULTY_DEFINED_COLOUR_CUTOFF + ? default + : new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = colour.ForStarDifficultyText(difficulty).Opacity((difficulty - OsuColour.STAR_DIFFICULTY_DEFINED_COLOUR_CUTOFF) / (10 - OsuColour.STAR_DIFFICULTY_DEFINED_COLOUR_CUTOFF) / 2), + Radius = 4 + }, Height = 0 }); ``` as a bonus but I'm not that confident in myself. --------- Co-authored-by: Dean Herbert <pe@ppy.sh>
Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…g text colour Merged 2 upstream ppy/osu commits: - 0ecb892: Update resources (2026.420.0) - c148e20: Fix illegible star rating text colour in ranked play intro animation (ppy#37429) Conflict resolution: keep fork's ProjectReference to osu-framework submodule, update ppy.osu.Game.Resources to 2026.420.0. Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…t APK signing Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/c9e6ebec-a8b6-4aa8-b446-27812ab3b780 Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
… workflow Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/c9e6ebec-a8b6-4aa8-b446-27812ab3b780 Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates ranked play intro visuals and Android release pipeline ergonomics, alongside bumping the resources package version (PR description also mentions Android Vulkan surface crash hardening in the framework submodule).
Changes:
- Bump
ppy.osu.Game.Resourcesto2026.420.0. - Adjust
StarRatingSequencestyling/colouring to useOverlayColourProvidershades and improve high-star text legibility. - Add optional keystore-related
workflow_dispatchinputs and selection priority logic inrelease.yml.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| osu.Game/osu.Game.csproj | Bumps resources package version to align with upstream. |
| osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Intro/StarRatingSequence.cs | Uses overlay theme colours and adjusts star-rating text colouring + proxy to avoid masking. |
| osu.Game.Tests/Visual/RankedPlay/TestSceneStarRatingSequence.cs | Adds a visual test scene for basic StarRatingSequence appearance/playback. |
| .github/workflows/release.yml | Adds workflow inputs for keystore material and implements input/secret/autogen priority logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| keystore_base64: | ||
| description: "Base64-encoded keystore (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_KEYSTORE_BASE64 secret." | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| key_alias: | ||
| description: "Signing key alias (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_SIGNING_KEY_ALIAS secret." | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| key_password: | ||
| description: "Signing key password (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_SIGNING_KEY_PASSWORD secret." | ||
| required: false | ||
| default: "" | ||
| type: string |
There was a problem hiding this comment.
The workflow_dispatch inputs keystore_base64, key_alias, and key_password are not secret-protected by GitHub Actions (their values are stored in the workflow run metadata and may be visible to anyone with access to the run). Using them for an Android signing keystore/password risks leaking the private signing key. Consider removing these inputs and only supporting repository/environment secrets (or another secret-protected mechanism) for providing signing material.
| keystore_base64: | |
| description: "Base64-encoded keystore (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_KEYSTORE_BASE64 secret." | |
| required: false | |
| default: "" | |
| type: string | |
| key_alias: | |
| description: "Signing key alias (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_SIGNING_KEY_ALIAS secret." | |
| required: false | |
| default: "" | |
| type: string | |
| key_password: | |
| description: "Signing key password (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_SIGNING_KEY_PASSWORD secret." | |
| required: false | |
| default: "" | |
| type: string |
| EFFECTIVE_KS="${INPUT_KEYSTORE_BASE64:-$KEYSTORE_BASE64}" | ||
| EFFECTIVE_ALIAS="${INPUT_KEY_ALIAS:-$KEY_ALIAS_SECRET}" | ||
| EFFECTIVE_PASS="${INPUT_KEY_PASSWORD:-$KEY_PASS_SECRET}" | ||
| EFFECTIVE_STORE_PASS="${INPUT_KEY_PASSWORD:-${STORE_PASS_SECRET:-$EFFECTIVE_PASS}}" | ||
|
|
||
| # Mask passwords so they never appear in logs. | ||
| if [ -n "$EFFECTIVE_PASS" ]; then echo "::add-mask::$EFFECTIVE_PASS"; fi | ||
| if [ -n "$EFFECTIVE_STORE_PASS" ]; then echo "::add-mask::$EFFECTIVE_STORE_PASS"; fi | ||
|
|
||
| if [ -n "$EFFECTIVE_KS" ]; then | ||
| # ── User provided a keystore (via input or secret) ────────────── | ||
| echo "$EFFECTIVE_KS" | base64 --decode > "$KS_PATH" |
There was a problem hiding this comment.
When a user-provided keystore is used, the base64 keystore content itself is still highly sensitive (it contains the private key). Even if this step doesn’t currently print it, it’s safer to mask EFFECTIVE_KS/INPUT_KEYSTORE_BASE64 via ::add-mask:: to avoid accidental leakage via debugging or error output.
| if [ -n "$EFFECTIVE_KS" ]; then | ||
| # ── User provided a keystore (via input or secret) ────────────── | ||
| echo "$EFFECTIVE_KS" | base64 --decode > "$KS_PATH" | ||
| echo "has_keystore=true" >> "$GITHUB_OUTPUT" | ||
| echo "generated=false" >> "$GITHUB_OUTPUT" | ||
| echo "key_alias=$KEY_ALIAS_SECRET" >> "$GITHUB_OUTPUT" | ||
| echo "key_pass=$KEY_PASS_SECRET" >> "$GITHUB_OUTPUT" | ||
| echo "store_pass=$STORE_PASS_SECRET" >> "$GITHUB_OUTPUT" | ||
| echo "✅ Using saved keystore from repository secrets." | ||
| echo "key_alias=${EFFECTIVE_ALIAS:-osu-release}" >> "$GITHUB_OUTPUT" | ||
| echo "key_pass=${EFFECTIVE_PASS}" >> "$GITHUB_OUTPUT" | ||
| echo "store_pass=${EFFECTIVE_STORE_PASS}" >> "$GITHUB_OUTPUT" |
There was a problem hiding this comment.
If EFFECTIVE_KS is set but EFFECTIVE_PASS (and/or EFFECTIVE_ALIAS) is empty, the workflow will continue and dotnet publish will receive empty signing parameters, which will likely fail later with a less actionable error. Add an explicit validation/early-exit here to require the necessary password/alias fields whenever a keystore is provided.
SIGSEGV null function pointer crash on SDLThread ~5s into Android startup. The Vulkan pipeline receives
IntPtr.Zerosurface handles when the Android native surface isn't ready, passes them through tovkCreateAndroidSurfaceKHRwhich dereferences a nullANativeWindow*. Separately,DrawThread.OnInitialize()bypassesAndroidGameHost.DrawFrame()'sIsSurfaceReadyguard entirely.Vulkan surface validation (framework submodule)
VkSurfaceUtil.cs— validateSurface,JniEnv, andANativeWindow_fromSurfacereturn before calling into the Vulkan driverVeldridDevice.cs— rejectIntPtr.ZeroforSurfaceHandle/JniEnvHandleon Android with descriptive exception instead of native crashAndroidGameHost.DrawFrame()— checkSurfaceHandle != IntPtr.Zeroin addition toIsSurfaceReady(the flag fires fromHandleResume()before the surface handle is actually valid)DrawThread.OnInitialize()— wrapBeginFrame/FinishFramein try-catch; non-fatal on Android when surface isn't ready yet, first regularDrawFrame()handles itUpstream merge
Merged 2 commits from
ppy/osumaster:0ecb892— Update resources (2026.420.0)c148e20— Fix illegible star rating text colour in ranked play intro (Fix illegible star rating text colour in ranked play intro animation ppy/osu#37429)Conflict: kept fork's
ProjectReferenceto framework submodule, updatedppy.osu.Game.Resourcesto 2026.420.0.Release workflow: optional keystore upload
Added
keystore_base64,key_alias,key_passwordinputs toworkflow_dispatch. Users can paste values fromSAVE-THESE-SECRETS.txtdirectly into the "Run workflow" form instead of configuring repo secrets. Priority chain: workflow inputs → repo secrets → auto-generate.Summary by Gitar
StarRatingSequenceUI by usingOverlayColourProviderand adding a proxy to fix masking issues.TestSceneStarRatingSequenceto verify the star rating appearance.ppy.osu.Game.Resourcesfrom2026.411.0to2026.420.0.This will update automatically on new commits.