blob: e2f1042e21443f4c179cb506796961e88af03b33 [file] [log] [blame]
#!/usr/bin/env bash
#
# Copyright (c) 2019-2020 Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
# Clone and sync all Trusted Firmware repositories.
#
# For every cloned repository, set its location to a variable so that the
# checked out location can be passed down to sub-jobs.
#
# Generate an environment file that can then be sourced by the caller.
set -e
ci_root="$(readlink -f "$(dirname "$0")/..")"
source "$ci_root/utils.sh"
clone_log="$workspace/clone_repos.log"
clone_data="$workspace/clone.data"
override_data="$workspace/override.data"
inject_data="$workspace/inject.data"
# File containing parameters for sub jobs
param_file="$workspace/env.param"
# Emit a parameter to sub jobs
emit_param() {
echo "$1=$2" >> "$param_file"
}
# Emit a parameter for code coverage metadata
code_cov_emit_param() {
emit_param "CC_$(echo ${1^^} | tr '-' _)_$2" "$3"
}
meta_data() {
echo "$1" >> "$clone_data"
}
# Path into the project filer where various pieces of scripts that override
# some CI environment variables are stored.
ci_overrides="$project_filer/ci-overrides"
display_override() {
echo
echo -n "Override: "
# Print the relative path of the override file.
echo "$1" | sed "s#$ci_overrides/\?##"
}
strip_var() {
local var="$1"
local val="$(echo "${!var}" | sed 's#^\s*\|\s*$##g')"
eval "$var=\"$val\""
}
prefix_tab() {
sed 's/^/\t/g' < "${1:?}"
}
prefix_arrow() {
sed 's/^/ > /g' < "${1:?}"
}
test_source() {
local file="${1:?}"
if ! bash -c "source $file" &>/dev/null; then
return 1
fi
source "$file"
return 0
}
# Whether we've overridden some CI environment variables.
has_overrides=0
# Whether we've injected environment via. Jenkins
has_env_inject=0
clone_and_sync() {
local stat
local topic
local refspec="${!ref}"
local s_before s_after s_diff
local reference_dir="$project_filer/ref-repos/${name?}"
local ref_repo
local ret
strip_var refspec
strip_var url
# Clone in the filter workspace
mkdir -p "$ci_scratch"
pushd "$ci_scratch"
# Seconds before
s_before="$(date +%s)"
# Clone repository to the directory same as its name; HEAD stays at
# master.
if [ -d "$reference_dir" ]; then
ref_repo="--reference $reference_dir"
fi
echo "$ref_repo $url $name $branch"
git clone -q $ref_repo "$url" "$name" &>"$clone_log"
code_cov_emit_param "${name}" "URL" "${url}"
stat="on branch master"
pushd "$name"
if [ "$refspec" ] && [ "$refspec" != "master" ]; then
# If a specific revision is specified, always use that.
git fetch -q origin "$refspec" &>"$clone_log"
git checkout -q FETCH_HEAD &>"$clone_log"
stat="refspec $refspec"
# If it's not a commit hash, have the refspec replicated on the
# clone so that downstream jobs can clone from this one using
# the same refspec.
if echo "$refspec" | grep -qv '^[a-f0-9]\+$'; then
git branch -f "$refspec" FETCH_HEAD
fi
fi
code_cov_emit_param "${name}" "REFSPEC" "${refspec}"
# Generate meta data. Eliminate any quoting in commit subject as it
# might cause problems when reporting back to Gerrit.
meta_data "$name: $stat"
meta_data " $(git show --quiet --format=%H): $(git show --quiet --format=%s | sed "s/[\"']/ /g")"
meta_data " Commit date: $(git show --quiet --format=%cd)"
meta_data
code_cov_emit_param "${name}" "COMMIT" "$(git show --quiet --format=%H)"
# Calculate elapsed seconds
s_after="$(date +%s)"
let "s_diff = $s_after - $s_before" || true
echo
echo "Repository: $url ($stat)"
prefix_arrow <(git show --quiet)
echo "Cloned in $s_diff seconds"
echo
popd
popd
emit_env "$loc" "$ci_scratch/$name"
emit_env "$ref" "$refspec"
}
# Environment file in Java property file format, that's soured in Jenkins job
env_file="$workspace/env"
rm -f "$env_file"
# Workspace on external filer where all repositories gets cloned so that they're
# accessible to all Jenkins slaves.
if upon "$local_ci"; then
ci_scratch="$workspace/filer"
else
scratch_owner="${JOB_NAME:?}-${BUILD_NUMBER:?}"
ci_scratch="$project_scratch/$scratch_owner"
tforg_key="$CI_BOT_KEY"
tforg_user="$CI_BOT_USERNAME"
fi
if [ -d "$ci_scratch" ]; then
# This could be because of jobs of same name running from
# production/staging/temporary VMs
echo "Scratch space $ci_scratch already exists; removing."
rm -rf "$ci_scratch"
fi
mkdir -p "$ci_scratch"
# Set CI_SCRATCH so that it'll be injected when sub-jobs are triggered.
emit_param "CI_SCRATCH" "$ci_scratch"
# However, on Jenkins v2, injected environment variables won't override current
# job's parameters. This means that the current job (the scratch owner, the job
# that's executing this script) would always observe CI_SCRATCH as empty, and
# therefore won't be able to remove it. Therefore, use a different variable
# other than CI_SCRATCH parameter for the current job to refer to the scratch
# space (although they both will have the same value!)
emit_env "SCRATCH_OWNER" "$scratch_owner"
emit_env "SCRATCH_OWNER_SPACE" "$ci_scratch"
strip_var CI_ENVIRONMENT
if [ "$CI_ENVIRONMENT" ]; then
{
echo
echo "Injected environment:"
prefix_tab <(echo "$CI_ENVIRONMENT")
echo
} >> "$inject_data"
cat "$inject_data"
tmp_env=$(mktempfile)
echo "$CI_ENVIRONMENT" > "$tmp_env"
source "$tmp_env"
cat "$tmp_env" >> "$env_file"
has_env_inject=1
fi
TF_REFSPEC="${tf_refspec:-$TF_REFSPEC}"
if not_upon "$no_tf"; then
# Clone Trusted Firmware repository
url="$tf_src_repo_url" name="trusted-firmware" ref="TF_REFSPEC" \
loc="TF_CHECKOUT_LOC" \
clone_and_sync
fi
TFTF_REFSPEC="${tftf_refspec:-$TFTF_REFSPEC}"
if not_upon "$no_tftf"; then
# Clone Trusted Firmware TF repository
url="$tftf_src_repo_url" name="trusted-firmware-tf" ref="TFTF_REFSPEC" \
loc="TFTF_CHECKOUT_LOC" \
clone_and_sync
fi
# Clone code coverage repository if code coverage is enabled
if not_upon "$no_cc"; then
pushd "$ci_scratch"
git clone -q $cc_src_repo_url cc_plugin -b $cc_src_repo_tag 2> /dev/null
popd
fi
SPM_REFSPEC="${spm_refspec:-$SPM_REFSPEC}"
if not_upon "$no_spm"; then
# Clone SPM repository
url="$spm_src_repo_url" name="spm" ref="SPM_REFSPEC" \
loc="SPM_CHECKOUT_LOC" clone_and_sync
fi
CI_REFSPEC="${ci_refspec:-$CI_REFSPEC}"
if not_upon "$no_ci"; then
# Clone Trusted Firmware CI repository
url="$tf_ci_repo_url" name="trusted-firmware-ci" ref="CI_REFSPEC" \
loc="CI_ROOT" clone_and_sync
fi
TF_M_TESTS_REFSPEC="${tf_m_tests_refspec:-$TF_M_TESTS_REFSPEC}"
if not_upon "$no_tfm_tests"; then
url="$tf_m_tests_src_repo_url" name="tf-m-tests" ref="TF_M_TESTS_REFSPEC" \
loc="TF_M_TESTS_PATH" clone_and_sync
fi
TF_M_EXTRAS_REFSPEC="${tf_m_extras_refspec:-$TF_M_EXTRAS_REFSPEC}"
if not_upon "$no_tfm_extras"; then
url="$tf_m_extras_src_repo_url" name="tf-m-extras" ref="TF_M_EXTRAS_REFSPEC" \
loc="TF_M_EXTRAS_PATH" clone_and_sync
fi
RMM_REFSPEC="${rmm_refspec:-$RMM_REFSPEC}"
if not_upon "$no_rmm"; then
url="$rmm_src_repo_url" name="tf-rmm" ref="RMM_REFSPEC" \
loc="RMM_PATH" clone_and_sync
fi
# Copy environment file to ci_scratch for sub-jobs' access
cp "$env_file" "$ci_scratch"
cp "$param_file" "$ci_scratch"
# Copy clone data so that it's available for sub-jobs' HTML reporting
if [ -f "$clone_data" ]; then
cp "$clone_data" "$ci_scratch"
fi
# vim: set tw=80 sw=8 noet: