Skip to content

Commit a5792a1

Browse files
committed
Initial commit
0 parents  commit a5792a1

282 files changed

Lines changed: 115718 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cargo/config.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Build acceleration: sccache compiler cache + mold linker.
2+
# Requires `mold` and `sccache` on PATH (e.g. `pacman -S mold sccache`).
3+
# Bypass per-build with `CARGO_BUILD_RUSTC_WRAPPER= cargo …` (skip sccache)
4+
# or `RUSTFLAGS= cargo …` (skip mold); see AGENTS.md "Build acceleration".
5+
[build]
6+
rustc-wrapper = "sccache"
7+
8+
[target.x86_64-unknown-linux-gnu]
9+
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

.github/workflows/ci.yml

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
# SPDX-FileCopyrightText: 2026 VisorCraft LLC
2+
# SPDX-License-Identifier: GPL-3.0-only
3+
#
4+
# Per-job CI layout. Each gate runs in its own runner
5+
# so failures pinpoint quickly and the build job (which needs Arch's
6+
# fresher Kirigami) doesn't block the faster checks. Workflow-level
7+
# interpolations are limited to `env:` values, which are safe against
8+
# shell injection from PR titles, branch names, or commit messages.
9+
10+
name: ci
11+
12+
on:
13+
push:
14+
branches: [master]
15+
pull_request:
16+
branches: [master]
17+
18+
env:
19+
CARGO_TERM_COLOR: always
20+
RUST_BACKTRACE: 1
21+
# cxx-qt's build script picks Qt up via qmake6 on $PATH.
22+
QMAKE: /usr/bin/qmake6
23+
24+
jobs:
25+
fmt:
26+
name: rustfmt
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v6
30+
- uses: dtolnay/rust-toolchain@stable
31+
with:
32+
components: rustfmt
33+
- run: cargo fmt --all -- --check
34+
35+
lint:
36+
name: clippy
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v6
40+
- name: Install Qt 6 + C++ toolchain + mold/sccache
41+
run: |
42+
sudo apt-get update
43+
sudo apt-get install -y --no-install-recommends \
44+
qt6-base-dev \
45+
qt6-declarative-dev \
46+
qt6-tools-dev \
47+
libgl1-mesa-dev \
48+
clang \
49+
mold \
50+
sccache \
51+
ninja-build
52+
- uses: dtolnay/rust-toolchain@stable
53+
with:
54+
components: clippy
55+
- uses: Swatinem/rust-cache@v2
56+
- run: cargo clippy --workspace --all-targets -- -D warnings
57+
58+
test:
59+
name: test (stable)
60+
runs-on: ubuntu-latest
61+
steps:
62+
- uses: actions/checkout@v6
63+
- name: Install Qt 6 + runtime + C++ toolchain + mold/sccache
64+
run: |
65+
sudo apt-get update
66+
sudo apt-get install -y --no-install-recommends \
67+
qt6-base-dev \
68+
qt6-declarative-dev \
69+
qt6-tools-dev \
70+
libgl1-mesa-dev \
71+
clang \
72+
mold \
73+
sccache \
74+
ninja-build
75+
- uses: dtolnay/rust-toolchain@stable
76+
- uses: Swatinem/rust-cache@v2
77+
- run: cargo test --workspace
78+
env:
79+
# The Landlock/seccomp enforcement tests assert kernel behavior that
80+
# shared GitHub runners (and some dev/CI shells) do not reliably provide:
81+
# Landlock reports ABI >= 1 (detection succeeds), but the fs read
82+
# restriction can be a no-op (e.g. namespaces, container policy).
83+
# `cat_denied_outside_allowed_path` would flake. Per the contract in
84+
# crates/linsync-sandbox/tests/sandbox_integration.rs (and Justfile
85+
# test recipe), the standard CI job + `just ci`/`just test` run with
86+
# LINSYNC_SANDBOX_SKIP=1. Real enforcement is exercised on a good
87+
# kernel+env by: env -u LINSYNC_SANDBOX_SKIP cargo test -p linsync-sandbox --test sandbox_integration
88+
LINSYNC_SANDBOX_SKIP: "1"
89+
90+
sandbox-stress:
91+
name: sandbox enforcement (best-effort)
92+
runs-on: ubuntu-latest
93+
continue-on-error: true
94+
# This job does not install mold/sccache; disable the workspace's
95+
# forced wrapper/linker settings so the stock ubuntu-latest toolchain
96+
# can compile and run the sandbox integration tests.
97+
env:
98+
CARGO_BUILD_RUSTC_WRAPPER: ""
99+
RUSTFLAGS: ""
100+
steps:
101+
- uses: actions/checkout@v6
102+
- uses: dtolnay/rust-toolchain@stable
103+
- uses: Swatinem/rust-cache@v2
104+
- run: cargo test -p linsync-sandbox --test sandbox_integration
105+
106+
build:
107+
name: build + smoke GUI (Arch)
108+
runs-on: ubuntu-latest
109+
container:
110+
image: archlinux:base-devel
111+
steps:
112+
- name: Install Arch Qt 6 + Kirigami dependencies
113+
run: |
114+
pacman -Sy --noconfirm --needed archlinux-keyring
115+
pacman -Syu --noconfirm --needed \
116+
git \
117+
curl \
118+
ca-certificates \
119+
pkgconf \
120+
qt6-base \
121+
qt6-declarative \
122+
qt6-tools \
123+
kirigami \
124+
clang \
125+
mold \
126+
sccache \
127+
ninja \
128+
mesa
129+
- uses: actions/checkout@v6
130+
- uses: dtolnay/rust-toolchain@stable
131+
- uses: Swatinem/rust-cache@v2
132+
- name: Build GUI binary (cxx-qt in-process host)
133+
env:
134+
QT_VERSION_MAJOR: "6"
135+
run: |
136+
cargo build -p linsync --release \
137+
--features 'linsync/cxxqt linsync/cxxqt-app'
138+
- name: GUI smoke (external QML host)
139+
env:
140+
QT_QPA_PLATFORM: offscreen
141+
run: bash scripts/gui-smoke.sh
142+
- name: GUI smoke (in-process cxx-qt host)
143+
env:
144+
QT_QPA_PLATFORM: offscreen
145+
run: LINSYNC_GUI_SMOKE_CXXQT=1 bash scripts/gui-smoke.sh
146+
147+
screenshots:
148+
name: GUI screenshots
149+
runs-on: ubuntu-latest
150+
container:
151+
image: archlinux:base-devel
152+
needs: build
153+
env:
154+
QT_QPA_PLATFORM: offscreen
155+
steps:
156+
- name: Install Arch Qt 6 + Kirigami + screenshot dependencies
157+
run: |
158+
pacman -Sy --noconfirm --needed archlinux-keyring
159+
pacman -Syu --noconfirm --needed \
160+
git \
161+
curl \
162+
ca-certificates \
163+
pkgconf \
164+
qt6-base \
165+
qt6-declarative \
166+
qt6-tools \
167+
kirigami \
168+
clang \
169+
mold \
170+
sccache \
171+
ninja \
172+
mesa \
173+
xorg-server-xvfb \
174+
imagemagick
175+
- uses: actions/checkout@v6
176+
- uses: dtolnay/rust-toolchain@stable
177+
- uses: Swatinem/rust-cache@v2
178+
- name: Build GUI binary
179+
env:
180+
QT_VERSION_MAJOR: "6"
181+
run: |
182+
cargo build -p linsync --release \
183+
--features 'linsync/cxxqt linsync/cxxqt-app'
184+
- name: Capture screenshots
185+
env:
186+
LINSYNC_BIN: target/release/linsync
187+
STARTUP_SLEEP: "6"
188+
run: bash scripts/gui-screenshot.sh
189+
- name: Upload screenshots
190+
if: always()
191+
uses: actions/upload-artifact@v7
192+
with:
193+
name: linsync-screenshots-${{ github.sha }}
194+
path: target/screenshots/*.png
195+
196+
a11y-check:
197+
name: accessibility label grep
198+
runs-on: ubuntu-latest
199+
steps:
200+
- uses: actions/checkout@v6
201+
- name: Check every Button/Switch/SpinBox/ComboBox/TextField has a label
202+
run: bash scripts/gui-smoke.sh --check-a11y
203+
204+
docs-drift-check:
205+
name: docs drift check (advisory)
206+
runs-on: ubuntu-latest
207+
if: github.event_name == 'pull_request'
208+
steps:
209+
- uses: actions/checkout@v6
210+
with:
211+
fetch-depth: 0
212+
- name: Check for feature-matrix / known-limitations drift
213+
env:
214+
GITHUB_BASE_REF: ${{ github.base_ref }}
215+
PR_TITLE: ${{ github.event.pull_request.title }}
216+
run: bash scripts/check-docs-drift.sh
217+
218+
deny:
219+
name: cargo-deny
220+
runs-on: ubuntu-latest
221+
# cargo-deny-action installs its own musl toolchain. Disable the
222+
# workspace's sccache wrapping (force = true in .cargo/config.toml)
223+
# for this job — the wrapper isn't available on the action's
224+
# toolchain path. RUSTFLAGS is similarly cleared so mold isn't a
225+
# hard requirement.
226+
env:
227+
CARGO_BUILD_RUSTC_WRAPPER: ""
228+
RUSTFLAGS: ""
229+
CC: cc
230+
CXX: c++
231+
steps:
232+
- uses: actions/checkout@v6
233+
- uses: dtolnay/rust-toolchain@stable
234+
- uses: EmbarkStudios/cargo-deny-action@v2
235+
236+
audit:
237+
name: cargo-audit
238+
runs-on: ubuntu-latest
239+
steps:
240+
- uses: actions/checkout@v6
241+
- uses: dtolnay/rust-toolchain@stable
242+
- name: Install cargo-audit
243+
run: cargo install cargo-audit --locked
244+
- run: cargo audit
245+
246+
appstream-validate:
247+
name: appstream metadata
248+
runs-on: ubuntu-latest
249+
steps:
250+
- uses: actions/checkout@v6
251+
- run: sudo apt-get update && sudo apt-get install -y appstream
252+
- run: appstreamcli validate --no-net packaging/com.visorcraft.LinSync.metainfo.xml
253+
254+
desktop-validate:
255+
name: desktop file
256+
runs-on: ubuntu-latest
257+
steps:
258+
- uses: actions/checkout@v6
259+
- run: sudo apt-get update && sudo apt-get install -y desktop-file-utils
260+
- run: desktop-file-validate packaging/com.visorcraft.LinSync.desktop
261+
262+
# NOTE: Flatpak CI is currently disabled.
263+
# bilelmoussaoui/flatpak-github-actions only publishes kde-5.15 tags
264+
# (verified 2026-05-26); there's no KDE 6 base image. The Flatpak
265+
# manifest pins org.kde.Platform//6.10 at *runtime* but the CI host
266+
# needs a matching base. To re-enable, either:
267+
# 1. Set up flatpak-builder on a stock ubuntu-latest runner with
268+
# apt-get install flatpak flatpak-builder and `flatpak install`
269+
# org.kde.Platform//6.10 from flathub, OR
270+
# 2. Use a published flatpak-builder image that has KDE 6 SDK.
271+
# Local builds via `just flatpak-bundle` continue to work for now.

0 commit comments

Comments
 (0)