#!/bin/bash # Pretty name for PROJECT's version #rr[PROJECT_version] # PROJECT's git url #rr[PROJECT_url] # PROJECT's git revision parsable by git rev-parse. #rr[PROJECT_rev] # Baseline branch name for current configuration. These branches are # present in all above git repos. #rr[baseline_branch]="linaro-local/ci/CONFIGURATION" # PROJECT that we are testing in this build. Use ${rr[current_rev]} for # this project, and ${rr[baseline_branch]} for all other projects. #rr[current_project]="$current_project" # Git revision of ${rr[current_project]} to test. #rr[current_rev]="$current_rev" # Run mode: bisect or non-bisect. In bisect mode we do a couple things # slightly differently (e.g., don't touch repo in clone_repo() ). #rr[mode]="$mode" # Ignore failures in check_regression, which forces update_baseline(). #rr[reset_baseline]="$reset_baseline" # Target architecture to build for: arm or aarch64. #rr[target]="$target" # Top-level artifacts directory. #rr[top_artifacts]="$top_artifacts" # Reset artifacts to an empty state. ${rr[top_artifacts]}/results is the most # important artifact, since it records the metric of how successful the build # is. reset_artifacts () { ( set -euf -o pipefail # Clean ${rr[top_artifacts]} but preserve # - ${rr[top_artifacts]}/console.log and $run_step_artifacts/console.log, which # are being written to by run_step(). # - ${rr[top_artifacts]}/jenkins/*, which is cleaned by tcwg_kernel.yaml. fresh_dir ${rr[top_artifacts]} \ ${rr[top_artifacts]}/console.log \ $run_step_artifacts/console.log \ "${rr[top_artifacts]}/jenkins/*" # Set success metric to worst possible (-10). echo "Starting build" > ${rr[top_artifacts]}/results echo "-10" >> ${rr[top_artifacts]}/results local single_branch=${rr[baseline_branch]} # Clone base-artifacts so that run_step can rsync artifacts for skipped # steps. # base-artifacts repo is big and changes all the time, so we # fetch only the $baseline_branch, instead of all branches. rr[base-artifacts_rev]="${rr[base-artifacts_rev]-${rr[baseline_branch]}}" clone_or_update_repo base-artifacts ${rr[base-artifacts_rev]} https://git-us.linaro.org/toolchain/ci/base-artifacts.git auto $single_branch cat < /dev/null # Add baseline remote git_init_linaro_local_remote $project baseline $read_only # Checkout, now that we have both origin and baseline remotes ready. clone_or_update_repo $project $branch ${rr[${project}_url]} > /dev/null local cur_rev cur_rev=$(git_rev_parse_long $project HEAD) cat < ${rr[top_artifacts]}/trigger-bisect-on-failure < ${rr[top_artifacts]}/distance-to-baseline fi ) } # Prepare ABE tree for [partial] GNU builds prepare_abe () { ( set -euf -o pipefail clone_or_update_repo abe tested https://git-us.linaro.org/toolchain/abe.git > /dev/null cd abe # Add ccache wrappers. rm -rf $(pwd)/bin mkdir $(pwd)/bin cat > $(pwd)/bin/gcc < $(pwd)/bin/g++ <> ${rr[top_artifacts]}/results case "$component" in binutils) echo "-9" >> ${rr[top_artifacts]}/results ;; stage1) echo "-8" >> ${rr[top_artifacts]}/results ;; linux) echo "-7" >> ${rr[top_artifacts]}/results ;; glibc) echo "-6" >> ${rr[top_artifacts]}/results ;; stage2) echo "-5" >> ${rr[top_artifacts]}/results ;; *) assert false ;; esac touch $run_step_artifacts/build-ok fi ) } # Build LLVM build_llvm_1 () { ( set -euf -o pipefail clone_repo llvm # Copy only components from the monorepo that are required for kernel build rsync -a --del --exclude /tools/clang llvm/llvm/ llvm-src/ rsync -a --del llvm/clang/ llvm-src/tools/clang/ # Setup ccache and ninja wrappers. rm -rf $(pwd)/bin mkdir $(pwd)/bin cat > $(pwd)/bin/cc < $(pwd)/bin/c++ < $(pwd)/bin/ninja <> ${rr[top_artifacts]}/results echo "-1" >> ${rr[top_artifacts]}/results touch $run_step_artifacts/build-ok fi ) } # Check if current build regressed compared to the baseline # (unless ${rr[reset_baseline]} is set). check_regression () { ( set -euf -o pipefail if ! ${rr[reset_baseline]} && ! no_regression_p; then # Fail. false fi ) } # Commit current result and artifacts to the baseline repository update_baseline () { ( set -euf -o pipefail local amend="" local prev_head="" # We discard baseline entries for results worse or same than # the current one, but keep entries for results that are better # (so that we have a record of pending regressions). while no_regression_p; do if git -C base-artifacts rev-parse HEAD^ >/dev/null 2>&1; then prev_head=$(git -C base-artifacts rev-parse HEAD) git -C base-artifacts reset --hard HEAD^ else # We got to the beginning of git history, so amend the current # commit. The initial state of baseline is "empty" branch, # which we treat as worst possible in no_regression_p(). amend="--amend" prev_head="" break fi done # For every regression we want to keep artifacts for the first-bad # build, so discard one less than needed. if [ x"$prev_head" != x"" ]; then git -C base-artifacts reset --hard $prev_head fi # Rsync current artifacts. # !!! From this point on logs and other artifacts won't be included # in base-artifacts.git repo. rsync -a --del --exclude /.git ${rr[top_artifacts]}/ base-artifacts/ local build_rev build_rev=$(git -C ${rr[current_project]} rev-parse HEAD) cd base-artifacts git add . git commit $amend -m "${rr[current_project]}-$build_rev: $(tail -n1 ${rr[top_artifacts]}/results) $(cat ${rr[top_artifacts]}/results)" ) } # Push to ${rr[current_project]} baseline branch and to base-artifacts repo. push_baseline () { ( set -euf -o pipefail git_init_linaro_local_remote base-artifacts baseline false git_push base-artifacts baseline ${rr[baseline_branch]} git_push ${rr[current_project]} baseline ${rr[baseline_branch]} ) }