Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c73a103280 | ||
|
|
a5d194f730 | ||
|
|
6320436b88 |
@@ -2,6 +2,6 @@
|
||||
description: "Brief description of what this command does"
|
||||
---
|
||||
|
||||
Run build_and_push.sh, and supply a good git commit message. For example:
|
||||
Run increment_and_push.sh, and supply a good git commit message. For example:
|
||||
|
||||
./build_and_push.sh "Fixed the bug with nip05 implementation"
|
||||
./increment_and_push.sh "Fixed the bug with nip05 implementation"
|
||||
@@ -6,7 +6,7 @@
|
||||
--muted-color: #dddddd;
|
||||
--border-color: var(--muted-color);
|
||||
--font-family: "Courier New", Courier, monospace;
|
||||
--border-radius: 15px;
|
||||
--border-radius: 5px;
|
||||
--border-width: 1px;
|
||||
|
||||
/* Floating Tab Variables (8) */
|
||||
@@ -326,6 +326,7 @@ button:disabled {
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
|
||||
.config-table {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
@@ -695,15 +696,6 @@ button:disabled {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
/* Main Sections Wrapper */
|
||||
.main-sections-wrapper {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--border-width);
|
||||
}
|
||||
|
||||
.flex-section {
|
||||
flex: 1;
|
||||
|
||||
@@ -33,58 +33,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Sections Wrapper -->
|
||||
<div class="main-sections-wrapper">
|
||||
|
||||
<!-- Relay Connection Section -->
|
||||
<div id="relay-connection-section" class="flex-section">
|
||||
<div class="section">
|
||||
<h2>RELAY CONNECTION</h2>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="relay-connection-url">Relay URL:</label>
|
||||
<input type="text" id="relay-connection-url" value=""
|
||||
placeholder="ws://localhost:8888 or wss://relay.example.com">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="relay-pubkey-manual">Relay Pubkey (if not available via NIP-11):</label>
|
||||
<input type="text" id="relay-pubkey-manual" placeholder="64-character hex pubkey"
|
||||
pattern="[0-9a-fA-F]{64}" title="64-character hexadecimal public key">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="inline-buttons">
|
||||
<button type="button" id="connect-relay-btn">CONNECT TO RELAY</button>
|
||||
<button type="button" id="disconnect-relay-btn" disabled>DISCONNECT</button>
|
||||
<button type="button" id="restart-relay-btn" disabled>RESTART RELAY</button>
|
||||
</div>
|
||||
|
||||
<div class="status disconnected" id="relay-connection-status">NOT CONNECTED</div>
|
||||
|
||||
<!-- Relay Information Display -->
|
||||
<div id="relay-info-display" class="hidden">
|
||||
<h3>Relay Information (NIP-11)</h3>
|
||||
<table class="config-table" id="relay-info-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="relay-info-table-body">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div> <!-- End Main Sections Wrapper -->
|
||||
|
||||
<!-- DATABASE STATISTICS Section -->
|
||||
<div class="section flex-section" id="databaseStatisticsSection" style="display: none;">
|
||||
<div class="section-header">
|
||||
|
||||
372
api/index.js
372
api/index.js
@@ -26,6 +26,8 @@ let subscriptionId = null;
|
||||
let relayInfo = null;
|
||||
let isRelayConnected = false;
|
||||
let relayPubkey = null;
|
||||
// Simple relay URL object (replaces DOM element)
|
||||
let relayConnectionUrl = { value: '' };
|
||||
// Database statistics auto-refresh
|
||||
let statsAutoRefreshInterval = null;
|
||||
let countdownInterval = null;
|
||||
@@ -46,13 +48,6 @@ const persistentUserPubkey = document.getElementById('persistent-user-pubkey');
|
||||
const persistentUserAbout = document.getElementById('persistent-user-about');
|
||||
const persistentUserDetails = document.getElementById('persistent-user-details');
|
||||
const fetchConfigBtn = document.getElementById('fetch-config-btn');
|
||||
// Relay connection elements
|
||||
const relayConnectionUrl = document.getElementById('relay-connection-url');
|
||||
const relayPubkeyManual = document.getElementById('relay-pubkey-manual');
|
||||
const relayConnectionStatus = document.getElementById('relay-connection-status');
|
||||
const connectRelayBtn = document.getElementById('connect-relay-btn');
|
||||
const disconnectRelayBtn = document.getElementById('disconnect-relay-btn');
|
||||
const restartRelayBtn = document.getElementById('restart-relay-btn');
|
||||
const configDisplay = document.getElementById('config-display');
|
||||
const configTableBody = document.getElementById('config-table-body');
|
||||
|
||||
@@ -83,6 +78,7 @@ function log(message, type = 'INFO') {
|
||||
// UI logging removed - using console only
|
||||
}
|
||||
|
||||
|
||||
// NIP-59 helper: randomize created_at to thwart time-analysis (past 2 days)
|
||||
function randomNow() {
|
||||
const TWO_DAYS = 2 * 24 * 60 * 60; // 172800 seconds
|
||||
@@ -202,215 +198,9 @@ async function testWebSocketConnection(wsUrl) {
|
||||
});
|
||||
}
|
||||
|
||||
// Connect to relay (NIP-11 + WebSocket test)
|
||||
async function connectToRelay() {
|
||||
try {
|
||||
const url = relayConnectionUrl.value.trim();
|
||||
if (!url) {
|
||||
throw new Error('Please enter a relay URL');
|
||||
}
|
||||
|
||||
// Update UI to show connecting state
|
||||
updateRelayConnectionStatus('connecting');
|
||||
connectRelayBtn.disabled = true;
|
||||
|
||||
log(`Connecting to relay: ${url}`, 'INFO');
|
||||
|
||||
let fetchedRelayInfo;
|
||||
|
||||
try {
|
||||
// Step 1: Try to fetch NIP-11 relay information
|
||||
fetchedRelayInfo = await fetchRelayInfo(url);
|
||||
|
||||
// Check if NIP-11 response includes a pubkey
|
||||
if (fetchedRelayInfo.pubkey) {
|
||||
// NIP-11 provided pubkey - populate the manual input field
|
||||
log(`NIP-11 provided relay pubkey: ${fetchedRelayInfo.pubkey.substring(0, 16)}...`, 'INFO');
|
||||
relayPubkeyManual.value = fetchedRelayInfo.pubkey;
|
||||
} else {
|
||||
// NIP-11 response missing pubkey, check for manual input
|
||||
log('NIP-11 response missing pubkey, checking for manual input...', 'INFO');
|
||||
|
||||
const manualPubkey = relayPubkeyManual.value.trim();
|
||||
if (!manualPubkey) {
|
||||
throw new Error('Relay NIP-11 response does not include a pubkey. Please enter the relay pubkey manually (shown during relay startup).');
|
||||
}
|
||||
|
||||
if (!/^[0-9a-fA-F]{64}$/.test(manualPubkey)) {
|
||||
throw new Error('Manual relay pubkey must be exactly 64 hexadecimal characters');
|
||||
}
|
||||
|
||||
log(`Using manual relay pubkey: ${manualPubkey.substring(0, 16)}...`, 'INFO');
|
||||
|
||||
// Add manual pubkey to the fetched relay info
|
||||
fetchedRelayInfo.pubkey = manualPubkey;
|
||||
|
||||
// If relay info was completely empty, create minimal info
|
||||
if (Object.keys(fetchedRelayInfo).length === 1) {
|
||||
fetchedRelayInfo = {
|
||||
name: 'C-Relay (Manual Config)',
|
||||
description: 'C-Relay instance - pubkey provided manually',
|
||||
pubkey: manualPubkey,
|
||||
contact: 'admin@manual.config.relay',
|
||||
supported_nips: [1, 9, 11, 13, 15, 20, 33, 40, 42],
|
||||
software: 'https://github.com/0xtrr/c-relay',
|
||||
version: '1.0.0'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} catch (nip11Error) {
|
||||
// If NIP-11 completely fails (network error, etc.), require manual pubkey
|
||||
const manualPubkey = relayPubkeyManual.value.trim();
|
||||
if (!manualPubkey) {
|
||||
throw new Error(`NIP-11 fetch failed: ${nip11Error.message}. Please enter the relay pubkey manually if the relay hasn't been configured yet.`);
|
||||
}
|
||||
|
||||
if (!/^[0-9a-fA-F]{64}$/.test(manualPubkey)) {
|
||||
throw new Error('Manual relay pubkey must be exactly 64 hexadecimal characters');
|
||||
}
|
||||
|
||||
log(`NIP-11 failed, using manual relay pubkey: ${manualPubkey.substring(0, 16)}...`, 'INFO');
|
||||
|
||||
// Create minimal relay info with manual pubkey
|
||||
fetchedRelayInfo = {
|
||||
name: 'C-Relay (Manual Config)',
|
||||
description: 'C-Relay instance - pubkey provided manually',
|
||||
pubkey: manualPubkey,
|
||||
contact: 'admin@manual.config.relay',
|
||||
supported_nips: [1, 9, 11, 13, 15, 20, 33, 40, 42],
|
||||
software: 'https://github.com/0xtrr/c-relay',
|
||||
version: '1.0.0'
|
||||
};
|
||||
}
|
||||
|
||||
// Step 2: Test WebSocket connection
|
||||
await testWebSocketConnection(url);
|
||||
|
||||
// Step 3: Update global state
|
||||
relayInfo = fetchedRelayInfo;
|
||||
relayPubkey = fetchedRelayInfo.pubkey;
|
||||
isRelayConnected = true;
|
||||
|
||||
// Step 4: Update UI
|
||||
updateRelayConnectionStatus('connected');
|
||||
updateAdminSectionsVisibility();
|
||||
|
||||
// Step 5: Relay URL updated
|
||||
|
||||
// Step 6: Automatically load configuration and auth rules
|
||||
log('Relay connected successfully. Auto-loading configuration and auth rules...', 'INFO');
|
||||
|
||||
// Auto-fetch configuration
|
||||
setTimeout(() => {
|
||||
fetchConfiguration().catch(error => {
|
||||
log('Auto-fetch configuration failed: ' + error.message, 'ERROR');
|
||||
});
|
||||
}, 500);
|
||||
|
||||
// Auto-fetch auth rules
|
||||
setTimeout(() => {
|
||||
loadAuthRules().catch(error => {
|
||||
log('Auto-fetch auth rules failed: ' + error.message, 'ERROR');
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
// Auto-fetch database statistics
|
||||
setTimeout(() => {
|
||||
sendStatsQuery().catch(error => {
|
||||
log('Auto-fetch statistics failed: ' + error.message, 'ERROR');
|
||||
});
|
||||
}, 1500);
|
||||
|
||||
log(`Successfully connected to relay: ${relayInfo.name || 'Unknown'}`, 'INFO');
|
||||
|
||||
} catch (error) {
|
||||
log(`Failed to connect to relay: ${error.message}`, 'ERROR');
|
||||
updateRelayConnectionStatus('error');
|
||||
|
||||
// Reset state on failure
|
||||
relayInfo = null;
|
||||
relayPubkey = null;
|
||||
isRelayConnected = false;
|
||||
|
||||
} finally {
|
||||
connectRelayBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect from relay
|
||||
function disconnectFromRelay() {
|
||||
try {
|
||||
log('Disconnecting from relay...', 'INFO');
|
||||
|
||||
// Clean up relay pool if exists
|
||||
if (relayPool) {
|
||||
const url = relayConnectionUrl.value.trim();
|
||||
if (url) {
|
||||
relayPool.close([url]);
|
||||
}
|
||||
relayPool = null;
|
||||
subscriptionId = null;
|
||||
}
|
||||
|
||||
// Reset state
|
||||
relayInfo = null;
|
||||
relayPubkey = null;
|
||||
isRelayConnected = false;
|
||||
|
||||
// Update UI
|
||||
updateRelayConnectionStatus('disconnected');
|
||||
hideRelayInfo();
|
||||
updateAdminSectionsVisibility();
|
||||
|
||||
log('Disconnected from relay', 'INFO');
|
||||
|
||||
} catch (error) {
|
||||
log(`Error during relay disconnection: ${error.message}`, 'ERROR');
|
||||
}
|
||||
}
|
||||
|
||||
// Update relay connection status UI
|
||||
function updateRelayConnectionStatus(status) {
|
||||
if (!relayConnectionStatus) return;
|
||||
|
||||
switch (status) {
|
||||
case 'connecting':
|
||||
relayConnectionStatus.textContent = 'CONNECTING...';
|
||||
relayConnectionStatus.className = 'status connected';
|
||||
connectRelayBtn.disabled = true;
|
||||
disconnectRelayBtn.disabled = true;
|
||||
restartRelayBtn.disabled = true;
|
||||
break;
|
||||
case 'connected':
|
||||
relayConnectionStatus.textContent = 'CONNECTED';
|
||||
relayConnectionStatus.className = 'status connected';
|
||||
connectRelayBtn.disabled = true;
|
||||
disconnectRelayBtn.disabled = false;
|
||||
restartRelayBtn.disabled = false;
|
||||
break;
|
||||
case 'disconnected':
|
||||
relayConnectionStatus.textContent = 'NOT CONNECTED';
|
||||
relayConnectionStatus.className = 'status disconnected';
|
||||
connectRelayBtn.disabled = false;
|
||||
disconnectRelayBtn.disabled = true;
|
||||
restartRelayBtn.disabled = true;
|
||||
break;
|
||||
case 'error':
|
||||
relayConnectionStatus.textContent = 'CONNECTION FAILED';
|
||||
relayConnectionStatus.className = 'status error';
|
||||
connectRelayBtn.disabled = false;
|
||||
disconnectRelayBtn.disabled = true;
|
||||
restartRelayBtn.disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide relay information display (placeholder for removed functionality)
|
||||
function hideRelayInfo() {
|
||||
// Relay info display functionality has been removed
|
||||
console.log('Relay info display functionality has been removed');
|
||||
}
|
||||
|
||||
// Check for existing authentication state with multiple API methods and retry logic
|
||||
async function checkExistingAuthWithRetries() {
|
||||
@@ -501,13 +291,85 @@ async function restoreAuthenticationState(pubkey) {
|
||||
showProfileInHeader();
|
||||
loadUserProfile();
|
||||
|
||||
// Note: Configuration fetching now requires explicit relay connection
|
||||
// User must connect to relay manually after login
|
||||
console.log('✅ Authentication state restored - connect to relay to fetch configuration');
|
||||
// Automatically set up relay connection (but don't show admin sections yet)
|
||||
await setupAutomaticRelayConnection();
|
||||
|
||||
console.log('✅ Authentication state restored successfully');
|
||||
}
|
||||
|
||||
// Automatically set up relay connection based on current page URL
|
||||
async function setupAutomaticRelayConnection(showSections = false) {
|
||||
try {
|
||||
// Get the current page URL and convert to WebSocket URL
|
||||
const currentUrl = window.location.href;
|
||||
let relayUrl = '';
|
||||
|
||||
if (currentUrl.startsWith('https://')) {
|
||||
relayUrl = currentUrl.replace('https://', 'wss://');
|
||||
} else if (currentUrl.startsWith('http://')) {
|
||||
relayUrl = currentUrl.replace('http://', 'ws://');
|
||||
} else {
|
||||
// Fallback for development
|
||||
relayUrl = 'ws://localhost:8888';
|
||||
}
|
||||
|
||||
// Remove any path components to get just the base URL
|
||||
const url = new URL(relayUrl);
|
||||
relayUrl = `${url.protocol}//${url.host}`;
|
||||
|
||||
// Set the relay URL
|
||||
relayConnectionUrl.value = relayUrl;
|
||||
|
||||
console.log('🔗 Auto-setting relay URL to:', relayUrl);
|
||||
|
||||
// Fetch relay info to get pubkey
|
||||
try {
|
||||
const httpUrl = relayUrl.replace('ws', 'http').replace('wss', 'https');
|
||||
const relayInfo = await fetchRelayInfo(httpUrl);
|
||||
|
||||
if (relayInfo && relayInfo.pubkey) {
|
||||
relayPubkey = relayInfo.pubkey;
|
||||
console.log('🔑 Auto-fetched relay pubkey:', relayPubkey.substring(0, 16) + '...');
|
||||
} else {
|
||||
// Use fallback pubkey
|
||||
relayPubkey = '4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa';
|
||||
console.log('⚠️ Using fallback relay pubkey');
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('⚠️ Could not fetch relay info, using fallback pubkey:', error.message);
|
||||
relayPubkey = '4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa';
|
||||
}
|
||||
|
||||
// Initialize relay pool for admin API communication
|
||||
if (!relayPool) {
|
||||
relayPool = new window.NostrTools.SimplePool();
|
||||
console.log('🔌 Initialized SimplePool for admin API communication');
|
||||
}
|
||||
|
||||
// Set up subscription to receive admin API responses
|
||||
await subscribeToConfiguration();
|
||||
console.log('📡 Subscription established for admin API responses');
|
||||
|
||||
// Mark as connected
|
||||
isRelayConnected = true;
|
||||
|
||||
// Only show admin sections if explicitly requested
|
||||
if (showSections) {
|
||||
updateAdminSectionsVisibility();
|
||||
}
|
||||
|
||||
console.log('✅ Automatic relay connection setup complete');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to setup automatic relay connection:', error);
|
||||
// Still mark as connected to allow basic functionality
|
||||
isRelayConnected = true;
|
||||
if (showSections) {
|
||||
updateAdminSectionsVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy function for backward compatibility
|
||||
async function checkExistingAuth() {
|
||||
return await checkExistingAuthWithRetries();
|
||||
@@ -540,6 +402,8 @@ async function initializeApp() {
|
||||
if (wasAlreadyLoggedIn) {
|
||||
console.log('User was already logged in, showing profile in header');
|
||||
showProfileInHeader();
|
||||
// Show admin sections since user is already authenticated and relay is connected
|
||||
updateAdminSectionsVisibility();
|
||||
} else {
|
||||
console.log('No existing authentication found, showing login modal');
|
||||
showLoginModal();
|
||||
@@ -569,9 +433,8 @@ function handleAuthEvent(event) {
|
||||
showProfileInHeader();
|
||||
loadUserProfile();
|
||||
|
||||
// Note: Configuration fetching now requires explicit relay connection
|
||||
// User must connect to relay manually after login
|
||||
console.log('Login successful. Connect to relay to access admin functions.');
|
||||
// Automatically set up relay connection and show admin sections
|
||||
setupAutomaticRelayConnection(true);
|
||||
|
||||
} else if (error) {
|
||||
console.log(`Authentication error: ${error}`);
|
||||
@@ -586,8 +449,9 @@ function handleLogoutEvent() {
|
||||
isLoggedIn = false;
|
||||
currentConfig = null;
|
||||
|
||||
// Clean up relay connection
|
||||
disconnectFromRelay();
|
||||
// Reset relay connection state
|
||||
isRelayConnected = false;
|
||||
relayPubkey = null;
|
||||
|
||||
// Reset UI - hide profile and show login modal
|
||||
hideProfileFromHeader();
|
||||
@@ -615,7 +479,18 @@ function updateAdminSectionsVisibility() {
|
||||
|
||||
// Start/stop auto-refresh based on visibility
|
||||
if (shouldShow && databaseStatisticsSection && databaseStatisticsSection.style.display === 'block') {
|
||||
// Load statistics immediately, then start auto-refresh
|
||||
sendStatsQuery().catch(error => {
|
||||
console.log('Auto-fetch statistics failed: ' + error.message);
|
||||
});
|
||||
startStatsAutoRefresh();
|
||||
// Also load configuration and auth rules automatically when sections become visible
|
||||
fetchConfiguration().catch(error => {
|
||||
console.log('Auto-fetch configuration failed: ' + error.message);
|
||||
});
|
||||
loadAuthRules().catch(error => {
|
||||
console.log('Auto-load auth rules failed: ' + error.message);
|
||||
});
|
||||
} else {
|
||||
stopStatsAutoRefresh();
|
||||
}
|
||||
@@ -862,8 +737,6 @@ async function logout() {
|
||||
// Stop auto-refresh before disconnecting
|
||||
stopStatsAutoRefresh();
|
||||
|
||||
// Clean up relay connection
|
||||
disconnectFromRelay();
|
||||
|
||||
// Clean up configuration pool
|
||||
if (relayPool) {
|
||||
@@ -882,6 +755,10 @@ async function logout() {
|
||||
isLoggedIn = false;
|
||||
currentConfig = null;
|
||||
|
||||
// Reset relay connection state
|
||||
isRelayConnected = false;
|
||||
relayPubkey = null;
|
||||
|
||||
// Reset UI - hide profile and show login modal
|
||||
hideProfileFromHeader();
|
||||
// showLoginModal() removed - handled by handleLogoutEvent()
|
||||
@@ -890,7 +767,6 @@ async function logout() {
|
||||
updateAdminSectionsVisibility();
|
||||
|
||||
log('Logged out successfully', 'INFO');
|
||||
|
||||
} catch (error) {
|
||||
log('Logout failed: ' + error.message, 'ERROR');
|
||||
}
|
||||
@@ -1834,28 +1710,6 @@ fetchConfigBtn.addEventListener('click', function (e) {
|
||||
|
||||
|
||||
|
||||
// Relay connection event handlers
|
||||
connectRelayBtn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
connectToRelay().catch(error => {
|
||||
console.log('Relay connection failed: ' + error.message);
|
||||
});
|
||||
});
|
||||
|
||||
disconnectRelayBtn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
disconnectFromRelay();
|
||||
});
|
||||
|
||||
restartRelayBtn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
sendRestartCommand().catch(error => {
|
||||
log(`Restart command failed: ${error.message}`, 'ERROR');
|
||||
});
|
||||
});
|
||||
|
||||
// ================================
|
||||
// AUTH RULES MANAGEMENT FUNCTIONS
|
||||
@@ -3840,37 +3694,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Set default relay URL based on where the page is being served from
|
||||
function setDefaultRelayUrl() {
|
||||
const relayUrlInput = document.getElementById('relay-connection-url');
|
||||
if (!relayUrlInput) return;
|
||||
|
||||
// Get the current page's protocol and hostname
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const hostname = window.location.hostname;
|
||||
const port = window.location.port;
|
||||
|
||||
// Construct the relay URL
|
||||
let relayUrl;
|
||||
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
||||
// For localhost, default to ws://localhost:8888
|
||||
relayUrl = 'ws://localhost:8888';
|
||||
} else {
|
||||
// For production, use the same hostname with WebSocket protocol
|
||||
// Remove port from URL since relay typically runs on standard ports (80/443)
|
||||
relayUrl = `${protocol}//${hostname}`;
|
||||
}
|
||||
|
||||
relayUrlInput.value = relayUrl;
|
||||
log(`Default relay URL set to: ${relayUrl}`, 'INFO');
|
||||
}
|
||||
|
||||
// Initialize the app
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('C-Relay Admin API interface loaded');
|
||||
|
||||
// Set default relay URL based on current page location
|
||||
setDefaultRelayUrl();
|
||||
|
||||
// Ensure admin sections are hidden by default on page load
|
||||
updateAdminSectionsVisibility();
|
||||
|
||||
@@ -1,616 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Global variables
|
||||
COMMIT_MESSAGE=""
|
||||
RELEASE_MODE=false
|
||||
|
||||
show_usage() {
|
||||
echo "C-Relay Build and Push Script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 \"commit message\" - Default: compile, increment patch, commit & push"
|
||||
echo " $0 -r \"commit message\" - Release: compile x86+arm64, increment minor, create release"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 \"Fixed event validation bug\""
|
||||
echo " $0 --release \"Major release with new features\""
|
||||
echo ""
|
||||
echo "Default Mode (patch increment):"
|
||||
echo " - Compile C-Relay"
|
||||
echo " - Increment patch version (v1.2.3 → v1.2.4)"
|
||||
echo " - Git add, commit with message, and push"
|
||||
echo ""
|
||||
echo "Release Mode (-r flag):"
|
||||
echo " - Compile C-Relay for x86_64 and arm64 (dynamic and static versions)"
|
||||
echo " - Increment minor version, zero patch (v1.2.3 → v1.3.0)"
|
||||
echo " - Git add, commit, push, and create Gitea release"
|
||||
echo ""
|
||||
echo "Requirements for Release Mode:"
|
||||
echo " - For ARM64 builds: make install-arm64-deps (optional - will build x86_64 only if missing)"
|
||||
echo " - For static builds: sudo apt-get install musl-dev libcap-dev libuv1-dev libev-dev"
|
||||
echo " - Gitea token in ~/.gitea_token for release uploads"
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-r|--release)
|
||||
RELEASE_MODE=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# First non-flag argument is the commit message
|
||||
if [[ -z "$COMMIT_MESSAGE" ]]; then
|
||||
COMMIT_MESSAGE="$1"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate inputs
|
||||
if [[ -z "$COMMIT_MESSAGE" ]]; then
|
||||
print_error "Commit message is required"
|
||||
echo ""
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we're in a git repository
|
||||
check_git_repo() {
|
||||
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
print_error "Not in a git repository"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to get current version and increment appropriately
|
||||
increment_version() {
|
||||
local increment_type="$1" # "patch" or "minor"
|
||||
|
||||
print_status "Getting current version..."
|
||||
|
||||
# Get the highest version tag (not chronologically latest)
|
||||
LATEST_TAG=$(git tag -l 'v*.*.*' | sort -V | tail -n 1 || echo "")
|
||||
if [[ -z "$LATEST_TAG" ]]; then
|
||||
LATEST_TAG="v0.0.0"
|
||||
print_warning "No version tags found, starting from $LATEST_TAG"
|
||||
fi
|
||||
|
||||
# Extract version components (remove 'v' prefix)
|
||||
VERSION=${LATEST_TAG#v}
|
||||
|
||||
# Parse major.minor.patch using regex
|
||||
if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
MAJOR=${BASH_REMATCH[1]}
|
||||
MINOR=${BASH_REMATCH[2]}
|
||||
PATCH=${BASH_REMATCH[3]}
|
||||
else
|
||||
print_error "Invalid version format in tag: $LATEST_TAG"
|
||||
print_error "Expected format: v0.1.0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Increment version based on type
|
||||
if [[ "$increment_type" == "minor" ]]; then
|
||||
# Minor release: increment minor, zero patch
|
||||
NEW_MINOR=$((MINOR + 1))
|
||||
NEW_PATCH=0
|
||||
NEW_VERSION="v${MAJOR}.${NEW_MINOR}.${NEW_PATCH}"
|
||||
print_status "Release mode: incrementing minor version"
|
||||
else
|
||||
# Default: increment patch
|
||||
NEW_PATCH=$((PATCH + 1))
|
||||
NEW_VERSION="v${MAJOR}.${MINOR}.${NEW_PATCH}"
|
||||
print_status "Default mode: incrementing patch version"
|
||||
fi
|
||||
|
||||
print_status "Current version: $LATEST_TAG"
|
||||
print_status "New version: $NEW_VERSION"
|
||||
|
||||
# Export for use in other functions
|
||||
export NEW_VERSION
|
||||
}
|
||||
|
||||
# Function to compile the C-Relay project
|
||||
compile_project() {
|
||||
print_status "Compiling C-Relay..."
|
||||
|
||||
# Clean previous build
|
||||
if make clean > /dev/null 2>&1; then
|
||||
print_success "Cleaned previous build"
|
||||
else
|
||||
print_warning "Clean failed or no Makefile found"
|
||||
fi
|
||||
|
||||
# Force regenerate main.h to pick up new tags
|
||||
if make force-version > /dev/null 2>&1; then
|
||||
print_success "Regenerated main.h"
|
||||
else
|
||||
print_warning "Failed to regenerate main.h"
|
||||
fi
|
||||
|
||||
# Compile the project
|
||||
if make > /dev/null 2>&1; then
|
||||
print_success "C-Relay compiled successfully"
|
||||
else
|
||||
print_error "Compilation failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to build release binaries
|
||||
build_release_binaries() {
|
||||
print_status "Building release binaries..."
|
||||
|
||||
# Build x86_64 version
|
||||
print_status "Building x86_64 version..."
|
||||
make clean > /dev/null 2>&1
|
||||
if make x86 > /dev/null 2>&1; then
|
||||
if [[ -f "build/c_relay_x86" ]]; then
|
||||
cp build/c_relay_x86 c-relay-x86_64
|
||||
print_success "x86_64 binary created: c-relay-x86_64"
|
||||
else
|
||||
print_error "x86_64 binary not found after compilation"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "x86_64 build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to build ARM64 version
|
||||
print_status "Attempting ARM64 build..."
|
||||
make clean > /dev/null 2>&1
|
||||
if make arm64 > /dev/null 2>&1; then
|
||||
if [[ -f "build/c_relay_arm64" ]]; then
|
||||
cp build/c_relay_arm64 c-relay-arm64
|
||||
print_success "ARM64 binary created: c-relay-arm64"
|
||||
else
|
||||
print_warning "ARM64 binary not found after compilation"
|
||||
fi
|
||||
else
|
||||
print_warning "ARM64 build failed - ARM64 cross-compilation not properly set up"
|
||||
print_status "Only x86_64 binary will be included in release"
|
||||
fi
|
||||
|
||||
# Build static x86_64 version
|
||||
print_status "Building static x86_64 version..."
|
||||
make clean > /dev/null 2>&1
|
||||
if make static-musl-x86_64 > /dev/null 2>&1; then
|
||||
if [[ -f "build/c_relay_static_musl_x86_64" ]]; then
|
||||
cp build/c_relay_static_musl_x86_64 c-relay-static-x86_64
|
||||
print_success "Static x86_64 binary created: c-relay-static-x86_64"
|
||||
else
|
||||
print_warning "Static x86_64 binary not found after compilation"
|
||||
fi
|
||||
else
|
||||
print_warning "Static x86_64 build failed - MUSL development packages may not be installed"
|
||||
print_status "Run 'sudo apt-get install musl-dev libcap-dev libuv1-dev libev-dev' to enable static builds"
|
||||
fi
|
||||
|
||||
# Try to build static ARM64 version
|
||||
print_status "Attempting static ARM64 build..."
|
||||
make clean > /dev/null 2>&1
|
||||
if make static-musl-arm64 > /dev/null 2>&1; then
|
||||
if [[ -f "build/c_relay_static_musl_arm64" ]]; then
|
||||
cp build/c_relay_static_musl_arm64 c-relay-static-arm64
|
||||
print_success "Static ARM64 binary created: c-relay-static-arm64"
|
||||
else
|
||||
print_warning "Static ARM64 binary not found after compilation"
|
||||
fi
|
||||
else
|
||||
print_warning "Static ARM64 build failed - ARM64 cross-compilation or MUSL ARM64 packages not set up"
|
||||
fi
|
||||
|
||||
# Restore normal build
|
||||
make clean > /dev/null 2>&1
|
||||
make > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to commit and push changes
|
||||
git_commit_and_push() {
|
||||
print_status "Preparing git commit..."
|
||||
|
||||
# Stage all changes
|
||||
if git add . > /dev/null 2>&1; then
|
||||
print_success "Staged all changes"
|
||||
else
|
||||
print_error "Failed to stage changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if there are changes to commit
|
||||
if git diff --staged --quiet; then
|
||||
print_warning "No changes to commit"
|
||||
else
|
||||
# Commit changes
|
||||
if git commit -m "$NEW_VERSION - $COMMIT_MESSAGE" > /dev/null 2>&1; then
|
||||
print_success "Committed changes"
|
||||
else
|
||||
print_error "Failed to commit changes"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create new git tag
|
||||
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Created tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag $NEW_VERSION already exists"
|
||||
fi
|
||||
|
||||
# Push changes and tags
|
||||
print_status "Pushing to remote repository..."
|
||||
if git push > /dev/null 2>&1; then
|
||||
print_success "Pushed changes"
|
||||
else
|
||||
print_error "Failed to push changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Push only the new tag to avoid conflicts with existing tags
|
||||
if git push origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Pushed tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag push failed, trying force push..."
|
||||
if git push --force origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Force-pushed updated tag: $NEW_VERSION"
|
||||
else
|
||||
print_error "Failed to push tag: $NEW_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to commit and push changes without creating a tag (tag already created)
|
||||
git_commit_and_push_no_tag() {
|
||||
print_status "Preparing git commit..."
|
||||
|
||||
# Stage all changes
|
||||
if git add . > /dev/null 2>&1; then
|
||||
print_success "Staged all changes"
|
||||
else
|
||||
print_error "Failed to stage changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if there are changes to commit
|
||||
if git diff --staged --quiet; then
|
||||
print_warning "No changes to commit"
|
||||
else
|
||||
# Commit changes
|
||||
if git commit -m "$NEW_VERSION - $COMMIT_MESSAGE" > /dev/null 2>&1; then
|
||||
print_success "Committed changes"
|
||||
else
|
||||
print_error "Failed to commit changes"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Push changes and tags
|
||||
print_status "Pushing to remote repository..."
|
||||
if git push > /dev/null 2>&1; then
|
||||
print_success "Pushed changes"
|
||||
else
|
||||
print_error "Failed to push changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Push only the new tag to avoid conflicts with existing tags
|
||||
if git push origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Pushed tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag push failed, trying force push..."
|
||||
if git push --force origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Force-pushed updated tag: $NEW_VERSION"
|
||||
else
|
||||
print_error "Failed to push tag: $NEW_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to create Gitea release
|
||||
create_gitea_release() {
|
||||
print_status "Creating Gitea release..."
|
||||
|
||||
# Check for Gitea token
|
||||
if [[ ! -f "$HOME/.gitea_token" ]]; then
|
||||
print_warning "No ~/.gitea_token found. Skipping release creation."
|
||||
print_warning "Create ~/.gitea_token with your Gitea access token to enable releases."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
|
||||
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/c-relay"
|
||||
|
||||
# Create release
|
||||
print_status "Creating release $NEW_VERSION..."
|
||||
local response=$(curl -s -X POST "$api_url/releases" \
|
||||
-H "Authorization: token $token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\": \"$NEW_VERSION\", \"name\": \"$NEW_VERSION\", \"body\": \"$COMMIT_MESSAGE\"}")
|
||||
|
||||
local upload_result=false
|
||||
|
||||
if echo "$response" | grep -q '"id"'; then
|
||||
print_success "Created release $NEW_VERSION"
|
||||
if upload_release_binaries "$api_url" "$token"; then
|
||||
upload_result=true
|
||||
fi
|
||||
elif echo "$response" | grep -q "already exists"; then
|
||||
print_warning "Release $NEW_VERSION already exists"
|
||||
if upload_release_binaries "$api_url" "$token"; then
|
||||
upload_result=true
|
||||
fi
|
||||
else
|
||||
print_error "Failed to create release $NEW_VERSION"
|
||||
print_error "Response: $response"
|
||||
|
||||
# Try to check if the release exists anyway
|
||||
print_status "Checking if release exists..."
|
||||
local check_response=$(curl -s -H "Authorization: token $token" "$api_url/releases/tags/$NEW_VERSION")
|
||||
if echo "$check_response" | grep -q '"id"'; then
|
||||
print_warning "Release exists but creation response was unexpected"
|
||||
if upload_release_binaries "$api_url" "$token"; then
|
||||
upload_result=true
|
||||
fi
|
||||
else
|
||||
print_error "Release does not exist and creation failed"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Return based on upload success
|
||||
if [[ "$upload_result" == true ]]; then
|
||||
return 0
|
||||
else
|
||||
print_error "Binary upload failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to upload release binaries
|
||||
upload_release_binaries() {
|
||||
local api_url="$1"
|
||||
local token="$2"
|
||||
local upload_success=true
|
||||
|
||||
# Get release ID with more robust parsing
|
||||
print_status "Getting release ID for $NEW_VERSION..."
|
||||
local response=$(curl -s -H "Authorization: token $token" "$api_url/releases/tags/$NEW_VERSION")
|
||||
local release_id=$(echo "$response" | grep -o '"id":[0-9]*' | head -n1 | cut -d: -f2)
|
||||
|
||||
if [[ -z "$release_id" ]]; then
|
||||
print_error "Could not get release ID for $NEW_VERSION"
|
||||
print_error "API Response: $response"
|
||||
|
||||
# Try to list all releases to debug
|
||||
print_status "Available releases:"
|
||||
curl -s -H "Authorization: token $token" "$api_url/releases" | grep -o '"tag_name":"[^"]*"' | head -5
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_success "Found release ID: $release_id"
|
||||
|
||||
# Upload x86_64 binary
|
||||
if [[ -f "c-relay-x86_64" ]]; then
|
||||
print_status "Uploading x86_64 binary..."
|
||||
local upload_response=$(curl -s -w "\n%{http_code}" -X POST "$api_url/releases/$release_id/assets" \
|
||||
-H "Authorization: token $token" \
|
||||
-F "attachment=@c-relay-x86_64;filename=c-relay-${NEW_VERSION}-linux-x86_64")
|
||||
|
||||
local http_code=$(echo "$upload_response" | tail -n1)
|
||||
local response_body=$(echo "$upload_response" | head -n -1)
|
||||
|
||||
if [[ "$http_code" == "201" ]]; then
|
||||
print_success "Uploaded x86_64 binary successfully"
|
||||
else
|
||||
print_error "Failed to upload x86_64 binary (HTTP $http_code)"
|
||||
print_error "Response: $response_body"
|
||||
upload_success=false
|
||||
fi
|
||||
else
|
||||
print_warning "x86_64 binary not found: c-relay-x86_64"
|
||||
fi
|
||||
|
||||
# Upload ARM64 binary
|
||||
if [[ -f "c-relay-arm64" ]]; then
|
||||
print_status "Uploading ARM64 binary..."
|
||||
local upload_response=$(curl -s -w "\n%{http_code}" -X POST "$api_url/releases/$release_id/assets" \
|
||||
-H "Authorization: token $token" \
|
||||
-F "attachment=@c-relay-arm64;filename=c-relay-${NEW_VERSION}-linux-arm64")
|
||||
|
||||
local http_code=$(echo "$upload_response" | tail -n1)
|
||||
local response_body=$(echo "$upload_response" | head -n -1)
|
||||
|
||||
if [[ "$http_code" == "201" ]]; then
|
||||
print_success "Uploaded ARM64 binary successfully"
|
||||
else
|
||||
print_error "Failed to upload ARM64 binary (HTTP $http_code)"
|
||||
print_error "Response: $response_body"
|
||||
upload_success=false
|
||||
fi
|
||||
else
|
||||
print_warning "ARM64 binary not found: c-relay-arm64"
|
||||
fi
|
||||
|
||||
# Upload static x86_64 binary
|
||||
if [[ -f "c-relay-static-x86_64" ]]; then
|
||||
print_status "Uploading static x86_64 binary..."
|
||||
local upload_response=$(curl -s -w "\n%{http_code}" -X POST "$api_url/releases/$release_id/assets" \
|
||||
-H "Authorization: token $token" \
|
||||
-F "attachment=@c-relay-static-x86_64;filename=c-relay-${NEW_VERSION}-linux-x86_64-static")
|
||||
|
||||
local http_code=$(echo "$upload_response" | tail -n1)
|
||||
local response_body=$(echo "$upload_response" | head -n -1)
|
||||
|
||||
if [[ "$http_code" == "201" ]]; then
|
||||
print_success "Uploaded static x86_64 binary successfully"
|
||||
else
|
||||
print_error "Failed to upload static x86_64 binary (HTTP $http_code)"
|
||||
print_error "Response: $response_body"
|
||||
upload_success=false
|
||||
fi
|
||||
else
|
||||
print_warning "Static x86_64 binary not found: c-relay-static-x86_64"
|
||||
fi
|
||||
|
||||
# Upload static ARM64 binary
|
||||
if [[ -f "c-relay-static-arm64" ]]; then
|
||||
print_status "Uploading static ARM64 binary..."
|
||||
local upload_response=$(curl -s -w "\n%{http_code}" -X POST "$api_url/releases/$release_id/assets" \
|
||||
-H "Authorization: token $token" \
|
||||
-F "attachment=@c-relay-static-arm64;filename=c-relay-${NEW_VERSION}-linux-arm64-static")
|
||||
|
||||
local http_code=$(echo "$upload_response" | tail -n1)
|
||||
local response_body=$(echo "$upload_response" | head -n -1)
|
||||
|
||||
if [[ "$http_code" == "201" ]]; then
|
||||
print_success "Uploaded static ARM64 binary successfully"
|
||||
else
|
||||
print_error "Failed to upload static ARM64 binary (HTTP $http_code)"
|
||||
print_error "Response: $response_body"
|
||||
upload_success=false
|
||||
fi
|
||||
else
|
||||
print_warning "Static ARM64 binary not found: c-relay-static-arm64"
|
||||
fi
|
||||
|
||||
# Return success/failure status
|
||||
if [[ "$upload_success" == true ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to clean up release binaries
|
||||
cleanup_release_binaries() {
|
||||
local force_cleanup="$1" # Optional parameter to force cleanup even on failure
|
||||
|
||||
if [[ "$force_cleanup" == "force" ]] || [[ "$upload_success" == true ]]; then
|
||||
if [[ -f "c-relay-x86_64" ]]; then
|
||||
rm -f c-relay-x86_64
|
||||
print_status "Cleaned up x86_64 binary"
|
||||
fi
|
||||
if [[ -f "c-relay-arm64" ]]; then
|
||||
rm -f c-relay-arm64
|
||||
print_status "Cleaned up ARM64 binary"
|
||||
fi
|
||||
if [[ -f "c-relay-static-x86_64" ]]; then
|
||||
rm -f c-relay-static-x86_64
|
||||
print_status "Cleaned up static x86_64 binary"
|
||||
fi
|
||||
if [[ -f "c-relay-static-arm64" ]]; then
|
||||
rm -f c-relay-static-arm64
|
||||
print_status "Cleaned up static ARM64 binary"
|
||||
fi
|
||||
else
|
||||
print_warning "Keeping binary files due to upload failures"
|
||||
print_status "Files available for manual upload:"
|
||||
if [[ -f "c-relay-x86_64" ]]; then
|
||||
print_status " - c-relay-x86_64"
|
||||
fi
|
||||
if [[ -f "c-relay-arm64" ]]; then
|
||||
print_status " - c-relay-arm64"
|
||||
fi
|
||||
if [[ -f "c-relay-static-x86_64" ]]; then
|
||||
print_status " - c-relay-static-x86_64"
|
||||
fi
|
||||
if [[ -f "c-relay-static-arm64" ]]; then
|
||||
print_status " - c-relay-static-arm64"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_status "C-Relay Build and Push Script"
|
||||
|
||||
# Check prerequisites
|
||||
check_git_repo
|
||||
|
||||
if [[ "$RELEASE_MODE" == true ]]; then
|
||||
print_status "=== RELEASE MODE ==="
|
||||
|
||||
# Increment minor version for releases
|
||||
increment_version "minor"
|
||||
|
||||
# Create new git tag BEFORE compilation so version.h picks it up
|
||||
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Created tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag $NEW_VERSION already exists, removing and recreating..."
|
||||
git tag -d "$NEW_VERSION" > /dev/null 2>&1
|
||||
git tag "$NEW_VERSION" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Compile project first (will now pick up the new tag)
|
||||
compile_project
|
||||
|
||||
# Build release binaries
|
||||
build_release_binaries
|
||||
|
||||
# Commit and push (but skip tag creation since we already did it)
|
||||
git_commit_and_push_no_tag
|
||||
|
||||
# Create Gitea release with binaries
|
||||
if create_gitea_release; then
|
||||
print_success "Release $NEW_VERSION completed successfully!"
|
||||
print_status "Binaries uploaded to Gitea release"
|
||||
upload_success=true
|
||||
else
|
||||
print_error "Release creation or binary upload failed"
|
||||
upload_success=false
|
||||
fi
|
||||
|
||||
# Cleanup (only if upload was successful)
|
||||
cleanup_release_binaries
|
||||
|
||||
else
|
||||
print_status "=== DEFAULT MODE ==="
|
||||
|
||||
# Increment patch version for regular commits
|
||||
increment_version "patch"
|
||||
|
||||
# Create new git tag BEFORE compilation so version.h picks it up
|
||||
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Created tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag $NEW_VERSION already exists, removing and recreating..."
|
||||
git tag -d "$NEW_VERSION" > /dev/null 2>&1
|
||||
git tag "$NEW_VERSION" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Compile project (will now pick up the new tag)
|
||||
compile_project
|
||||
|
||||
# Commit and push (but skip tag creation since we already did it)
|
||||
git_commit_and_push_no_tag
|
||||
|
||||
print_success "Build and push completed successfully!"
|
||||
print_status "Version $NEW_VERSION pushed to repository"
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute main function
|
||||
main
|
||||
331
increment_and_push.sh
Executable file
331
increment_and_push.sh
Executable file
@@ -0,0 +1,331 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Global variables
|
||||
COMMIT_MESSAGE=""
|
||||
RELEASE_MODE=false
|
||||
|
||||
show_usage() {
|
||||
echo "C-Relay Increment and Push Script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 \"commit message\" - Default: increment patch, commit & push"
|
||||
echo " $0 -r \"commit message\" - Release: increment minor, create release"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 \"Fixed event validation bug\""
|
||||
echo " $0 --release \"Major release with new features\""
|
||||
echo ""
|
||||
echo "Default Mode (patch increment):"
|
||||
echo " - Increment patch version (v1.2.3 → v1.2.4)"
|
||||
echo " - Git add, commit with message, and push"
|
||||
echo ""
|
||||
echo "Release Mode (-r flag):"
|
||||
echo " - Increment minor version, zero patch (v1.2.3 → v1.3.0)"
|
||||
echo " - Git add, commit, push, and create Gitea release"
|
||||
echo ""
|
||||
echo "Requirements for Release Mode:"
|
||||
echo " - Gitea token in ~/.gitea_token for release uploads"
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-r|--release)
|
||||
RELEASE_MODE=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# First non-flag argument is the commit message
|
||||
if [[ -z "$COMMIT_MESSAGE" ]]; then
|
||||
COMMIT_MESSAGE="$1"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate inputs
|
||||
if [[ -z "$COMMIT_MESSAGE" ]]; then
|
||||
print_error "Commit message is required"
|
||||
echo ""
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we're in a git repository
|
||||
check_git_repo() {
|
||||
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
print_error "Not in a git repository"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to get current version and increment appropriately
|
||||
increment_version() {
|
||||
local increment_type="$1" # "patch" or "minor"
|
||||
|
||||
print_status "Getting current version..."
|
||||
|
||||
# Get the highest version tag (not chronologically latest)
|
||||
LATEST_TAG=$(git tag -l 'v*.*.*' | sort -V | tail -n 1 || echo "")
|
||||
if [[ -z "$LATEST_TAG" ]]; then
|
||||
LATEST_TAG="v0.0.0"
|
||||
print_warning "No version tags found, starting from $LATEST_TAG"
|
||||
fi
|
||||
|
||||
# Extract version components (remove 'v' prefix)
|
||||
VERSION=${LATEST_TAG#v}
|
||||
|
||||
# Parse major.minor.patch using regex
|
||||
if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
MAJOR=${BASH_REMATCH[1]}
|
||||
MINOR=${BASH_REMATCH[2]}
|
||||
PATCH=${BASH_REMATCH[3]}
|
||||
else
|
||||
print_error "Invalid version format in tag: $LATEST_TAG"
|
||||
print_error "Expected format: v0.1.0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Increment version based on type
|
||||
if [[ "$increment_type" == "minor" ]]; then
|
||||
# Minor release: increment minor, zero patch
|
||||
NEW_MINOR=$((MINOR + 1))
|
||||
NEW_PATCH=0
|
||||
NEW_VERSION="v${MAJOR}.${NEW_MINOR}.${NEW_PATCH}"
|
||||
print_status "Release mode: incrementing minor version"
|
||||
else
|
||||
# Default: increment patch
|
||||
NEW_PATCH=$((PATCH + 1))
|
||||
NEW_VERSION="v${MAJOR}.${MINOR}.${NEW_PATCH}"
|
||||
print_status "Default mode: incrementing patch version"
|
||||
fi
|
||||
|
||||
print_status "Current version: $LATEST_TAG"
|
||||
print_status "New version: $NEW_VERSION"
|
||||
|
||||
# Export for use in other functions
|
||||
export NEW_VERSION
|
||||
}
|
||||
|
||||
# Function to commit and push changes
|
||||
git_commit_and_push() {
|
||||
print_status "Preparing git commit..."
|
||||
|
||||
# Stage all changes
|
||||
if git add . > /dev/null 2>&1; then
|
||||
print_success "Staged all changes"
|
||||
else
|
||||
print_error "Failed to stage changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if there are changes to commit
|
||||
if git diff --staged --quiet; then
|
||||
print_warning "No changes to commit"
|
||||
else
|
||||
# Commit changes
|
||||
if git commit -m "$NEW_VERSION - $COMMIT_MESSAGE" > /dev/null 2>&1; then
|
||||
print_success "Committed changes"
|
||||
else
|
||||
print_error "Failed to commit changes"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create new git tag
|
||||
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Created tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag $NEW_VERSION already exists"
|
||||
fi
|
||||
|
||||
# Push changes and tags
|
||||
print_status "Pushing to remote repository..."
|
||||
if git push > /dev/null 2>&1; then
|
||||
print_success "Pushed changes"
|
||||
else
|
||||
print_error "Failed to push changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Push only the new tag to avoid conflicts with existing tags
|
||||
if git push origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Pushed tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag push failed, trying force push..."
|
||||
if git push --force origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Force-pushed updated tag: $NEW_VERSION"
|
||||
else
|
||||
print_error "Failed to push tag: $NEW_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to commit and push changes without creating a tag (tag already created)
|
||||
git_commit_and_push_no_tag() {
|
||||
print_status "Preparing git commit..."
|
||||
|
||||
# Stage all changes
|
||||
if git add . > /dev/null 2>&1; then
|
||||
print_success "Staged all changes"
|
||||
else
|
||||
print_error "Failed to stage changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if there are changes to commit
|
||||
if git diff --staged --quiet; then
|
||||
print_warning "No changes to commit"
|
||||
else
|
||||
# Commit changes
|
||||
if git commit -m "$NEW_VERSION - $COMMIT_MESSAGE" > /dev/null 2>&1; then
|
||||
print_success "Committed changes"
|
||||
else
|
||||
print_error "Failed to commit changes"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Push changes and tags
|
||||
print_status "Pushing to remote repository..."
|
||||
if git push > /dev/null 2>&1; then
|
||||
print_success "Pushed changes"
|
||||
else
|
||||
print_error "Failed to push changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Push only the new tag to avoid conflicts with existing tags
|
||||
if git push origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Pushed tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag push failed, trying force push..."
|
||||
if git push --force origin "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Force-pushed updated tag: $NEW_VERSION"
|
||||
else
|
||||
print_error "Failed to push tag: $NEW_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to create Gitea release
|
||||
create_gitea_release() {
|
||||
print_status "Creating Gitea release..."
|
||||
|
||||
# Check for Gitea token
|
||||
if [[ ! -f "$HOME/.gitea_token" ]]; then
|
||||
print_warning "No ~/.gitea_token found. Skipping release creation."
|
||||
print_warning "Create ~/.gitea_token with your Gitea access token to enable releases."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
|
||||
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/c-relay"
|
||||
|
||||
# Create release
|
||||
print_status "Creating release $NEW_VERSION..."
|
||||
local response=$(curl -s -X POST "$api_url/releases" \
|
||||
-H "Authorization: token $token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\": \"$NEW_VERSION\", \"name\": \"$NEW_VERSION\", \"body\": \"$COMMIT_MESSAGE\"}")
|
||||
|
||||
if echo "$response" | grep -q '"id"'; then
|
||||
print_success "Created release $NEW_VERSION"
|
||||
return 0
|
||||
elif echo "$response" | grep -q "already exists"; then
|
||||
print_warning "Release $NEW_VERSION already exists"
|
||||
return 0
|
||||
else
|
||||
print_error "Failed to create release $NEW_VERSION"
|
||||
print_error "Response: $response"
|
||||
|
||||
# Try to check if the release exists anyway
|
||||
print_status "Checking if release exists..."
|
||||
local check_response=$(curl -s -H "Authorization: token $token" "$api_url/releases/tags/$NEW_VERSION")
|
||||
if echo "$check_response" | grep -q '"id"'; then
|
||||
print_warning "Release exists but creation response was unexpected"
|
||||
return 0
|
||||
else
|
||||
print_error "Release does not exist and creation failed"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_status "C-Relay Increment and Push Script"
|
||||
|
||||
# Check prerequisites
|
||||
check_git_repo
|
||||
|
||||
if [[ "$RELEASE_MODE" == true ]]; then
|
||||
print_status "=== RELEASE MODE ==="
|
||||
|
||||
# Increment minor version for releases
|
||||
increment_version "minor"
|
||||
|
||||
# Create new git tag BEFORE compilation so version.h picks it up
|
||||
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Created tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag $NEW_VERSION already exists, removing and recreating..."
|
||||
git tag -d "$NEW_VERSION" > /dev/null 2>&1
|
||||
git tag "$NEW_VERSION" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Commit and push (but skip tag creation since we already did it)
|
||||
git_commit_and_push_no_tag
|
||||
|
||||
# Create Gitea release
|
||||
if create_gitea_release; then
|
||||
print_success "Release $NEW_VERSION completed successfully!"
|
||||
else
|
||||
print_error "Release creation failed"
|
||||
fi
|
||||
|
||||
else
|
||||
print_status "=== DEFAULT MODE ==="
|
||||
|
||||
# Increment patch version for regular commits
|
||||
increment_version "patch"
|
||||
|
||||
# Create new git tag BEFORE compilation so version.h picks it up
|
||||
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
|
||||
print_success "Created tag: $NEW_VERSION"
|
||||
else
|
||||
print_warning "Tag $NEW_VERSION already exists, removing and recreating..."
|
||||
git tag -d "$NEW_VERSION" > /dev/null 2>&1
|
||||
git tag "$NEW_VERSION" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Commit and push (but skip tag creation since we already did it)
|
||||
git_commit_and_push_no_tag
|
||||
|
||||
print_success "Increment and push completed successfully!"
|
||||
print_status "Version $NEW_VERSION pushed to repository"
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute main function
|
||||
main
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user