feat: add support for git remotes with port specified inline

Closes #8093
This commit is contained in:
Jose Diaz-Gonzalez
2025-11-19 23:11:26 -05:00
parent 67962ad527
commit 106b2c20f1
3 changed files with 107 additions and 5 deletions

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
export DOKKU_PORT=${DOKKU_PORT:=22}
export DOKKU_PORT=${DOKKU_PORT:=}
export DOKKU_HOST=${DOKKU_HOST:=}
export DOKKU_APP_PATH=${DOKKU_APP_PATH:=}
@@ -62,6 +62,35 @@ fn-dokku-host() {
echo "$DOKKU_HOST"
}
fn-dokku-app() {
declare DOKKU_GIT_REMOTE="$1" DOKKU_REMOTE_HOST="$2"
remote_output="$(git remote -v 2>/dev/null | grep -Ei "^${DOKKU_GIT_REMOTE}\s" | head -n 1 | awk '{print $2}')"
# check if there is a scheme
if echo "$remote_output" | grep -qEi "ssh://"; then
echo "$remote_output" | grep -Ei "ssh://dokku@$DOKKU_REMOTE_HOST" | cut -f2 -d'@' | cut -f2 -d'/' 2>/dev/null
else
echo "$remote_output" | grep -Ei "dokku@$DOKKU_REMOTE_HOST" | cut -f2 -d'@' | cut -f2 -d':' 2>/dev/null
fi
}
fn-dokku-port() {
declare DOKKU_GIT_REMOTE="$1" DOKKU_REMOTE_HOST="$2"
remote_output="$(git remote -v 2>/dev/null | grep -Ei "^${DOKKU_GIT_REMOTE}\s" | head -n 1 | awk '{print $2}')"
if echo "$remote_output" | grep -qEi "ssh://"; then
local output="$(echo "$remote_output" | grep -Ei "ssh://dokku@$DOKKU_REMOTE_HOST" | cut -f2 -d'@' | cut -f1 -d'/' 2>/dev/null)"
# check if output has a : and if so, get the port
if echo "$output" | grep -qEi ":"; then
echo "$output" | cut -f2 -d':' 2>/dev/null
else
echo "22"
fi
else
echo "22"
fi
}
fn-get-remote() {
git config dokku.remote 2>/dev/null || echo "dokku"
}
@@ -122,13 +151,17 @@ main() {
if [[ -z "$APP" ]]; then
if [[ -d .git ]] || git rev-parse --git-dir &>/dev/null; then
set +e
APP=$(git remote -v 2>/dev/null | grep -Ei "^${DOKKU_GIT_REMOTE}\s" | grep -Ei "dokku@$DOKKU_REMOTE_HOST" | head -n 1 | cut -f2 -d'@' | cut -f1 -d' ' | cut -f2 -d':' 2>/dev/null)
APP="$(fn-dokku-app "$DOKKU_GIT_REMOTE" "$DOKKU_REMOTE_HOST")"
set -e
else
echo " ! This is not a git repository" 1>&2
fi
fi
if [[ -z "$DOKKU_PORT" ]]; then
DOKKU_PORT="$(fn-dokku-port "$DOKKU_GIT_REMOTE" "$DOKKU_REMOTE_HOST")"
fi
case "$CMD" in
remote:show)
echo "dokku-app: $APP"

View File

@@ -71,7 +71,7 @@ All commands have the application name automatically set via the `--app` flag on
The client supports several environment variables:
- `DOKKU_HOST` (default: `dokku` git remote): Used to interact with a specific remote server. Can be overridden via the `--remote` flag.
- `DOKKU_HOST` (default: `dokku` git remote): Used to interact with a specific remote server. Can be overridden via the `--remote` flag. Must specify the `--app` flag when specified.
- `DOKKU_PORT` (default: `22`): Used to specify a port to connect to the Dokku server on.
It also supports several flags (all flags unspecified here are passed as is to the server):
@@ -99,6 +99,12 @@ To list all available remotes, run `dokku remote:list`. This is equivalent to ru
To add a remote, run `dokku remote:add $REMOTE_NAME dokku@dokku.me:$APP_NAME`, replacing `$REMOTE_NAME` with your desired remote name, the `$APP_NAME` with your desired app name and the host `dokku.me` with your Dokku host. This is equivalent to running `git remote add $REMOTE_NAME dokku@dokku.me:$APP_NAME`.
The following remote formats are supported:
- `dokku@HOSTNAME.TLD:APP_NAME`
- `ssh://dokku@HOSTNAME.TLD/APP_NAME`
- `ssh://dokku@HOSTNAME.TLD:HOST_PORT/APP_NAME`
To remove a remote, run `dokku remote:remove $REMOTE_NAME`. This is equivalent to running `git remote remove $REMOTE_NAME`.
By default, the remote in use is `dokku`. To change the remote the client uses by default, run `dokku remote:set $REMOTE_NAME`, where `$REMOTE_NAME` is the name of your desired remote. This will not check the value specified, so that remote *must* be available or errors will occur when running normal client commands. Note that specifying `--remote` when running dokku commands will override this configuration value.

View File

@@ -53,7 +53,6 @@ teardown() {
assert_output_contains "dokku-constructed-remote: ssh://dokku@example.com:22/$TEST_APP"
# handle custom DOKKU_HOST (no app name detected without --app flag)
export DOKKU_HOST="example.com"
run /bin/bash -c "DOKKU_HOST="example.net" DOKKU_APP_PATH=$DOKKU_APP_PATH ${BATS_TEST_DIRNAME}/../../contrib/dokku_client.sh remote:show"
echo "output: $output"
echo "status: $status"
@@ -87,11 +86,75 @@ teardown() {
assert_success
assert_output_contains "dokku-app: $TEST_APP"
assert_output_contains "dokku-git-remote: dokku"
assert_output_contains "dokku-host: example.com"
assert_output_not_contains "dokku-host: example.com"
assert_output_not_contains "dokku-host: example.net"
assert_output_contains "dokku-host: "
assert_output_contains "dokku-port: 2222"
assert_output_contains "dokku-remote-host: example.com"
assert_output_contains "dokku-ssh-user: dokku"
assert_output_contains "dokku-constructed-remote: ssh://dokku@example.com:2222/$TEST_APP"
# handle remote with scheme (no port): ssh://dokku@example.com/app-name
run /bin/bash -c "git -C "$DOKKU_APP_PATH" remote set-url dokku 'ssh://dokku@example.com:22/$TEST_APP'"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "DOKKU_APP_PATH=$DOKKU_APP_PATH ${BATS_TEST_DIRNAME}/../../contrib/dokku_client.sh remote:show"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "dokku-app: $TEST_APP"
assert_output_contains "dokku-git-remote: dokku"
assert_output_not_contains "dokku-host: example.com"
assert_output_not_contains "dokku-host: example.net"
assert_output_contains "dokku-host: "
assert_output_contains "dokku-port: 22"
assert_output_contains "dokku-remote-host: example.com"
assert_output_contains "dokku-ssh-user: dokku"
assert_output_contains "dokku-constructed-remote: ssh://dokku@example.com:22/$TEST_APP"
# handle remote with scheme (with port): ssh://dokku@example.com:2222/app-name
run /bin/bash -c "git -C "$DOKKU_APP_PATH" remote set-url dokku 'ssh://dokku@example.com:2222/$TEST_APP'"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "DOKKU_APP_PATH=$DOKKU_APP_PATH ${BATS_TEST_DIRNAME}/../../contrib/dokku_client.sh remote:show"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "dokku-app: $TEST_APP"
assert_output_contains "dokku-git-remote: dokku"
assert_output_not_contains "dokku-host: example.com"
assert_output_not_contains "dokku-host: example.net"
assert_output_contains "dokku-host: "
assert_output_contains "dokku-port: 2222"
assert_output_contains "dokku-remote-host: example.com"
assert_output_contains "dokku-ssh-user: dokku"
assert_output_contains "dokku-constructed-remote: ssh://dokku@example.com:2222/$TEST_APP"
# #8093: ssh://dokku@pipescan.shipit.dev:2222/pipescan
run /bin/bash -c "git -C "$DOKKU_APP_PATH" remote set-url dokku 'ssh://dokku@pipescan.shipit.dev:2222/pipescan'"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "DOKKU_APP_PATH=$DOKKU_APP_PATH ${BATS_TEST_DIRNAME}/../../contrib/dokku_client.sh remote:show"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "dokku-app: pipescan"
assert_output_contains "dokku-git-remote: dokku"
assert_output_not_contains "dokku-host: example.com"
assert_output_not_contains "dokku-host: example.net"
assert_output_contains "dokku-host: "
assert_output_contains "dokku-port: 2222"
assert_output_contains "dokku-remote-host: pipescan.shipit.dev"
assert_output_contains "dokku-ssh-user: dokku"
assert_output_contains "dokku-constructed-remote: ssh://dokku@pipescan.shipit.dev:2222/pipescan"
}
@test "(client) no args should print help" {
# dokku container is not run with a TTY on GitHub Actions so we don't get normal output
# https://github.com/actions/runner/issues/241