Skip to content

Commit 897e8b8

Browse files
Improve CI and minor cleanup
- Warnings as errors in CI - Re-enable gdunit4 tests in CI - Better exception handling - SRP cleanup for packet gen scripts - Improve githook and CI workflow
1 parent 510b855 commit 897e8b8

47 files changed

Lines changed: 1421 additions & 874 deletions

Some content is hidden

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

.githooks/pre-commit

Lines changed: 320 additions & 114 deletions
Large diffs are not rendered by default.

.github/workflows/pr_ci.yml

Lines changed: 130 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,83 @@ jobs:
3535
3636
BASE_SHA="${{ github.event.pull_request.base.sha }}"
3737
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
38-
CHANGED="$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")"
38+
mapfile -t CHANGED_PATHS < <(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
3939
4040
echo "Changed files:"
41-
printf '%s\n' "$CHANGED"
41+
printf '%s\n' "${CHANGED_PATHS[@]}"
4242
4343
build_godotutils=false
4444
build_visualize=false
4545
build_packetgen=false
4646
build_optionsgen=false
4747
build_template=false
4848
49-
echo "$CHANGED" | grep -q "^Template\.GodotUtils/" && build_godotutils=true || true
50-
echo "$CHANGED" | grep -q "^Template\.Visualize/" && build_visualize=true || true
51-
echo "$CHANGED" | grep -q "^Template\.PacketGen/" && build_packetgen=true || true
52-
echo "$CHANGED" | grep -q "^Template\.OptionsGen/" && build_optionsgen=true || true
53-
echo "$CHANGED" | grep -Eq "\.cs$" && build_optionsgen=true || true
54-
echo "$CHANGED" | grep -q "^Template/" && build_template=true || true
49+
declare -a changed_cs=()
50+
declare -a format_godotutils=()
51+
declare -a format_visualize=()
52+
declare -a format_packetgen=()
53+
declare -a format_optionsgen=()
54+
declare -a format_template=()
55+
declare -a format_fallback=()
56+
57+
for changed_path in "${CHANGED_PATHS[@]}"; do
58+
[[ -z "$changed_path" ]] && continue
59+
60+
case "$changed_path" in
61+
Template.GodotUtils/*)
62+
build_godotutils=true
63+
;;
64+
Template.Visualize/*)
65+
build_visualize=true
66+
;;
67+
Template.PacketGen/*)
68+
build_packetgen=true
69+
;;
70+
Template.OptionsGen/*)
71+
build_optionsgen=true
72+
;;
73+
Template/*)
74+
build_template=true
75+
;;
76+
esac
77+
78+
case "$changed_path" in
79+
*.cs)
80+
changed_cs+=("$changed_path")
81+
;;
82+
esac
83+
done
84+
85+
for cs_path in "${changed_cs[@]}"; do
86+
case "$cs_path" in
87+
Template.GodotUtils/*.cs)
88+
format_godotutils+=("$cs_path")
89+
;;
90+
Template.Visualize/*.cs)
91+
format_visualize+=("$cs_path")
92+
;;
93+
Template.PacketGen/*.cs)
94+
format_packetgen+=("$cs_path")
95+
;;
96+
Template.OptionsGen/*.cs)
97+
format_optionsgen+=("$cs_path")
98+
;;
99+
Template/*.cs)
100+
format_template+=("$cs_path")
101+
;;
102+
*)
103+
format_fallback+=("$cs_path")
104+
;;
105+
esac
106+
done
55107
56108
if $build_visualize; then
57109
build_godotutils=true
58110
fi
59111
60-
if echo "$CHANGED" | grep -Eq "^(Template\.sln|\.editorconfig|NuGet\.config|\.githooks/|\.github/workflows/)"; then
112+
changed_lines="$(printf '%s\n' "${CHANGED_PATHS[@]}")"
113+
114+
if echo "$changed_lines" | grep -Eq "^(Template\.sln|\.editorconfig|NuGet\.config|\.githooks/|\.github/workflows/)"; then
61115
build_godotutils=true
62116
build_visualize=true
63117
build_packetgen=true
@@ -74,69 +128,116 @@ jobs:
74128
build_template=true
75129
fi
76130
131+
has_cs_changes=false
132+
if [[ "${#changed_cs[@]}" -gt 0 ]]; then
133+
has_cs_changes=true
134+
fi
135+
136+
write_output_array() {
137+
local output_name="$1"
138+
shift
139+
local -a output_values=("$@")
140+
141+
{
142+
echo "${output_name}<<EOF"
143+
printf '%s\n' "${output_values[@]}"
144+
echo "EOF"
145+
} >> "$GITHUB_OUTPUT"
146+
}
147+
77148
{
78149
echo "build_godotutils=$build_godotutils"
79150
echo "build_visualize=$build_visualize"
80151
echo "build_packetgen=$build_packetgen"
81152
echo "build_optionsgen=$build_optionsgen"
82153
echo "build_template=$build_template"
154+
echo "has_cs_changes=$has_cs_changes"
83155
} >> "$GITHUB_OUTPUT"
84156
157+
write_output_array "format_godotutils_includes" "${format_godotutils[@]}"
158+
write_output_array "format_visualize_includes" "${format_visualize[@]}"
159+
write_output_array "format_packetgen_includes" "${format_packetgen[@]}"
160+
write_output_array "format_optionsgen_includes" "${format_optionsgen[@]}"
161+
write_output_array "format_template_includes" "${format_template[@]}"
162+
write_output_array "format_fallback_includes" "${format_fallback[@]}"
163+
85164
- name: Restore
165+
if: steps.changes.outputs.has_cs_changes == 'true'
86166
run: dotnet restore Template.sln
87167

168+
- name: Skip .NET validation when no C# changes
169+
if: steps.changes.outputs.has_cs_changes != 'true'
170+
run: echo "No C# changes detected. Skipping .NET format/build/test validation."
171+
88172
- name: Format checks (targeted)
173+
if: steps.changes.outputs.has_cs_changes == 'true'
89174
shell: bash
90175
run: |
91176
set -euo pipefail
92177
93-
if [[ "${{ steps.changes.outputs.build_godotutils }}" == "true" ]]; then
94-
dotnet format Template.GodotUtils/GodotUtils.csproj --verify-no-changes
178+
if [[ "${{ steps.changes.outputs.has_cs_changes }}" != "true" ]]; then
179+
echo "No C# changes detected. Skipping format checks."
180+
exit 0
95181
fi
96182
97-
if [[ "${{ steps.changes.outputs.build_visualize }}" == "true" ]]; then
98-
dotnet format Template.Visualize/Visualize.csproj --verify-no-changes
99-
fi
183+
run_format_check() {
184+
local target="$1"
185+
local include_blob="$2"
100186
101-
if [[ "${{ steps.changes.outputs.build_packetgen }}" == "true" ]]; then
102-
dotnet format Template.PacketGen/PacketGen.sln --verify-no-changes
103-
fi
187+
if [[ -z "$include_blob" ]]; then
188+
return 0
189+
fi
104190
105-
if [[ "${{ steps.changes.outputs.build_optionsgen }}" == "true" ]]; then
106-
dotnet format Template.OptionsGen/OptionsGen/OptionsGen.csproj --verify-no-changes
107-
fi
191+
local -a includes=()
192+
while IFS= read -r line; do
193+
[[ -z "$line" ]] && continue
194+
includes+=("$line")
195+
done <<< "$include_blob"
108196
109-
if [[ "${{ steps.changes.outputs.build_template }}" == "true" ]]; then
110-
dotnet format Template/Template.csproj --verify-no-changes
111-
fi
197+
if [[ "${#includes[@]}" -eq 0 ]]; then
198+
return 0
199+
fi
200+
201+
dotnet format "$target" --verify-no-changes --include "${includes[@]}"
202+
}
203+
204+
run_format_check Template.GodotUtils/GodotUtils.csproj "${{ steps.changes.outputs.format_godotutils_includes }}"
205+
run_format_check Template.Visualize/Visualize.csproj "${{ steps.changes.outputs.format_visualize_includes }}"
206+
run_format_check Template.PacketGen/PacketGen.sln "${{ steps.changes.outputs.format_packetgen_includes }}"
207+
run_format_check Template.OptionsGen/OptionsGen/OptionsGen.csproj "${{ steps.changes.outputs.format_optionsgen_includes }}"
208+
run_format_check Template/Template.csproj "${{ steps.changes.outputs.format_template_includes }}"
209+
run_format_check Template.sln "${{ steps.changes.outputs.format_fallback_includes }}"
112210
113211
- name: Targeted builds
212+
if: steps.changes.outputs.has_cs_changes == 'true'
114213
shell: bash
115214
run: |
116215
set -euo pipefail
117216
118217
if [[ "${{ steps.changes.outputs.build_godotutils }}" == "true" ]]; then
119-
dotnet build Template.GodotUtils/GodotUtils.csproj --no-restore -p:BuildExtras=true
218+
dotnet build Template.GodotUtils/GodotUtils.csproj --no-restore -p:BuildExtras=true -warnaserror
120219
fi
121220
122221
if [[ "${{ steps.changes.outputs.build_visualize }}" == "true" ]]; then
123-
dotnet build Template.Visualize/Visualize.csproj --no-restore -p:BuildExtras=true
222+
dotnet build Template.Visualize/Visualize.csproj --no-restore -p:BuildExtras=true -warnaserror
124223
fi
125224
126225
if [[ "${{ steps.changes.outputs.build_packetgen }}" == "true" ]]; then
127-
dotnet build Template.PacketGen/PacketGen/PacketGen.csproj -c Release --no-restore
226+
dotnet build Template.PacketGen/PacketGen/PacketGen.csproj -c Release --no-restore -warnaserror
128227
fi
129228
130229
if [[ "${{ steps.changes.outputs.build_optionsgen }}" == "true" ]]; then
131-
dotnet build Template.OptionsGen/OptionsGen/OptionsGen.csproj -c Release --no-restore
230+
dotnet build Template.OptionsGen/OptionsGen/OptionsGen.csproj -c Release --no-restore -warnaserror
132231
fi
133232
134233
if [[ "${{ steps.changes.outputs.build_template }}" == "true" ]]; then
135-
dotnet build Template/Template.csproj --no-restore
234+
dotnet build Template/Template.csproj --no-restore -warnaserror
136235
fi
137236
138237
- name: Full solution build
139-
run: dotnet build Template.sln --no-restore
238+
if: steps.changes.outputs.has_cs_changes == 'true'
239+
run: dotnet build Template.sln --no-restore -warnaserror
140240

141241
- name: Tests
242+
if: steps.changes.outputs.has_cs_changes == 'true'
142243
run: dotnet test Template.PacketGen/PacketGen.Tests/PacketGen.Tests.csproj --no-build

Template.GodotUtils/Extensions/RayCast2DExtensions.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,11 @@ public static void SetCollisionMask(this RayCast2D node, params int[] values)
4545
/// </summary>
4646
public static void ExcludeRaycastParents(this RayCast2D raycast, Node parent)
4747
{
48-
if (parent == null)
49-
return;
50-
51-
if (parent is CollisionObject2D collision)
52-
raycast.AddException(collision);
53-
54-
ExcludeRaycastParents(raycast, parent.GetParentOrNull<Node>());
48+
RayCastParentTraversal.ForEachParent(parent, node =>
49+
{
50+
if (node is CollisionObject2D collision)
51+
raycast.AddException(collision);
52+
});
5553
}
5654

5755
/// <summary>

Template.GodotUtils/Extensions/RayCast3DExtensions.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,10 @@ public static int GetRaycastsColliding(this RayCast3D[] raycasts)
3030
/// </summary>
3131
public static void ExcludeRaycastParents(this RayCast3D raycast)
3232
{
33-
ExcludeParents(raycast, raycast.GetParent());
34-
}
35-
36-
private static void ExcludeParents(RayCast3D raycast, Node parent)
37-
{
38-
if (parent == null)
39-
return;
40-
41-
if (parent is CollisionObject3D collision)
42-
raycast.AddException(collision);
43-
44-
ExcludeParents(raycast, parent.GetParentOrNull<Node>());
33+
RayCastParentTraversal.ForEachParent(raycast.GetParent(), node =>
34+
{
35+
if (node is CollisionObject3D collision)
36+
raycast.AddException(collision);
37+
});
4538
}
4639
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using Godot;
3+
4+
namespace GodotUtils;
5+
6+
internal static class RayCastParentTraversal
7+
{
8+
public static void ForEachParent(Node? parent, Action<Node> callback)
9+
{
10+
while (parent != null)
11+
{
12+
callback(parent);
13+
parent = parent.GetParentOrNull<Node>();
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)