mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-17 14:17:21 +00:00
Add desktop app downloads page and release workflow
- Add GitHub Actions workflow for building desktop apps (Windows/macOS/Linux) - Create /downloads page with GitHub releases integration - Update README with download links - Automated release creation on desktop-v* tags Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bad838c659
commit
b8d5062f3e
5 changed files with 394 additions and 0 deletions
7
.claude/settings.local.json
Normal file
7
.claude/settings.local.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git add:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
143
.github/workflows/release-desktop.yml
vendored
Normal file
143
.github/workflows/release-desktop.yml
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
name: Release Desktop Apps
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'desktop-v*' # Trigger on tags like desktop-v1.0.0
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version number (e.g., 1.0.0)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
version: ${{ steps.get_version.outputs.version }}
|
||||
steps:
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=${GITHUB_REF#refs/tags/desktop-v}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: desktop-v${{ steps.get_version.outputs.version }}
|
||||
release_name: AeThex OS Desktop v${{ steps.get_version.outputs.version }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: |
|
||||
# AeThex OS Desktop v${{ steps.get_version.outputs.version }}
|
||||
|
||||
## Downloads
|
||||
- **Windows**: Download the `.msi` installer
|
||||
- **macOS**: Download the `.dmg` file
|
||||
- **Linux**: Download the `.AppImage`, `.deb`, or `.rpm` file
|
||||
|
||||
## What's New
|
||||
- Desktop application release
|
||||
- Cross-platform support (Windows, macOS, Linux)
|
||||
- Native performance with Tauri
|
||||
|
||||
## Installation
|
||||
- **Windows**: Run the MSI installer
|
||||
- **macOS**: Open the DMG and drag to Applications
|
||||
- **Linux**: Make AppImage executable with `chmod +x` and run, or install DEB/RPM
|
||||
|
||||
build-desktop:
|
||||
needs: create-release
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: 'macos-latest'
|
||||
args: '--target universal-apple-darwin'
|
||||
- platform: 'ubuntu-22.04'
|
||||
args: ''
|
||||
- platform: 'windows-latest'
|
||||
args: ''
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install dependencies (Ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev \
|
||||
libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: Install frontend dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Install Tauri dependencies
|
||||
working-directory: shell/aethex-shell
|
||||
run: npm install
|
||||
|
||||
- name: Build Tauri app
|
||||
working-directory: shell/aethex-shell
|
||||
run: npm run tauri build -- ${{ matrix.args }}
|
||||
|
||||
- name: Upload Windows MSI
|
||||
if: matrix.platform == 'windows-latest'
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ./shell/aethex-shell/src-tauri/target/release/bundle/msi/aethex-os_${{ needs.create-release.outputs.version }}_x64_en-US.msi
|
||||
asset_name: AeThex-OS-${{ needs.create-release.outputs.version }}-Windows-x64.msi
|
||||
asset_content_type: application/x-msi
|
||||
|
||||
- name: Upload macOS DMG
|
||||
if: matrix.platform == 'macos-latest'
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ./shell/aethex-shell/src-tauri/target/universal-apple-darwin/release/bundle/dmg/AeThex OS_${{ needs.create-release.outputs.version }}_universal.dmg
|
||||
asset_name: AeThex-OS-${{ needs.create-release.outputs.version }}-macOS-universal.dmg
|
||||
asset_content_type: application/x-apple-diskimage
|
||||
|
||||
- name: Upload Linux AppImage
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ./shell/aethex-shell/src-tauri/target/release/bundle/appimage/aethex-os_${{ needs.create-release.outputs.version }}_amd64.AppImage
|
||||
asset_name: AeThex-OS-${{ needs.create-release.outputs.version }}-Linux-x86_64.AppImage
|
||||
asset_content_type: application/x-executable
|
||||
|
||||
- name: Upload Linux DEB
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ./shell/aethex-shell/src-tauri/target/release/bundle/deb/aethex-os_${{ needs.create-release.outputs.version }}_amd64.deb
|
||||
asset_name: AeThex-OS-${{ needs.create-release.outputs.version }}-Linux-amd64.deb
|
||||
asset_content_type: application/vnd.debian.binary-package
|
||||
|
|
@ -16,6 +16,15 @@
|
|||
- 📱 **Mobile Application** - Capacitor-based app (Android/iOS)
|
||||
- 🐧 **Linux Distribution** - Bootable OS replacing traditional operating systems
|
||||
|
||||
## 📥 Downloads
|
||||
|
||||
### Desktop Application
|
||||
- **[Download for Windows, macOS, or Linux](https://github.com/AeThex-Corporation/AeThex-OS/releases/latest)** - Latest desktop releases
|
||||
- **[All Releases](https://github.com/AeThex-Corporation/AeThex-OS/releases)** - View all versions
|
||||
|
||||
### Web Application
|
||||
- **[Use Online](https://aethex.app)** - No installation required
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
Choose your deployment mode:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import Login from "@/pages/login";
|
|||
import Admin from "@/pages/admin";
|
||||
import Pitch from "@/pages/pitch";
|
||||
import Builds from "@/pages/builds";
|
||||
import Downloads from "@/pages/downloads";
|
||||
import AdminArchitects from "@/pages/admin-architects";
|
||||
import AdminProjects from "@/pages/admin-projects";
|
||||
import AdminCredentials from "@/pages/admin-credentials";
|
||||
|
|
@ -90,6 +91,7 @@ function Router() {
|
|||
<Route path="/admin/notifications">{() => <ProtectedRoute><AdminNotifications /></ProtectedRoute>}</Route>
|
||||
<Route path="/pitch" component={Pitch} />
|
||||
<Route path="/builds" component={Builds} />
|
||||
<Route path="/downloads" component={Downloads} />
|
||||
<Route path="/os" component={AeThexOS} />
|
||||
<Route path="/os/link">{() => <ProtectedRoute><OsLink /></ProtectedRoute>}</Route>
|
||||
<Route path="/network" component={Network} />
|
||||
|
|
|
|||
233
client/src/pages/downloads.tsx
Normal file
233
client/src/pages/downloads.tsx
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
import { Download, Monitor, Apple, Code, Package } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Release {
|
||||
tag_name: string;
|
||||
name: string;
|
||||
published_at: string;
|
||||
assets: Array<{
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
size: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default function Downloads() {
|
||||
const [latestRelease, setLatestRelease] = useState<Release | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('https://api.github.com/repos/AeThex-Corporation/AeThex-OS/releases')
|
||||
.then(res => res.json())
|
||||
.then(releases => {
|
||||
// Find the latest desktop release (tagged with desktop-v*)
|
||||
const desktopRelease = releases.find((r: Release) =>
|
||||
r.tag_name.startsWith('desktop-v')
|
||||
);
|
||||
setLatestRelease(desktopRelease || null);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to fetch releases:', err);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const getAssetByPlatform = (platform: string) => {
|
||||
if (!latestRelease) return null;
|
||||
return latestRelease.assets.find(asset =>
|
||||
asset.name.toLowerCase().includes(platform.toLowerCase())
|
||||
);
|
||||
};
|
||||
|
||||
const formatBytes = (bytes: number) => {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 text-white p-8">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="text-center mb-12">
|
||||
<h1 className="text-5xl font-bold bg-gradient-to-r from-cyan-400 to-emerald-400 bg-clip-text text-transparent mb-4">
|
||||
Download AeThex OS
|
||||
</h1>
|
||||
<p className="text-slate-400 text-lg">
|
||||
Get the desktop application for Windows, macOS, or Linux
|
||||
</p>
|
||||
{latestRelease && (
|
||||
<div className="mt-4 text-sm text-slate-500">
|
||||
Latest Version: {latestRelease.tag_name.replace('desktop-v', '')} •
|
||||
Released {new Date(latestRelease.published_at).toLocaleDateString()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="text-center py-12">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-cyan-400 mx-auto"></div>
|
||||
<p className="mt-4 text-slate-400">Loading releases...</p>
|
||||
</div>
|
||||
) : !latestRelease ? (
|
||||
<div className="bg-slate-800/50 rounded-lg p-8 text-center border border-slate-700">
|
||||
<Package className="w-16 h-16 text-slate-600 mx-auto mb-4" />
|
||||
<h2 className="text-2xl font-bold mb-2">No Desktop Releases Yet</h2>
|
||||
<p className="text-slate-400 mb-6">
|
||||
Desktop releases are coming soon. In the meantime, you can:
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a
|
||||
href="https://aethex.app"
|
||||
className="px-6 py-3 bg-gradient-to-r from-cyan-600 to-emerald-600 rounded-lg font-semibold hover:from-cyan-500 hover:to-emerald-500 transition-all"
|
||||
>
|
||||
Use Web Version
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/AeThex-Corporation/AeThex-OS"
|
||||
className="px-6 py-3 bg-slate-700 rounded-lg font-semibold hover:bg-slate-600 transition-all flex items-center gap-2"
|
||||
>
|
||||
<Code className="w-5 h-5" />
|
||||
Build from Source
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
{/* Windows */}
|
||||
<DownloadCard
|
||||
icon={<Monitor className="w-12 h-12" />}
|
||||
platform="Windows"
|
||||
description="MSI Installer for Windows 10/11"
|
||||
asset={getAssetByPlatform('windows')}
|
||||
formatBytes={formatBytes}
|
||||
color="from-blue-600 to-blue-400"
|
||||
/>
|
||||
|
||||
{/* macOS */}
|
||||
<DownloadCard
|
||||
icon={<Apple className="w-12 h-12" />}
|
||||
platform="macOS"
|
||||
description="Universal DMG for Intel & Apple Silicon"
|
||||
asset={getAssetByPlatform('macos')}
|
||||
formatBytes={formatBytes}
|
||||
color="from-slate-600 to-slate-400"
|
||||
/>
|
||||
|
||||
{/* Linux */}
|
||||
<DownloadCard
|
||||
icon={<Code className="w-12 h-12" />}
|
||||
platform="Linux"
|
||||
description="AppImage & DEB packages"
|
||||
asset={getAssetByPlatform('linux')}
|
||||
formatBytes={formatBytes}
|
||||
color="from-orange-600 to-orange-400"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Additional Info */}
|
||||
<div className="mt-12 grid md:grid-cols-2 gap-6">
|
||||
<div className="bg-slate-800/30 rounded-lg p-6 border border-slate-700">
|
||||
<h3 className="text-xl font-bold mb-4 flex items-center gap-2">
|
||||
<Package className="w-6 h-6 text-cyan-400" />
|
||||
Installation Instructions
|
||||
</h3>
|
||||
<div className="space-y-3 text-slate-300 text-sm">
|
||||
<div>
|
||||
<strong className="text-white">Windows:</strong> Run the MSI installer and follow the prompts
|
||||
</div>
|
||||
<div>
|
||||
<strong className="text-white">macOS:</strong> Open the DMG file and drag AeThex OS to Applications
|
||||
</div>
|
||||
<div>
|
||||
<strong className="text-white">Linux (AppImage):</strong> Make executable with <code className="bg-slate-900 px-2 py-1 rounded">chmod +x</code> and run
|
||||
</div>
|
||||
<div>
|
||||
<strong className="text-white">Linux (DEB):</strong> Install with <code className="bg-slate-900 px-2 py-1 rounded">sudo dpkg -i filename.deb</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-slate-800/30 rounded-lg p-6 border border-slate-700">
|
||||
<h3 className="text-xl font-bold mb-4 flex items-center gap-2">
|
||||
<Download className="w-6 h-6 text-emerald-400" />
|
||||
Other Options
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
<a
|
||||
href="https://aethex.app"
|
||||
className="block p-3 bg-slate-700/50 rounded hover:bg-slate-700 transition-all"
|
||||
>
|
||||
<div className="font-semibold text-cyan-400">Web Application</div>
|
||||
<div className="text-sm text-slate-400">Use AeThex OS directly in your browser</div>
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/AeThex-Corporation/AeThex-OS/releases"
|
||||
className="block p-3 bg-slate-700/50 rounded hover:bg-slate-700 transition-all"
|
||||
>
|
||||
<div className="font-semibold text-emerald-400">All Releases</div>
|
||||
<div className="text-sm text-slate-400">View all versions and changelogs</div>
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/AeThex-Corporation/AeThex-OS"
|
||||
className="block p-3 bg-slate-700/50 rounded hover:bg-slate-700 transition-all"
|
||||
>
|
||||
<div className="font-semibold text-orange-400">Build from Source</div>
|
||||
<div className="text-sm text-slate-400">Clone the repository and build locally</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function DownloadCard({
|
||||
icon,
|
||||
platform,
|
||||
description,
|
||||
asset,
|
||||
formatBytes,
|
||||
color
|
||||
}: {
|
||||
icon: React.ReactNode;
|
||||
platform: string;
|
||||
description: string;
|
||||
asset: any;
|
||||
formatBytes: (bytes: number) => string;
|
||||
color: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="bg-slate-800/50 rounded-lg p-6 border border-slate-700 hover:border-slate-600 transition-all">
|
||||
<div className={`w-16 h-16 rounded-lg bg-gradient-to-br ${color} flex items-center justify-center mb-4`}>
|
||||
{icon}
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold mb-2">{platform}</h3>
|
||||
<p className="text-slate-400 text-sm mb-4">{description}</p>
|
||||
|
||||
{asset ? (
|
||||
<>
|
||||
<div className="text-xs text-slate-500 mb-3">
|
||||
{formatBytes(asset.size)}
|
||||
</div>
|
||||
<a
|
||||
href={asset.browser_download_url}
|
||||
className="block w-full px-4 py-3 bg-gradient-to-r from-cyan-600 to-emerald-600 rounded-lg font-semibold text-center hover:from-cyan-500 hover:to-emerald-500 transition-all flex items-center justify-center gap-2"
|
||||
>
|
||||
<Download className="w-5 h-5" />
|
||||
Download
|
||||
</a>
|
||||
</>
|
||||
) : (
|
||||
<div className="text-sm text-slate-500 text-center py-3">
|
||||
Not available yet
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue