Skip to content

Commit e62b4c0

Browse files
committed
CI fixes
1 parent 35a2652 commit e62b4c0

21 files changed

+135
-80
lines changed

.github/scripts/check_relevance.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
import subprocess
22
import sys
3-
4-
def get_last_tag():
5-
try:
6-
result = subprocess.run(
7-
["git", "tag", "--sort=-creatordate"],
8-
capture_output=True, text=True, check=True
9-
)
10-
tags = result.stdout.strip().split('\n')
11-
return tags[0] if tags and tags[0] else None
12-
except:
13-
return None
3+
import os
4+
from git_utils import get_last_tag
145

156
def has_relevant_changes(since_tag):
167
if not since_tag:
@@ -37,17 +28,22 @@ def has_relevant_changes(since_tag):
3728
print(f"Relevant change detected in: {f}")
3829
return True
3930
return False
40-
except:
41-
return True # Default to true if something fails
31+
except subprocess.CalledProcessError:
32+
return True # Default to true if git diff fails
4233

4334
def main():
4435
last_tag = get_last_tag()
45-
if has_relevant_changes(last_tag):
46-
print("relevance=true")
47-
sys.exit(0)
48-
else:
49-
print("relevance=false")
50-
sys.exit(0)
36+
relevance = "true" if has_relevant_changes(last_tag) else "false"
37+
38+
print(f"relevance={relevance}")
39+
40+
# Also write to GITHUB_OUTPUT if present
41+
output_file = os.getenv("GITHUB_OUTPUT")
42+
if output_file:
43+
with open(output_file, "a") as f:
44+
f.write(f"relevance={relevance}\n")
45+
46+
sys.exit(0)
5147

5248
if __name__ == "__main__":
5349
main()

.github/scripts/generate_changelog.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,6 @@
1-
import subprocess
2-
import os
3-
import re
41
import argparse
2+
from git_utils import get_last_tag
53

6-
def get_last_tag():
7-
"""Returns the most recent git tag."""
8-
try:
9-
# Get all tags sorted by date desc
10-
result = subprocess.run(
11-
["git", "tag", "--sort=-creatordate"],
12-
capture_output=True, text=True, check=True
13-
)
14-
tags = result.stdout.strip().split('\n')
15-
if not tags or tags[0] == "":
16-
return None
17-
return tags[0]
18-
except subprocess.CalledProcessError:
19-
return None
204

215
def get_commits(since_tag=None):
226
"""Returns list of commit messages since the given tag (or all if None)."""
@@ -63,7 +47,7 @@ def parse_commits(commits):
6347
categories["Styling"].append(commit)
6448
elif lower_commit.startswith("docs"):
6549
categories["Documentation"].append(commit)
66-
elif lower_commit.startswith(tuple(["chore", "refactor", "style", "test", "ci", "build"])):
50+
elif lower_commit.startswith(tuple(["chore", "refactor", "test", "ci", "build"])):
6751
categories["Maintenance"].append(commit)
6852
else:
6953
# Filter out merge commits from "Other" list if we want clean output

.github/scripts/git_utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import subprocess
2+
3+
def get_last_tag():
4+
"""Returns the most recent git tag."""
5+
try:
6+
# Get all tags sorted by date desc
7+
result = subprocess.run(
8+
["git", "tag", "--sort=-creatordate"],
9+
capture_output=True, text=True, check=True
10+
)
11+
tags = result.stdout.strip().split('\n')
12+
if not tags or tags[0] == "":
13+
return None
14+
return tags[0]
15+
except subprocess.CalledProcessError:
16+
return None

.github/scripts/release_summary.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import sys
2-
import os
32

43
def main():
54
if len(sys.argv) < 3:
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Nightly Release
1+
name: Weekly Release
22

33
on:
44
schedule:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,4 @@ test_flet_controls.py
113113
test_tabs.py
114114
test_tabs_2.py
115115
pytest_out.txt
116+
mock_script.ps1

src/generate_addons.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ def ask(self, query):
3838
if "hi" in q or "hallo" in q:
3939
return "Hallo! Ich bin der interner SwitchCraft AI Helper. Wie kann ich dir heute beim Paketieren helfen?"
4040
if "who are you" in q or "wer bist du" in q:
41-
return "I am the built-in SwitchCraft AI Assistant. I can help with silent switches, MSI properties, and Intune deployments."
41+
return "Ich bin der integrierte SwitchCraft AI Assistent. Ich kann dir bei Silent-Switches, MSI-Properties und Intune-Deployments helfen."
4242
if "silent" in q or "switches" in q:
4343
sw = self.ctx.get("install_silent", "/S")
4444
return f"Für dieses Paket wurden folgende Silent-Switches erkannt: `{sw}`. Du kannst diese im Packaging Wizard noch anpassen."
4545
if "intune" in q:
4646
return "Um Apps nach Intune hochzuladen, stelle sicher, dass du die Graph API Credentials in den Einstellungen hinterlegt hast."
47-
return f"Ich habe deine Frage zu '{query}' verstanden, kann aber ohne aktive Gemini/OpenAI Verbindung keine tiefergehende Analyse durchführen. Nutze den Packaging Wizard für automatische Erkennungen!"
47+
return f"Ich habe deine Frage zu '{query}' verstanden, kann aber ohne aktive Verbindung zu Gemini oder OpenAI keine tiefergehende Analyse durchführen. Nutze den Packaging Wizard für automatische Erkennungen!"
4848
"""
4949
create_addon("AI Assistant", "ai", {"service.py": ai_service_code})
5050

src/switchcraft/assets/lang/de.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
"analyzing": "Analysiere",
3636
"analysis_complete": "Analyse abgeschlossen",
3737
"ai_helper": "KI Helfer",
38+
"ai_stub_greeting": "Hallo! Ich bin dein lokaler KI-Assistent. Ich kann dir bei Paketierungsfragen helfen, auch wenn du keinen API-Key konfiguriert hast.",
39+
"ai_stub_welcome": "Hallo! Ich bin der lokale SwitchCraft KI-Helfer. Ich laufe derzeit im eingeschränkten Modus, da das KI-Addon nicht installiert ist, aber ich kann dir trotzdem einige grundlegende Tipps geben!",
3840
"error": "Fehler",
3941
"file_not_found": "Datei nicht gefunden.",
4042
"unknown_installer": "Installer-Typ konnte nicht erkannt werden.",

src/switchcraft/assets/lang/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
"analyzing": "Analyzing",
3636
"analysis_complete": "Analysis Complete",
3737
"ai_helper": "AI Helper",
38+
"ai_stub_greeting": "Hello! I am your local AI assistant. I can help you with packaging questions even when you don't have an API key configured.",
39+
"ai_stub_welcome": "Hello! I am the local SwitchCraft AI helper. I'm currently running in limited mode because the AI addon is not installed, but I can still give you some basic tips!",
3840
"error": "Error",
3941
"file_not_found": "File not found.",
4042
"unknown_installer": "Could not identify installer type.",

src/switchcraft/gui_modern/utils/view_utils.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,67 @@ class ViewMixin:
77
"""Mixin for common view functionality."""
88

99
def _show_snack(self, msg, color="GREEN"):
10-
"""Show a snackbar message on the page."""
10+
"""Show a snackbar message on the page using modern API."""
1111
try:
12-
# Check if self has app_page or page
1312
page = getattr(self, "app_page", getattr(self, "page", None))
1413
if not page:
15-
logger.debug("Cannot show snackbar: No page reference found")
1614
return
1715

1816
page.snack_bar = ft.SnackBar(ft.Text(msg), bgcolor=color)
19-
if hasattr(page, "open"):
20-
page.open(page.snack_bar)
21-
else:
22-
page.snack_bar.open = True
23-
page.update()
17+
# Use newer API for showing snackbar
18+
page.open(page.snack_bar)
2419
except Exception as e:
2520
logger.debug(f"Failed to show snackbar: {e}")
21+
22+
def _open_path(self, path):
23+
"""Cross-platform path opener (Folder or File)."""
24+
import os
25+
import platform
26+
import subprocess
27+
import webbrowser
28+
29+
try:
30+
if not os.path.exists(path):
31+
self._show_snack(f"Path does not exist: {path}", "RED")
32+
return
33+
34+
system = platform.system()
35+
if system == "Windows":
36+
os.startfile(path)
37+
elif system == "Darwin": # macOS
38+
subprocess.run(["open", path], check=True)
39+
else: # Linux
40+
subprocess.run(["xdg-open", path], check=True)
41+
except Exception as e:
42+
logger.debug(f"Default opener failed, falling back to webbrowser: {e}")
43+
try:
44+
webbrowser.open(f"file:///{path}")
45+
except Exception as e2:
46+
self._show_snack(f"Failed to open path: {path}", "RED")
47+
logger.error(f"Failed to open path: {e2}")
48+
def _close_dialog(self, dialog=None):
49+
"""Close a dialog on the page."""
50+
try:
51+
page = getattr(self, "app_page", getattr(self, "page", None))
52+
if not page:
53+
return
54+
55+
if dialog:
56+
dialog.open = False
57+
dialog.update()
58+
59+
# Fallback for older Flet or to ensure it's removed from overlay
60+
if hasattr(page, "close"):
61+
try:
62+
page.close(dialog)
63+
except:
64+
pass
65+
elif hasattr(page, "close_dialog"):
66+
try:
67+
page.close_dialog()
68+
except:
69+
pass
70+
71+
page.update()
72+
except Exception as e:
73+
logger.debug(f"Failed to close dialog: {e}")

0 commit comments

Comments
 (0)