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
taylorsilva authored Mar 16, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 9c16470 + 3b4a09c commit 2b63599
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
@@ -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: [email protected]: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.

@@ -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`).
26 changes: 23 additions & 3 deletions assets/common.sh
Original file line number Diff line number Diff line change
@@ -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
@@ -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")

31 changes: 30 additions & 1 deletion assets/in
Original file line number Diff line number Diff line change
@@ -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"
@@ -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"

0 comments on commit 2b63599

Please sign in to comment.