Skip to content
Branch: master
Find file Copy path
Find file Copy path
3 contributors

Users who have contributed to this file

@ccojocar @cjwagner @nicoaragon
65 lines (50 sloc) 6.05 KB

Life of a Prow Job

I comment /test all on a Pull Request (PR). In response, GitHub posts my comment to Prow, via a webhook. See examples for webhook payloads here.

Prow's Kubernetes cluster uses an ingress resource for terminating TLS, and routing traffic to the hook service resource. This document describes the configuration for the ingress resource. The ingress resource sends traffic to the "hook" service. This document describes the configuration for the "hook" service.

The "hook" service routes traffic to the "hook" application. This deployment resource defines the pods that "hook" is comprised of.

The pods for "hook" run the "Hook" executable. "hook" listens for incoming http requests and translates them to "GitHub event objects". Afterwards, "hook" broadcasts these events to Prow Plugins. In the case of my /test all comment, "hook" builds an "Issue Comment Event".

Prow plugins receive 2 objects: 1) a GitHub event object, and 2) a "client agent object". The Client agent object contains 7 clients: GitHub, Prow jobs, Kubernetes, Git, Slack, Owners, and Bugzilla. These 7 clients are initialized by "hook", during start-up. This is what "client agent objects" look like:

type ClientAgent struct {
	GitHubClient     github.Client
	ProwJobClient    prowv1.ProwJobInterface
	KubernetesClient kubernetes.Interface
	GitClient        *git.Client
	SlackClient      *slack.Client
	OwnersClient     *repoowners.Client
	BugzillaClient   bugzilla.Client

"hook" multiplexes events by looking at "X-GitHub-Event", a custom http header. Afterwards, a PluginAgent object, initialized during Hook's startup, selects plugins to handle events. See events.go for more details, and check plugins.yaml for a list of plugins per repo.

"hook" delivers an event that represents my /test all comment to the Trigger plugin. The Trigger plugin validates the PR before running tests. One such validation is, for instance, that the author is a member of the organization or that the PR is labeled ok-to-test. The function called handleGenericCommentEvent (implementec by handleGenericComment) describes Trigger's logic.

Finally, handleGenericComment determines presubmit jobs to run. The list of jobs supplied by the Config object, in the PluginClient object, will be used to find suitable jobs.

Next, the trigger plugin talks to the Kubernetes API server and creates a ProwJob Custom Resource with the information from the issue comment.

Pod details aside, the resulting Prow job looks like this:

kind: ProwJob
  name: 32456927-35d9-11e7-8d95-0a580a6c1504
  job: pull-test-infra-bazel
  decorate: true
    - image:
    base_ref: master
    base_sha: 064678510782db5b382df478bb374aaa32e577ea
    org: kubernetes
    - author: ixdy
      number: 2716
      sha: dc32ccc9ea3672ccc523b7cbaa8b00360b4183cd
    repo: test-infra
  type: presubmit
  startTime: 2017-05-10T23:34:22.567457715Z
  state: triggered

Every thirty seconds, cmd/plank runs Sync. Sync runs syncKubernetesJob for each Prow job and pod. Because the above Prow job lacks a corresponding Kubernetes pod, Sync creates one in the test-pods namespace. Finally, Sync updates the status line on the PR with a link to Gubernator. Gubernator handles real-time logs and results.

When the Prow job ends, the syncKubernetesJob method updates the ProwJob status to success and sets the status line on GitHub to success. The status update makes a green check-mark show up on the PR.

A day later, cmd/sinker notices that the job and pod are a day old and deletes them from the Kubernetes API server.

You can’t perform that action at this time.