From 61e5b989c9e0a50e609b4b880a7e10e443315e2c Mon Sep 17 00:00:00 2001 From: noctuum <25441068+noctuum@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:01:07 +0500 Subject: [PATCH] fix(setup): verify all, refuse encrypted SSH key A failed verify still saves the config and exits with status 1. --- docs/SETUP.md | 6 +++--- scripts/setup.sh | 22 +++++++++++++------ tests/setup.bats | 56 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/docs/SETUP.md b/docs/SETUP.md index a2f442d..4f6d203 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -56,12 +56,12 @@ With `gh` installed and authenticated (`gh auth login`), setup is one command: It runs five steps in order: 1. **identity**: your name and email for AUR git commits -2. **ssh**: an existing SSH key for the AUR +2. **ssh**: an existing SSH key for the AUR. CI uses the key without a prompt, so the step refuses a key with a passphrase and prints the commands that make a copy without one. 3. **gpg**: optional GPG commit signing 4. **secrets**: pushes `AUR_SSH_KEY`, `AUR_GIT_NAME`, `AUR_GIT_EMAIL` and, with GPG, `GPG_SIGNING_KEY` to your GitHub repo 5. **verify**: checks identity, SSH access to the AUR, GPG signing and the secrets -The script reads the GitHub repo from the `origin` remote and asks for `owner/repo` when that fails. It saves your answers to `.aurtomator.conf`. +The script reads the GitHub repo from the `origin` remote and asks for `owner/repo` when that fails. It saves your answers to `.aurtomator.conf`, also when `verify` finds a problem. ## Identity @@ -121,7 +121,7 @@ That output works in CI only for a key without a passphrase. For a key with one, ./scripts/setup.sh verify ``` -It checks identity, SSH access, GPG signing when configured, and the secrets when `gh` is available. +It checks identity, SSH access, GPG signing when configured, and the secrets when `gh` is available. When a check fails, the others still run, and `verify` then prints how many failed and exits with status 1. ## GPG signing (optional) diff --git a/scripts/setup.sh b/scripts/setup.sh index 2820e66..372ca6c 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -153,7 +153,12 @@ setup_ssh() { if [[ "$key_check" == ssh-* ]]; then ok "SSH key: $AUR_SSH_KEY" elif echo "$key_check" | grep -qi "incorrect passphrase"; then - ok "SSH key: $AUR_SSH_KEY (passphrase-protected)" + fail "SSH key has a passphrase: $AUR_SSH_KEY" + printf "\n CI uses the key without a prompt. Remove the passphrase from a copy:\n" + printf " cp %s %s-ci\n" "$AUR_SSH_KEY" "$AUR_SSH_KEY" + printf " ssh-keygen -p -N '' -f %s-ci\n" "$AUR_SSH_KEY" + printf " ./scripts/setup.sh ssh --ssh-key %s-ci\n\n" "$AUR_SSH_KEY" + return 1 else fail "Not a valid private key: $AUR_SSH_KEY" return 1 @@ -436,7 +441,7 @@ verify_all() { ok "Identity: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" else fail "Identity: git author name/email not configured" - ((errors++)) + errors=$((errors + 1)) fi # SSH (AUR returns exit 1 even on success, so check output for "Welcome") @@ -446,7 +451,7 @@ verify_all() { ok "SSH: aur.archlinux.org accessible" else fail "SSH: cannot connect to aur.archlinux.org" - ((errors++)) + errors=$((errors + 1)) fi # GPG (only if configured) @@ -455,7 +460,7 @@ verify_all() { ok "GPG: signing works with $GPG_KEY_ID" else fail "GPG: cannot sign with $GPG_KEY_ID" - ((errors++)) + errors=$((errors + 1)) fi else ok "GPG: skipped (not configured)" @@ -480,7 +485,7 @@ verify_all() { ok "Secrets: ${secret_count}/${secret_expected} configured" else warn "Secrets: ${secret_count}/${secret_expected} configured" - ((errors++)) + errors=$((errors + 1)) fi else warn "Secrets: cannot verify (gh not available)" @@ -492,6 +497,7 @@ verify_all() { else printf "\n %s%s%d issue(s) found.%s Fix and re-run:\n" "$YELLOW" "$BOLD" "$errors" "$RESET" printf " ./scripts/setup.sh verify\n\n" + return 1 fi } @@ -555,13 +561,16 @@ if [[ ${#STEPS[@]} -eq 5 ]]; then FULL_SETUP=true fi +# A failed verify still saves the config, so the re-run it suggests has +# the values of this run +EXIT_STATUS=0 for step in "${STEPS[@]}"; do case "$step" in identity) setup_identity ;; ssh) setup_ssh ;; gpg) setup_gpg ;; secrets) setup_secrets ;; - verify) verify_all ;; + verify) verify_all || EXIT_STATUS=1 ;; esac if [[ "$FULL_SETUP" == "false" ]]; then save_config @@ -571,3 +580,4 @@ done if [[ "$FULL_SETUP" == "true" ]]; then save_config fi +exit "$EXIT_STATUS" diff --git a/tests/setup.bats b/tests/setup.bats index 23a6d44..759ea97 100644 --- a/tests/setup.bats +++ b/tests/setup.bats @@ -183,6 +183,16 @@ EOF chmod +x "$TEST_TMPDIR/mock-bin/gh" } +# Helper: ssh that the AUR refuses, as for a key missing from the account +mock_ssh_denied() { + cat >"$TEST_TMPDIR/mock-bin/ssh" <<'EOF' +#!/usr/bin/env bash +echo "aur@aur.archlinux.org: Permission denied (publickey)." >&2 +exit 255 +EOF + chmod +x "$TEST_TMPDIR/mock-bin/ssh" +} + # Helper: gpg for the passphrase strip flow on PASSKEY003. The main keyring # exports the key with its passphrase, the temporary keyring (--homedir) # exports the copy @@ -430,6 +440,43 @@ EOF [[ "$output" == *"Ready."* ]] } +@test "setup verify: runs every check after a failed one" { + write_full_config "VALIDKEY123" + mock_ssh_denied + + run "$TEST_TMPDIR/scripts/setup.sh" verify --non-interactive + [ "$status" -eq 1 ] + [[ "$output" == *"✗ SSH: cannot connect to aur.archlinux.org"* ]] + [[ "$output" == *"✓ GPG: signing works with VALIDKEY123"* ]] + [[ "$output" == *"✓ Secrets: 4/4 configured"* ]] + [[ "$output" == *"1 issue(s) found."* ]] +} + +@test "setup verify: counts every failed check" { + cat >"$TEST_TMPDIR/.aurtomator.conf" <