# GitHub Webhook - Go sample

A handler written in Go that demonstrates interacting with GitHub
through a webhook.

## Prerequisites

*  A Kubernetes cluster with Knative installed. Follow the
   [installation instructions](https://github.com/knative/docs/blob/master/install/README.md)
   if you need to create one.
*  [Docker](https://www.docker.com) installed and running on your local machine,
   and a Docker Hub account configured (we'll use it for a container registry).
*  An account on [GitHub](https://github.com) with read/write access to a 
   repository.

## Build the sample code

1. Use Docker to build a container image for this service. Replace 
   `{username}` with your Docker Hub username in the following commands.

  ```shell
  export DOCKER_HUB_USERNAME=username

  # Build the container, run from the project folder
  docker build -t ${DOCKER_HUB_USERNAME}/gitwebhook-go . 

  # Push the container to the registry
  docker push ${DOCKER_HUB_USERNAME}/gitwebhook-go
  ```

1. Create a secret that holds two values from GitHub, a personal access token
   used to make API requests to GitHub, and a webhook secret, used to validate
   incoming requests.

   1. Follow the GitHub instructions to [create a personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/).
      Ensure to grant the `repo` permission to give read/write access to the
      personal access token.
   1. Base64 encode the access token:

      ```shell
      $ echo -n "45d382d4a9a93c453fb7c8adc109121e7c29fa3ca" | base64
      NDVkMzgyZDRhOWE5M2M0NTNmYjdjOGFkYzEwOTEyMWU3YzI5ZmEzY2E=
      ```

   1. Copy the encoded access token into `github-secret.yaml` next to `personalAccessToken:`.
   1. Create a webhook secert value unique to this sample, base64 encode it, and
      copy it into `github-secret.yaml` next to `webhookSecret:`:

      ```shell
      $ echo -n "mygithubwebhooksecret" | base64
      bXlnaXRodWJ3ZWJob29rc2VjcmV0
      ```

   1. Apply the secret to your cluster:

       ```shell
       kubectl apply --filename github-secret.yaml
       ```

1. Next, update the `service.yaml` file in the project to reference the tagged
   image from step 1.

  ```yaml
  apiVersion: serving.knative.dev/v1alpha1
  kind: Service
  metadata:
    name: gitwebhook
    namespace: default
  spec:
    runLatest:
      configuration:
        revisionTemplate:
          spec:
            container:
              # Replace {DOCKER_HUB_USERNAME} with your actual docker hub username
              image: docker.io/{DOCKER_HUB_USERNAME}/gitwebhook-go
              env:
              - name: SECRET_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: githubsecret
                    key: secretToken
              - name: ACCESS_TOKEN
                valueFrom:
                    secretKeyRef:
                      name: githubsecret
                      key: accessToken
  ```

1. Use `kubectl` to apply the `service.yaml` file.

```shell
$ kubectl apply --filename service.yaml
service "gitwebhook" created
```

1. Finally, once the service is running, create the webhook from your GitHub repo
   to the URL for this service. For this to work properly you will
   need to [configure a custom domain](https://github.com/knative/docs/blob/master/serving/using-a-custom-domain.md)
   and [assign a static IP address](https://github.com/knative/docs/blob/master/serving/gke-assigning-static-ip-address.md).

    1. Retrieve the hostname for this service, using the following command:

        ```shell
        $ kubectl get ksvc gitwebhook \
           --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain

        NAME                DOMAIN
        gitwebhook          gitwebhook.default.example.com
        ```

    1. Browse on GitHub to the repository where you want to create a webhook.
    1. Click **Settings**, then **Webhooks**, then **Add webhook**.
    1. Enter the **Payload URL** as `http://{DOMAIN}`, with the value of DOMAIN listed above.
    1. Set the **Content type** to `application/json`. 
    1. Enter the **Secret** value to be the same as the original base used for
       `webhookSecret` above (the original value, not the base64 encoded value).
    1. Select **Disable** under SSL Validation, unless you've [enabled SSL](https://github.com/knative/docs/blob/master/serving/using-an-ssl-cert.md).
    1. Click **Add webhook** to create the webhook.

## Exploring

Once deployed, you can inspect the created resources with `kubectl` commands:

```shell
# This will show the Knative service that we created:
kubectl get ksvc --output yaml

# This will show the Route, created by the service:
kubectl get route --output yaml

# This will show the Configuration, created by the service:
kubectl get configurations --output yaml

# This will show the Revision, created by the Configuration:
kubectl get revisions --output yaml
```

## Testing the service

Now that you have the service running and the webhook created, send a Pull
Request to the same GitHub repo where you added the webhook. If all is working
right, you'll see the title of the PR will be modified, with the text
`(looks pretty legit)` appended the end of the title.

## Cleaning up

To clean up the sample service:

```shell
kubectl delete --filename service.yaml
```

