James E. Blair 78276a58c5 Fix prepare-workspace-git operating on existing repos
Commit 8003cdc76ca177061b1a462d07efaff83e18491b causes problems
if the remote repo already exists (e.g., the worker node is static
and not ephemeral) because it unconditionally removes settings
which are only conditionally set if the workspace is newly cloned.

Fix that by remove the Ansible "creates" check from the task and
executing the set calls unconditionally (but also, recreate the
functionality of the create check for the cloning part of the
task, which is what we're really trying to avoid).

This will run a few extra command such as clearing the bare flag
and also resetting the origin remote.  That should be fine in
this role since we expect it to do whatever it takes to make the
remote repo the same as the local one.

Also, resync test-prepare-workspace-git.

Change-Id: Ife12992df9ce2b0ce199b3980a4baa255cb0f28a
2024-07-23 17:18:03 -07:00

82 lines
3.2 KiB
YAML

- name: Filter zuul projects if sync-only-required-projects flag is set
set_fact:
_zuul_projects: >
{{ _zuul_projects | default({}) |
combine({ zj_project.key : zj_project.value }) }}
with_dict: "{{ zuul.projects }}"
loop_control:
loop_var: zj_project
when:
- prepare_workspace_sync_required_projects_only
- zj_project.value.canonical_name == zuul.project.canonical_name or zj_project.value.required
- name: Don't filter zuul projects if flag is false
set_fact:
_zuul_projects: "{{ zuul.projects }}"
when: not prepare_workspace_sync_required_projects_only
# Do all the steps in a single shell script. This reduces the number of times
# ansible must loop over the list of projects which reduces the amount of
# task startup time we incur.
- name: Set initial repo states in workspace
shell: |
set -ex
if [ ! -d "{{ zuul_workspace_root }}/{{ zj_project.src_dir }}" ] ; then
if [ -d "{{ cached_repos_root }}/{{ zj_project.canonical_name }}" ] ; then
# We do a bare clone here first so that we skip creating a working
# copy that will be overwritten later anyway.
git clone --bare {{ cached_repos_root }}/{{ zj_project.canonical_name }} {{ zuul_workspace_root }}/{{ zj_project.src_dir }}/.git
else
git init {{ zuul_workspace_root }}/{{ zj_project.src_dir }}
fi
cd {{ zuul_workspace_root }}/{{ zj_project.src_dir }}
git config --local --bool core.bare false
git remote -v | grep origin && git remote rm origin || true
git remote add origin file:///dev/null
fi
cd {{ zuul_workspace_root }}/{{ zj_project.src_dir }}
# Allow pushing to non-bare repo
git config --local receive.denyCurrentBranch ignore
# Allow deleting current branch
git config --local receive.denyDeleteCurrent ignore
with_items: "{{ _zuul_projects.values() }}"
loop_control:
loop_var: zj_project
# We're using git in a shell script because it is faster and the module
# doesn't support features we need.
tags:
- skip_ansible_lint
- name: Include tasks to synchronize src repos to workspace directory
include_tasks: sync-project.yaml
with_dict: "{{ _zuul_projects }}"
loop_control:
loop_var: zj_project
# Do this as a multi-line shell so that we can do the loop once
- name: Update remote repository state correctly
shell: |
set -eu
# Reset is needed because we pushed to a non-bare repo
git reset --hard
# Clean is needed because we pushed to a non-bare repo
git clean -xdf
# Undo the config setting we did above
git config --local --unset receive.denyCurrentBranch
git config --local --unset receive.denyDeleteCurrent
# checkout the branch matching the branch set up by the executor
git checkout {% if mirror_workspace_quiet %}--quiet{% endif %} {{ zj_project.value.checkout }}
# put out a status line with the current HEAD
echo "{{ zj_project.value.canonical_name }} checked out to:"
git log --pretty=oneline -1
args:
chdir: "{{ zuul_workspace_root }}/{{ zj_project.value.src_dir }}"
with_dict: "{{ _zuul_projects }}"
loop_control:
loop_var: zj_project
# ANSIBLE0006: Skip linting since it triggers on the "git" command,
# but we prefer the shell above
tags:
- skip_ansible_lint