Merge pull request #9003 from dokku/8995-git-auth-status-distinct-exit-codes-for-missing-vs-differing-netrc-entry

Distinct git:auth-status exit codes for netrc state
This commit is contained in:
Jose Diaz-Gonzalez
2026-09-02 20:53:45 -04:00
committed by GitHub
3 changed files with 86 additions and 15 deletions

View File

@@ -204,7 +204,7 @@ echo "personal-access-token" | dokku git:auth github.com username
> [!IMPORTANT] > [!IMPORTANT]
> New as of 0.38.0 > New as of 0.38.0
The `git:auth-status` command reports whether the configured `netrc` entry matches a desired state without exposing the underlying file. It exits `0` when the configured state matches and `1` otherwise. This allows external tooling such as configuration management systems to perform idempotent updates without reading `$DOKKU_ROOT/.netrc` directly. The `git:auth-status` command reports whether the configured `netrc` entry matches a desired state without exposing the underlying file. This allows external tooling such as configuration management systems to perform idempotent updates without reading `$DOKKU_ROOT/.netrc` directly.
```shell ```shell
# check whether github.com is configured with the expected credentials # check whether github.com is configured with the expected credentials
@@ -214,6 +214,19 @@ dokku git:auth-status github.com username personal-access-token
dokku git:auth-status github.com dokku git:auth-status github.com
``` ```
The result is reported via the exit code:
| Exit code | Description |
| --------- | ----------- |
| `0` | The configured `netrc` entry matches the requested state. |
| `1` | There is no `netrc` entry for the specified host. |
| `2` | There is a `netrc` entry for the specified host, but it does not match the requested state. |
| `3` | The command was called with invalid arguments and the state could not be checked. |
The distinction between `1` and `2` allows a caller to tell a host that needs a `netrc` entry created apart from a host whose existing credentials would be replaced, without issuing a second call.
When called without a username, the requested state is that no `netrc` entry exists for the host. An existing entry is therefore reported as `2`, and `1` is never returned.
As with `git:auth`, the password may be provided via `STDIN`: As with `git:auth`, the password may be provided via `STDIN`:
```shell ```shell

View File

@@ -108,25 +108,30 @@ cmd-git-auth-status() {
declare desc="reports whether netrc authentication matches the requested state" declare desc="reports whether netrc authentication matches the requested state"
local cmd="git:auth-status" local cmd="git:auth-status"
[[ "$1" == "$cmd" ]] && shift 1 [[ "$1" == "$cmd" ]] && shift 1
local exit_code_missing_entry=1 exit_code_differing_entry=2 exit_code_invalid_arguments=3
declare HOST="$1" USERNAME="$2" PASSWORD="$3" declare HOST="$1" USERNAME="$2" PASSWORD="$3"
[[ -z "$HOST" ]] && dokku_log_fail "Please supply a git host" [[ -z "$HOST" ]] && DOKKU_FAIL_EXIT_CODE="$exit_code_invalid_arguments" dokku_log_fail "Please supply a git host"
PASSWORD="$(fn-git-auth-read-password "$USERNAME" "$PASSWORD")" PASSWORD="$(fn-git-auth-read-password "$USERNAME" "$PASSWORD")"
if [[ -n "$USERNAME" ]] && [[ -z "$PASSWORD" ]]; then if [[ -n "$USERNAME" ]] && [[ -z "$PASSWORD" ]]; then
dokku_log_fail "Missing password for netrc auth entry" DOKKU_FAIL_EXIT_CODE="$exit_code_invalid_arguments" dokku_log_fail "Missing password for netrc auth entry"
fi fi
local current local current
current="$(netrc get "$HOST" 2>/dev/null)" || current="" current="$(netrc get "$HOST" 2>/dev/null)" || current=""
if [[ -z "$current" ]]; then
[[ -z "$USERNAME" ]] && return 0
return "$exit_code_missing_entry"
fi
if [[ -z "$USERNAME" ]]; then if [[ -z "$USERNAME" ]]; then
[[ -z "$current" ]] && return 0 return "$exit_code_differing_entry"
return 1
fi fi
[[ "$current" == "${USERNAME}:${PASSWORD}" ]] && return 0 [[ "$current" == "${USERNAME}:${PASSWORD}" ]] && return 0
return 1 return "$exit_code_differing_entry"
} }
fn-git-auth-read-password() { fn-git-auth-read-password() {

View File

@@ -185,12 +185,18 @@ teardown() {
run /bin/bash -c "dokku git:auth-status" run /bin/bash -c "dokku git:auth-status"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_failure assert_exit_status 3
assert_output_contains "Please supply a git host"
run /bin/bash -c "dokku git:auth-status github.com" run /bin/bash -c "dokku git:auth-status github.com"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_success assert_exit_status 0
run /bin/bash -c "dokku git:auth-status github.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 1
run /bin/bash -c "dokku git:auth github.com username password" run /bin/bash -c "dokku git:auth github.com username password"
echo "output: $output" echo "output: $output"
@@ -200,38 +206,85 @@ teardown() {
run /bin/bash -c "dokku git:auth-status github.com" run /bin/bash -c "dokku git:auth-status github.com"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_failure assert_exit_status 2
run /bin/bash -c "dokku git:auth-status github.com username password" run /bin/bash -c "dokku git:auth-status github.com username password"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_success assert_exit_status 0
run /bin/bash -c "dokku git:auth-status github.com username wrong-password" run /bin/bash -c "dokku git:auth-status github.com username wrong-password"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_failure assert_exit_status 2
run /bin/bash -c "dokku git:auth-status github.com other-username password" run /bin/bash -c "dokku git:auth-status github.com other-username password"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_failure assert_exit_status 2
run /bin/bash -c "dokku git:auth-status github.com username" run /bin/bash -c "dokku git:auth-status github.com username"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_failure assert_exit_status 3
assert_output_contains "Missing password for netrc auth entry" assert_output_contains "Missing password for netrc auth entry"
run /bin/bash -c "printf 'password' | dokku git:auth-status github.com username" run /bin/bash -c "printf 'password' | dokku git:auth-status github.com username"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_success assert_exit_status 0
run /bin/bash -c "printf 'wrong-password' | dokku git:auth-status github.com username" run /bin/bash -c "printf 'wrong-password' | dokku git:auth-status github.com username"
echo "output: $output" echo "output: $output"
echo "status: $status" echo "status: $status"
assert_failure assert_exit_status 2
}
@test "(git:auth-status) distinguishes a missing entry from a differing entry" {
run /bin/bash -c "dokku git:auth auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:auth-status auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 1
run /bin/bash -c "dokku git:auth-status auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_exit_status 0
run /bin/bash -c "dokku git:auth auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:auth-status auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 0
run /bin/bash -c "dokku git:auth-status auth-status.example.com username other-password"
echo "output: $output"
echo "status: $status"
assert_exit_status 2
run /bin/bash -c "dokku git:auth-status auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_exit_status 2
run /bin/bash -c "dokku git:auth auth-status.example.com"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:auth-status auth-status.example.com username password"
echo "output: $output"
echo "status: $status"
assert_exit_status 1
} }
@test "(git) git:sync new [errors]" { @test "(git) git:sync new [errors]" {