-
Notifications
You must be signed in to change notification settings - Fork 580
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix API prefix path in github-add-comment task
The parameter API_PATH_PREFIX has not been used in the script. Because of that the task did not work for GitHub Enterprise Server.
- Loading branch information
1 parent
edca078
commit c4bd640
Showing
7 changed files
with
589 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# 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. | ||
|
||
## Install the Task | ||
|
||
``` | ||
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/github-add-comment/0.7/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. | ||
|
||
## Platforms | ||
|
||
The Task can be run on `linux/amd64`, `linux/s390x` and `linux/ppc64le` platforms. | ||
|
||
## 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
--- | ||
apiVersion: tekton.dev/v1beta1 | ||
kind: Task | ||
metadata: | ||
name: github-add-comment | ||
labels: | ||
app.kubernetes.io/version: "0.7" | ||
annotations: | ||
tekton.dev/categories: Git | ||
tekton.dev/pipelines.minVersion: "0.17.0" | ||
tekton.dev/tags: github | ||
tekton.dev/displayName: "add github comment" | ||
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le" | ||
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: AUTH_TYPE | ||
description: | | ||
The type of authentication to use. You could use the less secure "Basic" for example | ||
type: string | ||
default: Bearer | ||
|
||
- 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 | ||
authHeader = "$(params.AUTH_TYPE) " + os.environ["GITHUBTOKEN"] | ||
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="$(params.API_PATH_PREFIX)", 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": authHeader, | ||
}) | ||
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": authHeader, | ||
}) | ||
resp = conn.getresponse() | ||
if not str(resp.status).startswith("2"): | ||
print("Error: %d" % (resp.status)) | ||
print(resp.read()) | ||
sys.exit(1) | ||
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")) |
35 changes: 35 additions & 0 deletions
35
task/github-add-comment/0.7/tests/fixtures/github-post-comment.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Default GitHub | ||
--- | ||
headers: | ||
method: PATCH | ||
path: /repos/{repo:[^/]+/[^/]+}/issues/comments/{comment:[0-9]+} | ||
response: | ||
status: 200 | ||
output: '{"status": 200}' | ||
content-type: text/json | ||
--- | ||
headers: | ||
method: GET | ||
path: /repos/{repo:[^/]+/[^/]+}/issues/{issue:[0-9]+}/comments | ||
response: | ||
status: 200 | ||
content-type: text/json | ||
file: /fixtures/list-comment-response.json | ||
|
||
# GitHub Enterprise Server | ||
--- | ||
headers: | ||
method: PATCH | ||
path: /api/v3/repos/{repo:[^/]+/[^/]+}/issues/comments/{comment:[0-9]+} | ||
response: | ||
status: 200 | ||
output: '{"status": 200}' | ||
content-type: text/json | ||
--- | ||
headers: | ||
method: GET | ||
path: /api/v3/repos/{repo:[^/]+/[^/]+}/issues/{issue:[0-9]+}/comments | ||
response: | ||
status: 200 | ||
content-type: text/json | ||
file: /fixtures/list-comment-response-ghe.json |
Oops, something went wrong.