GitHub webhook sample - Go

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

Before you begin

  • A Kubernetes cluster with Knative installed. Follow the installation instructions if you need to create one.
  • Docker 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 with read/write access to a repository.

Build the sample code

  1. Download a copy of the code:

    git clone -b "release-0.6" https://github.com/knative/docs knative-docs
    cd knative-docs/serving/samples/gitwebhook-go
    1. Use Docker to build a container image for this service. Replace username with your Docker Hub username in the following commands.
    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
  2. 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. Ensure to grant the repo permission to give read/write access to the personal access token.
    2. Base64 encode the access token:
       $ echo -n "45d382d4a9a93c453fb7c8adc109121e7c29fa3ca" | base64
       NDVkMzgyZDRhOWE5M2M0NTNmYjdjOGFkYzEwOTEyMWU3YzI5ZmEzY2E=
    1. Copy the encoded access token into github-secret.yaml next to personalAccessToken:.
    2. Create a webhook secert value unique to this sample, base64 encode it, and copy it into github-secret.yaml next to webhookSecret::
       $ echo -n "mygithubwebhooksecret" | base64
       bXlnaXRodWJ3ZWJob29rc2VjcmV0
    1. Apply the secret to your cluster:
       kubectl apply --filename github-secret.yaml
    1. Next, update the service.yaml file in the project to reference the tagged image from step 1.
    apiVersion: serving.knative.dev/v1alpha1
    kind: Service
    metadata:
      name: gitwebhook
      namespace: default
    spec:
      - containers:
          # 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
  3. Use kubectl to apply the service.yaml file.

    $ 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 and assign a static IP address.

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

       $ 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.
    2. Click Settings, then Webhooks, then Add webhook.
    3. Enter the Payload URL as http://{DOMAIN}, with the value of DOMAIN listed above.
    4. Set the Content type to application/json.
    5. Enter the Secret value to be the same as the original base used for webhookSecret above (the original value, not the base64 encoded value).
    6. Select Disable under SSL Validation, unless you've enabled SSL.
    7. Click Add webhook to create the webhook.

Exploring

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

# 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:

kubectl delete --filename service.yaml