Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
b061e52
debug(ci): log per-kill error + full ps + child SigIgn/SigCgt
Jaro-c Apr 20, 2026
d6dd1ac
chore: untrack .claude/ local config, add to .gitignore
Jaro-c Apr 20, 2026
7553e08
test: treat zombies as dead in stop regression checks
Jaro-c Apr 20, 2026
d3ce1a7
release: bump to v0.8.6
Jaro-c Apr 20, 2026
e008f3a
chore(scripts): drop unused shell wrappers
Jaro-c Apr 20, 2026
ee31dac
feat(test): testdata/apps/ catalog + end-to-end smoke.sh
Jaro-c Apr 20, 2026
aeb48da
release: bump to v0.9.0
Jaro-c Apr 20, 2026
09cfa60
fix(test): drop node: prefix in sample HTTP apps for node 12 compat
Jaro-c Apr 20, 2026
587f3a9
release: bump to v0.9.1
Jaro-c Apr 20, 2026
71dd413
feat(test): PHP + Ruby workers, wire go-compiled end-to-end
Jaro-c Apr 20, 2026
06545a1
release: bump to v0.9.2
Jaro-c Apr 20, 2026
876db0f
fix(ci): DEBIAN_FRONTEND=noninteractive for smoke apt install
Jaro-c Apr 20, 2026
ab5f4e3
release: bump to v0.9.3
Jaro-c Apr 20, 2026
fa34017
refactor: consolidate /proc parsing + tighten gracefulKill + smoke he…
Jaro-c Apr 20, 2026
e313a3b
release: bump to v0.9.4
Jaro-c Apr 20, 2026
e0ada72
fix(daemon): show disabled specs in list instead of hiding them
Jaro-c Apr 20, 2026
60cb4e9
release: bump to v0.9.5
Jaro-c Apr 20, 2026
0f6feb2
refactor(daemon): extract registerLocked + fix proc.spec read race
Jaro-c Apr 20, 2026
98fb381
release: bump to v0.9.6
Jaro-c Apr 20, 2026
840e4dc
feat(cli): show process list with highlight after start/stop/restart
Jaro-c Apr 24, 2026
ab6a91b
release: bump to v0.9.7
Jaro-c Apr 24, 2026
d33bc8f
refactor(cli): unify post-action list helper + gate highlight padding
Jaro-c Apr 24, 2026
09b980c
release: bump to v0.9.8
Jaro-c Apr 24, 2026
10ca05e
docs(site): add Astro + Starlight documentation site
Jaro-c Apr 24, 2026
5f3466e
docs(site): redesign the landing with custom hero + feature grid
Jaro-c Apr 24, 2026
ed58cae
ci(pages): switch site build from npm to bun
Jaro-c Apr 24, 2026
8726265
fix(site): mobile overflow, OG image, SEO meta, single H1
Jaro-c Apr 24, 2026
2fbe50a
deps(ci)(deps): bump codecov/codecov-action from 5.5.4 to 6.0.0 (#9)
dependabot[bot] Apr 25, 2026
7c29742
deps(ci)(deps): bump github/codeql-action from 3.35.2 to 4.35.2 (#10)
dependabot[bot] Apr 25, 2026
f88e5a4
deps(ci)(deps): bump actions/attest-build-provenance from 2.4.0 to 4.…
dependabot[bot] Apr 25, 2026
727422f
deps(ci)(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1 (#12)
dependabot[bot] Apr 25, 2026
a7e2f47
deps(ci)(deps): bump oven-sh/setup-bun from 2.0.2 to 2.2.0 (#13)
dependabot[bot] Apr 25, 2026
a7bed88
ci(pages): bump build runtime to Node 24 LTS for Astro 6
Jaro-c Apr 25, 2026
667e11a
fix(site): landing fills viewport, drop Starlight 1080px cap
Jaro-c Apr 25, 2026
ce4569d
fix(site): rebalance landing spacing — 3-col features, capped table, …
Jaro-c Apr 25, 2026
18444ea
feat(site): polish landing — scroll reveals, terminal tilt, stat coun…
Jaro-c Apr 25, 2026
a60a206
fix(site): tighten header-to-hero gap on landing
Jaro-c Apr 25, 2026
2d9dcab
fix(site): kill prose top margin + trim hero pad so hero sits under h…
Jaro-c Apr 25, 2026
61d1b03
fix(site,readme): replace placeholder stats with measured numbers
Jaro-c Apr 25, 2026
93d0987
fix(site): align hero stat columns with equal-width grid
Jaro-c Apr 25, 2026
1914be2
feat(bench): add reproducible Lynx vs PM2 vs supervisord bench harness
Jaro-c Apr 25, 2026
82eeb57
fix(bench): pin host arg in jq + run supervisord in foreground
Jaro-c Apr 25, 2026
053b321
fix(bench): probe supervisord readiness via 'pid' (status exits 3 whe…
Jaro-c Apr 25, 2026
fb57554
docs(site,readme): wire CI bench numbers into the comparison
Jaro-c Apr 25, 2026
f4442f1
feat(daemon): emit lifecycle banners to per-app log files
Jaro-c Apr 25, 2026
3744d7f
test(debian): tighten smoke with binary-path and logrotate checks
Jaro-c Apr 25, 2026
69651ad
feat(daemon): emit lifecycle banners on start/stop/restart/exit (#14)
Jaro-c Apr 25, 2026
fb344f8
feat(daemon): rotate logs while running, not just at Start
Jaro-c Apr 25, 2026
0f2402d
fix(debian): align logrotate stanza with the daemon's internal rotation
Jaro-c Apr 25, 2026
5f24f68
feat(daemon): match logrotate weekly + delaycompress + 12 keeps in us…
Jaro-c Apr 25, 2026
3eab687
fix(debian): restore weekly + delaycompress + 12 keeps in logrotate s…
Jaro-c Apr 25, 2026
905d766
feat(daemon): full log-rotation parity (size+age+delaycompress, 12 ke…
Jaro-c Apr 25, 2026
831516a
test(daemon): cover cron tick → Restart → Restarts counter
Jaro-c Apr 25, 2026
774724b
refactor(paths,types): export IsRoot/WithinRoot, add DefaultNamespace
Jaro-c Apr 26, 2026
c857579
refactor(daemon/handlers): use paths helpers and typed states
Jaro-c Apr 26, 2026
bce5bcb
refactor(daemon/manager): unify restart/rotation paths, dedup state
Jaro-c Apr 26, 2026
dfa30f6
refactor(cli/list,show,expand): typed states and cmp.Compare
Jaro-c Apr 26, 2026
1df06dc
refactor(cli,lynxfile): adopt shared helpers, fix tokenizer
Jaro-c Apr 26, 2026
fcb9f6f
refactor(lynxd,transport): use paths.LogRoot, dedup ID generation
Jaro-c Apr 26, 2026
fa6e4dd
refactor(audit,updater): switch to jsonx, extract httpGet helper
Jaro-c Apr 26, 2026
be94f69
test(paths): cover IsRoot and WithinRoot
Jaro-c Apr 26, 2026
380f616
test: cover colorState, quoted lynxfile commands, httpGet
Jaro-c Apr 26, 2026
8d830e6
ci: disable codecov file fixes to fix patch coverage line mapping
Jaro-c Apr 26, 2026
03c2765
refactor: repo-wide simplify pass (#16)
Jaro-c Apr 26, 2026
05d6f62
test(types): cover ProcessState constants and JSON round-trip
Jaro-c Apr 26, 2026
670d0f7
test(paths): cover root-mode log dir resolution (46% → 92%)
Jaro-c Apr 26, 2026
e114b06
test(cli): boost errs/help/table coverage to ≥87%
Jaro-c Apr 26, 2026
f1f1ef9
test(daemon/handlers): cover spec/env-file/stop/resources validators …
Jaro-c Apr 26, 2026
df3dc85
test(metrics): cover cgroup collector and factory (52% → 86%)
Jaro-c Apr 26, 2026
dd0cd64
test(cli/show): cover render helpers and formatters (42% → 89%)
Jaro-c Apr 26, 2026
bbb7a3e
test(cli/startup): cover RealRunner and user-mode install paths (26% …
Jaro-c Apr 26, 2026
32d1e25
test(cli/update): cover findDebAsset and quiet/managed branches (30% …
Jaro-c Apr 26, 2026
f5d1a5c
test(cli/commands): expand coverage on monit, logs, installtools, exe…
Jaro-c Apr 26, 2026
4d95d04
test(cmd/lynxd): cover auditPath and isSystemDaemon helpers
Jaro-c Apr 26, 2026
1122fac
test(debian): add portable unit-test runner for postinst/prerm
Jaro-c Apr 26, 2026
3705ace
ci: drop OpenSSF Scorecard workflow and README badge
Jaro-c Apr 26, 2026
44e04ba
style: gofmt service_test.go struct alignment
Jaro-c Apr 26, 2026
829bd41
style: golines reformat test files to <120 col
Jaro-c Apr 26, 2026
08e926c
fix(paths): apply log-dir allowlist when daemon runs as lynx user
Jaro-c Apr 26, 2026
d1aeab8
fix(manager): gate env whitelist on system mode, not just euid==0
Jaro-c Apr 26, 2026
636b449
refactor(lynxd): consolidate isSystemDaemon via paths.IsSystemMode
Jaro-c Apr 26, 2026
292fe9b
fix(audit): open audit log with O_NOFOLLOW
Jaro-c Apr 26, 2026
726a98d
fix(debian): require lynx- prefix on systemd polkit unit names
Jaro-c Apr 26, 2026
42fa0ce
chore(bench): refresh tool versions and stabilize cold-start (#17)
Jaro-c Apr 26, 2026
cae6db1
feat(bench): show all tiers (light/medium/heavy) (#20)
Jaro-c Apr 26, 2026
4f37a4c
perf(manager): shrink per-process RSS at scale (#21)
Jaro-c Apr 26, 2026
0ccef23
fix(bench): pin third-party fetches by hash (#22)
Jaro-c Apr 26, 2026
04f3723
ci: restore OpenSSF Scorecard workflow (#23)
Jaro-c Apr 26, 2026
5a32847
fix(bench): install pm2 via npm ci against lockfile (#24)
Jaro-c Apr 26, 2026
da53525
chore(logs): reduce default tail from 200 to 40 lines (#25)
Jaro-c Apr 26, 2026
69e1e08
fix(daemon): look up lynxpm binary, not lynx (#26)
Jaro-c Apr 26, 2026
d599924
fix(cli): correct binary name in user-visible strings and comments (#27)
Jaro-c Apr 26, 2026
b821652
docs: complete lynx → lynxpm rename in user-facing docs (#28)
Jaro-c Apr 26, 2026
b373660
fix: complete lynx → lynxpm rename in residual call sites (#29)
Jaro-c Apr 26, 2026
eaaf248
ci: add binary-naming check (scripts + workflow) (#30)
Jaro-c Apr 26, 2026
a0df51b
release: v0.10.0 (#31)
Jaro-c Apr 26, 2026
1b70619
feat(logs): chronologically merge stdout/stderr
Jaro-c Apr 26, 2026
976c22c
fix(logs): surface lifecycle banners in merged output
Jaro-c Apr 26, 2026
6ca6696
test(logs): deflake follow merge by polling for entries
Jaro-c Apr 26, 2026
c2cba74
release: v0.11.0
Jaro-c Apr 26, 2026
b4eb5d3
ci(deps): update github-actions dependabot schedule to daily
Jaro-c Apr 27, 2026
dfe001c
feat(monit): add live process tree to single-process monitor
Jaro-c Apr 28, 2026
0a88c20
fix(monit): fix goimports grouping for golang.org/x/term import
Jaro-c Apr 28, 2026
e954a35
ci: retrigger Debian package tests
Jaro-c Apr 28, 2026
ec5da12
fix(monit): parse --json flag regardless of position in args
Jaro-c Apr 28, 2026
0870783
fix(monit): compact JSON output and poll for child procs in smoke test
Jaro-c Apr 28, 2026
fc9370b
test(monit): add unit tests for helper functions to reach 70% patch c…
Jaro-c Apr 28, 2026
4b73b4a
deps(go)(deps): bump github.com/bytedance/sonic from 1.15.0 to 1.15.1…
dependabot[bot] May 3, 2026
975f968
fix: resolve site routing via base URL injection, update landing page…
Jaro-c May 3, 2026
62babf3
chore: update Lynx metadata and homepage description for version 0.9.8
Jaro-c May 3, 2026
2732a25
docs: add comparison guides for PM2 and Supervisor and update site SE…
Jaro-c May 3, 2026
937aa6b
docs: enhance documentation with detailed descriptions, internal navi…
Jaro-c May 3, 2026
d4440f2
feat: add Schema.org breadcrumb JSON-LD metadata to all documentation…
Jaro-c May 3, 2026
fddb864
docs: add comprehensive Linux service and process management guide co…
Jaro-c May 3, 2026
10f4c2f
chore: bump version to 0.12.0
Jaro-c May 3, 2026
e11cdc4
ci: allow lynx-api in binary naming check (systemd unit naming docs e…
Jaro-c May 3, 2026
1835bfa
test: expand test coverage for signature verification, platform start…
Jaro-c May 3, 2026
dad47a4
test: add benchmarks for IPC round-trip latency and process tree scan…
Jaro-c May 4, 2026
44ebd0f
chore: update CI workflows with dependency scanning, execution constr…
Jaro-c May 4, 2026
7884e28
feat: add workflow inputs for custom ref and cache bypass to benchmar…
Jaro-c May 4, 2026
5301b8e
docs: simplify contribution branching model, clarify license terms, a…
Jaro-c May 4, 2026
6e731bb
docs: reorder sections and convert access model list to table in README
Jaro-c May 4, 2026
0180492
fix: update test expectations for signature encoding and whitespace f…
Jaro-c May 4, 2026
adbaf25
refactor: optimize string concatenation, modernize path/error handlin…
Jaro-c May 4, 2026
5572af2
refactor: address linting warnings and improve error handling across …
Jaro-c May 4, 2026
cd36948
fix(lint): resolve golangci-lint round-3 failures
Jaro-c May 4, 2026
82e7c9d
fix(lint): remove unused nolint directives and perfsprint in round-4
Jaro-c May 4, 2026
fb12c92
fix(lint): remove all remaining unused nolint:errcheck directives
Jaro-c May 4, 2026
9234692
deps(ci)(deps): bump docker/build-push-action from 6 to 7 (#35)
dependabot[bot] May 4, 2026
fcd7b43
deps(ci)(deps): bump docker/setup-buildx-action from 3 to 4 (#34)
dependabot[bot] May 4, 2026
0b84b82
deps(ci)(deps): bump github/codeql-action from 4.35.2 to 4.35.3 (#33)
dependabot[bot] May 4, 2026
519854d
ci: pin action SHAs to fix Scorecard Pinned-Dependencies alerts
Jaro-c May 4, 2026
7067d11
ci: add pre-commit configuration
Jaro-c May 4, 2026
6c93ddb
fix: strengthen log path validation and symlink containment to preven…
Jaro-c May 4, 2026
98d105d
chore: bump version to 0.13.0
Jaro-c May 4, 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
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "daily"
open-pull-requests-limit: 5
labels:
- "dependencies"
Expand Down
71 changes: 71 additions & 0 deletions .github/workflows/bench.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Bench

# Weekly supervisor benchmark. Numbers feed README + site stats; rerun on
# demand via workflow_dispatch. Pass a ref to benchmark any branch or commit.

on:
schedule:
- cron: "17 6 * * 1" # Mondays 06:17 UTC
workflow_dispatch:
inputs:
ref:
description: "Branch or commit SHA to benchmark (default: current branch)"
required: false
default: ""
no-cache:
description: "Force a clean Docker build (ignore layer cache)"
required: false
type: boolean
default: false

permissions:
contents: read

concurrency:
group: bench
cancel-in-progress: false

jobs:
bench:
name: Run supervisor bench
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ inputs.ref || github.ref }}

- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4

- name: Build the bench image
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
with:
context: .
file: scripts/bench/Dockerfile
tags: lynx-bench
load: true
no-cache: ${{ inputs.no-cache == true }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run the bench
run: |
mkdir -p out
docker run --rm \
-v "$PWD/out:/src/scripts/bench/out" \
lynx-bench

- name: Show results
run: |
echo "## Bench results" >> "$GITHUB_STEP_SUMMARY"
cat out/results.md >> "$GITHUB_STEP_SUMMARY"

- name: Upload artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: bench-${{ github.run_id }}
path: |
out/results.json
out/results.md
if-no-files-found: error
retention-days: 90
34 changes: 34 additions & 0 deletions .github/workflows/binary-naming.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Binary naming check

on:
pull_request:
paths:
- "cmd/**"
- "internal/**"
- "scripts/check-binary-naming.sh"
- ".github/workflows/binary-naming.yml"
push:
branches: [main]
paths:
- "cmd/**"
- "internal/**"
- "scripts/check-binary-naming.sh"
- ".github/workflows/binary-naming.yml"

permissions:
contents: read

concurrency:
group: binary-naming-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
name: Check lynxpm naming
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Run check
run: bash scripts/check-binary-naming.sh
14 changes: 9 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ jobs:
- name: Install golangci-lint
run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4

- name: golangci-lint (fast)
timeout-minutes: 3
run: golangci-lint run --fast-only --timeout=2m ./...
- name: golangci-lint
timeout-minutes: 5
run: golangci-lint run --timeout=4m ./...

test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand All @@ -69,15 +70,17 @@ jobs:
retention-days: 7

- name: Upload coverage to Codecov
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
with:
files: coverage.out
fail_ci_if_error: false
disable_file_fixes: true
token: ${{ secrets.CODECOV_TOKEN }}

build:
name: Build (${{ matrix.goarch }})
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
Expand All @@ -90,7 +93,7 @@ jobs:
go-version-file: go.mod
cache: true

- name: Build lynx
- name: Build lynxpm
env:
GOOS: linux
GOARCH: ${{ matrix.goarch }}
Expand All @@ -105,6 +108,7 @@ jobs:
vuln:
name: govulncheck
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ jobs:
cache: true

- name: Initialize CodeQL
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3
with:
languages: go
queries: security-extended,security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
uses: github/codeql-action/autobuild@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3
with:
category: "/language:go"
137 changes: 66 additions & 71 deletions .github/workflows/debian-tests.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
name: Debian package tests

on:
push:
# On main: only run after CI passes — no point building .deb if tests failed.
workflow_run:
workflows: ["CI"]
types: [completed]
branches: [main]
paths:
- "debian/**"
- ".github/workflows/debian-tests.yml"
- "cmd/**"
- "internal/**"
- "go.mod"
- "go.sum"
# On PRs: run directly with path filtering for fast feedback.
pull_request:
branches: [main]
paths:
Expand All @@ -24,11 +21,14 @@ permissions:
contents: read

concurrency:
group: debian-tests-${{ github.ref }}
group: debian-tests-${{ github.event.workflow_run.head_sha || github.ref }}
cancel-in-progress: true

jobs:
build-deb:
if: >
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
name: Build .deb
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -64,6 +64,22 @@ jobs:
path: debs/*.deb
retention-days: 7

- name: Cross-compile sample Go binary for smoke
# testdata/apps/go-compiled ships as source only; install-matrix
# containers lack a Go toolchain, so we build it here (CGO off
# for matching no-shlib-deps semantics with the real release
# binaries) and ship it alongside the .deb.
env:
CGO_ENABLED: "0"
run: make -C testdata/apps/go-compiled build

- name: Upload testdata-compiled artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: testdata-compiled
path: testdata/apps/go-compiled/go-compiled
retention-days: 7

lintian:
name: Lintian
needs: build-deb
Expand Down Expand Up @@ -97,11 +113,21 @@ jobs:
container:
image: ${{ matrix.image }}
steps:
# Need the repo source (testdata/smoke.sh + testdata/apps/) in
# addition to the built .deb, so the smoke can exercise real apps
# instead of inlining everything into the workflow yaml.
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: lynxpm-deb
path: debs

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: testdata-compiled
path: testdata/apps/go-compiled/

- name: Prepare container (block service start, no interactive prompts)
run: |
set -eux
Expand Down Expand Up @@ -134,78 +160,47 @@ jobs:
[ -d /var/lib/lynx-pm ]
[ -d /var/log/lynx-pm ]

- name: Smoke — user-mode daemon + CLI lifecycle
# Exercises start/list/show/logs/restart/stop/delete end-to-end against
# a user-mode lynxd (no systemd, no root). Catches IPC / manager /
# spec-parsing regressions that pure --version + install checks miss.
- name: Smoke — testdata/smoke.sh against installed .deb
# Delegates to the repo's smoke script so the scenarios stay in
# one place (reusable by local dev + CI). Covers every lifecycle
# command plus the namespace bulk selectors, the process-group
# forkstorm regression, the --max-restarts cap, and a real node
# HTTP listener — against the binary the .deb actually installs.
env:
# The apt install below pulls tzdata in on ubuntu:22.04 via
# ruby's dependency chain; without the noninteractive frontend
# tzdata's postinst asks for a geographic area on the tty and
# the whole job hangs until GH Actions kills it.
DEBIAN_FRONTEND: noninteractive
TZ: Etc/UTC
run: |
set -eux
apt-get install -y --no-install-recommends procps util-linux
# procps+util-linux for pgrep/pkill/runuser; one of each
# supported interpreter for the sample apps. php-cli + ruby
# added in v0.9.2 alongside the go-compiled artifact. bash/
# coreutils ship in the base image.
apt-get install -y --no-install-recommends \
procps util-linux nodejs python3 php-cli ruby
# The downloaded artifact lands without +x; make the binary
# executable before the smoke tries to run it.
chmod +x testdata/apps/go-compiled/go-compiled

# Unprivileged user for the user-mode daemon.
id testuser 2>/dev/null || useradd -m -s /bin/sh testuser

# Private XDG_RUNTIME_DIR the lynx socket helper will accept (0700).
# Hand the repo over to testuser so runuser can read it.
chown -R testuser:testuser "$GITHUB_WORKSPACE"
install -d -m 0700 -o testuser -g testuser /tmp/xdg-test

# Run the whole lifecycle as testuser.
runuser -u testuser -- sh -eu <<'SMOKE'
runuser -u testuser -- bash -eu <<SMOKE
export XDG_RUNTIME_DIR=/tmp/xdg-test
export HOME=/home/testuser
cd "$GITHUB_WORKSPACE"

lynxd >/tmp/lynxd.log 2>&1 &
DAEMON_PID=\$!
trap 'kill "\$DAEMON_PID" 2>/dev/null || true' EXIT

LYNX_DEBUG_STOP=1 lynxd >/tmp/lynxd.log 2>&1 &
DAEMON_PID=$!
trap 'kill "$DAEMON_PID" 2>/dev/null || true' EXIT

# Wait up to 5s for the socket to become responsive.
for i in $(seq 1 50); do
lynxpm list --json >/dev/null 2>&1 && break
sleep 0.1
done

# Sanity: empty list after a fresh daemon.
[ "$(lynxpm list --json)" = "[]" ]

# start → list → show → stop → delete.
lynxpm start "/bin/sleep 300" --name smoke-proc --restart never
lynxpm list --json | grep -q smoke-proc
lynxpm show smoke-proc >/dev/null
lynxpm stop smoke-proc
lynxpm delete smoke-proc
[ "$(lynxpm list --json)" = "[]" ]

# Regression guard for the process-group stop bug (v0.8.1).
# Extra diagnostics: dump ppid chain of the to-be-forked child
# so the lynxd.log excerpt later correlates with what
# walkDescendants was seeing at /proc scan time.
# Spawn a bash wrapper that backgrounds a long sleep and waits;
# then stop the wrapper and assert the child PID is also dead.
# Without kill(-pid, sig) this child would leak as an orphan
# and EADDRINUSE the next start in real deployments.
PIDFILE=/tmp/xdg-test/fork-child.pid
rm -f "$PIDFILE"
lynxpm start "bash -c 'sleep 300 & echo \$! > $PIDFILE; wait'" \
--name fork-smoke --restart never --shell
for i in $(seq 1 50); do
[ -s "$PIDFILE" ] && break
sleep 0.1
done
CHILD_PID=$(cat "$PIDFILE")
[ -n "$CHILD_PID" ] || { echo "FAIL: child PID never recorded"; exit 1; }
kill -0 "$CHILD_PID" 2>/dev/null || { echo "FAIL: child $CHILD_PID not alive before stop"; exit 1; }
echo "----- pre-stop process tree -----"
ps -ef | awk 'NR==1 || $2=='"$CHILD_PID"' || $3=='"$CHILD_PID"' || $2==$(pgrep -P '"$DAEMON_PID"' | head -1) || $3==$(pgrep -P '"$DAEMON_PID"' | head -1)' || true
echo "----- /proc/$CHILD_PID/stat -----"
cat /proc/$CHILD_PID/stat 2>/dev/null || true
echo "-----"
lynxpm stop fork-smoke
sleep 1
if kill -0 "$CHILD_PID" 2>/dev/null; then
echo "FAIL: child $CHILD_PID survived Stop — process group not killed"
exit 1
fi
lynxpm delete fork-smoke
[ "$(lynxpm list --json)" = "[]" ]
bash testdata/smoke.sh
SMOKE

- name: Dump lynxd log on failure
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Dependency Review

on:
pull_request:
branches: [main]

permissions:
contents: read

jobs:
review:
name: Review dependencies
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4
Loading
Loading