mirror of
https://github.com/tektoncd/catalog.git
synced 2024-11-21 05:55:35 +00:00
Add support for comment update to github comment task
Enhance the GitHub add comment task with the ability to update a comment if applicable. This achieved by tagging comments with and invisible (HTML comment) unique text, and looking for that text to identify a comment. This does not use the nodeid because that is generated by GitHub and it would require task users to store known node IDs somewhere across task executions. Signed-off-by: Andrea Frittoli <andrea.frittoli@gmail.com>
This commit is contained in:
parent
52b1848b00
commit
66df9ddf53
148
task/github-add-comment/0.4/README.md
Normal file
148
task/github-add-comment/0.4/README.md
Normal file
@ -0,0 +1,148 @@
|
||||
# Add a comment to an issue or a pull request
|
||||
|
||||
The `github-add-comment` task let you add a comment to a pull request or an
|
||||
issue.
|
||||
|
||||
## Changelog
|
||||
|
||||
- Added support for replacing a comment. It works by adding an invisible tag into the comment, which allows for
|
||||
later identification and update of the comment. It introduces two new parameters: `COMMENT_TAG` and `REPLACE`.
|
||||
|
||||
## Install the Task
|
||||
|
||||
```
|
||||
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/github-add-comment/0.4/github-add-comment.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"
|
||||
```
|
||||
|
||||
Check [this](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) to get personal access token for `Github`.
|
||||
|
||||
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 add comment to an issue or a pull request.
|
||||
|
||||
## Parameters
|
||||
|
||||
- **GITHUB_HOST_URL:**: The GitHub host domain (_default:_ `api.github.com`)
|
||||
- **API_PATH_PREFIX:**: The GitHub Enterprise has a prefix for the API path. _e.g:_ `/api/v3`
|
||||
- **REQUEST_URL:**: The GitHub pull request or issue url, _e.g:_
|
||||
`https://github.com/tektoncd/catalog/issues/46`
|
||||
- **COMMENT_OR_FILE:**: The actual comment to add or the filename inside the
|
||||
optional workspace `comment-file` containing comment to post. _e.g:_ `don't forget to eat your vegetables before commiting.` _or_ `input.txt`
|
||||
- **COMMENT_TAG:**: An invisible tag to be added into the comment. The tag is
|
||||
made invisible by embedding in an an HTML comment. The tag allows
|
||||
for later retrieval of the comment, and it allows replacing an existing comment. _e.g._ `myservice.[commit-sha]`. (_default:_ `""`).
|
||||
- **REPLACE:**: When a tag is specified, and `REPLACE` is `true`, look for a
|
||||
comment with a matching tag and replace it with the new comment. (_default:_ `false`).
|
||||
- **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`).
|
||||
|
||||
## Results
|
||||
|
||||
- **OLD_COMMENT:**: The old text of the comment, if any.
|
||||
- **NEW_COMMENT:**: The new text of the comment, if any.
|
||||
|
||||
## Workspaces
|
||||
|
||||
- **comment-file**: The optional workspace containing comment file to be posted.
|
||||
|
||||
## Usage
|
||||
|
||||
This TaskRun add a comment to an issue.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: TaskRun
|
||||
metadata:
|
||||
labels:
|
||||
tekton.dev/task: github-add-comment
|
||||
name: github-add-comment-to-pr-22
|
||||
spec:
|
||||
taskRef:
|
||||
kind: Task
|
||||
name: github-add-comment
|
||||
params:
|
||||
- name: REQUEST_URL
|
||||
value: https://github.com/chmouel/scratchpad/pull/46
|
||||
- name: COMMENT_OR_FILE
|
||||
value: |
|
||||
The cat went here and there
|
||||
And the moon spun round like a top,
|
||||
And the nearest kin of the moon,
|
||||
The creeping cat, looked up.
|
||||
Black Minnaloushe stared at the moon,
|
||||
For, wander and wail as he would,
|
||||
The pure cold light in the sky
|
||||
Troubled his animal blood.
|
||||
```
|
||||
|
||||
### When passing a comment via file
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: comment-cm
|
||||
data:
|
||||
input.txt: |
|
||||
This is the sample input comment via file.
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: TaskRun
|
||||
metadata:
|
||||
labels:
|
||||
tekton.dev/task: github-add-comment
|
||||
name: github-add-comment-to-pr-22
|
||||
spec:
|
||||
taskRef:
|
||||
kind: Task
|
||||
name: github-add-comment
|
||||
workspace:
|
||||
- name: comment-file
|
||||
configMap:
|
||||
name: comment-cm
|
||||
params:
|
||||
- name: REQUEST_URL
|
||||
value: https://github.com/chmouel/scratchpad/pull/46
|
||||
- name: COMMENT_OR_FILE
|
||||
value: "input.txt"
|
||||
```
|
||||
|
||||
### This TaskRun replaces a comment in an issue
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: TaskRun
|
||||
metadata:
|
||||
name: github-add-comment-to-pr-22
|
||||
spec:
|
||||
taskRef:
|
||||
kind: Task
|
||||
name: github-add-comment
|
||||
params:
|
||||
- name: REQUEST_URL
|
||||
value: https://github.com/chmouel/scratchpad/pull/46
|
||||
- name: COMMENT_TAG
|
||||
value: catalog-sha123abc
|
||||
- name: REPLACE
|
||||
value: "true"
|
||||
- name: COMMENT_OR_FILE
|
||||
value: |
|
||||
The cat went here and there
|
||||
And the moon spun round like a top,
|
||||
And the nearest kin of the moon,
|
||||
The creeping cat, looked up.
|
||||
Black Minnaloushe stared at the moon,
|
||||
For, wander and wail as he would,
|
||||
The pure cold light in the sky
|
||||
Troubled his animal blood.
|
184
task/github-add-comment/0.4/github-add-comment.yaml
Normal file
184
task/github-add-comment/0.4/github-add-comment.yaml
Normal file
@ -0,0 +1,184 @@
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: github-add-comment
|
||||
labels:
|
||||
app.kubernetes.io/version: "0.4"
|
||||
annotations:
|
||||
tekton.dev/pipelines.minVersion: "0.17.0"
|
||||
tekton.dev/tags: github
|
||||
tekton.dev/displayName: "add github comment"
|
||||
spec:
|
||||
description: >-
|
||||
This Task will add a comment to a pull request or an issue.
|
||||
|
||||
It can take either a filename or a comment as input and can
|
||||
post the comment back to GitHub accordingly.
|
||||
|
||||
workspaces:
|
||||
- name: comment-file
|
||||
optional: true
|
||||
description: The optional workspace containing comment file to be posted.
|
||||
|
||||
results:
|
||||
- name: OLD_COMMENT
|
||||
description: The old text of the comment, if any.
|
||||
|
||||
- name: NEW_COMMENT
|
||||
description: The new text of the comment, if any.
|
||||
|
||||
params:
|
||||
- name: GITHUB_HOST_URL
|
||||
description: |
|
||||
The GitHub host, adjust this if you run a GitHub enteprise.
|
||||
default: "api.github.com"
|
||||
type: string
|
||||
|
||||
- name: API_PATH_PREFIX
|
||||
description: |
|
||||
The API path prefix, GitHub Enterprise has a prefix e.g. /api/v3
|
||||
default: ""
|
||||
type: string
|
||||
|
||||
- name: REQUEST_URL
|
||||
description: |
|
||||
The GitHub issue or pull request URL where we want to add a new
|
||||
comment.
|
||||
type: string
|
||||
|
||||
- name: COMMENT_OR_FILE
|
||||
description: |
|
||||
The actual comment to add or the filename containing comment to post.
|
||||
type: string
|
||||
|
||||
- name: GITHUB_TOKEN_SECRET_NAME
|
||||
description: |
|
||||
The name of the Kubernetes Secret that contains the GitHub token.
|
||||
type: string
|
||||
default: github
|
||||
|
||||
- name: GITHUB_TOKEN_SECRET_KEY
|
||||
description: |
|
||||
The key within the Kubernetes Secret that contains the GitHub token.
|
||||
type: string
|
||||
default: token
|
||||
|
||||
- name: COMMENT_TAG
|
||||
description: |
|
||||
An invisible tag to be added into the comment. The tag is made
|
||||
invisible by embedding in an an HTML comment. The tag allows for later
|
||||
retrieval of the comment, and it allows replacing an existing comment.
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
- name: REPLACE
|
||||
description: |
|
||||
When a tag is specified, and `REPLACE` is `true`, look for a comment
|
||||
with a matching tag and replace it with the new comment.
|
||||
type: string
|
||||
default: "false" # Alternative value: "true"
|
||||
|
||||
steps:
|
||||
- name: post-comment
|
||||
workingDir: $(workspaces.comment-file.path)
|
||||
env:
|
||||
- name: GITHUBTOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: $(params.GITHUB_TOKEN_SECRET_NAME)
|
||||
key: $(params.GITHUB_TOKEN_SECRET_KEY)
|
||||
|
||||
image: registry.access.redhat.com/ubi8/ubi-minimal:8.2
|
||||
script: |
|
||||
#!/usr/libexec/platform-python
|
||||
import json
|
||||
import os
|
||||
import http.client
|
||||
import sys
|
||||
import urllib.parse
|
||||
|
||||
split_url = urllib.parse.urlparse(
|
||||
"$(params.REQUEST_URL)").path.split("/")
|
||||
|
||||
# This will convert https://github.com/foo/bar/pull/202 to
|
||||
# api url path /repos/foo/issues/
|
||||
api_url = "{base}/repos/{package}/issues/{id}".format(
|
||||
base="", package="/".join(split_url[1:3]), id=split_url[-1])
|
||||
|
||||
commentParamValue = "$(params.COMMENT_OR_FILE)"
|
||||
|
||||
# check if workspace is bound and parameter passed is a filename or not
|
||||
if "$(workspaces.comment-file.bound)" == "true" and os.path.exists(commentParamValue):
|
||||
commentParamValue = open(commentParamValue, "r").read()
|
||||
|
||||
# If a tag was specified, append it to the comment
|
||||
if "$(params.COMMENT_TAG)":
|
||||
commentParamValue += "<!-- {tag} -->".format(tag="$(params.COMMENT_TAG)")
|
||||
|
||||
data = {
|
||||
"body": commentParamValue,
|
||||
}
|
||||
|
||||
# This is for our fake github server
|
||||
if "$(params.GITHUB_HOST_URL)".startswith("http://"):
|
||||
conn = http.client.HTTPConnection("$(params.GITHUB_HOST_URL)".replace("http://", ""))
|
||||
else:
|
||||
conn = http.client.HTTPSConnection("$(params.GITHUB_HOST_URL)")
|
||||
|
||||
# If REPLACE is true, we need to search for comments first
|
||||
matching_comment = ""
|
||||
if "$(params.REPLACE)" == "true":
|
||||
if not "$(params.COMMENT_TAG)":
|
||||
print("REPLACE requested but no COMMENT_TAG specified")
|
||||
sys.exit(1)
|
||||
r = conn.request(
|
||||
"GET",
|
||||
api_url + "/comments",
|
||||
headers={
|
||||
"User-Agent": "TektonCD, the peaceful cat",
|
||||
"Authorization": "Bearer " + os.environ["GITHUBTOKEN"],
|
||||
})
|
||||
|
||||
resp = conn.getresponse()
|
||||
if not str(resp.status).startswith("2"):
|
||||
print("Error: %d" % (resp.status))
|
||||
print(resp.read())
|
||||
sys.exit(1)
|
||||
print(resp.status)
|
||||
|
||||
comments = json.loads(resp.read())
|
||||
print(comments)
|
||||
# If more than one comment is found take the last one
|
||||
matching_comment = [x for x in comments if '$(params.COMMENT_TAG)' in x['body']][-1:]
|
||||
if matching_comment:
|
||||
with open("$(results.OLD_COMMENT.path)", "w") as result_old:
|
||||
result_old.write(str(matching_comment[0]))
|
||||
matching_comment = matching_comment[0]['url']
|
||||
|
||||
if matching_comment:
|
||||
method = "PATCH"
|
||||
target_url = urllib.parse.urlparse(matching_comment).path
|
||||
else:
|
||||
method = "POST"
|
||||
target_url = api_url + "/comments"
|
||||
|
||||
print("Sending this data to GitHub with {}: ".format(method))
|
||||
print(data)
|
||||
r = conn.request(
|
||||
method,
|
||||
target_url,
|
||||
body=json.dumps(data),
|
||||
headers={
|
||||
"User-Agent": "TektonCD, the peaceful cat",
|
||||
"Authorization": "Bearer " + os.environ["GITHUBTOKEN"],
|
||||
})
|
||||
resp = conn.getresponse()
|
||||
if not str(resp.status).startswith("2"):
|
||||
print("Error: %d" % (resp.status))
|
||||
print(resp.read())
|
||||
else:
|
||||
with open("$(results.NEW_COMMENT.path)", "wb") as result_new:
|
||||
result_new.write(resp.read())
|
||||
print("a GitHub comment has been {} to $(params.REQUEST_URL)".format(
|
||||
"updated" if matching_comment else "added"))
|
8
task/github-add-comment/0.4/tests/fixtures/github-post-comment.yaml
vendored
Normal file
8
task/github-add-comment/0.4/tests/fixtures/github-post-comment.yaml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
headers:
|
||||
method: POST
|
||||
path: /repos/{repo:[^/]+/[^/]+}/issues/{issue:[0-9]+}/comments
|
||||
response:
|
||||
status: 200
|
||||
output: '{"status": 200}'
|
||||
content-type: text/json
|
3
task/github-add-comment/0.4/tests/pre-apply-task-hook.sh
Executable file
3
task/github-add-comment/0.4/tests/pre-apply-task-hook.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
kubectl -n ${tns} create secret generic github --from-literal token="secret"
|
31
task/github-add-comment/0.4/tests/run.yaml
Normal file
31
task/github-add-comment/0.4/tests/run.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Pipeline
|
||||
metadata:
|
||||
name: github-add-comment-test
|
||||
spec:
|
||||
workspaces:
|
||||
- name: comment-file
|
||||
optional: true
|
||||
tasks:
|
||||
- name: add-comment
|
||||
taskRef:
|
||||
name: github-add-comment
|
||||
workspaces:
|
||||
- name: comment-file
|
||||
workspace: comment-file
|
||||
params:
|
||||
- name: GITHUB_HOST_URL
|
||||
value: http://127.0.0.1:8080
|
||||
- name: COMMENT_OR_FILE
|
||||
value: "Hello from TektonCD test"
|
||||
- name: REQUEST_URL
|
||||
value: https://github.com/tektoncd/catalog/issues/1
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: PipelineRun
|
||||
metadata:
|
||||
name: github-add-comment-test-run
|
||||
spec:
|
||||
pipelineRef:
|
||||
name: github-add-comment-test
|
Loading…
Reference in New Issue
Block a user