Skip to content

Commit 94df55b

Browse files
authored
Merge pull request #219 from winnerspiros/copilot/fix-apk-crash-on-startup-again
Fix Android SIGSEGV at pc=0x0, merge upstream, add keystore upload to release workflow
2 parents fd7ced8 + 3ffb519 commit 94df55b

5 files changed

Lines changed: 96 additions & 19 deletions

File tree

.github/workflows/release.yml

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ on:
1717
required: false
1818
default: true
1919
type: boolean
20+
keystore_base64:
21+
description: "Base64-encoded keystore (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_KEYSTORE_BASE64 secret."
22+
required: false
23+
default: ""
24+
type: string
25+
key_alias:
26+
description: "Signing key alias (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_SIGNING_KEY_ALIAS secret."
27+
required: false
28+
default: ""
29+
type: string
30+
key_password:
31+
description: "Signing key password (from SAVE-THESE-SECRETS.txt). Overrides ANDROID_SIGNING_KEY_PASSWORD secret."
32+
required: false
33+
default: ""
34+
type: string
2035

2136
jobs:
2237
build-android:
@@ -82,17 +97,37 @@ jobs:
8297
run: |
8398
KS_PATH="${{ github.workspace }}/osu.Android/osu.keystore"
8499
85-
if [ -n "$KEYSTORE_BASE64" ]; then
86-
# ── User provided a persistent keystore secret ──────────────
87-
echo "$KEYSTORE_BASE64" | base64 --decode > "$KS_PATH"
100+
# Priority: workflow_dispatch inputs > repository secrets > auto-generate.
101+
# This lets users paste values from SAVE-THESE-SECRETS.txt directly into
102+
# the "Run workflow" form so they don't need to set up repo secrets.
103+
# Note: the auto-generated keystore uses the same password for both key and
104+
# store, so a single key_password input covers both. Users with separate
105+
# passwords should use repository secrets instead of workflow inputs.
106+
EFFECTIVE_KS="${INPUT_KEYSTORE_BASE64:-$KEYSTORE_BASE64}"
107+
EFFECTIVE_ALIAS="${INPUT_KEY_ALIAS:-$KEY_ALIAS_SECRET}"
108+
EFFECTIVE_PASS="${INPUT_KEY_PASSWORD:-$KEY_PASS_SECRET}"
109+
EFFECTIVE_STORE_PASS="${INPUT_KEY_PASSWORD:-${STORE_PASS_SECRET:-$EFFECTIVE_PASS}}"
110+
111+
# Mask passwords so they never appear in logs.
112+
if [ -n "$EFFECTIVE_PASS" ]; then echo "::add-mask::$EFFECTIVE_PASS"; fi
113+
if [ -n "$EFFECTIVE_STORE_PASS" ]; then echo "::add-mask::$EFFECTIVE_STORE_PASS"; fi
114+
115+
if [ -n "$EFFECTIVE_KS" ]; then
116+
# ── User provided a keystore (via input or secret) ──────────────
117+
echo "$EFFECTIVE_KS" | base64 --decode > "$KS_PATH"
88118
echo "has_keystore=true" >> "$GITHUB_OUTPUT"
89119
echo "generated=false" >> "$GITHUB_OUTPUT"
90-
echo "key_alias=$KEY_ALIAS_SECRET" >> "$GITHUB_OUTPUT"
91-
echo "key_pass=$KEY_PASS_SECRET" >> "$GITHUB_OUTPUT"
92-
echo "store_pass=$STORE_PASS_SECRET" >> "$GITHUB_OUTPUT"
93-
echo "✅ Using saved keystore from repository secrets."
120+
echo "key_alias=${EFFECTIVE_ALIAS:-osu-release}" >> "$GITHUB_OUTPUT"
121+
echo "key_pass=${EFFECTIVE_PASS}" >> "$GITHUB_OUTPUT"
122+
echo "store_pass=${EFFECTIVE_STORE_PASS}" >> "$GITHUB_OUTPUT"
123+
124+
if [ -n "$INPUT_KEYSTORE_BASE64" ]; then
125+
echo "✅ Using keystore from workflow dispatch inputs."
126+
else
127+
echo "✅ Using saved keystore from repository secrets."
128+
fi
94129
else
95-
# ── No secret → auto-generate a keystore for this build ─────
130+
# ── No keystore → auto-generate one for this build ──────────────
96131
# The APK will install fine on any device, but UPDATING from a
97132
# previous build signed with a DIFFERENT key will fail.
98133
# To avoid that, save the generated keystore as a secret
@@ -141,6 +176,9 @@ jobs:
141176
KEY_ALIAS_SECRET: ${{ secrets.ANDROID_SIGNING_KEY_ALIAS }}
142177
KEY_PASS_SECRET: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }}
143178
STORE_PASS_SECRET: ${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }}
179+
INPUT_KEYSTORE_BASE64: ${{ inputs.keystore_base64 }}
180+
INPUT_KEY_ALIAS: ${{ inputs.key_alias }}
181+
INPUT_KEY_PASSWORD: ${{ inputs.key_password }}
144182

145183
- name: Determine version
146184
id: version
@@ -308,6 +346,11 @@ jobs:
308346
echo ""
309347
echo " ⚡ After saving the secrets, all future builds will use the"
310348
echo " same keystore automatically — no more setup needed."
349+
echo ""
350+
echo " 💡 QUICK OPTION: You can also paste the values from"
351+
echo " SAVE-THESE-SECRETS.txt directly into the workflow"
352+
echo " dispatch inputs (keystore_base64, key_alias, key_password)"
353+
echo " when running the 'Build Android APK' workflow manually."
311354
echo "=================================================================="
312355
313356
# Create a GitHub Release with the APK attached.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using NUnit.Framework;
5+
using osu.Framework.Graphics;
6+
using osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Intro;
7+
8+
namespace osu.Game.Tests.Visual.RankedPlay
9+
{
10+
[TestFixture]
11+
public partial class TestSceneStarRatingSequence : RankedPlayTestScene
12+
{
13+
[Test]
14+
public void TestBasicAppearance()
15+
{
16+
float starRating = 5;
17+
18+
AddSliderStep("set star rating", 0f, 10, 5, sr => starRating = sr);
19+
AddStep("play sequence", () =>
20+
{
21+
StarRatingSequence sequence;
22+
23+
Child = sequence = new StarRatingSequence
24+
{
25+
Anchor = Anchor.Centre,
26+
Origin = Anchor.Centre
27+
};
28+
double delay = 0;
29+
sequence.Play(ref delay, starRating);
30+
});
31+
}
32+
}
33+
}

osu.Game/Screens/OnlinePlay/Matchmaking/RankedPlay/Intro/StarRatingSequence.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
using osu.Game.Beatmaps.Drawables;
1515
using osu.Game.Graphics;
1616
using osu.Game.Graphics.Sprites;
17+
using osu.Game.Overlays;
1718
using osuTK;
18-
using osuTK.Graphics;
1919

2020
namespace osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Intro
2121
{
@@ -35,27 +35,26 @@ public partial class StarRatingSequence : CompositeDrawable
3535
private float lastTickStdDev;
3636

3737
[BackgroundDependencyLoader]
38-
private void load(OsuColour colour, AudioManager audio)
38+
private void load(OsuColour colour, OverlayColourProvider overlayColourProvider, AudioManager audio)
3939
{
4040
Width = 600;
4141
AutoSizeAxes = Axes.Y;
4242
Anchor = Anchor.Centre;
4343
Origin = Anchor.Centre;
4444
Alpha = 0;
4545

46-
Masking = true;
47-
CornerRadius = 10;
48-
4946
InternalChild = new Container
5047
{
5148
AutoSizeAxes = Axes.Y,
5249
RelativeSizeAxes = Axes.X,
50+
Masking = true,
51+
CornerRadius = 10,
5352
Children = new Drawable[]
5453
{
5554
new Box
5655
{
57-
Colour = Color4.Black,
58-
Alpha = 0.2f,
56+
Colour = overlayColourProvider.Background5,
57+
Alpha = 0.8f,
5958
RelativeSizeAxes = Axes.Both,
6059
},
6160
new FillFlowContainer
@@ -88,7 +87,7 @@ private void load(OsuColour colour, AudioManager audio)
8887
new Box
8988
{
9089
Alpha = 0.4f,
91-
Colour = Color4.Black,
90+
Colour = overlayColourProvider.Background4,
9291
RelativeSizeAxes = Axes.Both,
9392
},
9493
bars = new Container<Bar>
@@ -204,7 +203,7 @@ public void Play(ref double delay, float starRating)
204203
RelativePositionAxes = Axes.X,
205204
X = starRating * 0.1f,
206205
Y = 34,
207-
Colour = colours.ForStarDifficulty(starRating),
206+
Colour = starRating < OsuColour.STAR_DIFFICULTY_DEFINED_COLOUR_CUTOFF ? colours.ForStarDifficulty(starRating) : colours.ForStarDifficultyText(starRating),
208207
Spacing = new Vector2(4, 0),
209208
Children =
210209
[
@@ -226,6 +225,8 @@ public void Play(ref double delay, float starRating)
226225
};
227226

228227
centerContainer.Add(container);
228+
// Avoid text getting masked out by inner containers
229+
AddInternal(container.CreateProxy());
229230

230231
container.FadeInFromZero(200)
231232
.ScaleTo(0)

osu.Game/osu.Game.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<PackageReference Include="Realm" Version="20.1.0" />
4141
<!-- Use winnerspiros/osu-framework fork (net10.0, optimized) via submodule instead of ppy NuGet package -->
4242
<ProjectReference Include="..\submodules\osu-framework\osu.Framework\osu.Framework.csproj" />
43-
<PackageReference Include="ppy.osu.Game.Resources" Version="2026.411.0" />
43+
<PackageReference Include="ppy.osu.Game.Resources" Version="2026.420.0" />
4444
<PackageReference Include="Sentry" Version="6.2.0" />
4545
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
4646
<PackageReference Include="SharpCompress" Version="0.47.3" />

submodules/osu-framework

0 commit comments

Comments
 (0)