#!/bin/bash # Pretty name for PROJECT's version #rr[PROJECT_version] # PROJECT's git url #rr[PROJECT_url] # PROJECT's git branch or SHA1 revision parsable by git rev-parse. # A special value "baseline" means that PROJECT is not being updated # in this build, and its baseline branch should be used. # In a successful build "update_baseline" step will update baseline # branches of all PROJECTs to the current values, thus setting # a baseline for the next build. #rr[PROJECT_branch] # PROJECT's git SHA1 revision. These are mostly used in manifests. #rr[PROJECT_rev] # Baseline branch name for current configuration. These branches should # be present in all above git repos (if ${rr[init_configuration]} is false). #rr[baseline_branch]="${rr[ci_project]}/${rr[ci_config]}" # 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" # Set rr[init_configuration] to 'true' for new projects/configurations # to initialize baseline branches in git repos. #rr[init_configuration]=false # Print round-robin components that are being updated in this build # (the ones using non-baseline branches). print_updated_components () { ( set -euf -o pipefail local delim="" local c for c in ${rr[components]}; do if [ x"${rr[${c}_branch]}" != x"baseline" ]; then printf "%s%s" "$delim" "$c" delim=${1- } fi done ) } # Print the single round-robin component being updated in this build. # Print nothing if multiple components are being updated. print_single_updated_component () { ( set -euf -o pipefail local -a updated_components updated_components=($(print_updated_components)) if [ ${#updated_components[@]} = 1 ]; then echo "${updated_components[0]}" fi ) } # 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 $run_step_top_artifacts \ $run_step_top_artifacts/console.log \ $run_step_artifacts/console.log \ "$run_step_top_artifacts/jenkins/*" 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]}}" if ${rr[init_configuration]-false}; then rr[base-artifacts_rev]=empty single_branch=empty fi 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 -C $project rev-parse HEAD) cat < /dev/null cd abe # Add ccache wrappers. rm -rf $(pwd)/bin mkdir $(pwd)/bin cat > $(pwd)/bin/gcc < $(pwd)/bin/g++ < $(pwd)/bin/cc < $(pwd)/bin/c++ < $(pwd)/bin/ninja <> ${rr[top_artifacts]}/trigger-build-$c done else local baseline_rev cur_rev baseline_rev=$(git_rev_parse_long $single_component ${rr[baseline_branch]} baseline) cur_rev=$(git -C $single_component rev-parse HEAD) cat > ${rr[top_artifacts]}/trigger-bisect </dev/null 2>&1; then # For every regression we want to keep artifacts for the first-bad # build, so reset to the most relevant regression (marked by reset-baseline). if [ -f base-artifacts/reset-baseline ] && ! ${rr[reset_baseline]}; then prev_head=$(git -C base-artifacts rev-parse HEAD) fi 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" break fi done if [ x"$prev_head" != x"" ]; then git -C base-artifacts reset --hard $prev_head fi # Rsync current artifacts. Make sure to use -I rsync option since # quite often size and timestamp on artifacts/results will be the same # as on base-artifacts/results due to "git reset --hard HEAD^" below. # This caused rsync's "quick check" heuristic to skip "results" file. # !!! From this point on, logs and other artifacts won't be included # in base-artifacts.git repo (though they will be uploaded to jenkins). rsync -aI --del --exclude /.git ${rr[top_artifacts]}/ base-artifacts/ local rev_count if [ x"$amend" = x"" ]; then rev_count=$(git -C base-artifacts rev-list --count HEAD) else rev_count="0" fi local msg_title="$rev_count" if ${rr[reset_baseline]}; then # Create a marker for builds that reset baselines (these are builds # for bisected regressions). touch base-artifacts/reset-baseline msg_title="$msg_title: first-bad" else msg_title="$msg_title: good" fi local single_component single_component=$(print_single_updated_component) if [ x"$single_component" != x"" ]; then local single_rev single_rev=$(git -C $single_component rev-parse HEAD) msg_title="$msg_title: $single_component-$single_rev" else msg_title="$msg_title: $(print_updated_components "-")" fi msg_title="$msg_title: $(tail -n1 ${rr[top_artifacts]}/results)" git -C base-artifacts add . git -C base-artifacts commit $amend -m "$msg_title $(cat ${rr[top_artifacts]}/results)" # We saw strange behavior with base-artifacts/results not being updated # in the rsync above. This should be fixed by "-I" rsync option, but # keep below asserts just in case. if [ x"$(diff -up ${rr[top_artifacts]}/results base-artifacts/results)" != x"" ] \ || [ x"$amend" = x"" -a x"$(git -C base-artifacts diff HEAD HEAD^ -- results)" = x"" ]; then cd base-artifacts git status cat results ls -la assert false fi ) } # Push to baseline branches 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]} local c for c in $(print_updated_components); do git_push $c baseline ${rr[baseline_branch]} done ) }