development
Desktop Downloads Feature - README
Complete guide for the desktop application downloads system that fetches releases from private GitHub repositories.
📋 Table of Contents
- Overview
- Quick Start
- Features
- Architecture
- Setup
- Usage
- Configuration
- API Reference
- Testing
- Deployment
- Troubleshooting
- Best Practices
Overview
This system provides secure download links for desktop applications stored in a private GitHub repository. It automatically detects platform and architecture from release assets and presents them in a user-friendly interface.
Key Features
- 🔒 Secure: GitHub tokens never exposed to clients
- 🚀 Fast: 5-minute response caching
- 📱 Responsive: Mobile-friendly design
- 🎯 Smart Detection: Automatic platform/architecture detection
- 🔧 Type-Safe: Full TypeScript support
- 📊 Testable: Built-in test utilities
Supported Platforms
- macOS: Apple Silicon (M1/M2/M3), Intel, Universal
- Windows: x64, ARM64, x86
- Linux: x64, ARM64 (AppImage, DEB, RPM, Snap)
Quick Start
1. Create GitHub Token
# Visit: https://github.com/settings/tokens
# Create token with 'repo' scope
# Copy the token
2. Configure Environment
# Create .env file
echo "GITHUB_TOKEN=ghp_your_token_here" > .env
3. Test Connection
# Verify GitHub API access
npm run test:releases
4. Start Development
# Start dev server
npm run dev
# Visit download page
open http://localhost:4321/download
Features
API Endpoint
Location: /src/pages/api/download-desktop-app.ts
- Fetches latest release from GitHub
- Authenticates with Personal Access Token
- Detects platforms and architectures
- Proxies downloads securely
- Caches responses (5 minutes)
- Full TypeScript types
Download Page
Location: /src/pages/download.astro
- Displays mobile app store links
- Shows desktop download options
- Real-time release fetching
- Platform-specific icons
- File size formatting
- Responsive design
Type System
Location: /src/types/github-releases.ts
- GitHub API response types
- Application-specific interfaces
- Platform detection patterns
- Type guards
- Full IntelliSense support
Architecture
┌─────────────┐
│ Browser │
│ (User) │
└──────┬──────┘
│ GET /download
▼
┌─────────────────┐
│ Download Page │ ← Astro SSG/SSR
└──────┬──────────┘
│ Fetch /api/download-desktop-app
▼
┌──────────────────────┐
│ API Endpoint │ ← Astro API Route
│ - Authenticate │
│ - Parse assets │
│ - Detect platforms │
└──────┬───────────────┘
│ Bearer Token Auth
▼
┌──────────────────┐
│ GitHub API │
│ Private Repo │
│ /releases │
└──────────────────┘
Data Flow
- User visits
/downloadpage - JavaScript fetches
/api/download-desktop-app - API authenticates with GitHub using token
- GitHub returns latest release data
- API parses assets and detects platforms
- API returns structured download links
- Page displays download buttons
- User clicks download
- API proxies download with GitHub auth
- User receives file
Setup
Prerequisites
- Node.js 18+ or compatible
- GitHub account with repository access
- Astro project (this is an Astro plugin/feature)
Installation
Files are already created. Just configure:
# 1. Copy environment template
cp .env.example .env
# 2. Edit .env and add your GitHub token
nano .env
# Add: GITHUB_TOKEN=ghp_your_actual_token
# 3. Install dependencies (if needed)
npm install
# 4. Test setup
npm run test:releases
GitHub Token Setup
Option 1: Classic Token
- Go to https://github.com/settings/tokens
- Click "Generate new token (classic)"
- Name: "PepakBasaJawa Downloads"
- Scopes: Select
repo(Full control of private repositories) - Expiration: Choose duration
- Generate and copy token
Option 2: Fine-Grained Token (Recommended)
- Go to https://github.com/settings/tokens?type=beta
- Click "Generate new token"
- Name: "PepakBasaJawa Downloads"
- Repository access: Select
setoelkahfi/pepakbasajawa - Permissions:
- Contents: Read-only
- Metadata: Read-only (auto-selected)
- Expiration: 1 year recommended
- Generate and copy token
Environment Variables
Development (.env):
env
GITHUB_TOKEN=ghp_your_token_here
Production: Add to your hosting platform's environment variables dashboard.
Usage
Creating Releases
Build your desktop apps (macOS, Windows, Linux)
Name files consistently:
pepakbasajawa-1.0.0-macos-arm64.dmg pepakbasajawa-1.0.0-macos-x64.dmg pepakbasajawa-1.0.0-windows-x64.exe pepakbasajawa-1.0.0-linux-x64.AppImageCreate GitHub release: ```bash
Via GitHub web interface
Or via gh CLI:
gh release create v1.0.0 \ dist/.dmg \ dist/.exe \ dist/*.AppImage \ --title "Release 1.0.0" \ --notes "Release notes here" ```
File Naming Convention
Format: {app}-{version}-{platform}-{arch}.{ext}
Examples:
- ✅ pepakbasajawa-1.0.0-macos-arm64.dmg
- ✅ pepakbasajawa-1.0.0-macos-x64.dmg
- ✅ pepakbasajawa-1.0.0-windows-x64.exe
- ✅ pepakbasajawa-1.0.0-windows-x64.msi
- ✅ pepakbasajawa-1.0.0-linux-x64.AppImage
- ✅ pepakbasajawa-1.0.0-linux-x64.deb
- ❌ app.dmg (too generic)
- ❌ release-v1.exe (no platform info)
Configuration
Adjust Cache Duration
Edit /src/pages/api/download-desktop-app.ts:
return new Response(JSON.stringify(responseData), {
status: 200,
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'public, max-age=300' // ← Change 300 to desired seconds
}
})
Change Repository
Edit /src/pages/api/download-desktop-app.ts:
const GITHUB_REPO = 'setoelkahfi/pepakbasajawa' // ← Change to your repo
Customize Platform Detection
Edit /src/types/github-releases.ts:
export const PLATFORM_PATTERNS = {
macOS: {
keywords: ['mac', 'darwin'], // ← Add more keywords
extensions: ['.dmg', '.pkg'],
// ...
}
}
API Reference
GET /api/download-desktop-app
Fetches available desktop downloads.
Response:
json
{
"version": "v1.0.0",
"name": "Release 1.0.0",
"published_at": "2024-01-15T10:00:00Z",
"downloads": [
{
"platform": "macOS",
"architecture": "Apple Silicon",
"url": "/api/download-desktop-app?action=download&assetId=12345",
"filename": "pepakbasajawa-1.0.0-macos-arm64.dmg",
"size": 125829120,
"version": "v1.0.0",
"assetId": 12345
}
]
}
GET /api/download-desktop-app?action=download&assetId={id}
Downloads a specific asset.
Parameters:
- action: Must be "download"
- assetId: GitHub asset ID from releases response
Response: HTTP 302 redirect to temporary download URL
Testing
Test GitHub Connection
npm run test:releases
Expected Output: ``` 🔍 Testing GitHub API Connection
✓ GitHub token found (ghp_abcd12...) ✓ Repository: setoelkahfi/pepakbasajawa ✓ Authenticated as: setoelkahfi ✓ Found release: Release 1.0.0
📋 Release Assets: ──────────────────────────────────── 🍎 pepakbasajawa-1.0.0-macos-arm64.dmg Platform: macOS (Apple Silicon) Size: 120.00 MB ...
✅ All tests passed! ```
Manual API Testing
# Test releases endpoint
curl http://localhost:4321/api/download-desktop-app | jq
# Test download (replace asset ID)
curl -L "http://localhost:4321/api/download-desktop-app?action=download&assetId=12345" \
-o test-download.dmg
Integration Testing
# Start dev server
npm run dev
# In another terminal, test endpoints
curl http://localhost:4321/api/download-desktop-app
# Test in browser
open http://localhost:4321/download
Deployment
Vercel
# Set environment variable
vercel env add GITHUB_TOKEN
# Paste your token when prompted
# Deploy
vercel --prod
Or via Vercel dashboard:
1. Project Settings → Environment Variables
2. Add GITHUB_TOKEN with your token
3. Redeploy
Netlify
# Via CLI
netlify env:set GITHUB_TOKEN your_token_here
# Deploy
netlify deploy --prod
Or via Netlify dashboard:
1. Site settings → Environment variables
2. Add variable: GITHUB_TOKEN
3. Redeploy site
Docker
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install && npm run build
ENV GITHUB_TOKEN=${GITHUB_TOKEN}
EXPOSE 4321
CMD ["npm", "run", "preview"]
Build and run:
bash
docker build -t pepakbasajawa-web .
docker run -e GITHUB_TOKEN=your_token -p 4321:4321 pepakbasajawa-web
Troubleshooting
Common Issues
1. "GITHUB_TOKEN is not configured"
Symptoms: API returns 500 error
Solutions:
- Check .env file exists and contains token
- Verify token is not empty or commented out
- Restart dev server after adding token
- In production, check environment variables in hosting dashboard
# Verify token is loaded
cat .env | grep GITHUB_TOKEN
# Restart server
npm run dev
2. "Failed to fetch releases"
Symptoms: API returns error or 404
Solutions:
- Verify token has correct permissions (repo scope)
- Check token hasn't expired
- Confirm repository name is correct
- Ensure at least one release exists
# Test token manually
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/repos/setoelkahfi/pepakbasajawa/releases/latest
3. No downloads showing on page
Symptoms: Page loads but no desktop downloads appear
Solutions:
- Check browser console for errors
- Verify release is marked as "latest" (not draft)
- Ensure release has uploaded assets
- Run npm run test:releases to debug
4. Downloads not detected correctly
Symptoms: Files show as "Unknown" platform Solutions: - Check filename follows naming convention - Add platform keywords to filename - Verify file extension is standard (.dmg, .exe, .AppImage) - Update detection patterns if needed
5. Rate limit exceeded
Symptoms: API returns 403 after many requests
Solutions:
- Authenticated limit is 5,000/hour (should be plenty)
- Check cache is working (5-minute default)
- Monitor rate limit: curl https://api.github.com/rate_limit
- Consider increasing cache duration
Best Practices
Security
Never commit tokens
- Add
.envto.gitignore - Use environment variables
- Rotate tokens regularly
- Add
Use fine-grained tokens
- Limit scope to specific repository
- Read-only permissions
- Set expiration dates
Monitor token usage
- Check GitHub token logs
- Watch for suspicious activity
- Revoke compromised tokens immediately
Release Management
Consistent naming
- Use version tags (v1.0.0)
- Follow semantic versioning
- Include platform in filename
Complete releases
- Build all platforms
- Test on each platform
- Include changelogs
Automation
- Use GitHub Actions for releases
- Automate builds
- Run tests before publishing
Performance
Caching
- Keep 5-minute cache for balance
- Increase for stable releases
- Decrease for active development
Asset optimization
- Compress installers when possible
- Use appropriate formats
- Consider delta updates
CDN
- Consider CDN for large files
- GitHub provides good distribution
- Monitor download speeds
Support
Documentation
- Setup Guide:
DESKTOP_DOWNLOADS_SETUP.md - Quick Start:
QUICK_START_DOWNLOADS.md - Implementation Details:
IMPLEMENTATION_SUMMARY.md
Contact
- Email: info@pepakbasajawa.com
- Repository: https://github.com/setoelkahfi/pepakbasajawa
- Web: https://github.com/setoelkahfi/pepakbasajawa-web
Resources
License
This feature is part of the PepakBasaJawa project.
Version: 1.0.0
Last Updated: 2024
Status: ✅ Production Ready