summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/git
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 20:03:01 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 20:03:01 +0000
commita453ac31f3428614cceb99027f8efbdb9258a40b (patch)
treef61f87408f32a8511cbd91799f9cececb53e0374 /test/integration/targets/git
parentInitial commit. (diff)
downloadansible-a453ac31f3428614cceb99027f8efbdb9258a40b.tar.xz
ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.zip
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/integration/targets/git')
-rw-r--r--test/integration/targets/git/aliases2
-rw-r--r--test/integration/targets/git/handlers/cleanup-default.yml6
-rw-r--r--test/integration/targets/git/handlers/cleanup-freebsd.yml5
-rw-r--r--test/integration/targets/git/handlers/main.yml7
-rw-r--r--test/integration/targets/git/meta/main.yml3
-rw-r--r--test/integration/targets/git/tasks/ambiguous-ref.yml37
-rw-r--r--test/integration/targets/git/tasks/archive.yml135
-rw-r--r--test/integration/targets/git/tasks/change-repo-url.yml132
-rw-r--r--test/integration/targets/git/tasks/checkout-new-tag.yml54
-rw-r--r--test/integration/targets/git/tasks/depth.yml229
-rw-r--r--test/integration/targets/git/tasks/forcefully-fetch-tag.yml38
-rw-r--r--test/integration/targets/git/tasks/formats.yml40
-rw-r--r--test/integration/targets/git/tasks/gpg-verification.yml212
-rw-r--r--test/integration/targets/git/tasks/localmods.yml112
-rw-r--r--test/integration/targets/git/tasks/main.yml40
-rw-r--r--test/integration/targets/git/tasks/missing_hostkey.yml48
-rw-r--r--test/integration/targets/git/tasks/no-destination.yml13
-rw-r--r--test/integration/targets/git/tasks/reset-origin.yml25
-rw-r--r--test/integration/targets/git/tasks/separate-git-dir.yml132
-rw-r--r--test/integration/targets/git/tasks/setup-local-repos.yml45
-rw-r--r--test/integration/targets/git/tasks/setup.yml43
-rw-r--r--test/integration/targets/git/tasks/specific-revision.yml238
-rw-r--r--test/integration/targets/git/tasks/submodules.yml124
-rw-r--r--test/integration/targets/git/vars/main.yml97
24 files changed, 1817 insertions, 0 deletions
diff --git a/test/integration/targets/git/aliases b/test/integration/targets/git/aliases
new file mode 100644
index 00000000..f71c8117
--- /dev/null
+++ b/test/integration/targets/git/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group4
+skip/aix
diff --git a/test/integration/targets/git/handlers/cleanup-default.yml b/test/integration/targets/git/handlers/cleanup-default.yml
new file mode 100644
index 00000000..02a79882
--- /dev/null
+++ b/test/integration/targets/git/handlers/cleanup-default.yml
@@ -0,0 +1,6 @@
+# TODO remove everything we'd installed (see git_required_packages), not just git
+# problem is that we should not remove what we hadn't installed
+- name: remove git
+ package:
+ name: git
+ state: absent
diff --git a/test/integration/targets/git/handlers/cleanup-freebsd.yml b/test/integration/targets/git/handlers/cleanup-freebsd.yml
new file mode 100644
index 00000000..1ee35013
--- /dev/null
+++ b/test/integration/targets/git/handlers/cleanup-freebsd.yml
@@ -0,0 +1,5 @@
+- name: remove git fromn FreeBSD
+ pkgng:
+ name: git
+ state: absent
+ autoremove: yes
diff --git a/test/integration/targets/git/handlers/main.yml b/test/integration/targets/git/handlers/main.yml
new file mode 100644
index 00000000..875f513a
--- /dev/null
+++ b/test/integration/targets/git/handlers/main.yml
@@ -0,0 +1,7 @@
+- name: cleanup
+ include_tasks: "{{ cleanup_filename }}"
+ with_first_found:
+ - "cleanup-{{ ansible_distribution | lower }}.yml"
+ - "cleanup-default.yml"
+ loop_control:
+ loop_var: cleanup_filename
diff --git a/test/integration/targets/git/meta/main.yml b/test/integration/targets/git/meta/main.yml
new file mode 100644
index 00000000..34a77cb7
--- /dev/null
+++ b/test/integration/targets/git/meta/main.yml
@@ -0,0 +1,3 @@
+dependencies:
+ - prepare_tests
+ - setup_gnutar
diff --git a/test/integration/targets/git/tasks/ambiguous-ref.yml b/test/integration/targets/git/tasks/ambiguous-ref.yml
new file mode 100644
index 00000000..f06112e5
--- /dev/null
+++ b/test/integration/targets/git/tasks/ambiguous-ref.yml
@@ -0,0 +1,37 @@
+# test for https://github.com/ansible/ansible-modules-core/pull/3386
+
+- name: AMBIGUOUS-REF | clone repo
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+
+- name: AMBIGUOUS-REF | rename remote to be ambiguous
+ command: git remote rename origin v0.1
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: AMBIGUOUS-REF | switch to HEAD
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ remote: v0.1
+
+- name: AMBIGUOUS-REF | rev-parse remote HEAD
+ command: git rev-parse v0.1/HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_remote_head
+
+- name: AMBIGUOUS-REF | rev-parse local HEAD
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_local_head
+
+- assert:
+ that: git_remote_head.stdout == git_local_head.stdout
+
+- name: AMBIGUOUS-REF | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
diff --git a/test/integration/targets/git/tasks/archive.yml b/test/integration/targets/git/tasks/archive.yml
new file mode 100644
index 00000000..574559ef
--- /dev/null
+++ b/test/integration/targets/git/tasks/archive.yml
@@ -0,0 +1,135 @@
+- name: ARCHIVE | Clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: ARCHIVE | Archive repo using various archival format
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ archive: '{{ checkout_dir }}/test_role.{{ item }}'
+ register: git_archive
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+# The map filter was added in Jinja2 2.7, which is newer than the version on RHEL/CentOS 6,
+# so we skip this validation on those hosts
+- name: ARCHIVE | Assert that archives were downloaded
+ assert:
+ that: (git_archive.results | map(attribute='changed') | unique | list)[0]
+ when:
+ - "ansible_os_family == 'RedHat'"
+ - ansible_distribution_major_version is version('7', '>=')
+
+- name: ARCHIVE | Check if archive file is created or not
+ stat:
+ path: '{{ checkout_dir }}/test_role.{{ item }}'
+ register: archive_check
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+- name: ARCHIVE | Assert that archive files exist
+ assert:
+ that: (archive_check.results | map(attribute='stat.exists') | unique | list)[0]
+ when:
+ - "ansible_os_family == 'RedHat'"
+ - ansible_distribution_major_version is version('7', '>=')
+
+- name: ARCHIVE | Clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: ARCHIVE | Clone clean repo
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+
+# Check git archive functionality without update
+- name: ARCHIVE | Archive repo using various archival format and without update
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ update: no
+ archive: '{{ checkout_dir }}/test_role.{{ item }}'
+ register: git_archive
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+# The map filter was added in Jinja2 2.7, which is newer than the version on RHEL/CentOS 6,
+# so we skip this validation on those hosts
+- name: ARCHIVE | Assert that archives were downloaded
+ assert:
+ that: (git_archive.results | map(attribute='changed') | unique | list)[0]
+ when:
+ - "ansible_os_family == 'RedHat'"
+ - ansible_distribution_major_version is version('7', '>=')
+
+- name: ARCHIVE | Check if archive file is created or not
+ stat:
+ path: '{{ checkout_dir }}/test_role.{{ item }}'
+ register: archive_check
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+- name: ARCHIVE | Assert that archive files exist
+ assert:
+ that: (archive_check.results | map(attribute='stat.exists') | unique | list)[0]
+ when:
+ - "ansible_os_family == 'RedHat'"
+ - ansible_distribution_major_version is version('7', '>=')
+
+- name: ARCHIVE | Inspect archive file
+ command:
+ cmd: "{{ git_list_commands[item] }} {{ checkout_dir }}/test_role.{{ item }}"
+ warn: no
+ register: archive_content
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+# Does not work on RedHat6 (jinja2 too old?)
+- name: ARCHIVE | Ensure archive content is correct
+ assert:
+ that:
+ - item.stdout_lines | sort | first == 'defaults/'
+ with_items: "{{ archive_content.results }}"
+ when:
+ - ansible_os_family ~ ansible_distribution_major_version != 'RedHat6'
+
+- name: ARCHIVE | Clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: ARCHIVE | Generate an archive prefix
+ set_fact:
+ git_archive_prefix: '{{ range(2 ** 31, 2 ** 32) | random }}' # Generate some random archive prefix
+
+- name: ARCHIVE | Archive repo using various archival format and with an archive prefix
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ archive: '{{ checkout_dir }}/test_role.{{ item }}'
+ archive_prefix: '{{ git_archive_prefix }}/'
+ register: git_archive
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+- name: ARCHIVE | Prepare the target for archive(s) extraction
+ file:
+ state: directory
+ path: '{{ checkout_dir }}/{{ git_archive_prefix }}.{{ item }}'
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+- name: ARCHIVE | Extract the archive(s) into that target
+ unarchive:
+ src: '{{ checkout_dir }}/test_role.{{ item }}'
+ dest: '{{ checkout_dir }}/{{ git_archive_prefix }}.{{ item }}'
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+- name: ARCHIVE | Check if prefix directory exists in what's extracted
+ find:
+ path: '{{ checkout_dir }}/{{ git_archive_prefix }}.{{ item }}'
+ patterns: '{{ git_archive_prefix }}'
+ file_type: directory
+ register: archive_check
+ with_items: "{{ git_archive_extensions[ansible_os_family ~ ansible_distribution_major_version | default('default') ] | default(git_archive_extensions.default) }}"
+
+- name: ARCHIVE | Assert that prefix directory is found
+ assert:
+ that: '{{ item.matched == 1 }}'
+ with_items: "{{ archive_check.results }}"
diff --git a/test/integration/targets/git/tasks/change-repo-url.yml b/test/integration/targets/git/tasks/change-repo-url.yml
new file mode 100644
index 00000000..b12fca1f
--- /dev/null
+++ b/test/integration/targets/git/tasks/change-repo-url.yml
@@ -0,0 +1,132 @@
+# test change of repo url
+# see https://github.com/ansible/ansible-modules-core/pull/721
+
+- name: CHANGE-REPO-URL | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: CHANGE-REPO-URL | Clone example git repo
+ git:
+ repo: "{{ repo_update_url_1 }}"
+ dest: "{{ checkout_dir }}"
+
+- name: CHANGE-REPO-URL | Clone repo with changed url to the same place
+ git:
+ repo: "{{ repo_update_url_2 }}"
+ dest: "{{ checkout_dir }}"
+ register: clone2
+
+- assert:
+ that: "clone2 is successful"
+
+- name: CHANGE-REPO-URL | check url updated
+ shell: git remote show origin | grep Fetch
+ register: remote_url
+ args:
+ chdir: "{{ checkout_dir }}"
+ environment:
+ LC_ALL: C
+
+- assert:
+ that:
+ - "'git-test-new' in remote_url.stdout"
+ - "'git-test-old' not in remote_url.stdout"
+
+- name: CHANGE-REPO-URL | check for new content in git-test-new
+ stat: path={{ checkout_dir }}/newfilename
+ register: repo_content
+
+- name: CHANGE-REPO-URL | assert presence of new file in repo (i.e. working copy updated)
+ assert:
+ that: "repo_content.stat.exists"
+
+# Make sure 'changed' result is accurate in check mode.
+# See https://github.com/ansible/ansible-modules-core/pull/4243
+
+- name: CHANGE-REPO-URL | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: CHANGE-REPO-URL | clone repo
+ git:
+ repo: "{{ repo_update_url_1 }}"
+ dest: "{{ checkout_dir }}"
+
+- name: CHANGE-REPO-URL | clone repo with same url to same destination
+ git:
+ repo: "{{ repo_update_url_1 }}"
+ dest: "{{ checkout_dir }}"
+ register: checkout_same_url
+
+- name: CHANGE-REPO-URL | check repo not changed
+ assert:
+ that:
+ - checkout_same_url is not changed
+
+
+- name: CHANGE-REPO-URL | clone repo with new url to same destination
+ git:
+ repo: "{{ repo_update_url_2 }}"
+ dest: "{{ checkout_dir }}"
+ register: checkout_new_url
+
+- name: CHANGE-REPO-URL | check repo changed
+ assert:
+ that:
+ - checkout_new_url is changed
+
+
+- name: CHANGE-REPO-URL | clone repo with new url in check mode
+ git:
+ repo: "{{ repo_update_url_1 }}"
+ dest: "{{ checkout_dir }}"
+ register: checkout_new_url_check_mode
+ check_mode: True
+
+- name: CHANGE-REPO-URL | check repo reported changed in check mode
+ assert:
+ that:
+ - checkout_new_url_check_mode is changed
+ when: git_version.stdout is version(git_version_supporting_ls_remote, '>=')
+
+- name: CHANGE-REPO-URL | clone repo with new url after check mode
+ git:
+ repo: "{{ repo_update_url_1 }}"
+ dest: "{{ checkout_dir }}"
+ register: checkout_new_url_after_check_mode
+
+- name: CHANGE-REPO-URL | check repo still changed after check mode
+ assert:
+ that:
+ - checkout_new_url_after_check_mode is changed
+
+
+# Test that checkout by branch works when the branch is not in our current repo but the sha is
+
+- name: CHANGE-REPO-URL | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: CHANGE-REPO-URL | "Clone example git repo that we're going to modify"
+ git:
+ repo: "{{ repo_update_url_1 }}"
+ dest: "{{ checkout_dir }}/repo"
+
+- name: CHANGE-REPO-URL | Clone the repo again - this is what we test
+ git:
+ repo: "{{ checkout_dir }}/repo"
+ dest: "{{ checkout_dir }}/checkout"
+
+- name: CHANGE-REPO-URL | Add a branch to the repo
+ command: git branch new-branch
+ args:
+ chdir: "{{ checkout_dir }}/repo"
+
+- name: CHANGE-REPO-URL | Checkout the new branch in the checkout
+ git:
+ repo: "{{ checkout_dir}}/repo"
+ version: 'new-branch'
+ dest: "{{ checkout_dir }}/checkout"
diff --git a/test/integration/targets/git/tasks/checkout-new-tag.yml b/test/integration/targets/git/tasks/checkout-new-tag.yml
new file mode 100644
index 00000000..eac73f67
--- /dev/null
+++ b/test/integration/targets/git/tasks/checkout-new-tag.yml
@@ -0,0 +1,54 @@
+# test for https://github.com/ansible/ansible-modules-core/issues/527
+# clone a repo, add a tag to the same commit and try to checkout the new commit
+
+
+- name: clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: checkout example repo
+ git:
+ repo: "{{ repo_dir }}/format1"
+ dest: "{{ checkout_dir }}"
+
+- name: get tags of head
+ command: git tag --contains
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: listoftags
+
+- name: make sure the tag does not yet exist
+ assert:
+ that:
+ - "'newtag' not in listoftags.stdout_lines"
+
+- name: add tag in orig repo
+ command: git tag newtag
+ args:
+ chdir: "{{ repo_dir }}/format1"
+
+- name: update copy with new tag
+ git:
+ repo: "{{ repo_dir }}/format1"
+ dest: "{{checkout_dir}}"
+ version: newtag
+ register: update_new_tag
+
+- name: get tags of new head
+ command: git tag --contains
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: listoftags
+
+- name: check new head
+ assert:
+ that:
+ - update_new_tag is not changed
+ - "'newtag' in listoftags.stdout_lines"
+
+
+- name: clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
diff --git a/test/integration/targets/git/tasks/depth.yml b/test/integration/targets/git/tasks/depth.yml
new file mode 100644
index 00000000..547f84f7
--- /dev/null
+++ b/test/integration/targets/git/tasks/depth.yml
@@ -0,0 +1,229 @@
+# Test the depth option and fetching revisions that were ignored first
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: DEPTH | Clone example git repo with depth 1
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+
+- name: DEPTH | try to access earlier commit
+ command: "git checkout {{git_shallow_head_1.stdout}}"
+ register: checkout_early
+ failed_when: False
+ args:
+ chdir: '{{ checkout_dir }}'
+
+- name: DEPTH | make sure the old commit was not fetched
+ assert:
+ that: 'checkout_early.rc != 0'
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+# tests https://github.com/ansible/ansible/issues/14954
+- name: DEPTH | fetch repo again with depth=1
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ register: checkout2
+
+- assert:
+ that: "checkout2 is not changed"
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+- name: DEPTH | again try to access earlier commit
+ shell: "git checkout {{git_shallow_head_1.stdout}}"
+ register: checkout_early
+ failed_when: False
+ args:
+ chdir: '{{ checkout_dir }}'
+
+- name: DEPTH | again make sure the old commit was not fetched
+ assert:
+ that: 'checkout_early.rc != 0'
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+# make sure we are still able to fetch other versions
+- name: DEPTH | Clone same repo with older version
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: earlytag
+ register: cloneold
+
+- assert:
+ that: cloneold is successful
+
+- name: DEPTH | try to access earlier commit
+ shell: "git checkout {{git_shallow_head_1.stdout}}"
+ args:
+ chdir: '{{ checkout_dir }}'
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+# Test for https://github.com/ansible/ansible/issues/21316
+- name: DEPTH | Shallow clone with tag
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: earlytag
+ register: cloneold
+
+- assert:
+ that: cloneold is successful
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+
+ # Test for https://github.com/ansible/ansible-modules-core/issues/3456
+ # clone a repo with depth and version specified
+
+- name: DEPTH | clone repo with both version and depth specified
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: master
+
+- name: DEPTH | run a second time (now fetch, not clone)
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: master
+ register: git_fetch
+
+- name: DEPTH | ensure the fetch succeeded
+ assert:
+ that: git_fetch is successful
+
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: DEPTH | clone repo with both version and depth specified
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: master
+
+- name: DEPTH | switch to older branch with depth=1 (uses fetch)
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: earlybranch
+ register: git_fetch
+
+- name: DEPTH | ensure the fetch succeeded
+ assert:
+ that: git_fetch is successful
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+# test for https://github.com/ansible/ansible-modules-core/issues/3782
+# make sure shallow fetch works when no version is specified
+
+- name: DEPTH | checkout old repo
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+
+- name: DEPTH | "update repo"
+ shell: echo "3" > a; git commit -a -m "3"
+ args:
+ chdir: "{{ repo_dir }}/shallow"
+
+- name: DEPTH | fetch updated repo
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ register: git_fetch
+ ignore_errors: yes
+
+- name: DEPTH | get "a" file
+ slurp:
+ src: '{{ checkout_dir }}/a'
+ register: a_file
+
+- name: DEPTH | check update arrived
+ assert:
+ that:
+ - "{{ a_file.content | b64decode | trim }} == 3"
+ - git_fetch is changed
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+#
+# Make sure shallow fetch works when switching to (fetching) a new a branch
+#
+
+- name: DEPTH | clone from branch with depth specified
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow_branches'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: test_branch
+
+- name: DEPTH | check if clone is shallow
+ stat: path={{ checkout_dir }}/.git/shallow
+ register: is_shallow
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+- name: DEPTH | assert that clone is shallow
+ assert:
+ that:
+ - is_shallow.stat.exists
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+- name: DEPTH | switch to new branch (fetch) with the shallow clone
+ git:
+ repo: 'file://{{ repo_dir|expanduser }}/shallow_branches'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ version: new_branch
+ register: git_fetch
+
+- name: DEPTH | assert if switching a shallow clone to a new branch worked
+ assert:
+ that:
+ - git_fetch is changed
+
+- name: DEPTH | check if clone is still shallow
+ stat: path={{ checkout_dir }}/.git/shallow
+ register: is_shallow
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+- name: DEPTH | assert that clone still is shallow
+ assert:
+ that:
+ - is_shallow.stat.exists
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+- name: DEPTH | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
diff --git a/test/integration/targets/git/tasks/forcefully-fetch-tag.yml b/test/integration/targets/git/tasks/forcefully-fetch-tag.yml
new file mode 100644
index 00000000..47c37478
--- /dev/null
+++ b/test/integration/targets/git/tasks/forcefully-fetch-tag.yml
@@ -0,0 +1,38 @@
+# Tests against https://github.com/ansible/ansible/issues/67972
+
+# Do our first clone manually; there are no commits yet and Ansible doesn't like
+# that.
+- name: FORCEFULLY-FETCH-TAG | Clone the bare repo in a non-bare clone
+ shell: git clone {{ repo_dir }}/tag_force_push {{ repo_dir }}/tag_force_push_clone1
+
+- name: FORCEFULLY-FETCH-TAG | Prepare repo with a tag
+ shell: |
+ echo 1337 > leet;
+ git add leet;
+ git commit -m uh-oh;
+ git tag -f herewego;
+ git push --tags origin master
+ args:
+ chdir: "{{ repo_dir }}/tag_force_push_clone1"
+
+- name: FORCEFULLY-FETCH-TAG | clone the repo for the second time
+ git:
+ repo: "{{ repo_dir }}/tag_force_push"
+ dest: "{{ repo_dir }}/tag_force_push_clone2"
+
+- name: FORCEFULLY-FETCH-TAG | Forcefully overwrite the tag in clone1
+ shell: |
+ echo 1338 > leet;
+ git add leet;
+ git commit -m uh-oh;
+ git tag -f herewego;
+ git push -f --tags origin master
+ args:
+ chdir: "{{ repo_dir }}/tag_force_push_clone1"
+
+- name: FORCEFULLY-FETCH-TAG | Try to update the second clone
+ git:
+ repo: "{{ repo_dir }}/tag_force_push"
+ dest: "{{ repo_dir }}/tag_force_push_clone2"
+ force: yes
+ register: git_res
diff --git a/test/integration/targets/git/tasks/formats.yml b/test/integration/targets/git/tasks/formats.yml
new file mode 100644
index 00000000..e5fcda72
--- /dev/null
+++ b/test/integration/targets/git/tasks/formats.yml
@@ -0,0 +1,40 @@
+- name: FORMATS | initial checkout
+ git:
+ repo: "{{ repo_format1 }}"
+ dest: "{{ repo_dir }}/format1"
+ register: git_result
+
+- name: FORMATS | verify information about the initial clone
+ assert:
+ that:
+ - "'before' in git_result"
+ - "'after' in git_result"
+ - "not git_result.before"
+ - "git_result.changed"
+
+- name: FORMATS | repeated checkout
+ git:
+ repo: "{{ repo_format1 }}"
+ dest: "{{ repo_dir }}/format1"
+ register: git_result2
+
+- name: FORMATS | check for tags
+ stat:
+ path: "{{ repo_dir }}/format1/.git/refs/tags"
+ register: tags
+
+- name: FORMATS | check for HEAD
+ stat:
+ path: "{{ repo_dir }}/format1/.git/HEAD"
+ register: head
+
+- name: FORMATS | assert presence of tags/trunk/branches
+ assert:
+ that:
+ - "tags.stat.isdir"
+ - "head.stat.isreg"
+
+- name: FORMATS | verify on a reclone things are marked unchanged
+ assert:
+ that:
+ - "not git_result2.changed"
diff --git a/test/integration/targets/git/tasks/gpg-verification.yml b/test/integration/targets/git/tasks/gpg-verification.yml
new file mode 100644
index 00000000..8c8834a9
--- /dev/null
+++ b/test/integration/targets/git/tasks/gpg-verification.yml
@@ -0,0 +1,212 @@
+# Test for verification of GnuPG signatures
+
+- name: GPG-VERIFICATION | Create GnuPG verification workdir
+ tempfile:
+ state: directory
+ register: git_gpg_workdir
+
+- name: GPG-VERIFICATION | Define variables based on workdir
+ set_fact:
+ git_gpg_keyfile: "{{ git_gpg_workdir.path }}/testkey.asc"
+ git_gpg_source: "{{ git_gpg_workdir.path }}/source"
+ git_gpg_dest: "{{ git_gpg_workdir.path }}/dest"
+ git_gpg_gpghome: "{{ git_gpg_workdir.path }}/gpg"
+
+- name: GPG-VERIFICATION | Temporary store GnuPG test key
+ copy:
+ content: "{{ git_gpg_testkey }}"
+ dest: "{{ git_gpg_keyfile }}"
+
+- name: GPG-VERIFICATION | Create temporary GNUPGHOME directory
+ file:
+ path: "{{ git_gpg_gpghome }}"
+ state: directory
+ mode: 0700
+
+- name: GPG-VERIFICATION | Import GnuPG test key
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ command: gpg --import {{ git_gpg_keyfile }}
+
+- name: GPG-VERIFICATION | Create local GnuPG signed repository directory
+ file:
+ path: "{{ git_gpg_source }}"
+ state: directory
+
+- name: GPG-VERIFICATION | Generate local GnuPG signed repository
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ shell: |
+ set -e
+ git init
+ touch an_empty_file
+ git add an_empty_file
+ git commit --no-gpg-sign --message "Commit, and don't sign"
+ git tag lightweight_tag/unsigned_commit HEAD
+ git commit --allow-empty --gpg-sign --message "Commit, and sign"
+ git tag lightweight_tag/signed_commit HEAD
+ git tag --annotate --message "This is not a signed tag" unsigned_annotated_tag HEAD
+ git commit --allow-empty --gpg-sign --message "Commit, and sign"
+ git tag --sign --message "This is a signed tag" signed_annotated_tag HEAD
+ git checkout -b some_branch/signed_tip master
+ git commit --allow-empty --gpg-sign --message "Commit, and sign"
+ git checkout -b another_branch/unsigned_tip master
+ git commit --allow-empty --no-gpg-sign --message "Commit, and don't sign"
+ git checkout master
+ args:
+ chdir: "{{ git_gpg_source }}"
+
+- name: GPG-VERIFICATION | Get hash of an unsigned commit
+ command: git show-ref --hash --verify refs/tags/lightweight_tag/unsigned_commit
+ args:
+ chdir: "{{ git_gpg_source }}"
+ register: git_gpg_unsigned_commit
+
+- name: GPG-VERIFICATION | Get hash of a signed commit
+ command: git show-ref --hash --verify refs/tags/lightweight_tag/signed_commit
+ args:
+ chdir: "{{ git_gpg_source }}"
+ register: git_gpg_signed_commit
+
+- name: GPG-VERIFICATION | Clone repo and verify signed HEAD
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ verify_commit: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Clone repo and verify a signed lightweight tag
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: lightweight_tag/signed_commit
+ verify_commit: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Clone repo and verify an unsigned lightweight tag (should fail)
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: lightweight_tag/unsigned_commit
+ verify_commit: yes
+ register: git_verify
+ ignore_errors: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Check that unsigned lightweight tag verification failed
+ assert:
+ that:
+ - git_verify is failed
+ - git_verify.msg is match("Failed to verify GPG signature of commit/tag.+")
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Clone repo and verify a signed commit
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: "{{ git_gpg_signed_commit.stdout }}"
+ verify_commit: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Clone repo and verify an unsigned commit
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: "{{ git_gpg_unsigned_commit.stdout }}"
+ verify_commit: yes
+ register: git_verify
+ ignore_errors: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Check that unsigned commit verification failed
+ assert:
+ that:
+ - git_verify is failed
+ - git_verify.msg is match("Failed to verify GPG signature of commit/tag.+")
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Clone repo and verify a signed annotated tag
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: signed_annotated_tag
+ verify_commit: yes
+
+- name: GPG-VERIFICATION | Clone repo and verify an unsigned annotated tag (should fail)
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: unsigned_annotated_tag
+ verify_commit: yes
+ register: git_verify
+ ignore_errors: yes
+
+- name: GPG-VERIFICATION | Check that unsigned annotated tag verification failed
+ assert:
+ that:
+ - git_verify is failed
+ - git_verify.msg is match("Failed to verify GPG signature of commit/tag.+")
+
+- name: GPG-VERIFICATION | Clone repo and verify a signed branch
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: some_branch/signed_tip
+ verify_commit: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Clone repo and verify an unsigned branch (should fail)
+ environment:
+ - GNUPGHOME: "{{ git_gpg_gpghome }}"
+ git:
+ repo: "{{ git_gpg_source }}"
+ dest: "{{ git_gpg_dest }}"
+ version: another_branch/unsigned_tip
+ verify_commit: yes
+ register: git_verify
+ ignore_errors: yes
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Check that unsigned branch verification failed
+ assert:
+ that:
+ - git_verify is failed
+ - git_verify.msg is match("Failed to verify GPG signature of commit/tag.+")
+ when:
+ - git_version.stdout is version("2.1.0", '>=')
+
+- name: GPG-VERIFICATION | Stop gpg-agent so we can remove any locks on the GnuPG dir
+ command: gpgconf --kill gpg-agent
+ environment:
+ GNUPGHOME: "{{ git_gpg_gpghome }}"
+ ignore_errors: yes
+
+- name: GPG-VERIFICATION | Remove GnuPG verification workdir
+ file:
+ path: "{{ git_gpg_workdir.path }}"
+ state: absent
diff --git a/test/integration/targets/git/tasks/localmods.yml b/test/integration/targets/git/tasks/localmods.yml
new file mode 100644
index 00000000..09a1326d
--- /dev/null
+++ b/test/integration/targets/git/tasks/localmods.yml
@@ -0,0 +1,112 @@
+# test for https://github.com/ansible/ansible-modules-core/pull/5505
+- name: LOCALMODS | prepare old git repo
+ shell: rm -rf localmods; mkdir localmods; cd localmods; git init; echo "1" > a; git add a; git commit -m "1"
+ args:
+ chdir: "{{repo_dir}}"
+
+- name: LOCALMODS | checkout old repo
+ git:
+ repo: '{{ repo_dir }}/localmods'
+ dest: '{{ checkout_dir }}'
+
+- name: LOCALMODS | "update repo"
+ shell: echo "2" > a; git commit -a -m "2"
+ args:
+ chdir: "{{repo_dir}}/localmods"
+
+- name: LOCALMODS | "add local mods"
+ shell: echo "3" > a
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: LOCALMODS | fetch with local mods without force (should fail)
+ git:
+ repo: '{{ repo_dir }}/localmods'
+ dest: '{{ checkout_dir }}'
+ register: git_fetch
+ ignore_errors: yes
+
+- name: LOCALMODS | check fetch with localmods failed
+ assert:
+ that:
+ - git_fetch is failed
+
+- name: LOCALMODS | fetch with local mods with force
+ git:
+ repo: '{{ repo_dir }}/localmods'
+ dest: '{{ checkout_dir }}'
+ force: True
+ register: git_fetch_force
+ ignore_errors: yes
+
+- name: LOCALMODS | get "a" file
+ slurp:
+ src: '{{ checkout_dir }}/a'
+ register: a_file
+
+- name: LOCALMODS | check update arrived
+ assert:
+ that:
+ - "{{ a_file.content | b64decode | trim }} == 2"
+ - git_fetch_force is changed
+
+- name: LOCALMODS | clear checkout_dir
+ file: state=absent path={{ checkout_dir }}
+
+# localmods and shallow clone
+- name: LOCALMODS | prepare old git repo
+ shell: rm -rf localmods; mkdir localmods; cd localmods; git init; echo "1" > a; git add a; git commit -m "1"
+ args:
+ chdir: "{{repo_dir}}"
+
+- name: LOCALMODS | checkout old repo
+ git:
+ repo: '{{ repo_dir }}/localmods'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+
+- name: LOCALMODS | "update repo"
+ shell: echo "2" > a; git commit -a -m "2"
+ args:
+ chdir: "{{repo_dir}}/localmods"
+
+- name: LOCALMODS | "add local mods"
+ shell: echo "3" > a
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: LOCALMODS | fetch with local mods without force (should fail)
+ git:
+ repo: '{{ repo_dir }}/localmods'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ register: git_fetch
+ ignore_errors: yes
+
+- name: LOCALMODS | check fetch with localmods failed
+ assert:
+ that:
+ - git_fetch is failed
+
+- name: LOCALMODS | fetch with local mods with force
+ git:
+ repo: '{{ repo_dir }}/localmods'
+ dest: '{{ checkout_dir }}'
+ depth: 1
+ force: True
+ register: git_fetch_force
+ ignore_errors: yes
+
+- name: LOCALMODS | get "a" file
+ slurp:
+ src: '{{ checkout_dir }}/a'
+ register: a_file
+
+- name: LOCALMODS | check update arrived
+ assert:
+ that:
+ - "{{ a_file.content | b64decode | trim }} == 2"
+ - git_fetch_force is changed
+
+- name: LOCALMODS | clear checkout_dir
+ file: state=absent path={{ checkout_dir }}
diff --git a/test/integration/targets/git/tasks/main.yml b/test/integration/targets/git/tasks/main.yml
new file mode 100644
index 00000000..722713bf
--- /dev/null
+++ b/test/integration/targets/git/tasks/main.yml
@@ -0,0 +1,40 @@
+# test code for the git module
+# (c) 2014, James Tanner <tanner.jc@gmail.com>
+
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+- include_tasks: setup.yml
+- include_tasks: setup-local-repos.yml
+
+- include_tasks: formats.yml
+- include_tasks: missing_hostkey.yml
+- include_tasks: no-destination.yml
+- include_tasks: specific-revision.yml
+- include_tasks: submodules.yml
+- include_tasks: change-repo-url.yml
+- include_tasks: depth.yml
+- include_tasks: checkout-new-tag.yml
+- include_tasks: gpg-verification.yml
+ when:
+ - not gpg_version.stderr
+ - gpg_version.stdout
+ - not (ansible_os_family == 'RedHat' and ansible_distribution_major_version is version('7', '<'))
+- include_tasks: localmods.yml
+- include_tasks: reset-origin.yml
+- include_tasks: ambiguous-ref.yml
+- include_tasks: archive.yml
+- include_tasks: separate-git-dir.yml
+- include_tasks: forcefully-fetch-tag.yml
diff --git a/test/integration/targets/git/tasks/missing_hostkey.yml b/test/integration/targets/git/tasks/missing_hostkey.yml
new file mode 100644
index 00000000..02d5be35
--- /dev/null
+++ b/test/integration/targets/git/tasks/missing_hostkey.yml
@@ -0,0 +1,48 @@
+- name: MISSING-HOSTKEY | checkout ssh://git@github.com repo without accept_hostkey (expected fail)
+ git:
+ repo: '{{ repo_format2 }}'
+ dest: '{{ checkout_dir }}'
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+ ignore_errors: true
+
+- assert:
+ that:
+ - git_result is failed
+
+- name: MISSING-HOSTKEY | checkout git@github.com repo with accept_hostkey (expected pass)
+ git:
+ repo: '{{ repo_format2 }}'
+ dest: '{{ checkout_dir }}'
+ accept_hostkey: true
+ key_file: '{{ github_ssh_private_key }}'
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+ when: github_ssh_private_key is defined
+
+- assert:
+ that:
+ - git_result is changed
+ when: github_ssh_private_key is defined
+
+- name: MISSING-HOSTKEY | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
+ when: github_ssh_private_key is defined
+
+- name: MISSING-HOSTKEY | checkout ssh://git@github.com repo with accept_hostkey (expected pass)
+ git:
+ repo: '{{ repo_format3 }}'
+ dest: '{{ checkout_dir }}'
+ version: 'master'
+ accept_hostkey: false # should already have been accepted
+ key_file: '{{ github_ssh_private_key }}'
+ ssh_opts: '-o UserKnownHostsFile={{ output_dir }}/known_hosts'
+ register: git_result
+ when: github_ssh_private_key is defined
+
+- assert:
+ that:
+ - git_result is changed
+ when: github_ssh_private_key is defined
diff --git a/test/integration/targets/git/tasks/no-destination.yml b/test/integration/targets/git/tasks/no-destination.yml
new file mode 100644
index 00000000..1ef7f2fd
--- /dev/null
+++ b/test/integration/targets/git/tasks/no-destination.yml
@@ -0,0 +1,13 @@
+# Test a non-updating repo query with no destination specified
+
+- name: NO-DESTINATION | get info on a repo without updating and with no destination specified
+ git:
+ repo: '{{ repo_dir }}/minimal'
+ update: no
+ clone: no
+ accept_hostkey: yes
+ register: git_result
+
+- assert:
+ that:
+ - git_result is changed
diff --git a/test/integration/targets/git/tasks/reset-origin.yml b/test/integration/targets/git/tasks/reset-origin.yml
new file mode 100644
index 00000000..8fddd4b1
--- /dev/null
+++ b/test/integration/targets/git/tasks/reset-origin.yml
@@ -0,0 +1,25 @@
+- name: RESET-ORIGIN | Clean up the directories
+ file:
+ state: absent
+ path: "{{ item }}"
+ with_items:
+ - "{{ repo_dir }}/origin"
+ - "{{ checkout_dir }}"
+
+- name: RESET-ORIGIN | Create a directory
+ file:
+ name: "{{ repo_dir }}/origin"
+ state: directory
+
+- name: RESET-ORIGIN | Initialise the repo with a file named origin,see github.com/ansible/ansible/pull/22502
+ shell: git init; echo "PR 22502" > origin; git add origin; git commit -m "PR 22502"
+ args:
+ chdir: "{{ repo_dir }}/origin"
+
+- name: RESET-ORIGIN | Clone a git repo with file named origin
+ git:
+ repo: "{{ repo_dir }}/origin"
+ dest: "{{ checkout_dir }}"
+ remote: origin
+ update: no
+ register: status
diff --git a/test/integration/targets/git/tasks/separate-git-dir.yml b/test/integration/targets/git/tasks/separate-git-dir.yml
new file mode 100644
index 00000000..5b874043
--- /dev/null
+++ b/test/integration/targets/git/tasks/separate-git-dir.yml
@@ -0,0 +1,132 @@
+# test code for repositories with separate git dir updating
+# see https://github.com/ansible/ansible/pull/38016
+# see https://github.com/ansible/ansible/issues/30034
+
+- name: SEPARATE-GIT-DIR | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
+
+- name: SEPARATE-GIT-DIR | make a pre-exist repo dir
+ file:
+ state: directory
+ path: '{{ separate_git_dir }}'
+
+- name: SEPARATE-GIT-DIR | clone with a separate git dir
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ separate_git_dir: '{{ separate_git_dir }}'
+ ignore_errors: yes
+ register: result
+
+- name: SEPARATE-GIT-DIR | the clone will fail due to pre-exist dir
+ assert:
+ that: 'result is failed'
+
+- name: SEPARATE-GIT-DIR | delete pre-exist dir
+ file:
+ state: absent
+ path: '{{ separate_git_dir }}'
+
+- name: SEPARATE-GIT-DIR | clone again with a separate git dir
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ separate_git_dir: '{{ separate_git_dir }}'
+
+- name: SEPARATE-GIT-DIR | check the stat of git dir
+ stat:
+ path: '{{ separate_git_dir }}'
+ register: stat_result
+
+- name: SEPARATE-GIT-DIR | the git dir should exist
+ assert:
+ that: 'stat_result.stat.exists == True'
+
+- name: SEPARATE-GIT-DIR | update repo the usual way
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ separate_git_dir: '{{ separate_git_dir }}'
+ register: result
+
+- name: SEPARATE-GIT-DIR | update should not fail
+ assert:
+ that:
+ - result is not failed
+
+- name: SEPARATE-GIT-DIR | move the git dir to new place
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ separate_git_dir: '{{ separate_git_dir }}_new'
+ register: result
+
+- name: SEPARATE-GIT-DIR | the movement should not failed
+ assert:
+ that: 'result is not failed'
+
+- name: SEPARATE-GIT-DIR | check the stat of new git dir
+ stat:
+ path: '{{ separate_git_dir }}_new'
+ register: stat_result
+
+- name: SEPARATE-GIT-DIR | the new git dir should exist
+ assert:
+ that: 'stat_result.stat.exists == True'
+
+- name: SEPARATE-GIT-DIR | test the update
+ git:
+ repo: '{{ repo_format1 }}'
+ dest: '{{ checkout_dir }}'
+ register: result
+
+- name: SEPARATE-GIT-DIR | the update should not failed
+ assert:
+ that:
+ - result is not failed
+
+- name: SEPARATE-GIT-DIR | set git dir to non-existent dir
+ shell: "echo gitdir: /dev/null/non-existent-dir > .git"
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: SEPARATE-GIT-DIR | update repo the usual way
+ git:
+ repo: "{{ repo_format1 }}"
+ dest: "{{ checkout_dir }}"
+ ignore_errors: yes
+ register: result
+
+- name: SEPARATE-GIT-DIR | check update has failed
+ assert:
+ that:
+ - result is failed
+
+- name: SEPARATE-GIT-DIR | set .git file to bad format
+ shell: "echo some text gitdir: {{ checkout_dir }} > .git"
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: SEPARATE-GIT-DIR | update repo the usual way
+ git:
+ repo: "{{ repo_format1 }}"
+ dest: "{{ checkout_dir }}"
+ ignore_errors: yes
+ register: result
+
+- name: SEPARATE-GIT-DIR | check update has failed
+ assert:
+ that:
+ - result is failed
+
+- name: SEPARATE-GIT-DIR | clear separate git dir
+ file:
+ state: absent
+ path: "{{ separate_git_dir }}_new"
+
+- name: SEPARATE-GIT-DIR | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
diff --git a/test/integration/targets/git/tasks/setup-local-repos.yml b/test/integration/targets/git/tasks/setup-local-repos.yml
new file mode 100644
index 00000000..584a1693
--- /dev/null
+++ b/test/integration/targets/git/tasks/setup-local-repos.yml
@@ -0,0 +1,45 @@
+- name: SETUP-LOCAL-REPOS | create dirs
+ file:
+ name: "{{ item }}"
+ state: directory
+ with_items:
+ - "{{ repo_dir }}/minimal"
+ - "{{ repo_dir }}/shallow"
+ - "{{ repo_dir }}/shallow_branches"
+ - "{{ repo_dir }}/tag_force_push"
+
+- name: SETUP-LOCAL-REPOS | prepare minimal git repo
+ shell: git init; echo "1" > a; git add a; git commit -m "1"
+ args:
+ chdir: "{{ repo_dir }}/minimal"
+
+- name: SETUP-LOCAL-REPOS | prepare git repo for shallow clone
+ shell: |
+ git init;
+ echo "1" > a; git add a; git commit -m "1"; git tag earlytag; git branch earlybranch;
+ echo "2" > a; git add a; git commit -m "2";
+ args:
+ chdir: "{{ repo_dir }}/shallow"
+
+- name: SETUP-LOCAL-REPOS | set old hash var for shallow test
+ command: 'git rev-parse HEAD~1'
+ register: git_shallow_head_1
+ args:
+ chdir: "{{ repo_dir }}/shallow"
+
+- name: SETUP-LOCAL-REPOS | prepare tmp git repo with two branches
+ shell: |
+ git init
+ echo "1" > a; git add a; git commit -m "1"
+ git checkout -b test_branch; echo "2" > a; git commit -m "2 on branch" a
+ git checkout -b new_branch; echo "3" > a; git commit -m "3 on new branch" a
+ args:
+ chdir: "{{ repo_dir }}/shallow_branches"
+
+# Make this a bare one, we need to be able to push to it from clones
+# We make the repo here for consistency with the other repos,
+# but we finish setting it up in forcefully-fetch-tag.yml.
+- name: SETUP-LOCAL-REPOS | prepare tag_force_push git repo
+ shell: git init --bare
+ args:
+ chdir: "{{ repo_dir }}/tag_force_push"
diff --git a/test/integration/targets/git/tasks/setup.yml b/test/integration/targets/git/tasks/setup.yml
new file mode 100644
index 00000000..16c56904
--- /dev/null
+++ b/test/integration/targets/git/tasks/setup.yml
@@ -0,0 +1,43 @@
+- name: SETUP | clean out the output_dir
+ file:
+ path: "{{ output_dir }}"
+ state: absent
+
+- name: SETUP | create clean output_dir
+ file:
+ path: "{{ output_dir }}"
+ state: directory
+
+- name: SETUP | install git
+ package:
+ name: '{{ item }}'
+ when: ansible_distribution != "MacOSX"
+ notify:
+ - cleanup
+ with_items: "{{ git_required_packages[ansible_os_family | default('default') ] | default(git_required_packages.default) }}"
+
+- name: SETUP | verify that git is installed so this test can continue
+ shell: which git
+
+- name: SETUP | get git version, only newer than {{git_version_supporting_depth}} has fixed git depth
+ shell: git --version | grep 'git version' | sed 's/git version //'
+ register: git_version
+
+- name: SETUP | get gpg version
+ shell: gpg --version 2>1 | head -1 | sed -e 's/gpg (GnuPG) //'
+ register: gpg_version
+
+- name: SETUP | set git global user.email if not already set
+ shell: git config --global user.email || git config --global user.email "noreply@example.com"
+
+- name: SETUP | set git global user.name if not already set
+ shell: git config --global user.name || git config --global user.name "Ansible Test Runner"
+
+- name: SETUP | create repo_dir
+ file:
+ path: "{{ repo_dir }}"
+ state: directory
+
+- name: SETUP | show git version
+ debug:
+ msg: "Running test with git {{ git_version.stdout }}"
diff --git a/test/integration/targets/git/tasks/specific-revision.yml b/test/integration/targets/git/tasks/specific-revision.yml
new file mode 100644
index 00000000..26fa7cf3
--- /dev/null
+++ b/test/integration/targets/git/tasks/specific-revision.yml
@@ -0,0 +1,238 @@
+# Test that a specific revision can be checked out
+
+- name: SPECIFIC-REVISION | clear checkout_dir
+ file:
+ state: absent
+ path: '{{ checkout_dir }}'
+
+- name: SPECIFIC-REVISION | clone to specific revision
+ git:
+ repo: "{{ repo_dir }}/format1"
+ dest: "{{ checkout_dir }}"
+ version: df4612ba925fbc1b3c51cbb006f51a0443bd2ce9
+
+- name: SPECIFIC-REVISION | check HEAD after clone to revision
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_result
+
+- assert:
+ that:
+ - 'git_result.stdout == "df4612ba925fbc1b3c51cbb006f51a0443bd2ce9"'
+
+- name: SPECIFIC-REVISION | update to specific revision
+ git:
+ repo: "{{ repo_dir }}/format1"
+ dest: "{{ checkout_dir }}"
+ version: 4e739a34719654db7b04896966e2354e1256ea5d
+ register: git_result
+
+- assert:
+ that:
+ - git_result is changed
+
+- name: SPECIFIC-REVISION | check HEAD after update to revision
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_result
+
+- assert:
+ that:
+ - 'git_result.stdout == "4e739a34719654db7b04896966e2354e1256ea5d"'
+
+- name: SPECIFIC-REVISION | update to HEAD from detached HEAD state
+ git:
+ repo: "{{ repo_dir }}/format1"
+ dest: "{{ checkout_dir }}"
+ version: HEAD
+ register: git_result
+
+- assert:
+ that:
+ - git_result is changed
+
+# Test a revision not available under refs/heads/ or refs/tags/
+
+- name: SPECIFIC-REVISION | attempt to get unavailable revision
+ git:
+ repo: "{{ repo_dir }}/format1"
+ dest: "{{ checkout_dir }}"
+ version: 5473e343e33255f2da0b160f53135c56921d875c
+ ignore_errors: true
+ register: git_result
+
+- assert:
+ that:
+ - git_result is failed
+
+# Same as the previous test, but this time we specify which ref
+# contains the SHA1
+- name: SPECIFIC-REVISION | update to revision by specifying the refspec
+ git:
+ repo: https://github.com/ansible/ansible-examples.git
+ dest: '{{ checkout_dir }}'
+ version: 5473e343e33255f2da0b160f53135c56921d875c
+ refspec: refs/pull/7/merge
+
+- name: SPECIFIC-REVISION | check HEAD after update with refspec
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_result
+
+- assert:
+ that:
+ - 'git_result.stdout == "5473e343e33255f2da0b160f53135c56921d875c"'
+
+# try out combination of refspec and depth
+- name: SPECIFIC-REVISION | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | update to revision by specifying the refspec with depth=1
+ git:
+ repo: https://github.com/ansible/ansible-examples.git
+ dest: '{{ checkout_dir }}'
+ version: 5473e343e33255f2da0b160f53135c56921d875c
+ refspec: refs/pull/7/merge
+ depth: 1
+
+- name: SPECIFIC-REVISION | check HEAD after update with refspec
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_result
+
+- assert:
+ that:
+ - 'git_result.stdout == "5473e343e33255f2da0b160f53135c56921d875c"'
+
+- name: SPECIFIC-REVISION | try to access other commit
+ shell: git checkout 0ce1096
+ register: checkout_shallow
+ failed_when: False
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | "make sure the old commit was not fetched, task is 'forced success'"
+ assert:
+ that:
+ - checkout_shallow.rc != 0
+ - checkout_shallow is successful
+ when: git_version.stdout is version(git_version_supporting_depth, '>=')
+
+- name: SPECIFIC-REVISION | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | clone to revision by specifying the refspec
+ git:
+ repo: https://github.com/ansible/ansible-examples.git
+ dest: "{{ checkout_dir }}"
+ version: 5473e343e33255f2da0b160f53135c56921d875c
+ refspec: refs/pull/7/merge
+
+- name: SPECIFIC-REVISION | check HEAD after update with refspec
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: git_result
+
+- assert:
+ that:
+ - 'git_result.stdout == "5473e343e33255f2da0b160f53135c56921d875c"'
+
+# Test that a forced shallow checkout referincing branch only always fetches latest head
+
+- name: SPECIFIC-REVISION | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ item }}"
+ with_items:
+ - "{{ checkout_dir }}"
+ - "{{ checkout_dir }}.copy"
+
+- name: SPECIFIC-REVISION | create original repo dir
+ file:
+ state: directory
+ path: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | prepare origina repo
+ shell: git init; echo "1" > a; git add a; git commit -m "1"
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | clone example repo locally
+ git:
+ repo: "{{ checkout_dir }}"
+ dest: "{{ checkout_dir }}.copy"
+
+- name: SPECIFIC-REVISION | create branch in original
+ command: git checkout -b test/branch
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | get commit for HEAD on new branch
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}.copy"
+ register: originaltip0
+
+- name: SPECIFIC-REVISION | shallow force checkout new branch in copy
+ git:
+ repo: "{{ checkout_dir }}"
+ dest: "{{ checkout_dir }}.copy"
+ version: test/branch
+ depth: 1
+ force: yes
+
+- name: SPECIFIC-REVISION | create new commit in original
+ shell: git init; echo "2" > b; git add b; git commit -m "2"
+ args:
+ chdir: "{{ checkout_dir }}"
+
+- name: SPECIFIC-REVISION | get commit for new HEAD on original branch
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}"
+ register: originaltip1
+
+- name: SPECIFIC-REVISION | get commit for HEAD on new branch
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}.copy"
+ register: newtip
+
+- name: SPECIFIC-REVISION | assert that copy is still pointing at previous tip
+ assert:
+ that:
+ - newtip.stdout == originaltip0.stdout
+
+- name: SPECIFIC-REVISION | create a local modification in the copy
+ shell: echo "3" > c
+ args:
+ chdir: "{{ checkout_dir }}.copy"
+
+- name: SPECIFIC-REVISION | shallow force checkout new branch in copy (again)
+ git:
+ repo: "{{ checkout_dir }}"
+ dest: "{{ checkout_dir }}.copy"
+ version: test/branch
+ depth: 1
+ force: yes
+
+- name: SPECIFIC-REVISION | get commit for HEAD on new branch
+ command: git rev-parse HEAD
+ args:
+ chdir: "{{ checkout_dir }}.copy"
+ register: newtip
+
+- name: SPECIFIC-REVISION | make sure copy tip is not pointing at previous sha and that new tips match
+ assert:
+ that:
+ - newtip.stdout != originaltip0.stdout
+ - newtip.stdout == originaltip1.stdout
diff --git a/test/integration/targets/git/tasks/submodules.yml b/test/integration/targets/git/tasks/submodules.yml
new file mode 100644
index 00000000..647d1e23
--- /dev/null
+++ b/test/integration/targets/git/tasks/submodules.yml
@@ -0,0 +1,124 @@
+#
+# Submodule tests
+#
+
+# Repository A with submodules defined (repo_submodules)
+# .gitmodules file points to Repository I
+# Repository B forked from A that has newer commits (repo_submodules_newer)
+# .gitmodules file points to Repository II instead of I
+# .gitmodules file also points to Repository III
+# Repository I for submodule1 (repo_submodule1)
+# Has 1 file checked in
+# Repository II forked from I that has newer commits (repo_submodule1_newer)
+# Has 2 files checked in
+# Repository III for a second submodule (repo_submodule2)
+# Has 1 file checked in
+
+- name: SUBMODULES | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: SUBMODULES | Test that clone without recursive does not retrieve submodules
+ git:
+ repo: "{{ repo_submodules }}"
+ version: 45c6c07ef10fd9e453d90207e63da1ce5bd3ae1e
+ dest: "{{ checkout_dir }}"
+ recursive: no
+
+- name: SUBMODULES | List submodule1
+ command: 'ls -1a {{ checkout_dir }}/submodule1'
+ register: submodule1
+
+- name: SUBMODULES | Ensure submodu1 is at the appropriate commit
+ assert:
+ that: '{{ submodule1.stdout_lines | length }} == 2'
+
+- name: SUBMODULES | clear checkout_dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+
+- name: SUBMODULES | Test that clone with recursive retrieves submodules
+ git:
+ repo: "{{ repo_submodules }}"
+ dest: "{{ checkout_dir }}"
+ version: 45c6c07ef10fd9e453d90207e63da1ce5bd3ae1e
+ recursive: yes
+
+- name: SUBMODULES | List submodule1
+ command: 'ls -1a {{ checkout_dir }}/submodule1'
+ register: submodule1
+
+- name: SUBMODULES | Ensure submodule1 is at the appropriate commit
+ assert:
+ that: '{{ submodule1.stdout_lines | length }} == 4'
+
+- name: SUBMODULES | Copy the checkout so we can run several different tests on it
+ command: 'cp -pr {{ checkout_dir }} {{ checkout_dir }}.bak'
+
+
+- name: SUBMODULES | Test that update without recursive does not change submodules
+ git:
+ repo: "{{ repo_submodules }}"
+ version: d2974e4bbccdb59368f1d5eff2205f0fa863297e
+ dest: "{{ checkout_dir }}"
+ recursive: no
+ update: yes
+ track_submodules: yes
+
+- name: SUBMODULES | List submodule1
+ command: 'ls -1a {{ checkout_dir }}/submodule1'
+ register: submodule1
+
+- name: SUBMODULES | Stat submodule2
+ stat:
+ path: "{{ checkout_dir }}/submodule2"
+ register: submodule2
+
+- name: SUBMODULES | List submodule2
+ command: ls -1a {{ checkout_dir }}/submodule2
+ register: submodule2
+
+- name: SUBMODULES | Ensure both submodules are at the appropriate commit
+ assert:
+ that:
+ - '{{ submodule1.stdout_lines|length }} == 4'
+ - '{{ submodule2.stdout_lines|length }} == 2'
+
+
+- name: SUBMODULES | Remove checkout dir
+ file:
+ state: absent
+ path: "{{ checkout_dir }}"
+
+- name: SUBMODULES | Restore checkout to prior state
+ command: 'cp -pr {{ checkout_dir }}.bak {{ checkout_dir }}'
+
+
+- name: SUBMODULES | Test that update with recursive updated existing submodules
+ git:
+ repo: "{{ repo_submodules }}"
+ version: d2974e4bbccdb59368f1d5eff2205f0fa863297e
+ dest: "{{ checkout_dir }}"
+ update: yes
+ recursive: yes
+ track_submodules: yes
+
+- name: SUBMODULES | List submodule 1
+ command: 'ls -1a {{ checkout_dir }}/submodule1'
+ register: submodule1
+
+- name: SUBMODULES | Ensure submodule1 is at the appropriate commit
+ assert:
+ that: '{{ submodule1.stdout_lines | length }} == 5'
+
+
+- name: SUBMODULES | Test that update with recursive found new submodules
+ command: 'ls -1a {{ checkout_dir }}/submodule2'
+ register: submodule2
+
+- name: SUBMODULES | Enusre submodule2 is at the appropriate commit
+ assert:
+ that: '{{ submodule2.stdout_lines | length }} == 4'
diff --git a/test/integration/targets/git/vars/main.yml b/test/integration/targets/git/vars/main.yml
new file mode 100644
index 00000000..a5bae5ba
--- /dev/null
+++ b/test/integration/targets/git/vars/main.yml
@@ -0,0 +1,97 @@
+git_archive_extensions:
+ default:
+ - tar.gz
+ - tar
+ - tgz
+ - zip
+ RedHat6:
+ - tar
+ - zip
+
+git_required_packages:
+ default:
+ - git
+ - gzip
+ - tar
+ - unzip
+ - zip
+ FreeBSD:
+ - git
+ - gzip
+ - unzip
+ - zip
+
+git_list_commands:
+ tar.gz: tar -tf
+ tar: tar -tf
+ tgz: tar -tf
+ zip: unzip -Z1
+
+checkout_dir: '{{ output_dir }}/git'
+repo_dir: '{{ output_dir }}/local_repos'
+separate_git_dir: '{{ output_dir }}/sep_git_dir'
+repo_format1: 'https://github.com/jimi-c/test_role'
+repo_format2: 'git@github.com:jimi-c/test_role.git'
+repo_format3: 'ssh://git@github.com/jimi-c/test_role.git'
+repo_submodules: 'https://github.com/abadger/test_submodules_newer.git'
+repo_submodule1: 'https://github.com/abadger/test_submodules_subm1.git'
+repo_submodule2: 'https://github.com/abadger/test_submodules_subm2.git'
+repo_update_url_1: 'https://github.com/ansible-test-robinro/git-test-old'
+repo_update_url_2: 'https://github.com/ansible-test-robinro/git-test-new'
+known_host_files:
+ - "{{ lookup('env','HOME') }}/.ssh/known_hosts"
+ - '/etc/ssh/ssh_known_hosts'
+git_version_supporting_depth: 1.9.1
+git_version_supporting_ls_remote: 1.7.5
+# path to a SSH private key for use with github.com (tests skipped if undefined)
+# github_ssh_private_key: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa"
+git_gpg_testkey: |
+ -----BEGIN PGP PRIVATE KEY BLOCK-----
+
+ lQOYBFlkmX0BCACtE81Xj/351nnvwnAWMf8ZUP9B1YOPe9ohqNsCQY1DxODVJc9y
+ ljCoh9fTdoHXuaUMUFistozxCMP81RuZxfbfsGePnl8OAOgWT5Sln6yEG45oClJ0
+ RmJJZdDT1lF3VaVwK9NQ5E1oqmk1IOjISi7iFa9TmMn1h7ISP/p+/xtMxQhzUXt8
+ APAEhRdc9FfwxaxCHKZBiM7ND+pAm6vpom07ZUgxSppsrXZAxDncTwAeCumDpeOL
+ LAcSBsw02swOIHFfqHNrkELLr4KJqws+zeAk6R2nq0k16AVdNX+Rb7T3OKmuLawx
+ HXe8rKpaw0RC+JCogZK4tz0KDNuZPLW2Y5JJABEBAAEAB/4zkKpFk79p35YNskLd
+ wgCMRN7/+MKNDavUCnBRsEELt0z7BBxVudx+YZaSSITvxj4fuJJqxqqgJ2no2n8y
+ JdJjG7YHCnqse+WpvAUAAV4PL/ySD704Kj4fOwfoDTrRUIGNNWlseNB9RgQ5UXg5
+ MCzeq/JD+En3bnnFySzzCENUcAQfu2FVYgKEiKaKL5Djs6p5w/jTm+Let3EsIczb
+ ykJ8D4/G/tSrNdp/g10DDy+VclWMhMFqmFesedvytE8jzCVxPKOoRkFTGrX76gIK
+ eMVxHIYxdCfSTHLjBykMGO9gxfk9lf18roNYs0VV2suyi4fVFxEozSAxwWlwKrXn
+ 0arvBADPsm5NjlZ5uR06YKbpUUwPTYcwLbasic0qHuUWgNsTVv8dd2il/jbha77m
+ StU7qRJ1jwbFEFxx7HnTmeGfPbdyKe2qyLJUyD/rpQSC5YirisUchtG8nZsHlnzn
+ k10SIeB480tkgkdMQx1Eif40aiuQb09/TxaaXAEFKttZhEO4RwQA1VQ8a0IrMBI2
+ i4WqaIDNDl3x61JvvFD74v43I0AHKmZUPwcgAd6q2IvCDaKH0hIuBKu6BGq6DPvx
+ Oc/4r3iRn/xccconxRop2A9ffa00B/eQXrBq+uLBQfyiFL9UfkU8eTAAgbDKRxjY
+ ScaevoBbbYxkpgJUCL6VnoSdXlbNOO8EAL2ypsVkDmXNgR8ZT8cKSUft47di5T+9
+ mhT1qmD62B+D86892y2QAohmUDadYRK9m9WD91Y7gOMeNhYj9qbxyPprPYUL0aPt
+ L8KS1H73C5WQMOsl2RyIw81asss30LWghsFIJ1gz8gVEjXhV+YC6W9XQ42iabmRR
+ A67f5sqK1scuO0q0KUFuc2libGUgVGVzdCBSdW5uZXIgPG5vcmVwbHlAZXhhbXBs
+ ZS5jb20+iQE3BBMBCAAhBQJZZJl9AhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheA
+ AAoJEK0vcLBcXpbYi/kH/R0xk42MFpGd4pndTAsVIjRk/VhmhFc1v6sBeR40GXlt
+ hyEeOQQnIeHKLhsVT6YnfFZa8b4JwgTD6NeIiibOAlLgaKOWNwZu8toixMPVAzfQ
+ cRei+/gFXNil0FmBwWreVBDppuIn6XiSEPik0C7eCcw4lD+A+BbL3WGkp+OSQPho
+ hodIU02hgkrgs/6YJPats8Rgzw9hICsa2j0MjnG6P2z9atMz6tw2SiE5iBl7mZ2Z
+ zG/HiplleMhf/G8OZOskrWkKiLbpSPfQSKdOFkw1C6yqOlQ+HmuCZ56oyxtpItET
+ R11uAKt+ABdi4DX3FQQ+A+bGJ1+aKrcorZ8Z8s0XhPo=
+ =tV71
+ -----END PGP PRIVATE KEY BLOCK-----
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+
+ mQENBFlkmX0BCACtE81Xj/351nnvwnAWMf8ZUP9B1YOPe9ohqNsCQY1DxODVJc9y
+ ljCoh9fTdoHXuaUMUFistozxCMP81RuZxfbfsGePnl8OAOgWT5Sln6yEG45oClJ0
+ RmJJZdDT1lF3VaVwK9NQ5E1oqmk1IOjISi7iFa9TmMn1h7ISP/p+/xtMxQhzUXt8
+ APAEhRdc9FfwxaxCHKZBiM7ND+pAm6vpom07ZUgxSppsrXZAxDncTwAeCumDpeOL
+ LAcSBsw02swOIHFfqHNrkELLr4KJqws+zeAk6R2nq0k16AVdNX+Rb7T3OKmuLawx
+ HXe8rKpaw0RC+JCogZK4tz0KDNuZPLW2Y5JJABEBAAG0KUFuc2libGUgVGVzdCBS
+ dW5uZXIgPG5vcmVwbHlAZXhhbXBsZS5jb20+iQE3BBMBCAAhBQJZZJl9AhsDBQsJ
+ CAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEK0vcLBcXpbYi/kH/R0xk42MFpGd4pnd
+ TAsVIjRk/VhmhFc1v6sBeR40GXlthyEeOQQnIeHKLhsVT6YnfFZa8b4JwgTD6NeI
+ iibOAlLgaKOWNwZu8toixMPVAzfQcRei+/gFXNil0FmBwWreVBDppuIn6XiSEPik
+ 0C7eCcw4lD+A+BbL3WGkp+OSQPhohodIU02hgkrgs/6YJPats8Rgzw9hICsa2j0M
+ jnG6P2z9atMz6tw2SiE5iBl7mZ2ZzG/HiplleMhf/G8OZOskrWkKiLbpSPfQSKdO
+ Fkw1C6yqOlQ+HmuCZ56oyxtpItETR11uAKt+ABdi4DX3FQQ+A+bGJ1+aKrcorZ8Z
+ 8s0XhPo=
+ =mUYY
+ -----END PGP PUBLIC KEY BLOCK-----