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
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
shellcheck:
name: shellcheck
# Pinned runner image: shellcheck comes from its apt repo, so the image
# decides the version (ubuntu-24.04 ships 0.9.x, stricter on SC2015 than
# 0.11). Moving to a newer image is a deliberate change.
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Show shellcheck version
run: shellcheck --version
- name: Run shellcheck on all shell scripts
run: |
find . -type f -name '*.sh' -not -path './.git/*' -print0 \
| xargs -0 --no-run-if-empty shellcheck --severity=style

actionlint:
name: actionlint
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Lint workflows
# `go run module@version` fetches a fixed release, verified against the
# Go checksum database (sum.golang.org).
run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 -color

gitleaks:
name: gitleaks
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Scan for committed secrets
uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

smoke:
name: script smoke test
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Syntax check every script (bash -n)
run: |
find . -type f -name '*.sh' -not -path './.git/*' -print0 \
| xargs -0 --no-run-if-empty -n1 bash -n
- name: Smoke test self-test (goes red on each F-0024 failure mode)
run: bash scripts/test-smoke-selftest.sh
- name: Smoke each entrypoint (--help, no sudo) and README symlink targets
run: bash scripts/test-smoke.sh
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,40 @@ sudo ln -s /home/mregra/dev/fedora-workstation-scripts/system-health/system-heal
```

Then follow the per-project READMEs for configuration and automation details.

## Continuous integration

Every push to `main` and every pull request runs `.github/workflows/ci.yml`:

- **shellcheck** — static analysis of every `*.sh` (the runner's shellcheck is
older than Fedora's and a little stricter; the version is printed in the log).
- **actionlint** — lints the workflow files.
- **gitleaks** — scans for committed secrets.
- **script smoke test** — `bash -n` on every script plus `scripts/test-smoke.sh`,
which guards against the ways `fedora-maintenance.service` failed (F-0024). It
reads the `ln -s` lines and the `ExecStart=` lines from the READMEs and fails if:
- a script behind a symlink or a direct repo path (`%h/.../fedora-workstation-scripts/<path>`)
is missing, has no shebang or is not committed as executable (`100755`),
so the unit would fail with `status=203/EXEC`;
- an `ExecStart` runs a `/usr/local/bin` or `~/.local/bin` name that no README
symlink creates, or runs nothing from this repo;
- a script that declares `# smoke-modes: ...` is started with no mode, an
unknown mode, or `%i` in a unit that is not a template (`name@.service`),
so it would exit 1 with its usage text;
- a user unit (`~/.config/systemd/user`) runs a script that calls `need_root`
without `sudo`.

It also runs every `*.sh` outside `scripts/` with `--help` (no `sudo`, no side
effects). A script whose source never mentions `--help` is reported and not
run. `scripts/test-smoke-selftest.sh` proves the smoke test goes red on each
of those failures.

Every runnable script therefore supports `--help`. When you move a script,
update its README symlink line in the same change. When you add a mode to
`fedora-maintenance.sh`, add it to its `# smoke-modes:` line. Run the checks
locally with:

```bash
bash scripts/test-smoke.sh
bash scripts/test-smoke-selftest.sh
```
13 changes: 13 additions & 0 deletions bug-bounty-agent/install-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
# Run as your normal user (not root) — tools install to ~/go/bin and ~/.local/bin.
set -Eeuo pipefail

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
cat <<'EOF'
install-tools.sh — install security tooling for the bug-bounty orchestrator.

Usage:
bash install-tools.sh Install Python deps, Go tools, nmap, sqlmap, etc.
bash install-tools.sh --help Show this help and exit.

Run as your normal user (not root). Tools install to ~/go/bin and ~/.local/bin.
EOF
exit 0
fi

say() { printf '\n=== %s ===\n' "$1"; }
ok() { printf ' OK: %s\n' "$1"; }
skip() { printf ' SKIP: %s (already installed)\n' "$1"; }
Expand Down
20 changes: 17 additions & 3 deletions bug-bounty-agent/nightly-launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,23 @@
# Output and logs go to ./output/ and ./nightly.log
set -Eeuo pipefail

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
cat <<'EOF'
nightly-launch.sh — queue tonight's orchestrator run and detach it.

Usage:
bash nightly-launch.sh scope.yaml
bash nightly-launch.sh scope.yaml --phases recon scan
bash nightly-launch.sh --help

Output and logs go to ./output/ and ./nightly.log; PID is written to nightly.pid.
EOF
exit 0
fi

SCOPE="${1:-scope.yaml}"
shift || true
EXTRA_ARGS="${*}"
EXTRA_ARGS=("$@")
LOG="nightly.log"
PID_FILE="nightly.pid"

Expand All @@ -32,11 +46,11 @@ if [[ -f "$PID_FILE" ]]; then
rm -f "$PID_FILE"
fi

echo "Starting overnight run: scope=$SCOPE extra=${EXTRA_ARGS:-none}"
echo "Starting overnight run: scope=$SCOPE extra=${EXTRA_ARGS[*]:-none}"
echo "Log: $LOG"
echo "Kill with: kill \$(cat $PID_FILE)"

nohup python3 orchestrator.py --scope "$SCOPE" $EXTRA_ARGS \
nohup python3 orchestrator.py --scope "$SCOPE" "${EXTRA_ARGS[@]}" \
> "$LOG" 2>&1 &

echo $! > "$PID_FILE"
Expand Down
7 changes: 5 additions & 2 deletions fedora-maintenance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ Create these files under `~/.config/systemd/user`.

```ini
[Unit]
Description=Fedora maintenance (%i)
Description=Fedora maintenance (daily)

[Service]
Type=oneshot
ExecStart=/usr/bin/sudo -n /usr/local/bin/fedora-maintenance %i
ExecStart=/usr/bin/sudo -n /usr/local/bin/fedora-maintenance daily
Environment=NOTIFY_USER=mregra
```

Expand All @@ -105,6 +105,9 @@ systemctl --user enable --now fedora-maintenance.timer

If you use the user timers, make sure `sudo` is configured for passwordless
execution of the maintenance script (or it will prompt and fail in the background).
Always pass a mode in `ExecStart`: without one the script prints usage and exits 1.
`%i` only works in a template unit (`fedora-maintenance@.service`, Option B); in
`fedora-maintenance.service` it expands to an empty string.

### Option B: systemd system timers

Expand Down
9 changes: 9 additions & 0 deletions fedora-maintenance/fedora-maintenance.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env bash
# Modes accepted by main(); scripts/test-smoke.sh checks README ExecStart lines against it.
# smoke-modes: daily monthly major
set -Eeuo pipefail

LOG_FILE="/var/log/fedora-maintenance.log"
Expand Down Expand Up @@ -198,6 +200,8 @@ cleanup_system() {
say " OK (nothing to remove)"
log "No old kernels to remove"
else
# shellcheck disable=SC2086 # intentional word splitting: a space/newline
# separated list of kernel package names must expand to multiple args.
if dnf -y remove $old_kernels >>"$LOG_FILE" 2>&1; then
ok
else
Expand Down Expand Up @@ -316,6 +320,11 @@ main() {
local mode="${1:-}"
[[ -n "$mode" ]] || { usage; exit 1; }

if [[ "$mode" == "-h" || "$mode" == "--help" || "$mode" == "help" ]]; then
usage
exit 0
fi

MODE="$mode"
need_root "$@"
mkdir -p "$(dirname "$LOG_FILE")"
Expand Down
Loading
Loading