1
0
mirror of https://github.com/tektoncd/catalog.git synced 2024-11-21 05:55:35 +00:00

Task for creating GitHub deployments

This introduces a Task for creating GitHub deployments for a given
repository. This allows people who rely on GitHub deployment events
for their CD systems to be able create them from within a Tekton
pipeline.

This task is pretty much just a wrapper around the GitHub API for
creating deployments. The main params required are the ref
and environment for the deployment, and we fall back to the API's
defaults for the other params.
This commit is contained in:
jace-ys 2020-07-15 17:09:51 +08:00 committed by tekton-robot
parent a1cd5f81d2
commit dcaa00dca6
2 changed files with 221 additions and 0 deletions

View File

@ -0,0 +1,66 @@
## GitHub Create Deployment
The `github-create-deployment` Task lets you create a GitHub deployment.
See GitHub's deployment API on [creating a deployment](https://developer.github.com/v3/repos/deployments/#create-a-deployment) for more information.
### Install the Task
```
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/github-create-deployment/0.1/github-create-deployment.yaml
```
### Secrets
This Task requires access to a GitHub token set via a Kubernetes Secret. By default, the name of this Secret should be `github` and the secret key should be `token`, but you can configure this via the `GITHUB_TOKEN_SECRET_NAME` and `GITHUB_TOKEN_SECRET_KEY` [parameters](#parameters) described below.
To create such a Secret via `kubectl`:
```
kubectl create secret generic github --from-literal token="MY_TOKEN"
```
See GitHub's documentation on [Understanding scopes for OAuth Apps](https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/) to figure out what scopes you need to give to this token to create deployments.
### Parameters
- **GITHUB_HOST_URL:**: The GitHub host domain. (_default:_ `api.github.com`)
- **REPO_FULL_NAME:**: The GitHub repository full name. (_e.g:_ `tektoncd/catalog`)
- **REF**: The ref to deploy. This can be a branch, tag, or SHA. (_e.g:_ `master`)
- **TASK**: Specifies a task to execute. (_default:_ `deploy`)
- **AUTO_MERGE**: Attempts to automatically merge the default branch into the
requested ref, if it's behind the default branch. (_default:_ `true`)
- **REQUIRED_CONTEXTS**: The status contexts to verify against commit status checks. To
verify all unique contexts before creating a deployment, pass
in `*`. To bypass checking entirely, pass an empty string. (_default:_ `*`)
- **PAYLOAD**: JSON payload with extra information about the deployment. (_default:_ `""`)
- **ENVIRONMENT**: Name for the target deployment environment (_e.g:_ `production`).
- **DESCRIPTION**: Short description of the deployment. (_default:_ `""`).
- **GITHUB_TOKEN_SECRET_NAME**: The name of the Kubernetes Secret that
contains the GitHub token. (_default:_ `github`).
- **GITHUB_TOKEN_SECRET_KEY**: The key within the Kubernetes Secret that contains the GitHub token. (_default:_ `token`).
## Usage
This TaskRun creates a GitHub deployment for the given repository.
```yaml
---
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
labels:
tekton.dev/task: github-create-deployment
name: github-create-tektoncd-catalog-deployment
spec:
taskRef:
kind: Task
name: github-create-deployment
params:
- name: REPO_FULL_NAME
value: tektoncd/catalog
- name: REF
value: master
- name: ENVIRONMENT
value: staging
```

View File

@ -0,0 +1,155 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: github-create-deployment
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: github
tekton.dev/displayName: "create github deployment"
spec:
description: >-
This Task will create a GitHub deployment for a repository.
params:
- name: GITHUB_HOST_URL
description: |
The GitHub host, adjust this if you run a GitHub enterprise.
default: "api.github.com"
type: string
- name: REPO_FULL_NAME
description: |
The GitHub repository full name, i.e: tektoncd/catalog.
type: string
- name: REF
description: |
The ref to deploy. This can be a branch, tag, or SHA.
type: string
- name: TASK
description: |
Specifies a task to execute (e.g., deploy or deploy:migrations).
default: "deploy"
type: string
- name: AUTO_MERGE
description: |
Attempts to automatically merge the default branch into the
requested ref, if it's behind the default branch.
default: "true"
type: string
- name: REQUIRED_CONTEXTS
description: |
The status contexts to verify against commit status checks. To
verify all unique contexts before creating a deployment, pass
in "*". To bypass checking entirely, pass an empty string.
default: "*"
- name: PAYLOAD
description: |
JSON payload with extra information about the deployment.
default: ""
type: string
- name: ENVIRONMENT
description: |
Name for the target deployment environment (e.g., production, staging).
type: string
- name: DESCRIPTION
description: |
Short description of the deployment.
default: ""
type: string
- name: GITHUB_TOKEN_SECRET_NAME
description: |
The name of the Kubernetes Secret that contains the GitHub token.
default: "github"
type: string
- name: GITHUB_TOKEN_SECRET_KEY
description: |
The key within the Kubernetes Secret that contains the GitHub token.
default: "token"
type: string
steps:
- name: create-deployment
env:
- name: GITHUBTOKEN
valueFrom:
secretKeyRef:
name: $(params.GITHUB_TOKEN_SECRET_NAME)
key: $(params.GITHUB_TOKEN_SECRET_KEY)
image: registry.access.redhat.com/ubi8/ubi:8.2
script: |
#!/usr/libexec/platform-python
import http.client
import json
import os
import sys
deployment_url = "/repos/$(params.REPO_FULL_NAME)/deployments"
if "$(params.REQUIRED_CONTEXTS)" == "*":
required_contexts = None
elif "$(params.REQUIRED_CONTEXTS)" == "":
required_contexts = []
else:
required_contexts = "$(params.REQUIRED_CONTEXTS)".split(",")
# payload should either be a JSON object or an empty string
if "$(params.PAYLOAD)":
payload = json.loads("$(params.PAYLOAD)")
else:
payload = ""
data = {
"ref": "$(params.REF)",
"task": "$(params.TASK)",
"auto_merge": json.loads("$(params.AUTO_MERGE)"),
"required_contexts": required_contexts,
"payload": payload,
"environment": "$(params.ENVIRONMENT)",
"description": "$(params.DESCRIPTION)",
}
print("Sending this data to GitHub: ")
print(data)
conn = http.client.HTTPSConnection("$(params.GITHUB_HOST_URL)")
r = conn.request(
"POST",
deployment_url,
body=json.dumps(data),
headers={
"User-Agent": "TektonCD, the peaceful cat",
"Authorization": "Bearer " + os.environ["GITHUBTOKEN"],
})
resp = conn.getresponse()
# only look for 201 statuses to signify a deployment was successfully
# created, as a merged branch response returns a 202 status but does not
# actually create the deployment.
# https://developer.github.com/v3/repos/deployments/#merged-branch-response
if resp.status != 201:
print("Error: %d" % (resp.status))
print(resp.read())
sys.exit(1)
else:
body = json.loads(resp.read().decode())
print("GitHub deployment created for "
"$(params.REPO_FULL_NAME): "
"id={} branch={} sha={} environment={} url={}".format(
body["id"],
body["ref"],
body["sha"],
body["environment"],
body["url"]))