| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | # Overview - General
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Objective
 | 
					
						
							|  |  |  | Whenever a PR job is run on Travis, we want to build `angular.io` and upload the build artifacts to | 
					
						
							|  |  |  | a publicly accessible server so that collaborators (developers, designers, authors, etc) can preview | 
					
						
							|  |  |  | the changes without having to checkout and build the app locally. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Source code
 | 
					
						
							|  |  |  | In order to make it easier to administer the server and version-control the setup, we are using | 
					
						
							|  |  |  | [docker](https://www.docker.com) to run a container on a VM. The Dockerfile and all other files | 
					
						
							|  |  |  | necessary for creating the docker container are stored (and versioned) along with the angular.io | 
					
						
							|  |  |  | project's source code (currently part of the angular/angular repo) in the `aio-builds-setup/` | 
					
						
							|  |  |  | directory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Setup
 | 
					
						
							|  |  |  | The VM is hosted on [Google Compute Engine](https://cloud.google.com/compute/). The host OS is | 
					
						
							|  |  |  | debian:jessie. For more info how to set up the host VM take a look at the "Setting up the VM" | 
					
						
							|  |  |  | section in [TOC](_TOC.md). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Security model
 | 
					
						
							|  |  |  | Since we are managing a public server, it is important to take appropriate measures in order to | 
					
						
							|  |  |  | prevent abuse. For more details on the challenges and the chosen approach take a look at the | 
					
						
							|  |  |  | [security model](overview--security-model.md). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## The 10000 feet view
 | 
					
						
							|  |  |  | This section gives a brief summary of the several operations performed on CI and by the docker | 
					
						
							|  |  |  | container: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### On CI (Travis)
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | - Build job completes successfully. | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | - The CI script checks whether the build job was initiated by a PR against the angular/angular | 
					
						
							|  |  |  |   master branch. | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | - The CI script checks whether the PR has touched any files that might affect the angular.io app | 
					
						
							|  |  |  |   (currently the `aio/` or `packages/` directories, ignoring spec files). | 
					
						
							|  |  |  | - Optionally, the CI script can check whether the PR can be automatically verified (i.e. if the | 
					
						
							|  |  |  |   author of the PR is a member of one of the whitelisted GitHub teams or the PR has the specified | 
					
						
							|  |  |  |   "trusted PR" label). | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  |   **Note:** | 
					
						
							|  |  |  |   For security reasons, the same checks will be performed on the server as well. This is an optional | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |   step that can be used in case one wants to apply special logic depending on the outcome of the | 
					
						
							|  |  |  |   pre-verification. For example: | 
					
						
							|  |  |  |   1. One might want to deploy automatically verified PRs only. In that case, the pre-verification | 
					
						
							|  |  |  |      helps avoid the wasted overhead associated with uploads that are going to be rejected (e.g. | 
					
						
							|  |  |  |      building the artifacts, sending them to the server, running checks on the server, detecting the | 
					
						
							|  |  |  |      reasons of deployment failure and whether to fail the build, etc). | 
					
						
							|  |  |  |   2. One might want to apply additional logic (e.g. different tests) depending on whether the PR is | 
					
						
							|  |  |  |      automatically verified or not). | 
					
						
							|  |  |  | - The CI script gzips and uploads the build artifacts to the server. | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | More info on how to set things up on CI can be found [here](misc--integrate-with-ci.md). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Uploading build artifacts
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | - nginx receives the upload request. | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | - nginx checks that the uploaded gzip archive does not exceed the specified max file size, stores it | 
					
						
							|  |  |  |   in a temporary location and passes the filepath to the Node.js upload-server. | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | - The upload-server runs several checks to determine whether the request should be accepted and | 
					
						
							|  |  |  |   whether it should be publicly accessible or stored for later verification (more details can be | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  |   found [here](overview--security-model.md)). | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | - The upload-server changes the "visibility" of the associated PR, if necessary. For example, if | 
					
						
							|  |  |  |   builds for the same PR had been previously deployed as non-public and the current build has been | 
					
						
							| 
									
										
										
										
											2017-06-25 22:13:03 +03:00
										 |  |  |   automatically verified, all previous builds are made public as well. | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |   If the PR transitions from "non-public" to "public", the upload-server posts a comment on the | 
					
						
							|  |  |  |   corresponding PR on GitHub mentioning the SHAs and the links where the previews can be found. | 
					
						
							|  |  |  | - The upload-server verifies that the uploaded file is not trying to overwrite an existing build. | 
					
						
							| 
									
										
										
										
											2017-06-25 22:13:03 +03:00
										 |  |  | - The upload-server deploys the artifacts to a sub-directory named after the PR number and the first | 
					
						
							|  |  |  |   few characters of the SHA: `<PR>/<SHA>/` | 
					
						
							|  |  |  |   (Non-publicly accessible PRs will be stored in a different location, but again derived from the PR | 
					
						
							|  |  |  |   number and SHA.) | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | - If the PR is publicly accessible, the upload-server posts a comment on the corresponding PR on | 
					
						
							|  |  |  |   GitHub mentioning the SHA and the link where the preview can be found. | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 14:52:58 +03:00
										 |  |  | More info on the possible HTTP status codes and their meaning can be found | 
					
						
							|  |  |  | [here](overview--http-status-codes.md). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-27 19:43:02 +03:00
										 |  |  | ### Updating PR visibility
 | 
					
						
							|  |  |  | - nginx receives a natification that a PR has been updated and passes it through to the | 
					
						
							|  |  |  |   upload-server. This could, for example, be sent by a GitHub webhook every time a PR's labels | 
					
						
							|  |  |  |   change. | 
					
						
							|  |  |  |   E.g.: `ngbuilds.io/pr-updated` (payload: `{"number":<PR>,"action":"labeled"}`) | 
					
						
							|  |  |  | - The request contains the PR number (as `number`) and optionally the action that triggered the | 
					
						
							|  |  |  |   request (as `action`) in the payload. | 
					
						
							|  |  |  | - The upload-server verifies the payload and determines whether the `action` (if specified) could | 
					
						
							|  |  |  |   have led to PR visibility changes. Only requests that omit the `action` field altogether or | 
					
						
							|  |  |  |   specify an action that can affect visibility are further processed. | 
					
						
							|  |  |  |   (Currently, the only actions that are considered capable of affecting visibility are `labeled` and | 
					
						
							|  |  |  |   `unlabeled`.) | 
					
						
							|  |  |  | - The upload-server re-checks and if necessary updates the PR's visibility. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | More info on the possible HTTP status codes and their meaning can be found | 
					
						
							|  |  |  | [here](overview--http-status-codes.md). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | ### Serving build artifacts
 | 
					
						
							|  |  |  | - nginx receives a request for an uploaded resource on a subdomain corresponding to the PR and SHA. | 
					
						
							| 
									
										
										
										
											2017-03-25 22:48:36 -04:00
										 |  |  |   E.g.: `pr<PR>-<SHA>.ngbuilds.io/path/to/resource` | 
					
						
							|  |  |  | - nginx maps the subdomain to the correct sub-directory and serves the resource. | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  |   E.g.: `/<PR>/<SHA>/path/to/resource` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-27 19:43:02 +03:00
										 |  |  | More info on the possible HTTP status codes and their meaning can be found | 
					
						
							| 
									
										
										
										
											2017-06-19 14:52:58 +03:00
										 |  |  | [here](overview--http-status-codes.md). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-09 22:12:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### Removing obsolete artifacts
 | 
					
						
							|  |  |  | In order to avoid flooding the disk with unnecessary build artifacts, there is a cronjob that runs a | 
					
						
							|  |  |  | clean-up tasks once a day. The task retrieves all open PRs from GitHub and removes all directories | 
					
						
							|  |  |  | that do not correspond with an open PR. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Health-check
 | 
					
						
							|  |  |  | The docker service runs a periodic health-check that verifies the running conditions of the | 
					
						
							|  |  |  | container. This includes verifying the status of specific system services, the responsiveness of | 
					
						
							|  |  |  | nginx and the upload-server and internet connectivity. |