Compare commits
No commits in common. "master" and "v0.1.4" have entirely different histories.
@ -15,9 +15,6 @@ jobs:
|
||||
run: echo "${LOCIP} gitea.comnenos" >> /etc/hosts
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Install Build Dependencies
|
||||
run: |
|
||||
@ -62,17 +59,16 @@ jobs:
|
||||
- name: Create Release Archive
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
VERSION_NUM=${VERSION#v} # Remove 'v' prefix (e.g., v0.1.4 -> 0.1.4)
|
||||
mkdir -p release
|
||||
|
||||
# Copy AppImage (if it exists) - use version from build
|
||||
if [ -f publish/appimage/NotePad-${VERSION_NUM}-x86_64.AppImage ]; then
|
||||
cp publish/appimage/NotePad-${VERSION_NUM}-x86_64.AppImage \
|
||||
# Copy AppImage (if it exists)
|
||||
if [ -f publish/appimage/NotePad-0.1.0-x86_64.AppImage ]; then
|
||||
cp publish/appimage/NotePad-0.1.0-x86_64.AppImage \
|
||||
release/NotePad-${VERSION}-x86_64.AppImage
|
||||
fi
|
||||
|
||||
# Copy Linux Tarball
|
||||
cp publish/tarball/notepad-${VERSION_NUM}-linux-x64.tar.gz \
|
||||
cp publish/tarball/notepad-0.1.0-linux-x64.tar.gz \
|
||||
release/notepad-${VERSION}-linux-x64.tar.gz
|
||||
|
||||
# Create Windows zip
|
||||
@ -95,21 +91,6 @@ jobs:
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
|
||||
# Explicitly fetch the tag with annotation
|
||||
echo "Fetching tag ${VERSION} with annotation..."
|
||||
git fetch origin tag ${VERSION} --force
|
||||
|
||||
# Get the tag annotation message (not the commit message)
|
||||
echo "Extracting tag annotation..."
|
||||
TAG_MESSAGE=$(git cat-file tag ${VERSION} | sed '1,/^$/d')
|
||||
echo "Tag annotation: ${TAG_MESSAGE}"
|
||||
|
||||
# Create release body
|
||||
RELEASE_BODY=$(printf "%s\n\n## Downloads\n\n### Linux\n- **AppImage**: Portable, single-file executable (no installation needed)\n- **Tarball**: Extract and run \`sudo ./install.sh\` to install\n\n### Windows\n- **Zip**: Extract and run \`NotePad.exe\`" "$TAG_MESSAGE")
|
||||
|
||||
# Escape the full body for JSON
|
||||
RELEASE_BODY_JSON=$(printf '%s' "$RELEASE_BODY" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
||||
|
||||
# Create release
|
||||
curl -X POST "https://repos.gmgauthier.com/api/v1/repos/${GITHUB_REPOSITORY}/releases" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
@ -117,7 +98,7 @@ jobs:
|
||||
-d "{
|
||||
\"tag_name\": \"${VERSION}\",
|
||||
\"name\": \"NotePad ${VERSION}\",
|
||||
\"body\": \"${RELEASE_BODY_JSON}\"
|
||||
\"body\": \"Release ${VERSION}\n\n## Downloads\n\n### Linux\n- **AppImage**: Portable, single-file executable (no installation needed)\n- **Tarball**: Extract and run \`sudo ./install.sh\` to install\n\n### Windows\n- **Zip**: Extract and run \`NotePad.exe\`\"
|
||||
}" > release_response.json
|
||||
|
||||
RELEASE_ID=$(cat release_response.json | grep -o '"id":[0-9]*' | head -1 | cut -d':' -f2)
|
||||
|
||||
@ -15,12 +15,7 @@ public partial class App : Application
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
string? fileToOpen = null;
|
||||
if (desktop.Args?.Length > 0)
|
||||
{
|
||||
fileToOpen = desktop.Args[0];
|
||||
}
|
||||
desktop.MainWindow = new MainWindow(fileToOpen);
|
||||
desktop.MainWindow = new MainWindow();
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
|
||||
@ -4,27 +4,6 @@
|
||||
Title="Untitled - Notepad"
|
||||
Width="600" Height="400">
|
||||
|
||||
<Window.Styles>
|
||||
<Style Selector="Menu">
|
||||
<Setter Property="Background" Value="#D3D3D3"/>
|
||||
</Style>
|
||||
<Style Selector="MenuItem">
|
||||
<Setter Property="Background" Value="#D3D3D3"/>
|
||||
<Setter Property="Foreground" Value="Black"/>
|
||||
</Style>
|
||||
<Style Selector="MenuItem:pointerover /template/ Border#PART_LayoutRoot">
|
||||
<Setter Property="Background" Value="#A9A9A9"/>
|
||||
</Style>
|
||||
<Style Selector="MenuItem:open /template/ Popup#PART_Popup > Border">
|
||||
<Setter Property="Background" Value="#D3D3D3"/>
|
||||
<Setter Property="BorderBrush" Value="#A9A9A9"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
<Style Selector="Separator">
|
||||
<Setter Property="Background" Value="#A9A9A9"/>
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
|
||||
<DockPanel>
|
||||
<!-- Menu Bar -->
|
||||
<Menu DockPanel.Dock="Top">
|
||||
@ -36,7 +15,7 @@
|
||||
<Separator/>
|
||||
<MenuItem Header="E_xit" Click="OnExitClick"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Edit" x:Name="EditMenuItem">
|
||||
<MenuItem Header="_Edit">
|
||||
<MenuItem Header="_Undo" Click="OnUndoClick" InputGesture="Ctrl+Z"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Cu_t" Click="OnCutClick" InputGesture="Ctrl+X"/>
|
||||
@ -50,7 +29,7 @@
|
||||
<MenuItem Header="F_ormat">
|
||||
<MenuItem Header="_Word Wrap" x:Name="WordWrapMenuItem" Click="OnWordWrapToggle">
|
||||
<MenuItem.Icon>
|
||||
<CheckBox x:Name="WordWrapCheckBox" IsChecked="False" IsHitTestVisible="False"/>
|
||||
<CheckBox x:Name="WordWrapCheckBox" IsChecked="True" IsHitTestVisible="False"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
@ -64,7 +43,7 @@
|
||||
<TextBox x:Name="EditorTextBox"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="NoWrap"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
@ -73,9 +52,8 @@
|
||||
Background="White"
|
||||
Foreground="Black"
|
||||
CaretBrush="Black"
|
||||
FontFamily="Courier New,Liberation Mono,Courier,monospace"
|
||||
FontSize="13"
|
||||
ClearSelectionOnLostFocus="False">
|
||||
FontFamily="Consolas,Courier New,monospace"
|
||||
FontSize="12">
|
||||
<TextBox.Styles>
|
||||
<Style Selector="TextBox">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
|
||||
@ -17,11 +17,7 @@ namespace NotePad
|
||||
private bool _isModified;
|
||||
private string? _originalText;
|
||||
|
||||
public MainWindow() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public MainWindow(string? fileToOpen)
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
UpdateTitle();
|
||||
@ -30,30 +26,6 @@ namespace NotePad
|
||||
textBox.TextChanged += OnTextChanged;
|
||||
|
||||
Closing += OnWindowClosing;
|
||||
|
||||
if (!string.IsNullOrEmpty(fileToOpen) && File.Exists(fileToOpen))
|
||||
{
|
||||
_ = LoadFileAsync(fileToOpen);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadFileAsync(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = await File.ReadAllTextAsync(filePath);
|
||||
_currentFilePath = filePath;
|
||||
_currentFileName = Path.GetFileName(filePath);
|
||||
|
||||
this.FindControl<TextBox>("EditorTextBox")!.Text = text;
|
||||
_originalText = text;
|
||||
_isModified = false;
|
||||
UpdateTitle();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Silently ignore file loading errors on startup
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTitle()
|
||||
@ -294,17 +266,7 @@ namespace NotePad
|
||||
var textBox = this.FindControl<TextBox>("EditorTextBox")!;
|
||||
|
||||
checkBox.IsChecked = !checkBox.IsChecked;
|
||||
|
||||
if (checkBox.IsChecked == true)
|
||||
{
|
||||
textBox.TextWrapping = TextWrapping.Wrap;
|
||||
ScrollViewer.SetHorizontalScrollBarVisibility(textBox, Avalonia.Controls.Primitives.ScrollBarVisibility.Disabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
textBox.TextWrapping = TextWrapping.NoWrap;
|
||||
ScrollViewer.SetHorizontalScrollBarVisibility(textBox, Avalonia.Controls.Primitives.ScrollBarVisibility.Auto);
|
||||
}
|
||||
textBox.TextWrapping = checkBox.IsChecked == true ? TextWrapping.Wrap : TextWrapping.NoWrap;
|
||||
}
|
||||
|
||||
// Edit Menu
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
@ -7,15 +6,14 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
<ApplicationIcon>img\notepad-icon.ico</ApplicationIcon>
|
||||
<Version>0.1.17</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.3.12" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.12" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.12" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.12" />
|
||||
|
||||
<PackageReference Include="Avalonia" Version="11.3.12"/>
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.12"/>
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.12"/>
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.12"/>
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.12">
|
||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
set -e
|
||||
|
||||
APP_NAME="NotePad"
|
||||
VERSION="${1:-0.1.0}" # Use first argument or default to 0.1.0
|
||||
VERSION="0.1.0"
|
||||
ARCH="x86_64"
|
||||
|
||||
# Directories
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
BIN
NotePad/img/notepad-screenshot.png
Normal file
BIN
NotePad/img/notepad-screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@ -9,30 +9,9 @@ import sys
|
||||
import os
|
||||
import shutil
|
||||
import tarfile
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_version():
|
||||
"""Extract version from .csproj file"""
|
||||
csproj_path = Path("NotePad.csproj")
|
||||
if not csproj_path.exists():
|
||||
print("⚠️ WARNING: NotePad.csproj not found. Using default version 0.1.0")
|
||||
return "0.1.0"
|
||||
|
||||
try:
|
||||
tree = ET.parse(csproj_path)
|
||||
root = tree.getroot()
|
||||
version_elem = root.find(".//Version")
|
||||
if version_elem is not None and version_elem.text:
|
||||
return version_elem.text
|
||||
print("⚠️ WARNING: Version not found in .csproj. Using default version 0.1.0")
|
||||
return "0.1.0"
|
||||
except Exception as e:
|
||||
print(f"⚠️ WARNING: Failed to parse .csproj: {e}. Using default version 0.1.0")
|
||||
return "0.1.0"
|
||||
|
||||
|
||||
def run_command(cmd, description):
|
||||
"""Run a shell command and print status"""
|
||||
print(f"\n{'=' * 60}")
|
||||
@ -90,7 +69,7 @@ def build_windows_installer():
|
||||
print(f"\n⚠️ WARNING: Failed to create installer: {e}")
|
||||
|
||||
|
||||
def build_linux_tarball(version):
|
||||
def build_linux_tarball():
|
||||
"""Create tar.gz archive with install script"""
|
||||
print(f"\n{'=' * 60}")
|
||||
print("Creating Linux tar.gz archive")
|
||||
@ -121,13 +100,8 @@ def build_linux_tarball(version):
|
||||
shutil.copy(script_path, temp_dir / "notepad" / script)
|
||||
os.chmod(temp_dir / "notepad" / script, 0o755)
|
||||
|
||||
# Copy img directory (contains icon)
|
||||
img_dir = Path("img")
|
||||
if img_dir.exists():
|
||||
shutil.copytree(img_dir, temp_dir / "notepad" / "img")
|
||||
|
||||
# Create tar.gz
|
||||
tarball_path = tarball_dir / f"notepad-{version}-linux-x64.tar.gz"
|
||||
tarball_path = tarball_dir / "notepad-0.1.0-linux-x64.tar.gz"
|
||||
with tarfile.open(tarball_path, "w:gz") as tar:
|
||||
tar.add(temp_dir / "notepad", arcname="notepad")
|
||||
|
||||
@ -142,7 +116,7 @@ def build_linux_tarball(version):
|
||||
print(f" sudo ./install.sh")
|
||||
|
||||
|
||||
def build_linux_appimage(version):
|
||||
def build_linux_appimage():
|
||||
"""Build Linux AppImage"""
|
||||
build_script = Path("build-appimage.sh")
|
||||
if not build_script.exists():
|
||||
@ -151,7 +125,7 @@ def build_linux_appimage(version):
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["bash", str(build_script), version],
|
||||
["bash", str(build_script)],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
@ -216,11 +190,10 @@ def publish_platform(platform, linux_package='both'):
|
||||
|
||||
# Build Linux packages
|
||||
if platform == 'linux':
|
||||
version = get_version()
|
||||
if linux_package in ['appimage', 'both']:
|
||||
build_linux_appimage(version)
|
||||
build_linux_appimage()
|
||||
if linux_package in ['tarball', 'both']:
|
||||
build_linux_tarball(version)
|
||||
build_linux_tarball()
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@ -2,9 +2,7 @@
|
||||
|
||||
A simple cross-platform text editor built with Avalonia UI and .NET 8.
|
||||
|
||||
| Windows | Linux |
|
||||
|-----------------------------------------------------------------| ----- |
|
||||
|  |  |
|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
113
make-release.py
113
make-release.py
@ -1,113 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Release script for NotePad
|
||||
Automates version bumping, committing, tagging, and pushing
|
||||
"""
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_command(cmd, description):
|
||||
"""Run a command and handle errors"""
|
||||
print(f"\n→ {description}...")
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f"❌ ERROR: {description} failed!")
|
||||
print(f" {result.stderr}")
|
||||
sys.exit(1)
|
||||
|
||||
if result.stdout.strip():
|
||||
print(f" {result.stdout.strip()}")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def update_version_in_csproj(version):
|
||||
"""Update the version in NotePad.csproj"""
|
||||
csproj_path = Path("NotePad/NotePad.csproj")
|
||||
|
||||
if not csproj_path.exists():
|
||||
print(f"❌ ERROR: {csproj_path} not found!")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"\n→ Updating version to {version} in {csproj_path}...")
|
||||
|
||||
try:
|
||||
tree = ET.parse(csproj_path)
|
||||
root = tree.getroot()
|
||||
|
||||
version_elem = root.find(".//Version")
|
||||
if version_elem is not None:
|
||||
version_elem.text = version
|
||||
else:
|
||||
# Add Version element if it doesn't exist
|
||||
property_group = root.find(".//PropertyGroup")
|
||||
if property_group is not None:
|
||||
version_elem = ET.SubElement(property_group, "Version")
|
||||
version_elem.text = version
|
||||
else:
|
||||
print("❌ ERROR: Could not find PropertyGroup in .csproj")
|
||||
sys.exit(1)
|
||||
|
||||
tree.write(csproj_path, encoding='utf-8', xml_declaration=True)
|
||||
print(f" ✅ Version updated to {version}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ ERROR: Failed to update .csproj: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python3 make-release.py <version> [tag message]")
|
||||
print("")
|
||||
print("Examples:")
|
||||
print(" python3 make-release.py v0.1.6")
|
||||
print(" python3 make-release.py v0.1.6 'Added fireworks to launch animations'")
|
||||
sys.exit(1)
|
||||
|
||||
version_tag = sys.argv[1]
|
||||
|
||||
# Remove 'v' prefix for .csproj version
|
||||
version_num = version_tag.lstrip('v')
|
||||
|
||||
# Get tag message from remaining arguments
|
||||
tag_message = ' '.join(sys.argv[2:]) if len(sys.argv) > 2 else f"Release {version_tag}"
|
||||
|
||||
print("=" * 60)
|
||||
print(f"NotePad Release Script")
|
||||
print("=" * 60)
|
||||
print(f"Version: {version_tag}")
|
||||
print(f"Tag message: {tag_message}")
|
||||
print("=" * 60)
|
||||
|
||||
# Step 1: Update version in .csproj
|
||||
update_version_in_csproj(version_num)
|
||||
|
||||
# Step 2: Commit the version update
|
||||
commit_message = f"Incremented to version {version_tag}"
|
||||
run_command(["git", "add", "NotePad/NotePad.csproj"], "Staging .csproj")
|
||||
run_command(["git", "commit", "-m", commit_message], "Committing version update")
|
||||
|
||||
# Step 3: Push to origin master
|
||||
run_command(["git", "push", "origin", "master"], "Pushing to origin master")
|
||||
|
||||
# Step 4: Create git tag
|
||||
run_command(["git", "tag", "-a", version_tag, "-m", tag_message], f"Creating tag {version_tag}")
|
||||
|
||||
# Step 5: Push tag to origin
|
||||
run_command(["git", "push", "origin", version_tag], f"Pushing tag {version_tag}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("✅ Release completed successfully!")
|
||||
print("=" * 60)
|
||||
print(f"\nThe CI/CD workflow should now build and publish {version_tag}")
|
||||
print(f"Check your Gitea repository for the release.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user