Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
1c1da75
Remove AI plugin, fix web check, add test script
ikostan May 10, 2026
5f1e9ba
Update test_injection.sh
ikostan May 10, 2026
af567a9
Update project.godot
ikostan May 11, 2026
3dcf5f2
Bump DavidAnson/markdownlint-cli2-action from 23.0.0 to 23.2.0
dependabot[bot] May 11, 2026
4c725c3
Bump release-drafter/release-drafter from 7.2.0 to 7.3.0
dependabot[bot] May 11, 2026
9c896c7
Bump urllib3 from 2.6.3 to 2.7.0 in the pip group across 1 directory
dependabot[bot] May 11, 2026
0bfee27
Merge pull request #604 from ikostan/dependabot/github_actions/DavidA…
ikostan May 12, 2026
f0c90cd
Merge pull request #605 from ikostan/dependabot/github_actions/releas…
ikostan May 12, 2026
352e44b
Merge pull request #606 from ikostan/dependabot/pip/pip-c30c77f42d
ikostan May 12, 2026
4d7d861
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 12, 2026
632bb35
Add error handling for directory change.
ikostan May 12, 2026
9122662
Restore project.godot automatically after injection/export.
ikostan May 12, 2026
946f69e
Add explicit error handling for salt injection and patch steps.
ikostan May 12, 2026
2351da0
Update test_injection.sh
ikostan May 12, 2026
4069a07
Use CI-injected salt; remove JS eval
ikostan May 13, 2026
7794236
Update globals.gd
ikostan May 13, 2026
b77ebea
Update globals.gd
ikostan May 13, 2026
9b9f7e7
Use CI salt placeholder and auto-remove corrupted saves
ikostan May 13, 2026
4ddd331
Update globals.gd
ikostan May 13, 2026
6d4598e
Replace AWK-based salt injection with sed
ikostan May 13, 2026
0e7629e
style: format code with Black and isort
deepsource-autofix[bot] May 13, 2026
76d3f75
Update deploy_to_itch.yml
ikostan May 13, 2026
ef094ca
Update test_salt_injection.py
ikostan May 13, 2026
ff9bb38
Centralize salt injection into single script
ikostan May 13, 2026
5b41101
style: format code with Black and isort
deepsource-autofix[bot] May 13, 2026
510e383
One-line docstring should fit on one line with quotes
ikostan May 13, 2026
0a443a4
Add test cleanup and modernize encryption tests
ikostan May 13, 2026
c56cd0e
🚨 issue (security): Treating all web builds as automated tests weaken…
ikostan May 13, 2026
972cacb
Update test_salt_injection.py
ikostan May 13, 2026
69e2b1e
style: format code with Black and isort
deepsource-autofix[bot] May 13, 2026
5acee0b
Update globals.gd
ikostan May 13, 2026
5965881
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 13, 2026
fbf1b7e
suggestion (bug_risk): Handle failure cases when auto-deleting corrup…
ikostan May 13, 2026
a2776a3
Update run_browser_tests.sh
ikostan May 13, 2026
7f3b3a1
Update browser tests: disable plugins, inject salt
ikostan May 13, 2026
f8d82fd
Update browser_test.yml
ikostan May 14, 2026
60d126f
Increase timeouts and harden CI browser test script
ikostan May 14, 2026
d70c09c
Update back_flow_test.py
ikostan May 14, 2026
0a82016
Update back_flow_test.py
ikostan May 14, 2026
e660d4f
Add CI flag and secure test HTTP server
ikostan May 14, 2026
4cf704d
Update browser_test.yml
ikostan May 14, 2026
912bf49
Update test_injection.sh
ikostan May 14, 2026
18ac35e
Update test_encryption_logging.gd
ikostan May 14, 2026
d387493
suggestion (bug_risk): The sed pattern for disabling plugins may be o…
ikostan May 14, 2026
7d0bcd5
Scope sed replacement to [editor_plugins] section
ikostan May 14, 2026
aeb6ac3
suggestion (testing): Add tests for error/edge cases in salt injectio…
ikostan May 14, 2026
08bb8b1
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
0653f14
Update test_salt_injection.py
ikostan May 14, 2026
d2240f6
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 14, 2026
f150267
Update test_salt_injection.py
ikostan May 14, 2026
6e02079
Unused import stat
ikostan May 14, 2026
c075f20
Refactor CI salt injection tests to pytest
ikostan May 14, 2026
63934b4
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
f770f9a
CI: improve salt injection tests & workflow
ikostan May 14, 2026
b843bc5
Improve salt injection tests: robustness & strictness
ikostan May 14, 2026
93c6446
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
62a5fe4
Update test_ci_scripts.yml
ikostan May 14, 2026
d95a499
'subprocess.run' used without explicitly defining the value for 'che…
ikostan May 14, 2026
45c1ac7
prevent accidental data loss when an antivirus or the operating syste…
ikostan May 14, 2026
e574c14
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
f4055a6
Update globals.gd
ikostan May 14, 2026
59d8805
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 14, 2026
9ee7ea2
Duplicated ci Flag Injection
ikostan May 14, 2026
1fb1bad
Update test_ci_scripts.yml
ikostan May 14, 2026
4e62afc
ci: enforce UTF-8 and add CI test fixtures
ikostan May 14, 2026
fa3d0eb
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
ca18765
Inject CI flag per-preset and improve tests
ikostan May 14, 2026
8e2a0c1
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
57f71b4
Update browser_test.yml
ikostan May 14, 2026
f9be6de
Do not overwrite backup on repeated CI injection
ikostan May 14, 2026
bb45197
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
1d273ef
Unused import tempfile
ikostan May 14, 2026
e75ced5
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 14, 2026
f4c9c82
Update test_ci_flag_injection.py
ikostan May 14, 2026
b84beca
Update test_ci_flag_injection.py
ikostan May 14, 2026
55d61fb
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
e1b06a9
Use r""" if any backslashes in a docstring
ikostan May 14, 2026
1a4c934
Update audio_flow_test.py
ikostan May 14, 2026
dff39f6
Update globals.gd
ikostan May 14, 2026
30958dd
Inject CI flag under [preset.N]; update tests & CI
ikostan May 14, 2026
3651f6e
style: format code with Black and isort
deepsource-autofix[bot] May 14, 2026
704fc3a
Update test_ci_scripts.yml
ikostan May 14, 2026
4c1b4a2
Replace hardcoded timeouts with TEST_TIMEOUT
ikostan May 14, 2026
203dfdb
suggestion (testing): Consider adding a test that explicitly covers C…
ikostan May 14, 2026
b5c37b2
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 14, 2026
f818978
Update test_ci_flag_injection.py
ikostan May 14, 2026
6706aa2
🚨 suggestion (security): Logging the CI/test flag at INFO for every e…
ikostan May 15, 2026
12a63e3
style: format code with Black and isort
deepsource-autofix[bot] May 15, 2026
30bea46
issue (bug_risk): Accessing sys.stdout.encoding without a None check …
ikostan May 15, 2026
7b90208
Merge branch 'encryption-key-generation-failure-in-web-export' of htt…
ikostan May 15, 2026
7b24cea
Update test_injection.sh
ikostan May 15, 2026
5df68b9
Update tests/ci/test_salt_injection.py
ikostan May 15, 2026
a6023f0
Update test_salt_injection.py
ikostan May 15, 2026
a84fe07
Update browser_test.yml
ikostan May 15, 2026
c7cef19
macOS / BSD sed compatibility (test_injection.sh & inject_salt.sh)
ikostan May 15, 2026
83de3c4
suggestion (testing): Relax assertion on exact error message for empt…
ikostan May 15, 2026
3547227
Update test_injection.sh
ikostan May 15, 2026
d09b838
Update test_ci_flag_injection.py
ikostan May 15, 2026
7736e07
style: format code with Black and isort
deepsource-autofix[bot] May 15, 2026
dbf4db2
Update test_injection.sh
ikostan May 15, 2026
16dc801
Add CI utilities and refactor scripts
ikostan May 15, 2026
2329305
Use ci_utils.sh to disable editor plugins
ikostan May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint_readme.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
# Lints Markdown for formatting/spelling
# Pinned to SHA for security (was @v19)
# yamllint disable rule:line-length
uses: "DavidAnson/markdownlint-cli2-action@ce4853d43830c74c1753b39f3cf40f71c2031eb9"
uses: "DavidAnson/markdownlint-cli2-action@ded1f9488f68a970bc66ea5619e13e9b52e601cd"
# yamllint enable rule:line-length
with:
config: ".markdownlint-cli2.yaml"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release_drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
tag_name: "${{ steps.drafter.outputs.tag_name }}" # Expose from step
steps:
# yamllint disable-line rule:line-length
- uses: "release-drafter/release-drafter@5de93583980a40bd78603b6dfdcda5b4df377b32"
- uses: "release-drafter/release-drafter@c2e2804cc59f45f57076a99af580d0fedb697927"
id: drafter # Add ID to access outputs
with:
config-name: "release-drafter.yml" # Explicitly point to your config
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release_drafter_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: "ubuntu-latest"
steps:
# yamllint disable-line rule:line-length
- uses: "release-drafter/release-drafter@5de93583980a40bd78603b6dfdcda5b4df377b32"
- uses: "release-drafter/release-drafter@c2e2804cc59f45f57076a99af580d0fedb697927"
with:
config-name: "release-drafter.yml" # Your existing config
env:
Expand Down
4 changes: 2 additions & 2 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ window/vsync/vsync_mode=0

[editor_plugins]

enabled=PackedStringArray("res://addons/ai_autonomous_agent/plugin.cfg", "res://addons/gut/plugin.cfg")
enabled=PackedStringArray("res://addons/gut/plugin.cfg")

[game]

security/save_salt=""
security/save_salt="dev_fallback_salt"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

[gdunit4]

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ setuptools==80.10.2
six==1.17.0
text-unidecode==1.3
typing_extensions==4.15.0
urllib3==2.6.3
urllib3==2.7.0
33 changes: 20 additions & 13 deletions scripts/core/globals.gd
Original file line number Diff line number Diff line change
Expand Up @@ -458,29 +458,29 @@ func ensure_encryption_key() -> String:
## Generates a unique, deterministic encryption key for local save files.
## Generates a unique, deterministic encryption key for local save files.
func _get_encryption_key() -> String:
var salt: String = ProjectSettings.get_setting("game/security/save_salt", "dev_fallback_salt")
# Safe placeholder. This is an open source repo, so the REAL salt
# is injected by GitHub Actions / CI pipeline during the build process.
var salt: String = "CI_INJECT_SALT_HERE"

# 1. FAILSAFE: If the salt is literally empty, always abort to plaintext
# 1. FAILSAFE: If the salt is literally empty, always abort
if salt.is_empty():
log_message(
"🚨 ENCRYPTION ABORTED: Salt is empty. Falling back to plaintext.", LogLevel.WARNING
)
log_message("🚨 ENCRYPTION ABORTED: Salt is empty.", LogLevel.WARNING)
return ""

var is_automated_test: bool = false
if OS.has_feature("web"):
is_automated_test = JavaScriptBridge.eval("navigator.webdriver") == true

# 2. SECURITY GUARD: Prevent silent weak-key fallback in production.
# Safely assume web might be a test environment, skip JS eval
var is_automated_test: bool = OS.has_feature("web")
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
if not OS.has_feature("editor") and not OS.has_feature("debug") and not is_automated_test:
if salt == "dev_fallback_salt":
var error_msg: String = "CRITICAL SECURITY ERROR: Missing or weak salt."
if salt == "CI_INJECT_SALT_HERE":
var error_msg: String = "CRITICAL SECURITY ERROR: Missing production salt."
push_error(error_msg)
OS.crash(error_msg)
return ""
# FIX: OS.get_unique_id() crashes on Web

# FIX: Removed JavaScriptBridge.eval() from here. Calling JS from a
# class-level variable initialization silently crashes the WebAssembly module!
var device_id: String = "web_fallback"
if OS.get_name() != "Web":
if not OS.has_feature("web"):
device_id = OS.get_unique_id()

return (device_id + salt).sha256_text()
Expand Down Expand Up @@ -529,6 +529,13 @@ func safe_load_config(path: String) -> Dictionary:
),
LogLevel.ERROR
)
# --- AUTO-RECOVERY FIX ---
log_message(
"🗑️ Auto-deleting corrupted/orphaned save file to allow clean recovery.",
LogLevel.INFO
)
DirAccess.remove_absolute(path)
err = ERR_FILE_NOT_FOUND # Treat as a first-time boot so the game generates fresh defaults
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
else:
log_message("🔓 Successfully decrypted file: " + path, LogLevel.DEBUG)
else:
Expand Down
104 changes: 104 additions & 0 deletions workspace/test_injection.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/bash
# test_injection.sh

cleanup() {
if [ -f "globals.gd.backup" ]; then
echo "🧹 Cleaning up: Restoring globals.gd from backup..."
mv -f "globals.gd.backup" scripts/core/globals.gd
fi
if [ -f "project.godot.backup" ]; then
echo "🧹 Cleaning up: Restoring project.godot from backup..."
mv -f "project.godot.backup" project.godot
fi
}
trap cleanup EXIT INT TERM

GODOT_CMD="godot"
RAW_SECRET='T3st_S@lt!_2026#"\'
export PRODUCTION_SALT="$RAW_SECRET"

echo "=========================================="
echo " Starting Local CI/CD Simulation"
echo "=========================================="

if [ ! -f "scripts/core/globals.gd" ] || [ ! -f "project.godot" ]; then
echo "❌ ERROR: Required project files not found!"
exit 1
fi

cp scripts/core/globals.gd globals.gd.backup
cp project.godot project.godot.backup

echo "🗑️ Wiping previous web export files..."
rm -rf export/web/*
mkdir -p export/web

echo "🔌 Disabling editor plugins (GUT) to prevent headless crashes..."
sed -i 's/^enabled=PackedStringArray.*/enabled=PackedStringArray()/' project.godot

echo "⚙️ Injecting secret directly into GDScript bytecode..."
GODOT_ESCAPED=$(printf '%s' "$PRODUCTION_SALT" | sed 's/\\/\\\\/g; s/"/\\"/g')
SED_ESCAPED=$(printf '%s' "$GODOT_ESCAPED" | sed 's/\\/\\\\/g; s/&/\\&/g; s/|/\\|/g')

# Replace the safe placeholder with the real secret
sed -i "s|\"CI_INJECT_SALT_HERE\"|\"$SED_ESCAPED\"|g" scripts/core/globals.gd

Comment thread
coderabbitai[bot] marked this conversation as resolved.
echo "🎮 Exporting Godot project (Web preset)..."
$GODOT_CMD --verbose --headless --export-release "Web" export/web/index.html > export_log.txt 2>&1 &
GODOT_PID=$!

SECONDS=0
SPINNER="-\|/"
i=0
while kill -0 $GODOT_PID 2>/dev/null; do
i=$(( (i+1) % 4 ))
printf "\r⚙️ Godot is working... %s (Elapsed Time: %d seconds)" "${SPINNER:$i:1}" "$SECONDS"
sleep 1
done

printf "\r✅ Export process finished! (Total time: %d seconds) \n" "$SECONDS"

wait $GODOT_PID
if [ $? -ne 0 ]; then
echo "❌ FATAL: Godot engine crashed during export."
echo "📄 Printing the last 20 lines of the crash log:"
tail -n 20 export_log.txt
exit 1
fi

if [ ! -f "export/web/index.pck" ]; then
echo "❌ Export failed. index.pck not found."
exit 1
fi

if [ -f "./.github/scripts/patch_index_js.sh" ]; then
bash ./.github/scripts/patch_index_js.sh "export/web" || {
echo "❌ ERROR: patch_index_js.sh failed."
exit 1
}
fi

echo "✅ Build pipeline completed successfully."

echo "=========================================="
echo " Starting Local Game Server"
echo "=========================================="
cat << 'EOF' > export/web/serve.py
import http.server
PORT = 8080
class Handler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
super().end_headers()
if __name__ == '__main__':
with http.server.ThreadingHTTPServer(("", PORT), Handler) as httpd:
print(f"🚀 Game server running! Open http://localhost:{PORT} in your browser.")
httpd.serve_forever()
EOF

cd export/web || {
echo "❌ ERROR: Failed to change to export/web directory!"
exit 1
}
python3 serve.py
Loading