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 docs/SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)

Expand Down
22 changes: 16 additions & 6 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand All @@ -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)
Expand All @@ -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)"
Expand All @@ -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)"
Expand All @@ -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
}

Expand Down Expand Up @@ -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
Expand All @@ -571,3 +580,4 @@ done
if [[ "$FULL_SETUP" == "true" ]]; then
save_config
fi
exit "$EXIT_STATUS"
56 changes: 53 additions & 3 deletions tests/setup.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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" <<EOF
AUR_SSH_KEY="$TEST_TMPDIR/ssh/aur.pem"
EOF
mock_ssh_denied

run "$TEST_TMPDIR/scripts/setup.sh" verify --non-interactive
[ "$status" -eq 1 ]
[[ "$output" == *"✗ Identity: git author name/email not configured"* ]]
[[ "$output" == *"✗ SSH: cannot connect to aur.archlinux.org"* ]]
[[ "$output" == *"2 issue(s) found."* ]]
}

@test "setup: full setup saves the config when verify finds an issue" {
mock_ssh_denied

run "$TEST_TMPDIR/scripts/setup.sh" \
--git-name "Jane Doe" --git-email "jane@example.com" \
--ssh-key "$TEST_TMPDIR/ssh/aur.pem" --non-interactive
[ "$status" -eq 1 ]
[[ "$output" == *"1 issue(s) found."* ]]
grep -q 'GIT_AUTHOR_NAME="Jane Doe"' "$TEST_TMPDIR/.aurtomator.conf"
grep -q "AUR_SSH_KEY=\"$TEST_TMPDIR/ssh/aur.pem\"" "$TEST_TMPDIR/.aurtomator.conf"
}

# === Secrets step ===

@test "setup secrets: sets all secrets via gh" {
Expand Down Expand Up @@ -718,13 +765,16 @@ EOF

# === Passphrase-protected SSH key ===

@test "setup ssh: accepts passphrase-protected key" {
@test "setup ssh: refuses a passphrase-protected key" {
mkdir -p "$TEST_TMPDIR/ssh-pass"
ssh-keygen -t ed25519 -f "$TEST_TMPDIR/ssh-pass/key" -N "testpass" -q

run "$TEST_TMPDIR/scripts/setup.sh" ssh \
--ssh-key "$TEST_TMPDIR/ssh-pass/key" \
--non-interactive
[ "$status" -eq 0 ]
[[ "$output" == *"passphrase-protected"* ]]
[ "$status" -eq 1 ]
[[ "$output" == *"✗ SSH key has a passphrase: $TEST_TMPDIR/ssh-pass/key"* ]]
[[ "$output" == *"cp $TEST_TMPDIR/ssh-pass/key $TEST_TMPDIR/ssh-pass/key-ci"* ]]
[[ "$output" == *"ssh-keygen -p -N '' -f $TEST_TMPDIR/ssh-pass/key-ci"* ]]
[ ! -e "$TEST_TMPDIR/.aurtomator.conf" ]
}
Loading