Skip to content

Commit

Permalink
Merge pull request #388 from jpmorin/submodule-ssh-support
Browse files Browse the repository at this point in the history
SSH support for submodule
  • Loading branch information
taylorsilva authored Mar 16, 2024
2 parents 9c16470 + 3b4a09c commit 2b63599
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 12 deletions.
39 changes: 31 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,42 @@ Tracks the commits in a [git](http://git-scm.com/) repository.
* `fetch_tags`: *Optional.* If `true` the flag `--tags` will be used to fetch
all tags in the repository. If `false` no tags will be fetched.

* `submodule_credentials`: *Optional.* List of credentials for HTTP(s) auth when pulling/pushing private git submodules which are not stored in the same git server as the container repository.
Example:

```
* `submodule_credentials`: *Optional.* List of credentials for HTTP(s) or SSH auth when pulling git submodules which are not stored in the same git server as the container repository or are protected by a different private key.
* http(s) credentials:
* `host` : The host to connect too. Note that `host` is specified with no protocol extensions.
* `username` : Username for HTTP(S) auth when pulling submodule.
* `password` : Password for HTTP(S) auth when pulling submodule.
* ssh credentials:
* `url` : Submodule url, as specified in the `.gitmodule` file. Support full or relative ssh url.
* `private_key` : Private key for SSH auth when pulling submodule.
* `private_key_passphrase` : *Optional.* To unlock `private_key` if it is protected by a passphrase.
* exemple:
```yaml
submodule_credentials:
# http(s) credentials
- host: github.com
username: git-user
password: git-password
- <another-configuration>
# ssh credentials
- url: git@github.com:org-name/repo-name.git
private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W
<Lots more text>
DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l
-----END RSA PRIVATE KEY-----
private_key_passphrase: ssh-passphrase # (optionnal)
# ssh credentials with relative url
- url: ../org-name/repo-name.git
private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W
<Lots more text>
DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l
-----END RSA PRIVATE KEY-----
private_key_passphrase: ssh-passphrase # (optionnal)
```

Note that `host` is specified with no protocol extensions.

* `git_config`: *Optional.* If specified as (list of pairs `name` and `value`)
it will configure git global options, setting each name with each value.

Expand Down Expand Up @@ -292,7 +315,7 @@ the case.

* `.git/commit_message`: For publishing the Git commit message on successful builds.

* `.git/commit_timestamp`: For tagging builds with a timestamp.
* `.git/commit_timestamp`: For tagging builds with a timestamp.

* `.git/describe_ref`: Version reference detected and checked out. Can be templated with `describe_ref_options` parameter.
By default, it will contain the `<latest annoted git tag>-<the number of commit since the tag>-g<short_ref>` (eg. `v1.6.2-1-g13dfd7b`).
Expand Down
26 changes: 23 additions & 3 deletions assets/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ load_pubkey() {
if [ -s $private_key_path ]; then
chmod 0600 $private_key_path

eval $(ssh-agent) >/dev/null 2>&1
trap "kill $SSH_AGENT_PID" EXIT
SSH_ASKPASS_REQUIRE=force SSH_ASKPASS=$(dirname $0)/askpass.sh GIT_SSH_PRIVATE_KEY_PASS="$passphrase" DISPLAY= ssh-add $private_key_path >/dev/null
# create or re-initialize ssh-agent
init_ssh_agent

SSH_ASKPASS_REQUIRE=force SSH_ASKPASS=$(dirname $0)/askpass.sh GIT_SSH_PRIVATE_KEY_PASS="$passphrase" DISPLAY= ssh-add $private_key_path > /dev/null

mkdir -p ~/.ssh
cat > ~/.ssh/config <<EOF
Expand All @@ -35,6 +36,25 @@ EOF
fi
}

init_ssh_agent() {

# validate if ssh-agent exist
set +e
ssh-add -l &> /dev/null
exit_code=$?
set -e

if [[ ${exit_code} -eq 2 ]]; then
# ssh-agent does not exist, create ssh-agent
eval $(ssh-agent) > /dev/null 2>&1
trap "kill $SSH_AGENT_PID" EXIT
else
# ssh-agent exist, remove all identities
ssh-add -D &> /dev/null
fi

}

configure_https_tunnel() {
tunnel=$(jq -r '.source.https_tunnel // empty' <<< "$1")

Expand Down
31 changes: 30 additions & 1 deletion assets/in
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ if [ "$submodules" != "none" ]; then
sed -e 's/^submodule\.\(.\+\)\.path$/\1/'
} | while read submodule_name; do
submodule_path="$(git config --file .gitmodules --get "submodule.${submodule_name}.path")"
submodule_url="$(git config --file .gitmodules --get "submodule.${submodule_name}.url")"

if [ "$depth" -gt 0 ]; then
git config "submodule.${submodule_name}.update" "!$bin_dir/deepen_shallow_clone_until_ref_is_found_then_check_out $depth"
Expand All @@ -176,7 +177,35 @@ if [ "$submodules" != "none" ]; then
continue
fi

git submodule update --init --no-fetch $depthflag $submodule_parameters "$submodule_path"
# check for ssh submodule_credentials
submodule_cred=$(jq --arg submodule_url "${submodule_url}" '.source.submodule_credentials // [] | [.[] | select(.url==$submodule_url)] | first // empty' <<< ${payload})

if [[ -z ${submodule_cred} ]]; then

# update normally
git submodule update --init --no-fetch $depthflag $submodule_parameters "$submodule_path"

else

# create or re-initialize ssh-agent
init_ssh_agent

private_key=$(jq -r '.private_key' <<< ${submodule_cred})
passphrase=$(jq -r '.private_key_passphrase // empty' <<< ${submodule_cred})

private_key_path=$(mktemp -t git-resource-submodule-private-key.XXXXXX)
echo "${private_key}" > ${private_key_path}
chmod 0600 ${private_key_path}

# add submodule private_key identity
SSH_ASKPASS_REQUIRE=force SSH_ASKPASS=$(dirname $0)/askpass.sh GIT_SSH_PRIVATE_KEY_PASS="$passphrase" DISPLAY= ssh-add $private_key_path > /dev/null

git submodule update --init --no-fetch $depthflag $submodule_parameters "$submodule_path"

# restore main ssh-agent (if needed)
load_pubkey "${payload}"

fi

if [ "$depth" -gt 0 ]; then
git config --unset "submodule.${submodule_name}.update"
Expand Down

0 comments on commit 2b63599

Please sign in to comment.