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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Normalize line endings so shellcheck/shfmt checks stay deterministic.
* text=auto eol=lf

*.sh text eol=lf
72 changes: 72 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: lint

on:
pull_request:

permissions:
contents: read

env:
# Pinned tool version, kept up to date by Renovate (see renovate.json).
# renovate: datasource=github-releases depName=mvdan/sh
SHFMT_VERSION: v3.13.1

jobs:
shellcheck:
name: ShellCheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

# Scope: actively-maintained scripts only. The Arch installer
# (scripts/install-arch*, scripts/lib/install.sh) is excluded for now and
# tracked to be cleaned up later; scripts/install-arch also fails to parse
# (arithmetic with an embedded [ ] test). shellcheck reads .shellcheckrc.
- name: Run shellcheck
run: |
shellcheck --version
shellcheck -x \
setup \
install \
scripts/setup-arch \
scripts/setup-debian \
scripts/setup-fedora \
scripts/lib/common.sh \
config/fedora/snapper/*.sh \
config/fedora/grub-cryptomount/99_cryptomount_check \
vars/arch-vars \
vars/debian-vars \
vars/fedora-vars

shfmt:
name: shfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install shfmt
run: |
curl -fsSL -o /tmp/shfmt \
"https://github.com/mvdan/sh/releases/download/${SHFMT_VERSION}/shfmt_${SHFMT_VERSION}_linux_amd64"
chmod +x /tmp/shfmt

# scripts/install-arch is excluded: shfmt cannot parse line 498
# (a [ ] test inside $(( )) arithmetic). Everything else is formatted.
- name: Check formatting (-i 4 -ci)
run: |
/tmp/shfmt --version
/tmp/shfmt -d -i 4 -ci \
setup \
install \
scripts/lib/common.sh \
scripts/lib/install.sh \
scripts/install-arch-backup \
scripts/install-arch-reinstall \
scripts/setup-arch \
scripts/setup-debian \
scripts/setup-fedora \
config/fedora/snapper/*.sh \
config/fedora/grub-cryptomount/99_cryptomount_check \
vars/arch-vars \
vars/debian-vars \
vars/fedora-vars
11 changes: 11 additions & 0 deletions .shellcheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ShellCheck config for linux-setup
#
# Scripts source vars/* and scripts/lib/common.sh at runtime via ${REPO_ROOT},
# and many globals are assigned in one file but consumed in another (or read
# from sourced helpers). That architecture makes a few checks pure noise here:
#
# SC1091 can't follow non-constant 'source "${REPO_ROOT}/..."'
# SC2034 vars/* arrays + cross-file globals look "unused" within one file
# SC2016 intentional literal $VARs in _out '...' install hints / bash -c '...'
external-sources=true
disable=SC1091,SC2034,SC2016
12 changes: 9 additions & 3 deletions config/fedora/grub-cryptomount/99_cryptomount_check
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,17 @@ fi
echo "[${SCRIPT_NAME}] Line missing or incorrect. Current first line: '${FIRST_LINE}'"
echo "[${SCRIPT_NAME}] Fixing ${GRUB_CFG}..."

TMPFILE="$(mktemp)" || { echo "[${SCRIPT_NAME}] ERROR: Could not create temp file. Aborting."; exit 1; }
TMPFILE="$(mktemp)" || {
echo "[${SCRIPT_NAME}] ERROR: Could not create temp file. Aborting."
exit 1
}

grep -v '^cryptomount -u ' "$GRUB_CFG" > "$TMPFILE" || true
grep -v '^cryptomount -u ' "$GRUB_CFG" >"$TMPFILE" || true

{ echo "$EXPECTED_LINE"; cat "$TMPFILE"; } > "${GRUB_CFG}.new"
{
echo "$EXPECTED_LINE"
cat "$TMPFILE"
} >"${GRUB_CFG}.new"

mv "${GRUB_CFG}.new" "$GRUB_CFG"
rm -f "$TMPFILE"
Expand Down
8 changes: 4 additions & 4 deletions config/fedora/snapper/snapper-gui-pkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ desc=$(cat "$DESC_FILE" 2>/dev/null || echo "")
[[ -f "$PKG_FILE" ]] && exit 0

case "$ACTION" in
I|U|D|R)
echo "GUI install ${NAME}" > "$PKG_FILE"
I | U | D | R)
echo "GUI install ${NAME}" >"$PKG_FILE"
;;
E|O)
echo "GUI remove ${NAME}" > "$PKG_FILE"
E | O)
echo "GUI remove ${NAME}" >"$PKG_FILE"
;;
esac
4 changes: 2 additions & 2 deletions config/fedora/snapper/snapper-pre.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if [[ ! -d /usr/lib/sysimage/libdnf5 ]]; then
fi

desc=$(/usr/local/bin/snapper-desc.sh "$PID")
echo "$desc" > "$STATE_DIR/snapper_desc_${PID}"
echo "$desc" >"$STATE_DIR/snapper_desc_${PID}"

pre=$(snapper -c root create -c number -t pre -p -d "$desc") || exit 1
echo "$pre" > "$STATE_DIR/snapper_pre_${PID}"
echo "$pre" >"$STATE_DIR/snapper_pre_${PID}"
2 changes: 1 addition & 1 deletion install
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ main() {
--backup)
want_backup=1
;;
-h|--help)
-h | --help)
_usage
exit 0
;;
Expand Down
33 changes: 33 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":dependencyDashboard"
],
"packageRules": [
{
"description": "Auto-merge GitHub Actions and CI tool patch/minor/digest updates",
"matchManagers": ["github-actions", "custom.regex"],
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
"automerge": true
}
],
"customManagers": [
{
"description": "CI tool versions pinned in workflow env: blocks (annotated with # renovate:)",
"customType": "regex",
"managerFilePatterns": ["/^\\.github/workflows/.+\\.ya?ml$/"],
"matchStrings": [
"# renovate: datasource=(?<datasource>\\S+) depName=(?<depName>\\S+)(?: versioning=(?<versioning>\\S+))?\\s+\\w+_VERSION:\\s*[\"']?(?<currentValue>[^\"'\\s]+)"
]
},
{
"description": "nvm version pinned in setup scripts",
"customType": "regex",
"managerFilePatterns": ["/^scripts/setup-.+$/"],
"matchStrings": ["nvm-sh/nvm/(?<currentValue>v[0-9][0-9.]*)/"],
"depNameTemplate": "nvm-sh/nvm",
"datasourceTemplate": "github-tags"
}
]
}
41 changes: 22 additions & 19 deletions scripts/lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ _log_cmd_output() {
if [ -n "$output" ]; then
while IFS= read -r line; do
_log "OUT" "$line"
done <<< "$output"
done <<<"$output"
fi

return "$rc"
Expand Down Expand Up @@ -167,11 +167,11 @@ _prompt_yes_no() {
read -r -p "$prompt_msg" response

case $response in
[Yy]|[Yy][Ee][Ss])
[Yy] | [Yy][Ee][Ss])
_out "${prompt_msg} yes"
return 0
;;
[Nn]|[Nn][Oo])
[Nn] | [Nn][Oo])
_out "${prompt_msg} no"
return 1
;;
Expand All @@ -188,7 +188,10 @@ _prompt_yes_no() {

_to_ssh_url() {
local url=$1
echo "$url" | sed 's|https://github\.com/|git@github.com:|'
case "$url" in
https://github.com/*) echo "git@github.com:${url#https://github.com/}" ;;
*) echo "$url" ;;
esac
}

_set_ssh_remote() {
Expand All @@ -201,11 +204,11 @@ _set_ssh_remote() {
if [ "$https_url" != "$ssh_url" ]; then
_echo_run git remote set-url origin "$ssh_url"
fi
cd - > /dev/null || return 1
cd - >/dev/null || return 1
}

_check_firewall_service() {
command -v "$2" &> /dev/null && systemctl is-active --quiet "$1" && {
command -v "$2" &>/dev/null && systemctl is-active --quiet "$1" && {
SETUP_UFW=false
_info "Service $1 already installed/enabled. Check rules manually."
}
Expand Down Expand Up @@ -278,8 +281,8 @@ _ensure_systemd_enabled_now() {
}

_pacman_multilib_enabled() {
[ -f /etc/pacman.conf ] \
&& grep -A1 '^\[multilib\]' /etc/pacman.conf | grep -q '^Include = '
[ -f /etc/pacman.conf ] &&
grep -A1 '^\[multilib\]' /etc/pacman.conf | grep -q '^Include = '
}

_ensure_pacman_multilib() {
Expand Down Expand Up @@ -333,7 +336,7 @@ _setup_git_config() {
read -r -p " → " git_email

_echo_run mkdir -p "$config_dir"
cat > "$config_file" << EOF
cat >"$config_file" <<EOF
[user]
name = $git_name
email = $git_email
Expand Down Expand Up @@ -372,15 +375,15 @@ _setup_hostname() {
if command -v hostnamectl &>/dev/null; then
_echo_run sudo hostnamectl set-hostname "$hostname"
else
_echo_run sudo tee /etc/hostname > /dev/null <<< "$hostname"
_echo_run sudo tee /etc/hostname >/dev/null <<<"$hostname"
_echo_run sudo hostname "$hostname"
fi
}

_wheel_sudo_nopasswd_enabled() {
grep -rE '^[[:space:]]*#?[[:space:]]*%wheel[[:space:]].*NOPASSWD' \
/etc/sudoers /etc/sudoers.d/* 2>/dev/null \
| grep -qvE '^[[:space:]]*#'
/etc/sudoers /etc/sudoers.d/* 2>/dev/null |
grep -qvE '^[[:space:]]*#'
}

_setup_wheel_nopasswd_sudo() {
Expand All @@ -396,7 +399,7 @@ _setup_wheel_nopasswd_sudo() {
return 0
else
_info "Enabling NOPASSWD for %wheel in ${sudoers_file}..."
printf '%s\n' '%wheel ALL=(ALL) NOPASSWD: ALL' | _echo_run sudo tee "$sudoers_file" > /dev/null
printf '%s\n' '%wheel ALL=(ALL) NOPASSWD: ALL' | _echo_run sudo tee "$sudoers_file" >/dev/null
_echo_run sudo chmod 440 "$sudoers_file"
_echo_run sudo visudo -cf "$sudoers_file" || {
_error "sudoers validation failed; removing ${sudoers_file}"
Expand Down Expand Up @@ -454,8 +457,8 @@ _install_cursor_fedora() {
'enabled=1' \
'gpgcheck=1' \
"gpgkey=${key_url}" \
'repo_gpgcheck=1' \
| _echo_run sudo tee "$repo_file" > /dev/null
'repo_gpgcheck=1' |
_echo_run sudo tee "$repo_file" >/dev/null
fi

if rpm -q cursor &>/dev/null; then
Expand All @@ -480,11 +483,11 @@ _install_cursor_debian() {
if [ ! -f "$list_file" ]; then
_info "Adding Cursor APT repository..."
_echo_run sudo mkdir -p /usr/share/keyrings
_echo_run curl -fsSL https://downloads.cursor.com/keys/anysphere.asc \
| sudo gpg --dearmor -o "$keyring"
_echo_run curl -fsSL https://downloads.cursor.com/keys/anysphere.asc |
sudo gpg --dearmor -o "$keyring"
printf '%s\n' \
"deb [signed-by=${keyring}] https://downloads.cursor.com/aptrepo stable main" \
| _echo_run sudo tee "$list_file" > /dev/null
"deb [signed-by=${keyring}] https://downloads.cursor.com/aptrepo stable main" |
_echo_run sudo tee "$list_file" >/dev/null
if command -v nala &>/dev/null; then
_echo_run sudo nala update
else
Expand Down
Loading
Loading