Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c4caf31
feat: add .gitignore for packet-sender
maximka76667 Feb 18, 2026
708f327
feat: add no-sandbox fix for linux
maximka76667 Feb 18, 2026
a50bdc2
feat: some packet-sender tweaks
maximka76667 Feb 20, 2026
715edba
feat: add global boards state
maximka76667 Feb 20, 2026
8168f40
feat: increase backend resolving time
maximka76667 Feb 20, 2026
b6e9f00
fix: workflows
maximka76667 Feb 20, 2026
eb85a77
fix
maximka76667 Feb 20, 2026
47156f5
Update build.yaml
maximka76667 Feb 20, 2026
7ccfe4b
check
maximka76667 Feb 20, 2026
913fe95
Update build.yaml
maximka76667 Feb 20, 2026
322c199
fix
maximka76667 Feb 20, 2026
c55f0ac
feat: add building to frontend testing
maximka76667 Feb 21, 2026
225cbe5
feat: increase backend resolving time
maximka76667 Feb 21, 2026
6840db8
feat: include rpm and pacman distributives
maximka76667 Feb 21, 2026
4740414
fix: include dependencies and new files
maximka76667 Feb 21, 2026
33630b2
Update README.md
maximka76667 Feb 21, 2026
ee6441c
Update README.md
maximka76667 Feb 21, 2026
ef5bd72
feat: add stale boards indication
maximka76667 Feb 22, 2026
e2fc74e
feat: add backend logs window to electron
maximka76667 Feb 24, 2026
df01f6b
feat: fix menus
maximka76667 Feb 24, 2026
050b511
feat: update README.md
maximka76667 Feb 24, 2026
e4ce2d0
fix: logs path
maximka76667 Feb 24, 2026
e804e4b
feat: rename folders
maximka76667 Feb 24, 2026
8b64a88
fix: scrolling
maximka76667 Feb 24, 2026
e5bc6cc
feat: make main window reload after restart, handle better backend st…
maximka76667 Feb 26, 2026
58bff09
fix: fs import
maximka76667 Feb 26, 2026
86f0f5d
docs: update README.md
maximka76667 Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ jobs:
competition-view: ${{ steps.filter.outputs.competition-view == 'true' || github.event.inputs.rebuild-competition-view == 'true' || inputs.build-competition-view == true }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: dorny/paths-filter@v3
id: filter
with:
ref: "production"
base: ${{ github.event.before }}
filters: |
backend:
- 'backend/**/*'
Expand Down Expand Up @@ -113,7 +115,7 @@ jobs:
with:
workflow: build.yaml
branch: production
workflow_conclusion: success
workflow_conclusion: completed
name: backend-${{ matrix.platform }}
path: backend/cmd

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/frontend-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,8 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile --filter=testing-view --filter=ui --filter=core

- name: Build frontend
run: pnpm build --filter="./frontend/**"

- name: Run tests
run: pnpm test --filter="./frontend/**"
8 changes: 8 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ jobs:
echo "Updated version to:"
cat package.json | grep version

- name: Install Linux build dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y rpm libarchive-tools

# Download ONLY the appropriate backend for this platform
- name: Download Linux backend
if: runner.os == 'Linux'
Expand Down Expand Up @@ -182,6 +188,8 @@ jobs:
electron-app/dist/*.exe
electron-app/dist/*.AppImage
electron-app/dist/*.deb
electron-app/dist/*.rpm
electron-app/dist/*.pacman
electron-app/dist/*.dmg
electron-app/dist/*.zip
electron-app/dist/*.yml
Expand Down
2 changes: 1 addition & 1 deletion backend/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import (
"os"
"os/signal"

adj_module "github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/config"
"github.com/HyperloopUPV-H8/h9-backend/internal/flags"
"github.com/HyperloopUPV-H8/h9-backend/internal/pod_data"
"github.com/HyperloopUPV-H8/h9-backend/internal/update_factory"
vehicle_models "github.com/HyperloopUPV-H8/h9-backend/internal/vehicle/models"
adj_module "github.com/HyperloopUPV-H8/h9-backend/pkg/adj"
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport"
"github.com/HyperloopUPV-H8/h9-backend/pkg/websocket"
trace "github.com/rs/zerolog/log"
Expand Down
2 changes: 1 addition & 1 deletion backend/cmd/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"runtime/pprof"
"strings"

adj_module "github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/config"
"github.com/HyperloopUPV-H8/h9-backend/internal/flags"
"github.com/HyperloopUPV-H8/h9-backend/internal/pod_data"
"github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
adj_module "github.com/HyperloopUPV-H8/h9-backend/pkg/adj"
"github.com/HyperloopUPV-H8/h9-backend/pkg/logger"
data_logger "github.com/HyperloopUPV-H8/h9-backend/pkg/logger/data"
order_logger "github.com/HyperloopUPV-H8/h9-backend/pkg/logger/order"
Expand Down
2 changes: 1 addition & 1 deletion backend/cmd/setup_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import (
"net"
"time"

adj_module "github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/common"
"github.com/HyperloopUPV-H8/h9-backend/internal/config"
"github.com/HyperloopUPV-H8/h9-backend/internal/pod_data"
"github.com/HyperloopUPV-H8/h9-backend/internal/utils"
"github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
adj_module "github.com/HyperloopUPV-H8/h9-backend/pkg/adj"
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport"
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/network/tcp"
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/network/udp"
Expand Down
2 changes: 1 addition & 1 deletion backend/cmd/setup_vehicle.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import (
h "github.com/HyperloopUPV-H8/h9-backend/pkg/http"
"github.com/HyperloopUPV-H8/h9-backend/pkg/websocket"

adj_module "github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/common"
"github.com/HyperloopUPV-H8/h9-backend/internal/config"
"github.com/HyperloopUPV-H8/h9-backend/internal/pod_data"
"github.com/HyperloopUPV-H8/h9-backend/internal/update_factory"
"github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
adj_module "github.com/HyperloopUPV-H8/h9-backend/pkg/adj"
"github.com/HyperloopUPV-H8/h9-backend/pkg/broker"
connection_topic "github.com/HyperloopUPV-H8/h9-backend/pkg/broker/topics/connection"
data_topic "github.com/HyperloopUPV-H8/h9-backend/pkg/broker/topics/data"
Expand Down
2 changes: 1 addition & 1 deletion backend/internal/pod_data/measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"fmt"
"strings"

"github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/common"
"github.com/HyperloopUPV-H8/h9-backend/internal/utils"
"github.com/HyperloopUPV-H8/h9-backend/pkg/adj"
)

const EnumType = "enum"
Expand Down
2 changes: 1 addition & 1 deletion backend/internal/pod_data/pod_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package pod_data
import (
"github.com/HyperloopUPV-H8/h9-backend/internal/utils"

"github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/common"
"github.com/HyperloopUPV-H8/h9-backend/pkg/adj"
)

func NewPodData(adjBoards map[string]adj.Board, globalUnits map[string]utils.Operations) (PodData, error) {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 2 additions & 1 deletion electron-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pnpm run dist:linux # Linux
On macOS, the backend requires the loopback address `127.0.0.9` to be configured. If you encounter a "can't assign requested address" error when starting the backend, run:

```
sudo ipconfig set en0 INFORM 127.0.0.9
sudo ifconfig lo0 alias 127.0.0.9 up
```

## Available Scripts
Expand All @@ -89,6 +89,7 @@ sudo ipconfig set en0 INFORM 127.0.0.9
- `pnpm start` - Run application in development mode
- `pnpm run dist` - Build production executable
- `pnpm test` - Run tests
- `pnpm build-icons` - build icon from the icon.png file in the `/electron-app` folder
...and many custom variations (see package.json)

# Only works and makes sense after running `pnpm run dist`
Expand Down
106 changes: 46 additions & 60 deletions electron-app/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { execSync } from "child_process";
import { copyFileSync, cpSync, existsSync, mkdirSync, rmSync } from "fs";
import { cpSync, existsSync, mkdirSync, rmSync } from "fs";
import { dirname, join } from "path";
import { fileURLToPath } from "url";
import { logger } from "./src/utils/logger.js";
Expand All @@ -20,6 +20,7 @@ const CONFIG = {
type: "go",
path: join(ROOT, "backend"), // Root of backend (where package.json is)
output: join(__dirname, "binaries"),
entry: "./cmd",
commands: ["pnpm run build:ci"],
platforms: [
{
Expand Down Expand Up @@ -52,18 +53,43 @@ const CONFIG = {
},
],
},
"packet-sender": {
type: "rust",
path: join(ROOT, "packet-sender"),
output: join(__dirname, "binaries"),
commands: ["pnpm run build"],
binaryPath: "target/release/packet-sender",
platforms: [
{ id: "win64", ext: ".exe", tags: ["win", "windows"] },
{ id: "linux64", ext: "", tags: ["linux"] },
{ id: "mac64", ext: "", tags: ["mac", "macos"] },
],
},
// "packet-sender": {
// type: "go",
// path: join(ROOT, "packet-sender"),
// output: join(__dirname, "binaries"),
// entry: ".",
// commands: ["pnpm run build:ci"],
// platforms: [
// {
// id: "win64",
// goos: "windows",
// goarch: "amd64",
// ext: ".exe",
// tags: ["win", "windows"],
// },
// {
// id: "linux64",
// goos: "linux",
// goarch: "amd64",
// ext: "",
// tags: ["linux"],
// },
// {
// id: "mac64",
// goos: "darwin",
// goarch: "amd64",
// ext: "",
// tags: ["mac", "macos"],
// },
// {
// id: "macArm",
// goos: "darwin",
// goarch: "arm64",
// ext: "",
// tags: ["mac", "macos"],
// },
// ],
// },
"testing-view": {
type: "frontend",
path: join(ROOT, "frontend/testing-view"),
Expand Down Expand Up @@ -98,8 +124,8 @@ const run = (cmd, cwd, env = {}) => {
}
};

const buildBackend = (config, requestedPlatforms, extraArgs = "") => {
logger.info("Building Backend (Go)...");
const buildGo = (name, config, requestedPlatforms, extraArgs = "") => {
logger.info(`Building ${name} (Go)...`);
mkdirSync(config.output, { recursive: true });

const targets = config.platforms.filter((p) => {
Expand All @@ -112,22 +138,15 @@ const buildBackend = (config, requestedPlatforms, extraArgs = "") => {
return p.tags.some((tag) => requestedPlatforms.includes(tag));
});

if (targets.length === 0) {
logger.error(
`No matching platforms found for: ${requestedPlatforms.join(", ")}`
);
return false;
}

let success = true;
for (const p of targets) {
const filename = `backend-${p.goos}-${p.goarch}${p.ext}`;
const filename = `${name}-${p.goos}-${p.goarch}${p.ext}`;
logger.step(`Building ${p.goos}/${p.goarch}...`);

const entryPath = config.entry || ".";

for (const cmd of config.commands) {
// cmd is like "pnpm run build:ci --"
// We append the output flag and target directory
const buildCmd = `${cmd} -o "${join(config.output, filename)}" ${extraArgs} ./cmd`;
const buildCmd = `${cmd} -o "${join(config.output, filename)}" ${extraArgs} ${entryPath}`;

const result = run(buildCmd, config.path, {
GOOS: p.goos,
Expand All @@ -145,37 +164,6 @@ const buildBackend = (config, requestedPlatforms, extraArgs = "") => {
return success;
};

const buildRust = (name, config, requestedPlatforms, extraArgs = "") => {
logger.info(`Building ${name} (Rust)...`);
mkdirSync(config.output, { recursive: true });

for (const cmd of config.commands) {
// Only append extra args to build commands
const finalCmd = cmd.includes("build") ? `${cmd} ${extraArgs}` : cmd;
if (!run(finalCmd, config.path)) return false;
}

const isWin =
process.platform === "win32" ||
(requestedPlatforms && requestedPlatforms.includes("win"));
const ext = isWin ? ".exe" : "";

// Check for source binary
const sourceBin = join(config.path, config.binaryPath + ext);
const destName = `packet-sender${ext}`;
const destPath = join(config.output, destName);

logger.step(`Copying binary to ${destPath}...`);

if (existsSync(sourceBin)) {
copyFileSync(sourceBin, destPath);
return true;
} else {
logger.error(`Rust binary not found at ${sourceBin}`);
return false;
}
};

const buildFrontend = (name, config, extraArgs = "") => {
if (config.optional && !existsSync(join(config.path, "package.json"))) {
logger.warning(`Skipping ${name} (not initialized)`);
Expand Down Expand Up @@ -252,9 +240,7 @@ logger.header("Hyperloop Control Station Build");
let success = true;

if (config.type === "go") {
success = buildBackend(config, requestedPlatforms, extraArgs);
} else if (config.type === "rust") {
success = buildRust(key, config, requestedPlatforms, extraArgs);
success = buildGo(key, config, requestedPlatforms, extraArgs);
} else if (config.type === "frontend") {
success = buildFrontend(key, config, extraArgs);
if (success && !config.optional) frontendBuilt = true;
Expand Down
33 changes: 30 additions & 3 deletions electron-app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,68 @@
* Handles application lifecycle, initialization, and cleanup of processes and windows.
*/

import { app, BrowserWindow, dialog } from "electron";
import { app, BrowserWindow, dialog, screen } from "electron";
import pkg from "electron-updater";
import fs from "fs";
import { getConfigManager } from "./src/config/configInstance.js";
import { setupIpcHandlers } from "./src/ipc/handlers.js";
import { startBackend, stopBackend } from "./src/processes/backend.js";
import { stopPacketSender } from "./src/processes/packetSender.js";
import { logger } from "./src/utils/logger.js";
import { createLogWindow } from "./src/windows/logWindow.js";
import { createWindow } from "./src/windows/mainWindow.js";

const { autoUpdater } = pkg;

// Disable sandbox for Linux
if (process.platform === "linux") {
try {
const userns = fs
.readFileSync("/proc/sys/kernel/unprivileged_userns_clone", "utf8")
.trim();
if (userns === "0") {
app.commandLine.appendSwitch("no-sandbox");
}
} catch (e) {}

if (process.getuid && process.getuid() === 0) {
app.commandLine.appendSwitch("no-sandbox");
}
}

// Setup IPC handlers for renderer process communication
setupIpcHandlers();

app.setName("hyperloop-control-station");

// App lifecycle: wait for Electron to be ready
app.whenReady().then(async () => {
// Get the screen width and height
// Only can be used inside app.whenReady()
const { width: screenWidth, height: screenHeight } =
screen.getPrimaryDisplay().workAreaSize;

// Initialize ConfigManager and ensure config exists BEFORE starting backend
logger.electron.header("Initializing configuration...");
// Get ConfigManager instance (creates config from template if needed)
await getConfigManager();
logger.electron.header("Configuration ready");

const logWindow = createLogWindow(screenWidth, screenHeight);

// Start backend process
try {
await startBackend();
await startBackend(logWindow);
logger.electron.header("Backend process spawned");
} catch (error) {
// Start backend already shows these errors
return;
}

// Create main application window
createWindow();
const mainWindow = createWindow(screenWidth, screenHeight);
mainWindow.maximize();

logger.electron.header("Main application window created");

// Updater setup
Expand Down
5 changes: 4 additions & 1 deletion electron-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
},
"dependencies": {
"@iarna/toml": "^2.2.5",
"ansi-to-html": "^0.7.2",
"electron-store": "^11.0.2",
"electron-updater": "^6.7.3",
"picocolors": "^1.1.1"
Expand Down Expand Up @@ -106,7 +107,9 @@
"linux": {
"target": [
"AppImage",
"deb"
"deb",
"rpm",
"pacman"
],
"icon": "icons/512x512.png",
"category": "Utility",
Expand Down
Loading
Loading