diff --git a/README.md b/README.md index ecae6fc..fc97aa9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This repository contains the configuration files for the pre-merge checks for the LLVM project. This github project contains the documentation and the server configuration cluster of build machines that are used to check all incoming commits to the LLVM project. # User documentation -See [docs/user_doc.md](docs/user_doc.md) +If you are interested in a high-level overview and how to best use the tool see [docs/user_doc.md](docs/user_doc.md) # Cluster overview @@ -31,7 +31,7 @@ On the Jenkins side: There is no backup of the credentials. If you need to change it, generate a new one and update it in Jenkins and Phabricator. # Additional Information -* [Playbooks](docs/playbooks.md) for installing/upgrading +* [Playbooks](docs/playbooks.md) for installing/upgrading agents and testing changes. * [User documentation](docs/user_doc.md) * [Log of the service operations](https://github.com/google/llvm-premerge-checks/wiki/LLVM-pre-merge-tests-operations-blog) diff --git a/docs/playbooks.md b/docs/playbooks.md index d955ba7..1b2165d 100644 --- a/docs/playbooks.md +++ b/docs/playbooks.md @@ -139,7 +139,7 @@ To spawn a new windows agent: 1. Add a task to start agent when machine restarts (make sure to pass correct parameters). ``` git clone https://github.com/google/llvm-premerge-checks.git C:\llvm-premerge-checks -schtasks.exe /create /tn "Start Buildkite agent" /ru SYSTEM /SC ONSTART /DELAY 0005:00 /tr "powershell -command 'C:\llvm-premerge-checks\scripts\windows_agent_start_buildkite.ps1'" +schtasks.exe /create /tn "Start Buildkite agent" /ru SYSTEM /SC ONSTART /DELAY 0005:00 /tr "powershell -command 'C:\llvm-premerge-checks\scripts\windows_agent_start_buildkite.ps1 -workdir c:\ws'" ``` ### Jenkins @@ -174,6 +174,18 @@ Within a container set environment variables similar to [pipeline](https://githu Additionally set `WORKSPACE`, `PHID` and `DIFF_ID` parameters. Set `CONDUIT_TOKEN` with your personal one from `https://reviews.llvm.org/settings/user//page/apitokens/`. +## Custom environment variables for debugging + +Buildkite pipelines have a number of custom environment variables one can set to change their behavior to debug issues +or test changes. The best way is to look on pipeline generators (e.g. build_master_pipeline) + +## Testing changes before merging + +It's recommended to test even small changes before committing them to the `master` branch. + +1. create a branch with your changes, e.g. "my-feature" and push it to origin. +1. manually create a buildkite build in the pipeline you are updating and specify environment variable + `scripts_branch="my-feature"` (see other ) # Phabricator integration @@ -203,14 +215,4 @@ We have these build plans in Harbormaster: * [Plan 4](https://reviews.llvm.org/harbormaster/plan/4/) Builds for everyone * [Plan 3](https://reviews.llvm.org/harbormaster/plan/3/) Builds for beta testers -You can *disable* a build plan to stop it from building. - -## Per user Opt in/out - -You can also on a per-user bases opt in/out to premerge testing. -* To opt-in to pre-merge beta testing, add yourself to this project: -https://reviews.llvm.org/project/view/78/ -* To opt-out of pre-merge testing entirely, add yourself to this project: -https://reviews.llvm.org/project/view/83/ - -These projects are checked in the Herald rules above. +You can *disable* a build plan to stop it from building. \ No newline at end of file diff --git a/kubernetes/windows_agent_create.sh b/kubernetes/windows_agent_create.sh index d34e425..eca813e 100755 --- a/kubernetes/windows_agent_create.sh +++ b/kubernetes/windows_agent_create.sh @@ -28,8 +28,7 @@ NAME=$1 gcloud beta compute instances create "${NAME}" \ --project="${GCP_PROJECT}" \ --zone="${GCP_ZONE}" \ - --machine-type=n1-standard-32 \ - --local-ssd=device-name=local-ssd-0 \ + --machine-type=n2d-standard-16 \ --image=windows-server-2019-dc-for-containers-v20200714 \ --image-project=windows-cloud \ - --boot-disk-size=100GB + --boot-disk-size=200GB --boot-disk-type=pd-ssd diff --git a/scripts/buildkite/analyze_jobs.ipynb b/scripts/buildkite/analyze_jobs.ipynb index e37a76c..b277dd5 100644 --- a/scripts/buildkite/analyze_jobs.ipynb +++ b/scripts/buildkite/analyze_jobs.ipynb @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 724, "metadata": {}, "outputs": [], "source": [ @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 725, "metadata": {}, "outputs": [], "source": [ @@ -51,11 +51,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 726, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loaded 13566 entries\n" + ] + } + ], "source": [ "if os.path.exists(cache_file):\n", " with open(cache_file) as f:\n", @@ -65,11 +73,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 727, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loading page 1\n", + "loading page 2\n", + "loading page 3\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/723 is running , skipping\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/721 is running , skipping\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/719 is running , skipping\n", + "loading page 4\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/717 is running , skipping\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/715 is running , skipping\n", + "loading page 5\n", + "loading page 6\n", + "loading page 7\n", + "loading page 8\n", + "loading page 9\n", + "loading page 10\n", + "13706 jobs in total\n", + "saved 13706 entries\n" + ] + } + ], "source": [ "# load new jobs from Buildkite API\n", + "max_pages = 2000\n", "if True:\n", " existing = set()\n", " for j in builds:\n", @@ -80,7 +113,7 @@ "# existing = set()\n", " page = 1\n", " stop = False\n", - " while not stop:\n", + " while page <= max_pages:\n", " print('loading page', page)\n", " re = requests.get('https://api.buildkite.com/v2/organizations/llvm-project/builds',\n", " params={'page': page},\n", @@ -94,14 +127,15 @@ " break\n", " for j in x:\n", " if j['id'] in existing:\n", - " print('found existing job', j['id'])\n", - " stop = True\n", - " break\n", - " # TODO: skip running jobs \n", - " if (j['state'] == 'running') or (j['state'] == 'scheduled'):\n", - " print(j['web_url'], 'is', j['state'], ', skipping')\n", - " continue\n", - " builds.append(j)\n", + "# print('found existing job', j['id'])\n", + " # load some more pages as some of them might be running before and wasn't added. \n", + " max_pages = min(page + 5, max_pages)\n", + " else:\n", + " # skip running jobs \n", + " if (j['state'] == 'running') or (j['state'] == 'scheduled'):\n", + " print(j['web_url'], 'is', j['state'], ', skipping')\n", + " continue\n", + " builds.append(j)\n", " page += 1\n", " print(len(builds), 'jobs in total') \n", " with open(cache_file, 'w') as f:\n", @@ -111,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 728, "metadata": {}, "outputs": [], "source": [ @@ -138,7 +172,13 @@ "}\n", "\n", "sec = np.timedelta64(1, 's')\n", + "\n", "for b in builds:\n", + " env = b['env']\n", + " if 'ph_windows_agents' not in env:\n", + " continue\n", + " if 'scripts_branch' not in env:\n", + " continue\n", " d['id'].append(b['id'])\n", " d['number'].append(b['number'])\n", " d['pipeline'].append(b['pipeline']['slug'])\n", @@ -169,73 +209,610 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 729, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array(['llvm-master-build'], dtype=object)" + ] + }, + "execution_count": 729, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "jobs.pipeline.unique()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 730, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pipelinenamestep_keystateexit_statusagent_idagent_namerunnable_atstarted_atwait_durationfinished_atrun_duration
0llvm-master-build:seedling: setupNonepassed0f20d42d3-31cb-4e46-a3d6-699877e7b283premerge-debian-77f64f444-fm624-12020-07-27 18:10:162020-07-27 18:15:44.928328.9282020-07-27 18:15:47.7972.869
1llvm-master-build:windows: build and test windowswindowspassed0c9e48cee-e909-45b2-aa23-0d7335786499we32n1b2020-07-27 18:15:472020-07-28 01:36:57.68726470.6872020-07-28 02:26:08.7502951.063
2llvm-master-build:seedling: setupNonepassed0f20d42d3-31cb-4e46-a3d6-699877e7b283premerge-debian-77f64f444-fm624-12020-07-27 18:10:152020-07-27 18:15:34.989319.9892020-07-27 18:15:37.7212.732
3llvm-master-build:windows: build and test windowswindowspassed0d4d0a0a4-255b-4fdd-8aba-abb00ba0bf34we16c2b2020-07-27 18:15:372020-07-28 03:13:59.99632302.9962020-07-28 04:14:12.5213612.525
4llvm-master-build:seedling: setupNonepassed0f20d42d3-31cb-4e46-a3d6-699877e7b283premerge-debian-77f64f444-fm624-12020-07-27 18:10:142020-07-27 18:15:25.094311.0942020-07-27 18:15:27.9182.824
.......................................
189llvm-master-build:windows: build and test windowswindowspassed042f6f98d-15bd-4ad4-ac48-8626a752a154w16c2-12020-07-29 18:22:312020-07-29 20:23:50.6867279.6862020-07-29 21:23:50.2713599.585
190llvm-master-build:seedling: setupNonepassed0db5829eb-04bf-4700-9bec-423258de4a7dpremerge-debian-77f64f444-vxgx4-12020-07-29 18:21:472020-07-29 18:22:09.24322.2432020-07-29 18:22:12.3213.078
191llvm-master-build:windows: build and test windowswindowspassed042f6f98d-15bd-4ad4-ac48-8626a752a154w16c2-12020-07-29 18:22:122020-07-29 19:24:00.3453708.3452020-07-29 20:23:45.9673585.622
192llvm-master-build:seedling: setupNonepassed0db5829eb-04bf-4700-9bec-423258de4a7dpremerge-debian-77f64f444-vxgx4-12020-07-29 18:21:452020-07-29 18:21:49.1904.1902020-07-29 18:21:52.8623.672
193llvm-master-build:windows: build and test windowswindowspassed042f6f98d-15bd-4ad4-ac48-8626a752a154w16c2-12020-07-29 18:21:522020-07-29 18:21:54.8572.8572020-07-29 19:23:58.4713723.614
\n", + "

194 rows × 12 columns

\n", + "
" + ], + "text/plain": [ + " pipeline name step_key state \\\n", + "0 llvm-master-build :seedling: setup None passed \n", + "1 llvm-master-build :windows: build and test windows windows passed \n", + "2 llvm-master-build :seedling: setup None passed \n", + "3 llvm-master-build :windows: build and test windows windows passed \n", + "4 llvm-master-build :seedling: setup None passed \n", + ".. ... ... ... ... \n", + "189 llvm-master-build :windows: build and test windows windows passed \n", + "190 llvm-master-build :seedling: setup None passed \n", + "191 llvm-master-build :windows: build and test windows windows passed \n", + "192 llvm-master-build :seedling: setup None passed \n", + "193 llvm-master-build :windows: build and test windows windows passed \n", + "\n", + " exit_status agent_id \\\n", + "0 0 f20d42d3-31cb-4e46-a3d6-699877e7b283 \n", + "1 0 c9e48cee-e909-45b2-aa23-0d7335786499 \n", + "2 0 f20d42d3-31cb-4e46-a3d6-699877e7b283 \n", + "3 0 d4d0a0a4-255b-4fdd-8aba-abb00ba0bf34 \n", + "4 0 f20d42d3-31cb-4e46-a3d6-699877e7b283 \n", + ".. ... ... \n", + "189 0 42f6f98d-15bd-4ad4-ac48-8626a752a154 \n", + "190 0 db5829eb-04bf-4700-9bec-423258de4a7d \n", + "191 0 42f6f98d-15bd-4ad4-ac48-8626a752a154 \n", + "192 0 db5829eb-04bf-4700-9bec-423258de4a7d \n", + "193 0 42f6f98d-15bd-4ad4-ac48-8626a752a154 \n", + "\n", + " agent_name runnable_at \\\n", + "0 premerge-debian-77f64f444-fm624-1 2020-07-27 18:10:16 \n", + "1 we32n1b 2020-07-27 18:15:47 \n", + "2 premerge-debian-77f64f444-fm624-1 2020-07-27 18:10:15 \n", + "3 we16c2b 2020-07-27 18:15:37 \n", + "4 premerge-debian-77f64f444-fm624-1 2020-07-27 18:10:14 \n", + ".. ... ... \n", + "189 w16c2-1 2020-07-29 18:22:31 \n", + "190 premerge-debian-77f64f444-vxgx4-1 2020-07-29 18:21:47 \n", + "191 w16c2-1 2020-07-29 18:22:12 \n", + "192 premerge-debian-77f64f444-vxgx4-1 2020-07-29 18:21:45 \n", + "193 w16c2-1 2020-07-29 18:21:52 \n", + "\n", + " started_at wait_duration finished_at \\\n", + "0 2020-07-27 18:15:44.928 328.928 2020-07-27 18:15:47.797 \n", + "1 2020-07-28 01:36:57.687 26470.687 2020-07-28 02:26:08.750 \n", + "2 2020-07-27 18:15:34.989 319.989 2020-07-27 18:15:37.721 \n", + "3 2020-07-28 03:13:59.996 32302.996 2020-07-28 04:14:12.521 \n", + "4 2020-07-27 18:15:25.094 311.094 2020-07-27 18:15:27.918 \n", + ".. ... ... ... \n", + "189 2020-07-29 20:23:50.686 7279.686 2020-07-29 21:23:50.271 \n", + "190 2020-07-29 18:22:09.243 22.243 2020-07-29 18:22:12.321 \n", + "191 2020-07-29 19:24:00.345 3708.345 2020-07-29 20:23:45.967 \n", + "192 2020-07-29 18:21:49.190 4.190 2020-07-29 18:21:52.862 \n", + "193 2020-07-29 18:21:54.857 2.857 2020-07-29 19:23:58.471 \n", + "\n", + " run_duration \n", + "0 2.869 \n", + "1 2951.063 \n", + "2 2.732 \n", + "3 3612.525 \n", + "4 2.824 \n", + ".. ... \n", + "189 3599.585 \n", + "190 3.078 \n", + "191 3585.622 \n", + "192 3.672 \n", + "193 3723.614 \n", + "\n", + "[194 rows x 12 columns]" + ] + }, + "execution_count": 730, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "jobs" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 731, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/google/home/goncharov/etc/merge-checks/venv/lib/python3.7/site-packages/ipykernel_launcher.py:1: UserWarning: Boolean Series key will be reindexed to match DataFrame index.\n", + " \"\"\"Entry point for launching an IPython kernel.\n" + ] + } + ], "source": [ - "ds = jobs[jobs['pipeline'] == 'premerge-checks'][jobs['step_key'] == 'windows'][jobs['state']=='passed'][~jobs['agent_name'].str.startswith('buildkite-')][jobs['started_at'] > np.datetime64('2020-01-22')]" + "ds = jobs[jobs['pipeline'] == 'llvm-master-build'][jobs['step_key'] == 'windows'][jobs['state']=='passed'][~jobs['agent_name'].str.startswith('buildkite-')][jobs['started_at'] > np.datetime64('2020-01-22')]\n", + "ds = ds.drop_duplicates()\n", + "# remove one slowest run (repo checkout)\n", + "# t = ds.loc[ds.groupby([\"agent_name\"])[\"run_duration\"].idxmax()]\n", + "# ds = pd.concat([ds, t]).drop_duplicates(keep=False)" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 732, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/google/home/goncharov/etc/merge-checks/venv/lib/python3.7/site-packages/seaborn/categorical.py:2971: UserWarning: The `split` parameter has been renamed to `dodge`.\n", + " warnings.warn(msg, UserWarning)\n" + ] + }, + { + "data": { + "text/plain": [ + "(0.0, 5877.15505)" + ] + }, + "execution_count": 732, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ - " fig, ax = plt.subplots(figsize=(10,10)) # size of the plot (width, height)\n", + "fig, ax = plt.subplots(figsize=(10,10)) # size of the plot (width, height)\n", "\n", - " sns.swarmplot(\n", - " ax=ax,\n", - " x='run_duration',\n", - " y='agent_name',\n", - " split=True,\n", - " data=ds)" + "sns.swarmplot(\n", + " ax=ax,\n", + " x='run_duration',\n", + " y='agent_name',\n", + " split=True,\n", + " data=ds)\n", + "\n", + "plt.xlim(0, None)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 733, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
medianmeanstdcount_nonzero
run_durationrun_durationrun_durationrun_duration
agent_name
we16n1a4982.73805013.848800396.9260505.0
we16n1b4692.79304707.102222121.6241499.0
w16n2-13846.20903881.80960081.6577425.0
we16c2a3779.31103858.373400183.8226025.0
we16c2b3593.52003615.01620066.46000510.0
w16c2-13585.62203612.09280063.1206885.0
we16n1c3068.64403085.9271001412.88808610.0
we32n1b2964.45202964.17830059.21571210.0
we32n1a2880.91803031.068800428.1105685.0
we16c2c2366.51552377.4419001005.84782610.0
we32n1c2289.96052275.634700629.38680410.0
w642282.68602282.76980033.4819775.0
\n", + "
" + ], + "text/plain": [ + " median mean std count_nonzero\n", + " run_duration run_duration run_duration run_duration\n", + "agent_name \n", + "we16n1a 4982.7380 5013.848800 396.926050 5.0\n", + "we16n1b 4692.7930 4707.102222 121.624149 9.0\n", + "w16n2-1 3846.2090 3881.809600 81.657742 5.0\n", + "we16c2a 3779.3110 3858.373400 183.822602 5.0\n", + "we16c2b 3593.5200 3615.016200 66.460005 10.0\n", + "w16c2-1 3585.6220 3612.092800 63.120688 5.0\n", + "we16n1c 3068.6440 3085.927100 1412.888086 10.0\n", + "we32n1b 2964.4520 2964.178300 59.215712 10.0\n", + "we32n1a 2880.9180 3031.068800 428.110568 5.0\n", + "we16c2c 2366.5155 2377.441900 1005.847826 10.0\n", + "we32n1c 2289.9605 2275.634700 629.386804 10.0\n", + "w64 2282.6860 2282.769800 33.481977 5.0" + ] + }, + "execution_count": 733, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "t = pd.pivot_table(ds, values=['run_duration'], index=['agent_name'],\n", " aggfunc=[np.median, np.mean, np.std, np.count_nonzero])\n", "t = t.reindex(t.sort_values(by=('median', 'run_duration'), ascending=False).index)\n", "t" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```\n", + "// TODO: try with w64 w/o AV (temporary disabled)\n", + "w1 - 16 - non ssd 100 + ssd\n", + "w1a - 16 - non ssd 100 + ssd - AV (temp)\n", + "w4a - 16 - non ssd 100 + ssd - AV\n", + "w16-1 - 16 - non sdd 200 + ssd\n", + "w32-1 - 32 - non ssd 100 + ssd\n", + "w32-2 - 32 - non ssd 100 + ssd - AV\n", + "w32-2d - 32 - non ssd 200 + ssd\n", + "w64 - 64 - ssd 200 + ssd \n", + "w64a - 64 - ssd 200 + ssd - AV (temp)\n", + "wh63-3 - 64 low ram - non ssd 100 + ssd - AV\n", + "\n", + "buildkite-windows-16n1-exp\n", + "gcloud beta compute instances create \"${NAME}\" \\\n", + " --project=\"${GCP_PROJECT}\" \\\n", + " --zone=\"${GCP_ZONE}\" \\\n", + " --machine-type=n1-standard-16 \\\n", + " --local-ssd=device-name=local-ssd-0 \\\n", + " --image=windows-server-2019-dc-for-containers-v20200714 \\\n", + " --image-project=windows-cloud \\\n", + " --boot-disk-size=200GB --boot-disk-type=pd-ssd\n", + "\n", + "buildkite-32-experimental-1\n", + "gcloud beta compute instances create \"${NAME}\" \\\n", + " --project=\"${GCP_PROJECT}\" \\\n", + " --zone=\"${GCP_ZONE}\" \\\n", + " --machine-type=n1-standard-32 \\\n", + " --local-ssd=device-name=local-ssd-0 \\\n", + " --image=windows-server-2019-dc-for-containers-v20200714 \\\n", + " --image-project=windows-cloud \\\n", + " --boot-disk-size=200GB --boot-disk-type=pd-ssd\n", + "\n", + " \n", + "buildkite-16c2-exp\n", + "gcloud beta compute instances create \"${NAME}\" \\\n", + " --project=\"${GCP_PROJECT}\" \\\n", + " --zone=\"${GCP_ZONE}\" \\\n", + " --machine-type=c2-standard-16 \\\n", + " --local-ssd=device-name=local-ssd-0 \\\n", + " --local-ssd=interface=SCSI \\\n", + " --image=windows-server-2019-dc-for-containers-v20200714 \\\n", + " --image-project=windows-cloud \\\n", + " --boot-disk-size=200GB --boot-disk-type=pd-ssd\n", + " \n", + "...a: as is D:/ is a workdir (ealy run with full cache build)\n", + "...b: C:/ws as a workdir, no cache\n", + "```\n" + ] } ], "metadata": { diff --git a/scripts/buildkite/build_master_pipeline.py b/scripts/buildkite/build_master_pipeline.py index cdc1ce6..f46c82e 100755 --- a/scripts/buildkite/build_master_pipeline.py +++ b/scripts/buildkite/build_master_pipeline.py @@ -23,7 +23,7 @@ if __name__ == '__main__': no_cache = os.getenv('ph_no_cache') is not None filter_output = '--filter-output' if os.getenv('ph_no_filter_output') is None else '' projects = os.getenv('ph_projects', 'clang;clang-tools-extra;libc;libcxx;libcxxabi;lld;libunwind;mlir;openmp;polly') - log_level = os.getenv('ph_log_level', 'WARNING') + log_level = os.getenv('C', 'WARNING') notify_emails = list(filter(None, os.getenv('ph_notify_emails', '').split(','))) steps = [] linux_agents = {'queue': f'{queue_prefix}linux'} diff --git a/scripts/phabtalk/apply_patch2.py b/scripts/phabtalk/apply_patch2.py index 042a029..73d4ddd 100755 --- a/scripts/phabtalk/apply_patch2.py +++ b/scripts/phabtalk/apply_patch2.py @@ -146,9 +146,9 @@ class ApplyPatch: logging.info('Syncing local, origin and upstream...') self.repo.git.clean('-ffxdq') + self.repo.git.reset('--hard') self.repo.git.fetch('--all') self.repo.git.checkout('master') - self.repo.git.reset('--hard') if 'upstream' not in self.repo.remotes: self.repo.create_remote('upstream', url=LLVM_GITHUB_URL) self.repo.remotes.upstream.fetch()