Skip to content

Commit 2b63599

Browse files
authored
Merge pull request #388 from jpmorin/submodule-ssh-support
SSH support for submodule
2 parents 9c16470 + 3b4a09c commit 2b63599

File tree

3 files changed

+84
-12
lines changed

3 files changed

+84
-12
lines changed

README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,42 @@ Tracks the commits in a [git](http://git-scm.com/) repository.
6666
* `fetch_tags`: *Optional.* If `true` the flag `--tags` will be used to fetch
6767
all tags in the repository. If `false` no tags will be fetched.
6868

69-
* `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.
70-
Example:
71-
72-
```
69+
* `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.
70+
* http(s) credentials:
71+
* `host` : The host to connect too. Note that `host` is specified with no protocol extensions.
72+
* `username` : Username for HTTP(S) auth when pulling submodule.
73+
* `password` : Password for HTTP(S) auth when pulling submodule.
74+
* ssh credentials:
75+
* `url` : Submodule url, as specified in the `.gitmodule` file. Support full or relative ssh url.
76+
* `private_key` : Private key for SSH auth when pulling submodule.
77+
* `private_key_passphrase` : *Optional.* To unlock `private_key` if it is protected by a passphrase.
78+
* exemple:
79+
```yaml
7380
submodule_credentials:
81+
# http(s) credentials
7482
- host: github.com
7583
username: git-user
7684
password: git-password
77-
- <another-configuration>
85+
# ssh credentials
86+
- url: [email protected]:org-name/repo-name.git
87+
private_key: |
88+
-----BEGIN RSA PRIVATE KEY-----
89+
MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W
90+
<Lots more text>
91+
DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l
92+
-----END RSA PRIVATE KEY-----
93+
private_key_passphrase: ssh-passphrase # (optionnal)
94+
# ssh credentials with relative url
95+
- url: ../org-name/repo-name.git
96+
private_key: |
97+
-----BEGIN RSA PRIVATE KEY-----
98+
MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W
99+
<Lots more text>
100+
DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l
101+
-----END RSA PRIVATE KEY-----
102+
private_key_passphrase: ssh-passphrase # (optionnal)
78103
```
79104

80-
Note that `host` is specified with no protocol extensions.
81-
82105
* `git_config`: *Optional.* If specified as (list of pairs `name` and `value`)
83106
it will configure git global options, setting each name with each value.
84107

@@ -292,7 +315,7 @@ the case.
292315

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

295-
* `.git/commit_timestamp`: For tagging builds with a timestamp.
318+
* `.git/commit_timestamp`: For tagging builds with a timestamp.
296319

297320
* `.git/describe_ref`: Version reference detected and checked out. Can be templated with `describe_ref_options` parameter.
298321
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`).

assets/common.sh

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ load_pubkey() {
1212
if [ -s $private_key_path ]; then
1313
chmod 0600 $private_key_path
1414

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

1920
mkdir -p ~/.ssh
2021
cat > ~/.ssh/config <<EOF
@@ -35,6 +36,25 @@ EOF
3536
fi
3637
}
3738

39+
init_ssh_agent() {
40+
41+
# validate if ssh-agent exist
42+
set +e
43+
ssh-add -l &> /dev/null
44+
exit_code=$?
45+
set -e
46+
47+
if [[ ${exit_code} -eq 2 ]]; then
48+
# ssh-agent does not exist, create ssh-agent
49+
eval $(ssh-agent) > /dev/null 2>&1
50+
trap "kill $SSH_AGENT_PID" EXIT
51+
else
52+
# ssh-agent exist, remove all identities
53+
ssh-add -D &> /dev/null
54+
fi
55+
56+
}
57+
3858
configure_https_tunnel() {
3959
tunnel=$(jq -r '.source.https_tunnel // empty' <<< "$1")
4060

assets/in

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ if [ "$submodules" != "none" ]; then
166166
sed -e 's/^submodule\.\(.\+\)\.path$/\1/'
167167
} | while read submodule_name; do
168168
submodule_path="$(git config --file .gitmodules --get "submodule.${submodule_name}.path")"
169+
submodule_url="$(git config --file .gitmodules --get "submodule.${submodule_name}.url")"
169170

170171
if [ "$depth" -gt 0 ]; then
171172
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
176177
continue
177178
fi
178179

179-
git submodule update --init --no-fetch $depthflag $submodule_parameters "$submodule_path"
180+
# check for ssh submodule_credentials
181+
submodule_cred=$(jq --arg submodule_url "${submodule_url}" '.source.submodule_credentials // [] | [.[] | select(.url==$submodule_url)] | first // empty' <<< ${payload})
182+
183+
if [[ -z ${submodule_cred} ]]; then
184+
185+
# update normally
186+
git submodule update --init --no-fetch $depthflag $submodule_parameters "$submodule_path"
187+
188+
else
189+
190+
# create or re-initialize ssh-agent
191+
init_ssh_agent
192+
193+
private_key=$(jq -r '.private_key' <<< ${submodule_cred})
194+
passphrase=$(jq -r '.private_key_passphrase // empty' <<< ${submodule_cred})
195+
196+
private_key_path=$(mktemp -t git-resource-submodule-private-key.XXXXXX)
197+
echo "${private_key}" > ${private_key_path}
198+
chmod 0600 ${private_key_path}
199+
200+
# add submodule private_key identity
201+
SSH_ASKPASS_REQUIRE=force SSH_ASKPASS=$(dirname $0)/askpass.sh GIT_SSH_PRIVATE_KEY_PASS="$passphrase" DISPLAY= ssh-add $private_key_path > /dev/null
202+
203+
git submodule update --init --no-fetch $depthflag $submodule_parameters "$submodule_path"
204+
205+
# restore main ssh-agent (if needed)
206+
load_pubkey "${payload}"
207+
208+
fi
180209

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

0 commit comments

Comments
 (0)