<commit_before><?xml version='1.0' encoding='UTF-8'?>
<project>

  {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import common_job_configuration with context %}
  {{ common_job_configuration(job_config, job_environ) }}

  <builders>

    {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import copy_artifacts with context %}
    {{ copy_artifacts(job_config, job_environ) }}

    <hudson.tasks.Shell>
      <command>

        {% from 'common/libs/host_config_queries.sls' import get_system_host_primary_user_posix_home with context %}

        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import locate_dynamic_build_descriptor with context %}
        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import update_dynamic_build_descriptor with context %}

        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import common_build_script_header with context %}
        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import common_build_script_footer with context %}

        #######################################################################
        # Script header

        {{ common_build_script_header(job_config, job_environ) }}

        #######################################################################
        # Locate dynamic build descriptor.

        # NOTE: When we recover, we do not need to verify
        #       recovery dyn build desc. In fact, it cannot be verified
        #       as this is either standalone (no recovery dyn build desc)
        #       or belongs to a new build (with different dyn build desc).

        {{ locate_dynamic_build_descriptor(job_config, job_environ, check_init_dyn_build_desc = False) }}

        # IMPORTANT: We need to pass dyn build desc for the next job
        #            in the pipeline now (as there is no more
        #            updates of dyn build desc within this job)
        #            to pass the info generated in the jobs before.
        # NOTE: Skip dyn build desc commit because there is
        #       no updates expected during recovery.
        cp "${JOB_DYN_BUILD_DESC_PATH}" "${LATEST_DYN_BUILD_DESC_PATH}"

        # Detect if recovery is needed from the previous build.
        if [ ! -f "${RECOVERY_DYN_BUILD_DESC_PATH}" ]
        then
            # No recovery dynamic build descriptor available from
            # the previous build - nothing to do.
            echo "No need to recover from the previous build".

            # Set build unstable.
            # See: http://stackoverflow.com/a/8822743/441652
            eval "${JENKINS_CLI_TOOL_INVOKE_STRING} set-build-result unstable"

            exit 0
        fi

        # Save recovery build descriptor in the one used by the job.
        cp "${RECOVERY_DYN_BUILD_DESC_PATH}" "${JOB_DYN_BUILD_DESC_PATH}"

        #######################################################################
        # Normally, there should not be any changes or untracked files
        # as they are either ignored (by `.gitignore`) or
        # committed during the build pipeline.
        # Before proceeding with recovery, check if there are any local
        # changes or untracked files and stash them.

        {% for repo_name in pillar['system_features']['deploy_environment_sources']['source_repositories'].keys() %}
        {% set repo_config = pillar['system_features']['deploy_environment_sources']['source_repositories'][repo_name]['git'] %}

        {% if repo_name in pillar['system_features']['deploy_environment_sources']['repository_roles']['build_history_role'] %}

        # NOTE: We ignore `build_history_role` repo as it must start clean.

        {% else %}

        REPO_PATH="{{ get_system_host_primary_user_posix_home(repo_config['source_system_host']) }}/{{ repo_config['origin_uri_ssh_path'] }}"

        cd "${REPO_PATH}"
        # NOTE: Without `add -all` `diff-index` will not notice untracked files.
        git add --all
        if ! git diff-index --ignore-submodules=dirty --exit-code HEAD
        then
            git stash

            # NOTE: If the repository is a submodule, `git stash` would leave
            #       changes done by `git add` still staged.
            #       We run `git reset` to set them unstaged, otherwise
            #       `git checkout` for this repository may potentially
            #       fail due to local modifications (which are only
            #       "non-stashable" for submodules).
            git reset

            # Set job status to failed (but don't fail now, restore first)
            # in order to highlight stashed changes.
            if [ "${JOB_STATUS}" -lt '2' ]
            then
                JOB_STATUS='2'
            fi
        fi

        cd -

        {% endif %}

        {% endfor %}

        #######################################################################
        # Switch back to recovery branches.
<commit_msg>Reset non-stashable changes (normally, submodules)<commit_after><?xml version='1.0' encoding='UTF-8'?>
<project>

  {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import common_job_configuration with context %}
  {{ common_job_configuration(job_config, job_environ) }}

  <builders>

    {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import copy_artifacts with context %}
    {{ copy_artifacts(job_config, job_environ) }}

    <hudson.tasks.Shell>
      <command>

        {% from 'common/libs/host_config_queries.sls' import get_system_host_primary_user_posix_home with context %}

        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import locate_dynamic_build_descriptor with context %}
        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import update_dynamic_build_descriptor with context %}

        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import common_build_script_header with context %}
        {% from 'common/jenkins/configure_jobs_ext/common_xml_templates.lib.sls' import common_build_script_footer with context %}

        #######################################################################
        # Script header

        {{ common_build_script_header(job_config, job_environ) }}

        #######################################################################
        # Locate dynamic build descriptor.

        # NOTE: When we recover, we do not need to verify
        #       recovery dyn build desc. In fact, it cannot be verified
        #       as this is either standalone (no recovery dyn build desc)
        #       or belongs to a new build (with different dyn build desc).

        {{ locate_dynamic_build_descriptor(job_config, job_environ, check_init_dyn_build_desc = False) }}

        # IMPORTANT: We need to pass dyn build desc for the next job
        #            in the pipeline now (as there is no more
        #            updates of dyn build desc within this job)
        #            to pass the info generated in the jobs before.
        # NOTE: Skip dyn build desc commit because there is
        #       no updates expected during recovery.
        cp "${JOB_DYN_BUILD_DESC_PATH}" "${LATEST_DYN_BUILD_DESC_PATH}"

        # Detect if recovery is needed from the previous build.
        if [ ! -f "${RECOVERY_DYN_BUILD_DESC_PATH}" ]
        then
            # No recovery dynamic build descriptor available from
            # the previous build - nothing to do.
            echo "No need to recover from the previous build".

            # Set build unstable.
            # See: http://stackoverflow.com/a/8822743/441652
            eval "${JENKINS_CLI_TOOL_INVOKE_STRING} set-build-result unstable"

            exit 0
        fi

        # Save recovery build descriptor in the one used by the job.
        cp "${RECOVERY_DYN_BUILD_DESC_PATH}" "${JOB_DYN_BUILD_DESC_PATH}"

        #######################################################################
        # Normally, there should not be any changes or untracked files
        # as they are either ignored (by `.gitignore`) or
        # committed during the build pipeline.
        # Before proceeding with recovery, check if there are any local
        # changes or untracked files and stash them.

        {% for repo_name in pillar['system_features']['deploy_environment_sources']['source_repositories'].keys() %}
        {% set repo_config = pillar['system_features']['deploy_environment_sources']['source_repositories'][repo_name]['git'] %}

        {% if repo_name in pillar['system_features']['deploy_environment_sources']['repository_roles']['build_history_role'] %}

        # NOTE: We ignore `build_history_role` repo as it must start clean.

        {% else %}

        REPO_PATH="{{ get_system_host_primary_user_posix_home(repo_config['source_system_host']) }}/{{ repo_config['origin_uri_ssh_path'] }}"

        cd "${REPO_PATH}"
        # NOTE: Without `add -all` `diff-index` will not notice untracked files.
        git add --all
        # NOTE: We ignore any changes in submodules for parent repo.
        if ! git diff-index --ignore-submodules=all --exit-code HEAD
        then
            git stash

            # Set job status to failed (but don't fail now, restore first)
            # in order to highlight stashed changes.
            if [ "${JOB_STATUS}" -lt '2' ]
            then
                JOB_STATUS='2'
            fi
        fi

        # NOTE: If the repository is a submodule, `git stash` would leave
        #       changes done by `git add` still staged.
        #       We run `git reset` to set them unstaged, otherwise
        #       `git checkout` for this repository will fail
        #       fail due to local modifications (which are only
        #       "non-stashable" for submodules).
        git reset

        cd -

        {% endif %}

        {% endfor %}

        #######################################################################
        # Switch back to recovery branches.

{'fraction_non_alphanumeric': 0.13678684627575277, 'fraction_numerical': 0.003763866877971474, 'mean_word_length': 2.709404849375459, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 2, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 14}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1119396', 'n_tokens_mistral': 2782, 'n_tokens_neox': 2594, 'n_words': 798}