From c0e0550bce1488b3a7bb137ae18961801af4c29a Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Fri, 3 Mar 2023 02:34:29 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Make=20integration=20tests=20com?= =?UTF-8?q?patible=20w/=20modern=20Git=20(#80122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 Make integration tests compatible w/ modern Git This patch makes use of the `init.defaultBranch` setting to unify the test across new and old Git versions since one defaults to `master` and the other uses `main` for the default branch. Where possible, it uses the `HEAD` committish to avoid having to normalize the branch name. The change fixes the following integration tests: * `ansible-galaxy` * `ansible-galaxy-collection-scm` (recursive collection) * `git` * 🐛Replace `git-symbolic-ref` with a repo template This custom Git repository template emulates the `init.defaultBranch` setting on Git versions below 2.28. Ref: https://superuser.com/a/1559582. Other workarounds mentioned there, like invoking `git symbolic-ref HEAD refs/heads/main` after each `git init` turned out to have mysterious side effects that break the tests in surprising ways. * 🎨 Make Git integration test non-destructive This patch makes use of the `$HOME` environment variable to trick Git into using a user-global config generated in the temporary directory. --- .../tasks/setup_recursive_scm_dependency.yml | 7 ++- .../targets/ansible-galaxy/runme.sh | 7 ++- test/integration/targets/git/tasks/depth.yml | 9 ++-- .../git/tasks/forcefully-fetch-tag.yml | 4 +- .../targets/git/tasks/gpg-verification.yml | 10 ++-- .../targets/git/tasks/localmods.yml | 26 +++++++++- test/integration/targets/git/tasks/main.yml | 50 +++++++++++-------- .../targets/git/tasks/missing_hostkey.yml | 3 +- .../git/tasks/missing_hostkey_acceptnew.yml | 3 +- .../targets/git/tasks/reset-origin.yml | 9 +++- .../targets/git/tasks/setup-local-repos.yml | 33 ++++++++++-- test/integration/targets/git/tasks/setup.yml | 38 +++++++++++++- .../targets/git/tasks/single-branch.yml | 6 ++- .../targets/git/tasks/specific-revision.yml | 18 ++++++- test/integration/targets/git/vars/main.yml | 1 + 15 files changed, 176 insertions(+), 48 deletions(-) diff --git a/test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_recursive_scm_dependency.yml b/test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_recursive_scm_dependency.yml index dd307d72a4a..520dbe5c4eb 100644 --- a/test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_recursive_scm_dependency.yml +++ b/test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_recursive_scm_dependency.yml @@ -22,7 +22,12 @@ lineinfile: path: '{{ scm_path }}/namespace_2/collection_2/galaxy.yml' regexp: '^dependencies' - line: "dependencies: {'git+file://{{ scm_path }}/namespace_1/.git#collection_1/': 'master'}" + # NOTE: The committish is set to `HEAD` here because Git's default has + # NOTE: changed to `main` and it behaves differently in + # NOTE: different envs with different Git versions. + line: >- + dependencies: + {'git+file://{{ scm_path }}/namespace_1/.git#collection_1/': 'HEAD'} - name: Commit the changes shell: git add ./; git commit -m 'add collection' diff --git a/test/integration/targets/ansible-galaxy/runme.sh b/test/integration/targets/ansible-galaxy/runme.sh index 7d966e29e42..fcd826c3387 100755 --- a/test/integration/targets/ansible-galaxy/runme.sh +++ b/test/integration/targets/ansible-galaxy/runme.sh @@ -61,10 +61,13 @@ f_ansible_galaxy_create_role_repo_post() git add . git commit -m "local testing ansible galaxy role" + # NOTE: `HEAD` is used because the newer Git versions create + # NOTE: `main` by default and the older ones differ. We + # NOTE: want to avoid hardcoding them. git archive \ --format=tar \ --prefix="${repo_name}/" \ - master > "${repo_tar}" + HEAD > "${repo_tar}" # Configure basic (insecure) HTTPS-accessible repository galaxy_local_test_role_http_repo="${galaxy_webserver_root}/${galaxy_local_test_role}.git" if [[ ! -d "${galaxy_local_test_role_http_repo}" ]]; then @@ -354,7 +357,7 @@ pushd "${galaxy_testdir}" popd # ${galaxy_testdir} f_ansible_galaxy_status \ - "role info non-existant role" + "role info non-existent role" mkdir -p "${role_testdir}" pushd "${role_testdir}" diff --git a/test/integration/targets/git/tasks/depth.yml b/test/integration/targets/git/tasks/depth.yml index 547f84f7b55..3573dfbd581 100644 --- a/test/integration/targets/git/tasks/depth.yml +++ b/test/integration/targets/git/tasks/depth.yml @@ -95,14 +95,16 @@ repo: 'file://{{ repo_dir|expanduser }}/shallow' dest: '{{ checkout_dir }}' depth: 1 - version: master + version: >- + {{ git_default_branch }} - name: DEPTH | run a second time (now fetch, not clone) git: repo: 'file://{{ repo_dir|expanduser }}/shallow' dest: '{{ checkout_dir }}' depth: 1 - version: master + version: >- + {{ git_default_branch }} register: git_fetch - name: DEPTH | ensure the fetch succeeded @@ -120,7 +122,8 @@ repo: 'file://{{ repo_dir|expanduser }}/shallow' dest: '{{ checkout_dir }}' depth: 1 - version: master + version: >- + {{ git_default_branch }} - name: DEPTH | switch to older branch with depth=1 (uses fetch) git: diff --git a/test/integration/targets/git/tasks/forcefully-fetch-tag.yml b/test/integration/targets/git/tasks/forcefully-fetch-tag.yml index 47c37478b09..db35e048f4a 100644 --- a/test/integration/targets/git/tasks/forcefully-fetch-tag.yml +++ b/test/integration/targets/git/tasks/forcefully-fetch-tag.yml @@ -11,7 +11,7 @@ git add leet; git commit -m uh-oh; git tag -f herewego; - git push --tags origin master + git push --tags origin '{{ git_default_branch }}' args: chdir: "{{ repo_dir }}/tag_force_push_clone1" @@ -26,7 +26,7 @@ git add leet; git commit -m uh-oh; git tag -f herewego; - git push -f --tags origin master + git push -f --tags origin '{{ git_default_branch }}' args: chdir: "{{ repo_dir }}/tag_force_push_clone1" diff --git a/test/integration/targets/git/tasks/gpg-verification.yml b/test/integration/targets/git/tasks/gpg-verification.yml index 8c8834a9043..bd57ed1d6ba 100644 --- a/test/integration/targets/git/tasks/gpg-verification.yml +++ b/test/integration/targets/git/tasks/gpg-verification.yml @@ -37,8 +37,10 @@ environment: - GNUPGHOME: "{{ git_gpg_gpghome }}" shell: | - set -e + set -eEu + git init + touch an_empty_file git add an_empty_file git commit --no-gpg-sign --message "Commit, and don't sign" @@ -48,11 +50,11 @@ 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 checkout -b some_branch/signed_tip '{{ git_default_branch }}' git commit --allow-empty --gpg-sign --message "Commit, and sign" - git checkout -b another_branch/unsigned_tip master + git checkout -b another_branch/unsigned_tip '{{ git_default_branch }}' git commit --allow-empty --no-gpg-sign --message "Commit, and don't sign" - git checkout master + git checkout '{{ git_default_branch }}' args: chdir: "{{ git_gpg_source }}" diff --git a/test/integration/targets/git/tasks/localmods.yml b/test/integration/targets/git/tasks/localmods.yml index 09a1326d58c..258aecc246e 100644 --- a/test/integration/targets/git/tasks/localmods.yml +++ b/test/integration/targets/git/tasks/localmods.yml @@ -1,6 +1,17 @@ # 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" + shell: | + set -eEu + + rm -rf localmods + mkdir localmods + cd localmods + + git init + + echo "1" > a + git add a + git commit -m "1" args: chdir: "{{repo_dir}}" @@ -55,7 +66,18 @@ # 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" + shell: | + set -eEu + + rm -rf localmods + mkdir localmods + cd localmods + + git init + + echo "1" > a + git add a + git commit -m "1" args: chdir: "{{repo_dir}}" diff --git a/test/integration/targets/git/tasks/main.yml b/test/integration/targets/git/tasks/main.yml index ed06eab5aa7..c990251f335 100644 --- a/test/integration/targets/git/tasks/main.yml +++ b/test/integration/targets/git/tasks/main.yml @@ -16,27 +16,37 @@ # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . -- import_tasks: setup.yml -- import_tasks: setup-local-repos.yml +# NOTE: Moving `$HOME` to tmp dir allows this integration test be +# NOTE: non-destructive. There is no other way to instruct Git use a custom +# NOTE: config path. There are new `$GIT_CONFIG_KEY_{COUNT,KEY,VALUE}` vars +# NOTE: for setting specific configuration values but those are only available +# NOTE: since Git v2.31 which is why we cannot rely on them yet. -- import_tasks: formats.yml -- import_tasks: missing_hostkey.yml -- import_tasks: missing_hostkey_acceptnew.yml -- import_tasks: no-destination.yml -- import_tasks: specific-revision.yml -- import_tasks: submodules.yml -- import_tasks: change-repo-url.yml -- import_tasks: depth.yml -- import_tasks: single-branch.yml -- import_tasks: checkout-new-tag.yml -- include_tasks: gpg-verification.yml - when: +- block: + - import_tasks: setup.yml + - import_tasks: setup-local-repos.yml + + - import_tasks: formats.yml + - import_tasks: missing_hostkey.yml + - import_tasks: missing_hostkey_acceptnew.yml + - import_tasks: no-destination.yml + - import_tasks: specific-revision.yml + - import_tasks: submodules.yml + - import_tasks: change-repo-url.yml + - import_tasks: depth.yml + - import_tasks: single-branch.yml + - import_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', '<')) -- import_tasks: localmods.yml -- import_tasks: reset-origin.yml -- import_tasks: ambiguous-ref.yml -- import_tasks: archive.yml -- import_tasks: separate-git-dir.yml -- import_tasks: forcefully-fetch-tag.yml + - import_tasks: localmods.yml + - import_tasks: reset-origin.yml + - import_tasks: ambiguous-ref.yml + - import_tasks: archive.yml + - import_tasks: separate-git-dir.yml + - import_tasks: forcefully-fetch-tag.yml + environment: + HOME: >- + {{ remote_tmp_dir }} diff --git a/test/integration/targets/git/tasks/missing_hostkey.yml b/test/integration/targets/git/tasks/missing_hostkey.yml index 136c5d5dda6..d8a2a818386 100644 --- a/test/integration/targets/git/tasks/missing_hostkey.yml +++ b/test/integration/targets/git/tasks/missing_hostkey.yml @@ -35,7 +35,8 @@ git: repo: '{{ repo_format3 }}' dest: '{{ checkout_dir }}' - version: 'master' + version: >- + {{ git_default_branch }} accept_hostkey: false # should already have been accepted key_file: '{{ github_ssh_private_key }}' ssh_opts: '-o UserKnownHostsFile={{ remote_tmp_dir }}/known_hosts' diff --git a/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml b/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml index 3fd19067d82..338ae0813a9 100644 --- a/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml +++ b/test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml @@ -55,7 +55,8 @@ git: repo: '{{ repo_format3 }}' dest: '{{ checkout_dir }}' - version: 'master' + version: >- + {{ git_default_branch }} accept_newhostkey: false # should already have been accepted key_file: '{{ github_ssh_private_key }}' ssh_opts: '-o UserKnownHostsFile={{ remote_tmp_dir }}/known_hosts' diff --git a/test/integration/targets/git/tasks/reset-origin.yml b/test/integration/targets/git/tasks/reset-origin.yml index 8fddd4b1690..cb497c442d2 100644 --- a/test/integration/targets/git/tasks/reset-origin.yml +++ b/test/integration/targets/git/tasks/reset-origin.yml @@ -12,7 +12,14 @@ 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" + shell: | + set -eEu + + git init + + echo "PR 22502" > origin + git add origin + git commit -m "PR 22502" args: chdir: "{{ repo_dir }}/origin" diff --git a/test/integration/targets/git/tasks/setup-local-repos.yml b/test/integration/targets/git/tasks/setup-local-repos.yml index 584a16930cc..4626f1028bf 100644 --- a/test/integration/targets/git/tasks/setup-local-repos.yml +++ b/test/integration/targets/git/tasks/setup-local-repos.yml @@ -9,15 +9,32 @@ - "{{ 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" + shell: | + set -eEu + + 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"; + set -eEu + + 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" @@ -29,7 +46,10 @@ - name: SETUP-LOCAL-REPOS | prepare tmp git repo with two branches shell: | + set -eEu + 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 @@ -40,6 +60,9 @@ # 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 + shell: | + set -eEu + + 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 index 06511053a9f..982c03ff850 100644 --- a/test/integration/targets/git/tasks/setup.yml +++ b/test/integration/targets/git/tasks/setup.yml @@ -28,10 +28,44 @@ 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" + shell: 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" + shell: git config --global user.name 'Ansible Test Runner' + +- name: SETUP | set git global init.defaultBranch + shell: >- + git config --global init.defaultBranch '{{ git_default_branch }}' + +- name: SETUP | set git global init.templateDir + # NOTE: This custom Git repository template emulates the `init.defaultBranch` + # NOTE: setting on Git versions below 2.28. + # NOTE: Ref: https://superuser.com/a/1559582. + # NOTE: Other workarounds mentioned there, like invoking + # NOTE: `git symbolic-ref HEAD refs/heads/main` after each `git init` turned + # NOTE: out to have mysterious side effects that break the tests in surprising + # NOTE: ways. + shell: | + set -eEu + + git config --global \ + init.templateDir '{{ remote_tmp_dir }}/git-templates/git.git' + + mkdir -pv '{{ remote_tmp_dir }}/git-templates' + set +e + GIT_TEMPLATES_DIR=$(\ + 2>/dev/null \ + ls -1d \ + '/Library/Developer/CommandLineTools/usr/share/git-core/templates' \ + '/usr/local/share/git-core/templates' \ + '/usr/share/git-core/templates' \ + ) + set -e + >&2 echo "Found Git's default templates directory: ${GIT_TEMPLATES_DIR}" + cp -r "${GIT_TEMPLATES_DIR}" '{{ remote_tmp_dir }}/git-templates/git.git' + + echo 'ref: refs/heads/{{ git_default_branch }}' \ + > '{{ remote_tmp_dir }}/git-templates/git.git/HEAD' - name: SETUP | create repo_dir file: diff --git a/test/integration/targets/git/tasks/single-branch.yml b/test/integration/targets/git/tasks/single-branch.yml index 5cfb4d5b8f3..ca8457accc3 100644 --- a/test/integration/targets/git/tasks/single-branch.yml +++ b/test/integration/targets/git/tasks/single-branch.yml @@ -52,7 +52,8 @@ repo: 'file://{{ repo_dir|expanduser }}/shallow_branches' dest: '{{ checkout_dir }}' single_branch: yes - version: master + version: >- + {{ git_default_branch }} register: single_branch_3 - name: SINGLE_BRANCH | Clone example git repo using single_branch with version again @@ -60,7 +61,8 @@ repo: 'file://{{ repo_dir|expanduser }}/shallow_branches' dest: '{{ checkout_dir }}' single_branch: yes - version: master + version: >- + {{ git_default_branch }} register: single_branch_4 - name: SINGLE_BRANCH | List revisions diff --git a/test/integration/targets/git/tasks/specific-revision.yml b/test/integration/targets/git/tasks/specific-revision.yml index 26fa7cf3389..f1fe41d5626 100644 --- a/test/integration/targets/git/tasks/specific-revision.yml +++ b/test/integration/targets/git/tasks/specific-revision.yml @@ -162,7 +162,14 @@ path: "{{ checkout_dir }}" - name: SPECIFIC-REVISION | prepare origina repo - shell: git init; echo "1" > a; git add a; git commit -m "1" + shell: | + set -eEu + + git init + + echo "1" > a + git add a + git commit -m "1" args: chdir: "{{ checkout_dir }}" @@ -191,7 +198,14 @@ force: yes - name: SPECIFIC-REVISION | create new commit in original - shell: git init; echo "2" > b; git add b; git commit -m "2" + shell: | + set -eEu + + git init + + echo "2" > b + git add b + git commit -m "2" args: chdir: "{{ checkout_dir }}" diff --git a/test/integration/targets/git/vars/main.yml b/test/integration/targets/git/vars/main.yml index b38531f32a1..55c7c4384a0 100644 --- a/test/integration/targets/git/vars/main.yml +++ b/test/integration/targets/git/vars/main.yml @@ -41,6 +41,7 @@ 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_default_branch: main git_version_supporting_depth: 1.9.1 git_version_supporting_ls_remote: 1.7.5 git_version_supporting_single_branch: 1.7.10