diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2018-10-06 15:42:59 +0200 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2018-10-09 14:00:23 +0200 |
commit | 95150280bf6aecf1f68523453b93ce3c875e17ba (patch) | |
tree | 41ac687abdc216a4ecec53d8aee823d5b8e4b60b /etc/taskcluster/decision_task.py | |
parent | 545d54704a6f273dffa83a4191653dbe1a1e5d5f (diff) | |
download | servo-95150280bf6aecf1f68523453b93ce3c875e17ba.tar.gz servo-95150280bf6aecf1f68523453b93ce3c875e17ba.zip |
Rename decision-task.py to make it importable
Diffstat (limited to 'etc/taskcluster/decision_task.py')
-rw-r--r-- | etc/taskcluster/decision_task.py | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/etc/taskcluster/decision_task.py b/etc/taskcluster/decision_task.py new file mode 100644 index 00000000000..de44401eb38 --- /dev/null +++ b/etc/taskcluster/decision_task.py @@ -0,0 +1,394 @@ +# coding: utf8 + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import hashlib +import json +import os.path +import subprocess +from decisionlib import DecisionTask + + +def main(): + task_for = os.environ["TASK_FOR"] + + if task_for == "github-push": + linux_tidy_unit() + #linux_wpt() + android_arm32() + windows_dev() + + # https://tools.taskcluster.net/hooks/project-servo/daily + elif task_for == "daily": + daily_tasks_setup() + with_rust_nightly() + android_arm32() + + else: + raise ValueError("Unrecognized $TASK_FOR value: %r", task_for) + + +ping_on_daily_task_failure = "SimonSapin, nox, emilio" +build_artifacts_expiry = "1 week" +build_dependencies_artifacts_expiry = "1 month" +log_artifacts_expiry = "1 year" + +build_env = { + "RUST_BACKTRACE": "1", + "RUSTFLAGS": "-Dwarnings", + "CARGO_INCREMENTAL": "0", + "SCCACHE_IDLE_TIMEOUT": "1200", +} +linux_build_env = dict(**build_env, **{ + "CCACHE": "sccache", + "RUSTC_WRAPPER": "sccache", + "SHELL": "/bin/dash", # For SpiderMonkey’s build system +}) + + +def linux_tidy_unit(): + return decision.create_task( + task_name="Linux x86_64: tidy + dev build + unit tests", + script=""" + ./mach test-tidy --no-progress --all + ./mach build --dev + ./mach test-unit + ./mach package --dev + ./mach test-tidy --no-progress --self-test + python2.7 ./etc/memory_reports_over_time.py --test + python3 ./etc/taskcluster/mock.py + ./etc/ci/lockfile_changed.sh + ./etc/ci/check_no_panic.sh + """, + **linux_build_kwargs + ) + + +def with_rust_nightly(): + return decision.create_task( + task_name="Linux x86_64: with Rust Nightly", + script=""" + echo "nightly" > rust-toolchain + ./mach build --dev + ./mach test-unit + """, + **linux_build_kwargs + ) + + +def android_arm32(): + return decision.find_or_create_task( + index_bucket="build.android_armv7_release", + index_key=os.environ["GIT_SHA"], # Set in .taskcluster.yml + index_expiry=build_artifacts_expiry, + + task_name="Android ARMv7: build", + # file: NDK parses $(file $SHELL) to tell x86_64 from x86 + # wget: servo-media-gstreamer’s build script + script=""" + apt-get install -y --no-install-recommends openjdk-8-jdk-headless file wget + ./etc/ci/bootstrap-android-and-accept-licences.sh + ./mach build --android --release + """, + artifacts=[ + "/repo/target/armv7-linux-androideabi/release/servoapp.apk", + "/repo/target/armv7-linux-androideabi/release/servoview.aar", + ], + **linux_build_kwargs + ) + + +def windows_dev(): + python2_task = repack_msi( + url="https://www.python.org/ftp/python/2.7.15/python-2.7.15.amd64.msi", + sha256="5e85f3c4c209de98480acbf2ba2e71a907fd5567a838ad4b6748c76deb286ad7", + ) + gstreamer_task = repack_msi( + url="https://gstreamer.freedesktop.org/data/pkg/windows/" + + "1.14.3/gstreamer-1.0-devel-x86_64-1.14.3.msi", + sha256="b13ea68c1365098c66871f0acab7fd3daa2f2795b5e893fcbb5cd7253f2c08fa", + ) + return decision.create_task( + task_name="Windows x86_64: dev build + unit tests", + script=""" + python -m ensurepip + pip install virtualenv==16.0.0 + + ..\\rustup-init.exe --default-toolchain none -y + + set LIB=%HOMEDRIVE%%HOMEPATH%\\gst\\gstreamer\\1.0\\x86_64\\lib;%LIB% + + call mach.bat build --dev + call mach.bat test-unit + """, + mounts=[ + { + "directory": "git", + "format": "zip", + "content": { + "url": "https://github.com/git-for-windows/git/releases/download/" + + "v2.19.0.windows.1/MinGit-2.19.0-64-bit.zip", + "sha256": "424d24b5fc185a9c5488d7872262464f2facab4f1d4693ea8008196f14a3c19b", + } + }, + { + "directory": "python2", + "format": "zip", + "content": { + "taskId": python2_task, + "artifact": "public/repacked.zip", + } + }, + { + "directory": "gst", + "format": "zip", + "content": { + "taskId": gstreamer_task, + "artifact": "public/repacked.zip", + } + }, + { + "file": "rustup-init.exe", + "content": { + "url": "https://static.rust-lang.org/rustup/archive/" + + "1.13.0/i686-pc-windows-gnu/rustup-init.exe", + "sha256": "43072fbe6b38ab38cd872fa51a33ebd781f83a2d5e83013857fab31fc06e4bf0", + } + } + ], + homedir_path=[ + "git\\cmd", + "python2", + "python2\\Scripts", + ".cargo\\bin", + ], + dependencies=[ + python2_task, + gstreamer_task, + ], + sparse_checkout=[ + "/*", + "!/tests/wpt/metadata", + "!/tests/wpt/mozilla", + "!/tests/wpt/webgl", + "!/tests/wpt/web-platform-tests", + "/tests/wpt/web-platform-tests/tools", + ], + **windows_build_kwargs + ) + + +def repack_msi(url, sha256): + task_definition = dict( + task_name="Windows x86_64: repackage " + url.rpartition("/")[-1], + worker_type="servo-win2016", + with_repo=False, + script=""" + lessmsi x input.msi extracted\\ + cd extracted\\SourceDir + 7za a repacked.zip * + """, + mounts=[ + { + "file": "input.msi", + "content": { + "url": url, + "sha256": sha256, + } + }, + { + "directory": "lessmsi", + "format": "zip", + "content": { + "url": "https://github.com/activescott/lessmsi/releases/download/" + + "v1.6.1/lessmsi-v1.6.1.zip", + "sha256": "540b8801e08ec39ba26a100c855898f455410cecbae4991afae7bb2b4df026c7", + } + }, + { + "directory": "7zip", + "format": "zip", + "content": { + "url": "https://www.7-zip.org/a/7za920.zip", + "sha256": "2a3afe19c180f8373fa02ff00254d5394fec0349f5804e0ad2f6067854ff28ac", + } + } + ], + homedir_path=[ + "lessmsi", + "7zip", + ], + artifacts=[ + "extracted/SourceDir/repacked.zip", + ], + max_run_time_minutes=20, + ) + index_by = json.dumps(task_definition).encode("utf-8") + return decision.find_or_create_task( + index_bucket="by-task-definition", + index_key=hashlib.sha256(index_by).hexdigest(), + index_expiry=build_artifacts_expiry, + **task_definition + ) + + +def linux_wpt(): + release_build_task = linux_release_build() + total_chunks = 2 + for i in range(total_chunks): + this_chunk = i + 1 + wpt_chunk(release_build_task, total_chunks, this_chunk, extra=(this_chunk == 1)) + + +def linux_release_build(): + return decision.find_or_create_task( + index_bucket="build.linux_x86-64_release", + index_key=os.environ["GIT_SHA"], # Set in .taskcluster.yml + index_expiry=build_artifacts_expiry, + + task_name="Linux x86_64: release build", + script=""" + ./mach build --release --with-debug-assertions -p servo + ./etc/ci/lockfile_changed.sh + tar -czf /target.tar.gz \ + target/release/servo \ + target/release/build/osmesa-src-*/output \ + target/release/build/osmesa-src-*/out/lib/gallium + """, + artifacts=[ + "/target.tar.gz", + ], + **linux_build_kwargs + ) + + +def wpt_chunk(release_build_task, total_chunks, this_chunk, extra): + if extra: + name_extra = " + extra" + script_extra = """ + ./mach test-wpt-failure + ./mach test-wpt --release --binary-arg=--multiprocess --processes 24 \ + --log-raw test-wpt-mp.log \ + --log-errorsummary wpt-mp-errorsummary.log \ + eventsource + """ + else: + name_extra = "" + script_extra = "" + script = """ + ./mach test-wpt \ + --release \ + --processes 24 \ + --total-chunks "$TOTAL_CHUNKS" \ + --this-chunk "$THIS_CHUNK" \ + --log-raw test-wpt.log \ + --log-errorsummary wpt-errorsummary.log \ + --always-succeed + ./mach filter-intermittents\ + wpt-errorsummary.log \ + --log-intermittents intermittents.log \ + --log-filteredsummary filtered-wpt-errorsummary.log \ + --tracker-api default + """ + # FIXME: --reporter-api default + # IndexError: list index out of range + # File "/repo/python/servo/testing_commands.py", line 533, in filter_intermittents + # pull_request = int(last_merge.split(' ')[4][1:]) + create_run_task( + build_task=release_build_task, + task_name="Linux x86_64: WPT chunk %s / %s%s" % (this_chunk, total_chunks, name_extra), + script=script_extra + script, + env={ + "TOTAL_CHUNKS": total_chunks, + "THIS_CHUNK": this_chunk, + }, + ) + + +def create_run_task(*, build_task, script, **kwargs): + fetch_build = """ + ./etc/taskcluster/curl-artifact.sh ${BUILD_TASK_ID} target.tar.gz | tar -xz + """ + kwargs.setdefault("env", {})["BUILD_TASK_ID"] = build_task + kwargs.setdefault("dependencies", []).append(build_task) + kwargs.setdefault("artifacts", []).extend( + ("/repo/" + word, log_artifacts_expiry) + for word in script.split() if word.endswith(".log") + ) + return decision.create_task( + script=fetch_build + script, + max_run_time_minutes=60, + dockerfile=dockerfile_path("run"), + **kwargs + ) + + +def daily_tasks_setup(): + # ':' is not accepted in an index namepspace: + # https://docs.taskcluster.net/docs/reference/core/taskcluster-index/references/api + now = decision.now.strftime("%Y-%m-%d_%H-%M-%S") + index_path = "%s.daily.%s" % (decision.index_prefix, now) + # Index this task manually rather than with a route, + # so that it is indexed even if it fails. + decision.index_service.insertTask(index_path, { + "taskId": os.environ["TASK_ID"], + "rank": 0, + "data": {}, + "expires": decision.from_now_json(log_artifacts_expiry), + }) + + # Unlike when reacting to a GitHub event, + # the commit hash is not known until we clone the repository. + os.environ["GIT_SHA"] = \ + subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("utf8").strip() + + # On failure, notify a few people on IRC + # https://docs.taskcluster.net/docs/reference/core/taskcluster-notify/docs/usage + notify_route = "notify.irc-channel.#servo.on-failed" + decision.routes_for_all_subtasks.append(notify_route) + decision.scopes_for_all_subtasks.append("queue:route:" + notify_route) + decision.task_name_template = "Servo daily: %s. On failure, ping: " + ping_on_daily_task_failure + + +def dockerfile_path(name): + return os.path.join(os.path.dirname(__file__), "docker", name + ".dockerfile") + + +decision = DecisionTask( + task_name_template="Servo: %s", + index_prefix="project.servo.servo", + default_worker_type="servo-docker-worker", + docker_image_cache_expiry=build_dependencies_artifacts_expiry, +) + +# https://docs.taskcluster.net/docs/reference/workers/docker-worker/docs/caches +cache_scopes = [ + # FIMXE: move to servo-* cache names + "docker-worker:cache:cargo-*", +] +build_caches = { + "cargo-registry-cache": "/root/.cargo/registry", + "cargo-git-cache": "/root/.cargo/git", + "cargo-rustup": "/root/.rustup", + "cargo-sccache": "/root/.cache/sccache", +} +build_kwargs = { + "max_run_time_minutes": 60, +} +linux_build_kwargs = dict(**build_kwargs, **{ + "worker_type": "servo-docker-worker", + "dockerfile": dockerfile_path("build"), + "scopes": cache_scopes, + "cache": build_caches, + "env": linux_build_env, +}) +windows_build_kwargs = dict(**build_kwargs, **{ + "worker_type": "servo-win2016", + "env": build_env, +}) + + +if __name__ == "__main__": + main()
\ No newline at end of file |