Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
129 changes: 129 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
# Repo-wide clang-format config for STAR.
#
# Used as a default for trees that don't ship their own .clang-format —
# notably firmware/ (no nested .clang-format anywhere under it).
# daq-server/ has its own at daq-server/.clang-format (ColumnLimit: 100),
# which takes precedence for any file inside daq-server/ because
# clang-format walks up from each file and uses the nearest config.
#
# This config matches daq-server/.clang-format on every rule EXCEPT
# ColumnLimit (80 here, 100 there). Keep the two in sync on everything
# else when one is updated.

Language: Cpp
BasedOnStyle: Google

# Indentation
IndentWidth: 4
TabWidth: 4
UseTab: Never
ContinuationIndentWidth: 4

# Line length — 80 per team request
ColumnLimit: 80

# Braces
BreakBeforeBraces: Attach
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false

# Spacing
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpacesInParentheses: false
SpacesInSquareBrackets: false

# Alignment
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: true
AlignTrailingComments: true

# Includes
IncludeBlocks: Regroup
SortIncludes: true
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3

# Function formatting
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortBlocksOnASingleLine: false

# Pointer alignment
PointerAlignment: Left

# Reference alignment
ReferenceAlignment: Left

# Penalties for breaking
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200

# Line breaking
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true

# Namespace formatting
NamespaceIndentation: None
FixNamespaceComments: true

# Keep format for specific constructs
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1

# Constructor initializers
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4

# Access modifiers
AccessModifierOffset: -4

# Comment formatting
ReflowComments: true

# Macro formatting
IndentPPDirectives: None

# Lambda formatting
AllowShortLambdasOnASingleLine: None

# Template formatting
AlwaysBreakTemplateDeclarations: Yes
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
name: CI/CD Pipeline
name: DAQ Server CI/CD

# Quoted `on` — YAML 1.1 treats bare `on` as boolean true, which breaks workflow triggers in some parsers.
'on': [push, pull_request, workflow_dispatch]
'on':
push:
paths:
- 'daq-server/**'
- '.github/workflows/daq-server-ci.yml'
pull_request:
paths:
- 'daq-server/**'
- '.github/workflows/daq-server-ci.yml'
workflow_dispatch:

defaults:
run:
working-directory: daq-server

env:
BUILD_DIR: build
Expand All @@ -18,16 +31,44 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Install clang-format
run: |
# Install clang-format from the official LLVM apt repo so CI matches modern
# macOS/Linux dev environments. Ubuntu's default `clang-format` package is
# v18; designated-initializer formatting changed between v18 and v19, which
# produced false-positive format failures on code that's clean on developer
# laptops. Pinning to 19 keeps CI and local in sync.
#
# We use a /usr/local/bin/ symlink (not update-alternatives) because
# update-alternatives priorities can get out-shouted by Ubuntu's stock
# clang-format package. /usr/local/bin/ comes before /usr/bin/ on the
# default $PATH, so the symlink wins unconditionally.
- name: Install clang-format 19 (LLVM apt repo)
run: |
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc > /dev/null
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-19 main" | sudo tee /etc/apt/sources.list.d/llvm.list
sudo apt-get update
sudo apt-get install -y clang-format-17 || sudo apt-get install -y clang-format
sudo apt-get install -y clang-format-19
sudo ln -sf /usr/bin/clang-format-19 /usr/local/bin/clang-format
# Verify: this should print "Ubuntu clang-format version 19.x.x"
clang-format --version
which clang-format

# format.sh also runs `black --check` on Python under firmware/.
# --user avoids PEP 668 ("externally-managed-environment") on Ubuntu 22.04+.
#
# Pinned to 25.11.0 because: developer laptops with system Python 3.9 (macOS
# default) can't install black 26.x (requires Python ≥3.10). Pinning here
# keeps CI in sync with laptops until everyone has a newer Python.
- name: Install black
run: |
pip install --user black==25.11.0
echo "$HOME/.local/bin" >> $GITHUB_PATH

- name: Check code formatting
working-directory: .
run: |
chmod +x ./scripts/format.sh
if ! ./scripts/format.sh --check; then
echo "::error::Code formatting check failed. Run './scripts/format.sh' to fix."
chmod +x ./format.sh
if ! ./format.sh --check; then
echo "::error::Code formatting check failed. Run './format.sh' from the repo root to fix."
exit 1
fi
continue-on-error: false
Expand All @@ -46,23 +87,23 @@ jobs:
with:
node-version: '20.x'
cache: 'npm'
cache-dependency-path: diablo_server/frontend/package-lock.json
cache-dependency-path: daq-server/diablo_server/frontend/package-lock.json

# API routes import ../backend/src/* which uses @iarna/toml; install backend so resolution + alias work in next build.
- name: Install backend dependencies
working-directory: diablo_server/backend
working-directory: daq-server/diablo_server/backend
run: npm ci || npm install

- name: Install frontend dependencies
working-directory: diablo_server/frontend
working-directory: daq-server/diablo_server/frontend
run: npm ci || npm install

- name: Run frontend unit tests
working-directory: diablo_server/frontend
working-directory: daq-server/diablo_server/frontend
run: npm run test

- name: Verify Next.js build
working-directory: diablo_server/frontend
working-directory: daq-server/diablo_server/frontend
run: npm run test:build

# Build with multiple compilers (Release only)
Expand Down Expand Up @@ -116,7 +157,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.ccache
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ hashFiles('CMakeLists.txt', 'diablo_server/CMakeLists.txt', 'archive/legacy/utl/**/*.cpp', 'archive/legacy/utl/**/*.hpp', 'diablo_server/**/*.cpp', 'diablo_server/**/*.hpp') }}
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ hashFiles('daq-server/CMakeLists.txt', 'daq-server/diablo_server/CMakeLists.txt', 'daq-server/archive/legacy/utl/**/*.cpp', 'daq-server/archive/legacy/utl/**/*.hpp', 'daq-server/diablo_server/**/*.cpp', 'daq-server/diablo_server/**/*.hpp') }}
restore-keys: |
${{ runner.os }}-ccache-${{ matrix.compiler }}-

Expand Down Expand Up @@ -165,9 +206,9 @@ jobs:
with:
name: build-artifacts-${{ matrix.compiler }}-Release
path: |
${{ env.BUILD_DIR }}/lib/*.so
${{ env.BUILD_DIR }}/bin/daq_bridge
${{ env.BUILD_DIR }}/bin/sequencer_service
daq-server/${{ env.BUILD_DIR }}/lib/*.so
daq-server/${{ env.BUILD_DIR }}/bin/daq_bridge
daq-server/${{ env.BUILD_DIR }}/bin/sequencer_service
retention-days: 7

# Static analysis
Expand Down Expand Up @@ -210,7 +251,7 @@ jobs:
if: always()
with:
name: cppcheck-report
path: cppcheck-report.xml
path: daq-server/cppcheck-report.xml

- name: Run clang-tidy
run: |
Expand Down Expand Up @@ -306,7 +347,7 @@ jobs:
if: always()
with:
name: semgrep-report
path: semgrep-report.json
path: daq-server/semgrep-report.json

- name: Check for hardcoded secrets
run: |
Expand Down Expand Up @@ -535,10 +576,10 @@ jobs:
with:
node-version: '20.x'
cache: 'npm'
cache-dependency-path: diablo_server/frontend/package-lock.json
cache-dependency-path: daq-server/diablo_server/frontend/package-lock.json

- name: Install backend dependencies
run: cd diablo_server/backend && npm ci || npm install
run: cd diablo_server/backend && (npm ci || npm install)

- name: Install frontend dependencies and Playwright Chromium (system libs + browser)
run: |
Expand Down Expand Up @@ -573,7 +614,11 @@ jobs:
if: always()

steps:
# Override the workflow-level `defaults.run.working-directory: daq-server`.
# This job has no checkout step, so that directory doesn't exist on the
# runner — bash would fail to start with "No such file or directory".
- name: Check build status
working-directory: .
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "daq-server/external/uWebSockets"]
path = daq-server/external/uWebSockets
url = https://github.com/uNetworking/uWebSockets.git
21 changes: 0 additions & 21 deletions daq-server/.cursor/rules/submodules.mdc

This file was deleted.

2 changes: 1 addition & 1 deletion daq-server/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ repos:
hooks:
- id: check-formatting
name: Check code formatting
entry: bash -c './format.sh --check || exit 1'
entry: bash -c '"$(git rev-parse --show-toplevel)"/format.sh --check || exit 1'
language: system
files: \.(cpp|hpp|c|h)$
pass_filenames: false
Expand Down
24 changes: 16 additions & 8 deletions daq-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ All runtime config lives in `config/config.toml`. Key sections:
- `[calibration]` — Calibration service parameters

State machine transitions and actuator positions per state are defined in:
- `external/DiabloAvionics/test_guis/state_transitions.csv`
- `external/DiabloAvionics/test_guis/state_machine_actuators.csv`
- `firmware/test_guis/state_transitions.csv`
- `firmware/test_guis/state_machine_actuators.csv`

---

Expand Down Expand Up @@ -203,16 +203,24 @@ For production systemd services, see `deploy/systemd/`. The working directory fo

---

## Submodules
## External dependencies

Most code that used to live in external repos is now vendored in-tree:

| Path | Purpose |
|------|---------|
| `lib/DAQv2-Comms/` | ESP32 Ethernet packet format (CMake: `daqv2_comms`) |
| `firmware/` (PT_Board, RTD_Board, LC_Board, test_guis, …) | Board firmware + state machine CSV definitions (formerly `DiabloAvionics`) |
| `EngineDesign/` | Engine simulator (formerly `engine_sim` submodule; `daq-server/engine_sim` is a symlink to it) |

The one remaining real submodule:

| Submodule | Purpose |
|-----------|---------|
| `external/DAQv2-Comms` | ESP32 Ethernet packet format (CMake: `daqv2_comms`) |
| `external/DiabloAvionics` | Board firmware + state machine CSV definitions |
| `external/uWebSockets` | C++ WebSocket library used by OTA service |
| `daq-server/external/uWebSockets` | C++ WebSocket library used by OTA service |

Update all submodules:
Initialize / update:

```bash
git submodule update --remote --recursive
git submodule update --init --recursive
```
Loading
Loading