Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2419d5e
refactor: harden build provenance and releases
bashrusakh Aug 12, 2026
9b6cd40
fix(workflow): harden ruleset and build cleanup checks
bashrusakh Aug 13, 2026
f01b2d7
fix(custom-build): close zip traversal path
bashrusakh Aug 13, 2026
ebcdc22
fix(workflow): provide sqlx schema for rust ci
bashrusakh Aug 14, 2026
66bdd00
fix(custom-build): make zip path validation codeql-visible
bashrusakh Aug 14, 2026
642f36a
workflow: harden GitHub protection contract
bashrusakh Aug 14, 2026
3067576
docs: record corrective PR publication evidence
bashrusakh Aug 14, 2026
68e7f30
workflow: harden ruleset failure handling
bashrusakh Aug 14, 2026
4aea8a6
docs: record ruleset review evidence
bashrusakh Aug 14, 2026
1900160
workflow: align ruleset validation with repository responses
bashrusakh Aug 14, 2026
cd11aa3
ui: clarify custom endpoint ports
bashrusakh Aug 14, 2026
9cad830
test: cover legacy tag list contract
bashrusakh Aug 14, 2026
64e3202
api: remove obsolete tag protection fallback
bashrusakh Aug 14, 2026
8e14259
Merge remote-tracking branch 'origin/main' into refactor/deskforge-co…
bashrusakh Aug 15, 2026
6525071
workflow: pin CI toolchains and build image
bashrusakh Aug 15, 2026
460b424
workflow: rename client workflow contract
bashrusakh Aug 15, 2026
fa0b9c3
docs: record workflow migration status
bashrusakh Aug 15, 2026
f6494a0
docs: record workflow ruleset status
bashrusakh Aug 15, 2026
1bc2179
docs: finalize workflow migration records
bashrusakh Aug 16, 2026
b772153
docs: close workflow migration checklist
bashrusakh Aug 16, 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
29 changes: 17 additions & 12 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
# Delay before checking bandwidth downgrade (seconds)
#DOWNGRADE_START_CHECK=1800

# Relay server port
#HBBS_PORT=21117
# Relay server port (hbbr)
#HBBR_PORT=21117

# ============================
# HBBS (Rendezvous / Signal Server)
Expand Down Expand Up @@ -85,7 +85,7 @@
# Gin mode (release/debug/test)
#RUSTDESK_API_GIN_MODE=release

# Language for API responses (en, ru, fr, es, ko)
# Language for API responses (en, ru, zh-CN)
#RUSTDESK_API_LANG=en

# Enable web client (1=on, 0=off)
Expand Down Expand Up @@ -120,16 +120,16 @@
#RUSTDESK_API_POSTGRESQL_DBNAME=postgres
#RUSTDESK_API_POSTGRESQL_SSLMODE=disable

# RustDesk server addresses (announced to clients)
# RustDesk server endpoints (announced to clients; keep explicit ports where required)
#RUSTDESK_API_RUSTDESK_ID_SERVER=
#RUSTDESK_API_RUSTDESK_RELAY_SERVER=
#RUSTDESK_API_RUSTDESK_API_SERVER=
#RUSTDESK_API_RUSTDESK_WS_HOST=

# Path to the public key file (generated by hbbs on first run)
# Current public-key file contract: use the file generated by hbbs on first run.
#RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub

# Encryption key (same as HBBS KEY)
# Legacy raw key compatibility only; new deployments must use RUSTDESK_API_KEY_FILE.
#RUSTDESK_API_RUSTDESK_KEY=

# Enable personal API (1=on, 0=off)
Expand All @@ -152,7 +152,7 @@
#RUSTDESK_API_REDIS_ADDR=
#RUSTDESK_API_REDIS_PASSWORD=

# Cache type (memory/redis)
# Cache type (memory/file/redis)
#RUSTDESK_API_CACHE_TYPE=memory

# Proxy for outgoing connections (OAuth etc.)
Expand All @@ -163,15 +163,20 @@
# Custom Client Builder
# ============================

# Build agents use shared Docker volumes for job tickets.
# Build output is written to rdgen-data:/output/{build_id}/
# No additional env vars are required for basic operation.
# Manual/historical file-queue material only (not the current provider-dispatch
# build path): old agents used the shared Docker volume for job tickets and wrote
# output below rdgen-data:/output/{build_id}/. No additional env vars are required
# for the current provider-backed operation.

# Secret encryption key for data at rest (BUGS.md B-008).
# Encrypts the GitHub PAT, the workflow PayloadKey and permanent_password
# (stored inside custom_json) in the database with AES-256-GCM.
# Read directly from the environment (NOT via the RUSTDESK_API_ prefix).
# Use a long random value; keep it stable (rotating it makes existing
# encrypted rows unreadable). If unset, secrets are stored in plaintext.
# Use a long random value.
# Existing ciphertext requires the same key; key rotation is unsupported.
# Legacy plaintext rows remain readable; saving them again encrypts them when
# the key exists. If unset, new non-empty
# secret writes and secret-bearing Custom Builder operations are rejected rather
# than stored as plaintext.
# Must NOT reuse WORKFLOW_PAYLOAD_KEY (that one is shared with GitHub).
#SECRET_ENCRYPTION_KEY=
133 changes: 133 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Build

on:
push:
branches: [main]
paths:
- "api/**"
- "admin-ui/**"
- "server/**"
- "libs/**"
- "go.mod"
- "go.work"
- "go.work.sum"
- "docker/**"
- ".dockerignore"
- "Dockerfile"
- "docker-compose.yml"
- "docker-compose.yaml"
- "compose.yml"
- "compose.yaml"
- ".github/workflows/**"
pull_request:
paths:
- "api/**"
- "admin-ui/**"
- "server/**"
- "libs/**"
- "go.mod"
- "go.work"
- "go.work.sum"
- "docker/**"
- ".dockerignore"
- "Dockerfile"
- "docker-compose.yml"
- "docker-compose.yaml"
- "compose.yml"
- "compose.yaml"
- ".github/workflows/**"
workflow_dispatch:

permissions:
contents: read

jobs:
go:
name: Go checks
runs-on: ubuntu-24.04
defaults:
run:
working-directory: api
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: api/go.mod
cache: true
cache-dependency-path: |
api/go.sum
go.work.sum
- run: go test ./...
- run: go vet ./...
- run: go build -o /tmp/deskforge-apimain ./cmd/apimain.go

admin-ui:
name: Admin UI build
runs-on: ubuntu-24.04
defaults:
run:
working-directory: admin-ui
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 20
- run: npm ci
- run: npm run build

rust:
name: Rust checks
runs-on: ubuntu-24.04
env:
DATABASE_URL: sqlite:///tmp/deskforge-sqlx.sqlite3
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- run: rustup toolchain install 1.92.0 --profile minimal --component rustfmt
- run: cargo +1.92.0 fmt --all -- --check
working-directory: server
- run: cargo +1.92.0 fmt --all -- --check
working-directory: libs/hbb_common
- name: Prepare SQLx SQLite schema
run: |
python3 - <<'PY'
import sqlite3

with sqlite3.connect("/tmp/deskforge-sqlx.sqlite3") as connection:
connection.executescript(
"""
create table if not exists peer (
guid blob primary key not null,
id varchar(100) not null,
uuid blob not null,
pk blob not null,
created_at datetime not null default(current_timestamp),
user blob,
status tinyint,
note varchar(300),
info text not null
) without rowid;
create unique index if not exists index_peer_id on peer (id);
create index if not exists index_peer_user on peer (user);
create index if not exists index_peer_created_at on peer (created_at);
create index if not exists index_peer_status on peer (status);
"""
)
- run: cargo +1.92.0 check --locked
working-directory: server
- run: cargo +1.92.0 test --locked
working-directory: server

docker:
name: Docker build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- run: docker build -f docker/Dockerfile -t deskforge:ci .
77 changes: 77 additions & 0 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Build Test

on:
workflow_dispatch:

permissions:
contents: read

jobs:
focused:
name: Focused monorepo validation
runs-on: ubuntu-24.04
env:
DATABASE_URL: sqlite:///tmp/deskforge-sqlx.sqlite3
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: api/go.mod
cache: true
cache-dependency-path: |
api/go.sum
go.work.sum
- name: Go tests and vet
working-directory: api
run: |
go test ./...
go vet ./...
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 20
- name: Admin UI build
working-directory: admin-ui
run: |
npm ci
npm run build
- run: rustup toolchain install 1.92.0 --profile minimal --component rustfmt
- name: Rust format check
working-directory: server
run: cargo +1.92.0 fmt --all -- --check
- name: Shared Rust format check
working-directory: libs/hbb_common
run: cargo +1.92.0 fmt --all -- --check
- name: Prepare SQLx SQLite schema
run: |
python3 - <<'PY'
import sqlite3

with sqlite3.connect("/tmp/deskforge-sqlx.sqlite3") as connection:
connection.executescript(
"""
create table if not exists peer (
guid blob primary key not null,
id varchar(100) not null,
uuid blob not null,
pk blob not null,
created_at datetime not null default(current_timestamp),
user blob,
status tinyint,
note varchar(300),
info text not null
) without rowid;
create unique index if not exists index_peer_id on peer (id);
create index if not exists index_peer_user on peer (user);
create index if not exists index_peer_created_at on peer (created_at);
create index if not exists index_peer_status on peer (status);
"""
)
PY
- name: Rust check
working-directory: server
run: cargo +1.92.0 check --locked
- name: Rust tests
working-directory: server
run: cargo +1.92.0 test --locked
Loading