Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ jobs:
env:
SHELLCHECK_VERSION: "0.11.0"
SHELLCHECK_SHA256: "8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198"
SHFMT_VERSION: "3.13.1"
SHFMT_SHA256: "fb096c5d1ac6beabbdbaa2874d025badb03ee07929f0c9ff67563ce8c75398b1"
SHFMT_VERSION: "3.14.1"
SHFMT_SHA256: "76e77641faa025814b77f153b29796b8e6fa2fca03e0c76a691608b86c7ea7bf"
# The file-budget gate's "ceilings only go down" half needs origin/develop to diff the budget
# against. Without this it would SKIP that half and still exit 0 — a green that proves less
# than it looks like it does — so here it is fatal instead (#407).
Expand Down Expand Up @@ -143,7 +143,7 @@ jobs:
runs-on: ubuntu-24.04
env:
# Pin diff-cover (the patch-coverage gate); kcov + jq are pinned inside tests/coverage.sh.
DIFF_COVER_VERSION: "10.5.1"
DIFF_COVER_VERSION: "10.6.0"
PATCH_COVERAGE_MIN: "90" # new/changed lines in rigforge.sh + util must be this % covered
# Diff the PR against the branch it targets (develop or main). On a push, github.base_ref is empty,
# so fall back to the pushed branch itself — that's an empty diff that trivially passes.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
name: Workflow audit (zizmor)
runs-on: ubuntu-24.04
env:
ZIZMOR_VERSION: "1.29.0"
ZIZMOR_VERSION: "1.30.1"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ break them gratuitously:
make lint # or: make test (lint + the full dependency-free suite)
```

CI runs the same checks, so a clean local run keeps your PR green. (`make fmt` auto-applies the
`shfmt` formatting.) `make lint` also runs the topology gate and the **file budget gate** below.
CI runs the same checks with pinned tools (shfmt 3.14.1, diff-cover 10.6.0 for patch coverage,
and zizmor 1.30.1 for workflow security), so use matching versions when reproducing a CI finding.
(`make fmt` auto-applies the `shfmt` formatting.) `make lint` also runs the topology gate and the **file budget gate** below.
- Update the README or other docs when you change behavior or add options.
- New `config.json` keys are lowercase `snake_case`, matching Pithead. The three SCREAMING legacy
keys (`ACCESS_TOKEN`, `DONATION`, `HOME_DIR`) are frozen as-is — never rename a shipped key.
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ dev-setup: ## One-time local toolchain: linters + git hooks (brew or apt; versio
else echo "no brew/apt found — install shellcheck, shfmt, jq, yamllint, actionlint, pre-commit manually"; fi
pre-commit install
@echo "Hooks installed. CI-pinned versions to match (ci.yml/security.yml are the source of truth):"
@echo " shellcheck 0.11.0 · yamllint 1.38.0 · actionlint 1.7.7 · markdownlint-cli2 $(MARKDOWNLINT_VERSION) · gitleaks 8.30.1"
@echo " shellcheck 0.11.0 · yamllint 1.38.0 · actionlint 1.7.12 · markdownlint-cli2 $(MARKDOWNLINT_VERSION) · gitleaks 8.30.1"

ci: lint-all test-suite ## Everything CI runs that can run locally (adds the container e2e when Docker is up)
@if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then $(MAKE) test-e2e; else echo "docker unavailable — skipped the container e2e (CI runs it)"; fi
Expand Down
20 changes: 10 additions & 10 deletions tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3727,7 +3727,7 @@ cp "$ROOT/VERSION" "$NOB/"
cat >"$NOB/config.json" <<EOF
{ "HOME_DIR": "$NOB/home", "pools": [{"url": "h:3333"}] }
EOF
out="$( (cd "$NOB" && PATH="$STUBS:$PATH" STUB_UNAME_S=Darwin HOME="$NOB" RIGFORGE_HOME="$PWD" bash "$SCRIPT" start </dev/null 2>&1))"
out="$( (cd "$NOB" && PATH="$STUBS:$PATH" STUB_UNAME_S=Darwin HOME="$NOB" RIGFORGE_HOME="$PWD" bash "$SCRIPT" start </dev/null 2>&1) )"
assert_rc "macOS start with no built worker fails" "$?" "1"
assert_contains "macOS start with no worker points at setup" "$out" "Run 'setup' first"

Expand All @@ -3753,7 +3753,7 @@ assert_contains "start reports login-agent control" "$out" "login agent"
: >"$LCL"
out="$(mac_lr bash "$SCRIPT" stop)"
assert_contains "stop delegates to launchctl when enabled" "$(cat "$LCL")" "[launchctl] stop"
out="$( (cd "$MC" && PATH="$STUBS:$PATH" STUB_UNAME_S=Darwin HOME="$MC" CALL_LOG="$LCL" STUB_LAUNCHD_PID=4321 RIGFORGE_HOME="$PWD" bash "$SCRIPT" status </dev/null 2>&1))"
out="$( (cd "$MC" && PATH="$STUBS:$PATH" STUB_UNAME_S=Darwin HOME="$MC" CALL_LOG="$LCL" STUB_LAUNCHD_PID=4321 RIGFORGE_HOME="$PWD" bash "$SCRIPT" status </dev/null 2>&1) )"
assert_contains "status reads the launchd PID" "$out" "pid 4321"
out="$(mac_lr bash "$SCRIPT" disable)"
assert_rc "macOS disable exits 0" "$?" "0"
Expand Down Expand Up @@ -4643,7 +4643,7 @@ out="$(run_pool_doctor n "" '_tcp_probe() { return 1; }')"
assert_contains "pool: stopped + unreachable pool -> warn (#343)" "$out" "pool h:3333 is unreachable"
assert_contains "pool: unreachable pool counts as an issue (#343)" "$out" "issue(s) found"
# The real probe against a loopback port nothing listens on: refused, so rc != 0, instantly.
prb="$( (source "$SCRIPT" && set +e && _tcp_probe 127.0.0.1 1 && echo open || echo closed))"
prb="$( (source "$SCRIPT" && set +e && _tcp_probe 127.0.0.1 1 && echo open || echo closed) )"
assert_eq "tcp probe: closed loopback port reads closed (#343)" "$prb" "closed"

# #201: NPS regression detection — an EPYC reporting ONE NUMA node is NPS1 (a BIOS reset ate the
Expand Down Expand Up @@ -4671,8 +4671,8 @@ bd_nps() { (
assert_eq "bios detect: NPS1 EPYC pending (#201)" "$(bd_nps "$NPS/one" "AMD EPYC 7642 48-Core Processor")" "pending"
assert_eq "bios detect: NPS4 EPYC ok (#201)" "$(bd_nps "$NPS/four" "AMD EPYC 7642 48-Core Processor")" "ok"
assert_eq "bios detect: desktop unknown — never listed (#201)" "$(bd_nps "$NPS/one" "Generic CPU")" "unknown"
assert_contains "bios menu: NPS item names the CBS path (#201)" "$( (source "$SCRIPT" && _bios_menu generic numa_nps perf))" "NPS4"
assert_contains "bios menu: generic power_boost speaks EPYC too (#201)" "$( (source "$SCRIPT" && _bios_menu generic power_boost perf))" "cTDP"
assert_contains "bios menu: NPS item names the CBS path (#201)" "$( (source "$SCRIPT" && _bios_menu generic numa_nps perf) )" "NPS4"
assert_contains "bios menu: generic power_boost speaks EPYC too (#201)" "$( (source "$SCRIPT" && _bios_menu generic power_boost perf) )" "cTDP"

# ---------------------------------------------------------------------------
# Guided BIOS flow (#80): detect -> guide -> save -> re-verify, against the #78 firmware fixtures.
Expand Down Expand Up @@ -5324,7 +5324,7 @@ mkdir -p "$UNN/etc/systemd/system"
cat >"$UNN/config.json" <<EOF
{ "HOME_DIR": "$UNN/home", "pools": [{"url": "poolbox.lan:3333"}] }
EOF
out="$(printf 'n\n' | (cd "$UNN" && PATH="$STUBS:$PATH" SYSTEMD_DIR="$UNN/etc/systemd/system" RIGFORGE_HOME="$PWD" bash "$SCRIPT" uninstall 2>&1))"
out="$(printf 'n\n' | (cd "$UNN" && PATH="$STUBS:$PATH" SYSTEMD_DIR="$UNN/etc/systemd/system" RIGFORGE_HOME="$PWD" bash "$SCRIPT" uninstall 2>&1) )"
assert_rc "uninstall 'n' exits 0" "$?" "0"
assert_contains "uninstall 'n' reports it aborted" "$out" "Aborted"
assert_eq "uninstall 'n' left the service unit in place" "$([ -f "$UNN/etc/systemd/system/xmrig.service" ] && echo present || echo gone)" "present"
Expand Down Expand Up @@ -6501,11 +6501,11 @@ assert_contains "no headroom, no ceiling -> plain requirement, unchanged (#328 x
echo "== black-box: appliance mode (pithead#797 R1) =="
AP="$(mktemp -d "$SANDBOX/appliance.XXXXXX")"

out="$( (unset SYSTEMD_DIR && RIGFORGE_APPLIANCE=1 && source "$SCRIPT" && printf '%s|%s' "$SYSTEMD_DIR" "$ENABLE_RUNTIME"))"
out="$( (unset SYSTEMD_DIR && RIGFORGE_APPLIANCE=1 && source "$SCRIPT" && printf '%s|%s' "$SYSTEMD_DIR" "$ENABLE_RUNTIME") )"
assert_eq "flag presets /run/systemd/system + --runtime (#797)" "$out" "/run/systemd/system|--runtime"
out="$( (unset SYSTEMD_DIR && source "$SCRIPT" && printf '%s|%s' "$SYSTEMD_DIR" "$ENABLE_RUNTIME"))"
out="$( (unset SYSTEMD_DIR && source "$SCRIPT" && printf '%s|%s' "$SYSTEMD_DIR" "$ENABLE_RUNTIME") )"
assert_eq "no flag: /etc/systemd/system + persistent enable (#797)" "$out" "/etc/systemd/system|"
out="$( (SYSTEMD_DIR="$AP/custom-sd" && RIGFORGE_APPLIANCE=1 && source "$SCRIPT" && printf '%s' "$SYSTEMD_DIR"))"
out="$( (SYSTEMD_DIR="$AP/custom-sd" && RIGFORGE_APPLIANCE=1 && source "$SCRIPT" && printf '%s' "$SYSTEMD_DIR") )"
assert_eq "explicit SYSTEMD_DIR still wins under the flag (#797)" "$out" "$AP/custom-sd"

# Baked dependencies are verified against a restricted fixture PATH.
Expand Down Expand Up @@ -6929,7 +6929,7 @@ out="$(cd "$FR" && PATH="$STUBS:$PATH" RIGFORGE_HOME="$PWD" bash "$SCRIPT" resto
assert_rc "restore without an archive fails" "$?" "1"
out="$(cd "$FR" && PATH="$STUBS:$PATH" RIGFORGE_HOME="$PWD" bash "$SCRIPT" restore -y "$BK/nope.tar.gz" </dev/null 2>&1)"
assert_rc "restore of a missing archive fails" "$?" "1"
out="$(printf 'n\n' | (cd "$FR" && PATH="$STUBS:$PATH" RIGFORGE_HOME="$PWD" bash "$SCRIPT" restore "$ARCHIVE" 2>&1))"
out="$(printf 'n\n' | (cd "$FR" && PATH="$STUBS:$PATH" RIGFORGE_HOME="$PWD" bash "$SCRIPT" restore "$ARCHIVE" 2>&1) )"
assert_rc "restore cancels cleanly on 'n'" "$?" "0"
assert_contains "restore cancel message" "$out" "cancelled"
# A bad archive must fail LOUDLY and leave the existing good config.json untouched — a silent clobber here
Expand Down