From eb8beb71b9db00f5bb7aab172bebf23067b0d662 Mon Sep 17 00:00:00 2001 From: Maurizio Carboni Date: Tue, 30 Jul 2019 22:01:38 +0200 Subject: [PATCH 1/4] [FEATURE]Support adding comments to MRs --- README.md | 7 +++++++ scripts/out | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a24e01c..18422e8 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ Updates the merge request's `merge_status` which displays nicely in the GitLab U * `repository`: The path of the repository of the merge request's source branch (required) * `status`: The new status of the merge request (required, can be either `pending`, `running`, `success`, `failed`, or `canceled`) * `build_label`: The label of the build in GitLab (optional, defaults to `"Concourse"`) +* `comment`: Add a comment to the MRs open on the branch that is being target by concourse. Could be an object with `text/file` fields. +If just the `file` or `text` is specified it is used to populate the field, if both file and text are specified then the file is substituted in to replace `$FILE_CONTENT` in the text. ## Example @@ -88,4 +90,9 @@ jobs: params: repository: repo status: success + comment: + file: out/commt.txt + text: | + Add new comment. + $FILE_CONTENT ``` diff --git a/scripts/out b/scripts/out index 227ec5f..f34c927 100755 --- a/scripts/out +++ b/scripts/out @@ -12,7 +12,7 @@ source "$(dirname "$0")/common.sh" destination="$1" -if [ -z "${destination}" ]; then +if [[ -z "${destination}" ]]; then echo "Usage: $0 " >&2 exit 1 fi @@ -31,12 +31,15 @@ params="$(jq -r '.params // ""' < "${payload}")" path_to_repo="$(echo "${params}" | jq -r '.repository // ""')" new_status="$(echo "${params}" | jq -r '.status // ""')" build_label="$(echo "${params}" | jq -r '.build_label // "Concourse"')" +comment_text="$(echo "${params}" | jq -r '.comment.text // ""')" +comment_file="$(echo "${params}" | jq -r '.comment.file // ""')" +comment="" -if [ -z "${path_to_repo}" ]; then +if [[ -z "${path_to_repo}" ]]; then echo "please specify a repository" >&2 exit 1 fi -if [ -z "${new_status}" ]; then +if [[ -z "${new_status}" ]]; then echo "please specify a status" >&2 exit 1 fi @@ -54,13 +57,24 @@ else project_path="$(echo "${uri}" | sed -rn 's/(https?):\/\/([^\/]*)\/(.*)\.git/\3/p')" protocol="$(echo "${uri}" | sed -rn 's/(https?):\/\/([^\/]*)\/(.*)\.git/\1/p')" fi -if [ "${no_ssl}" == 'true' ]; then +if [[ "${no_ssl}" == 'true' ]]; then protocol='http' fi target_url="${ATC_EXTERNAL_URL}/teams/$(urlencode "${BUILD_TEAM_NAME}")/pipelines/$(urlencode "${BUILD_PIPELINE_NAME}")/jobs/$(urlencode "${BUILD_JOB_NAME}")/builds/$(urlencode "${BUILD_NAME}")" cd "${destination}" + +if [[ (! -z "${comment_text}") ]]; then + if [[ -z "${comment_file}" ]]; then + comment=${comment_text} + else + comment=$(echo "${comment_text}" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' | sed "s/\$FILE_CONTENT/$(sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' -e 's/[\/&]/\\&/g' "${comment_file}")/g") + fi +elif [[ (! -z "${comment_file}") ]]; then + comment=$(cat "${comment_file}") +fi + cd "${path_to_repo}" commit_sha="$(git rev-parse HEAD)" @@ -72,6 +86,22 @@ curl \ --data "{\"state\":\"${new_status}\",\"name\":\"${build_label}\",\"target_url\":\"${target_url}\"}" \ "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode "${project_path}")/statuses/${commit_sha}" +if [[ (! -z "${private_key}") && (! -z "${comment}") ]]; then + git_branch=$(git show-ref --heads | sed -n "s/^$(git rev-parse HEAD) refs\/heads\/\(.*\)/\1/p") + merge_requests=$(curl \ + --request GET \ + --header "PRIVATE-TOKEN: ${private_token}" \ + "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode ${project_path})/merge_requests?source_branch=${git_branch}") + + for merge_request_id in $(echo "${merge_requests}" | jq -r '.[].iid'); do + # Post comment to each merge request + curl \ + --request POST \ + --header "PRIVATE-TOKEN: ${private_token}" \ + "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode ${project_path})/merge_requests/$(urlencode ${merge_request_id})/notes?body=$(urlencode "${comment}")" + done +fi + version="{\"sha\":\"${commit_sha}\"}" jq -n "{ From 9c80a0eb44aa1846a85396fd93f6001b69b0d70c Mon Sep 17 00:00:00 2001 From: Maurizio Carboni Date: Wed, 31 Jul 2019 10:54:54 +0200 Subject: [PATCH 2/4] [FEATURE]Add support for multiple files --- Dockerfile | 4 +++- README.md | 17 ++++++++++++----- scripts/in | 2 +- scripts/out | 35 +++++++++++++++++++++++++---------- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Dockerfile b/Dockerfile index fd53295..3bb0e96 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,6 @@ -FROM concourse/buildroot:git +FROM alpine/git + +RUN apk add --no-cache curl curl-dev bash jq COPY scripts/ /opt/resource/ RUN chmod +x /opt/resource/* diff --git a/README.md b/README.md index 18422e8..b79eb6e 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,10 @@ Updates the merge request's `merge_status` which displays nicely in the GitLab U * `repository`: The path of the repository of the merge request's source branch (required) * `status`: The new status of the merge request (required, can be either `pending`, `running`, `success`, `failed`, or `canceled`) * `build_label`: The label of the build in GitLab (optional, defaults to `"Concourse"`) -* `comment`: Add a comment to the MRs open on the branch that is being target by concourse. Could be an object with `text/file` fields. -If just the `file` or `text` is specified it is used to populate the field, if both file and text are specified then the file is substituted in to replace `$FILE_CONTENT` in the text. +* `comment`: Add a comment to the MRs open on the branch that is being target by concourse. Could be an object with `text/file(s)` fields. +If just the `file(s)` or `text` is specified it is used to populate the field, if both file and text are specified then the file(s) is substituted in to the text comment. +If only one file is specified (field `file`) then it replace `$FILE_CONTENT` in the text. +If multiple files are specified (field `files`) then it replace a variable with the key of the file (look the example for a better clarification) ## Example @@ -91,8 +93,13 @@ jobs: repository: repo status: success comment: - file: out/commt.txt + files: + original: in/comment.txt + updated: out/comment.txt text: | - Add new comment. - $FILE_CONTENT + Original comment: + $original + + new comment: + $updated ``` diff --git a/scripts/in b/scripts/in index 8fe0fd6..4744f06 100755 --- a/scripts/in +++ b/scripts/in @@ -12,7 +12,7 @@ source "$(dirname "$0")/common.sh" destination="$1" -if [ -z "${destination}" ]; then +if [[ -z "${destination}" ]]; then echo "Usage: $0 " >&2 exit 1 fi diff --git a/scripts/out b/scripts/out index f34c927..d06dfac 100755 --- a/scripts/out +++ b/scripts/out @@ -27,12 +27,12 @@ uri="$(jq -r '.source.uri // ""' < "${payload}")" private_token="$(jq -r '.source.private_token // ""' < "${payload}")" private_key="$(jq -r '.source.private_key // ""' < "${payload}")" no_ssl="$(jq -r '.source.no_ssl // ""' < "${payload}")" -params="$(jq -r '.params // ""' < "${payload}")" -path_to_repo="$(echo "${params}" | jq -r '.repository // ""')" -new_status="$(echo "${params}" | jq -r '.status // ""')" -build_label="$(echo "${params}" | jq -r '.build_label // "Concourse"')" -comment_text="$(echo "${params}" | jq -r '.comment.text // ""')" -comment_file="$(echo "${params}" | jq -r '.comment.file // ""')" +path_to_repo="$(jq -c -r '.params.repository // ""' < "${payload}")" +new_status="$(jq -c -r '.params.status // ""' < "${payload}")" +build_label="$(jq -c -r '.params.build_label // "Concourse"' < "${payload}")" +comment_text="$(jq -c -r '.params.comment.text // ""' < "${payload}")" +comment_file="$(jq -c -r '.params.comment.file // ""' < "${payload}")" +comment_files="$(jq -c -r '.params.comment.files // ""' < "${payload}")" comment="" if [[ -z "${path_to_repo}" ]]; then @@ -65,11 +65,26 @@ target_url="${ATC_EXTERNAL_URL}/teams/$(urlencode "${BUILD_TEAM_NAME}")/pipeline cd "${destination}" +if [[ (-z "${comment_files}") && (! -z "${comment_file}") ]]; then + comment_files=$(echo "${comment_file}" | jq -c --raw-input '{ "FILE_CONTENT": . }') +fi + if [[ (! -z "${comment_text}") ]]; then - if [[ -z "${comment_file}" ]]; then - comment=${comment_text} - else - comment=$(echo "${comment_text}" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' | sed "s/\$FILE_CONTENT/$(sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' -e 's/[\/&]/\\&/g' "${comment_file}")/g") + comment=$(echo "${comment_text}" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g') + + if [[ ! -z "${comment_files}" ]]; then + for row in $(echo "${comment_files}" | jq -c -r 'to_entries[] | @base64'); do + _jq() { + echo ${row} | base64 -d | jq -r ${1} + } + + file_key=$(echo "\$$(_jq '.key')" | sed -e 's/[]\/$*.^[]/\\&/g') + file_name=$(_jq '.value') + file_content=$(cat | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' -e 's/[\/&]/\\&/g' "${file_name}") + + comment=$(echo "${comment}" | sed "s/${file_key}/${file_content}/g") + echo ${comment} + done fi elif [[ (! -z "${comment_file}") ]]; then comment=$(cat "${comment_file}") From 168d00e8ec9493b7aff747e317e48420d57f0b26 Mon Sep 17 00:00:00 2001 From: Maurizio Carboni Date: Thu, 1 Aug 2019 13:17:17 +0200 Subject: [PATCH 3/4] [FEATURE]Send note content has POST body to extend the size limit --- scripts/out | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/out b/scripts/out index d06dfac..d4a016f 100755 --- a/scripts/out +++ b/scripts/out @@ -106,14 +106,16 @@ if [[ (! -z "${private_key}") && (! -z "${comment}") ]]; then merge_requests=$(curl \ --request GET \ --header "PRIVATE-TOKEN: ${private_token}" \ - "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode ${project_path})/merge_requests?source_branch=${git_branch}") + "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode "${project_path}")/merge_requests?source_branch=${git_branch}") for merge_request_id in $(echo "${merge_requests}" | jq -r '.[].iid'); do # Post comment to each merge request curl \ --request POST \ + --data "$(echo "${comment}" | jq -c -R '{ "body": . }')" \ + --header "Content-Type: application/json" \ --header "PRIVATE-TOKEN: ${private_token}" \ - "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode ${project_path})/merge_requests/$(urlencode ${merge_request_id})/notes?body=$(urlencode "${comment}")" + "${protocol}://${gitlab_host}/api/v4/projects/$(urlencode "${project_path}")/merge_requests/$(urlencode "${merge_request_id}")/notes" done fi From 21a4b634addc4dc5ee5e7e71464b129ee9f45469 Mon Sep 17 00:00:00 2001 From: Maurizio Carboni Date: Thu, 1 Aug 2019 15:40:36 +0200 Subject: [PATCH 4/4] [FEATURE]If file doesn\'t exists, don\'t replace the value with it's contents --- scripts/out | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/out b/scripts/out index d4a016f..2e74f1c 100755 --- a/scripts/out +++ b/scripts/out @@ -80,10 +80,10 @@ if [[ (! -z "${comment_text}") ]]; then file_key=$(echo "\$$(_jq '.key')" | sed -e 's/[]\/$*.^[]/\\&/g') file_name=$(_jq '.value') - file_content=$(cat | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' -e 's/[\/&]/\\&/g' "${file_name}") - - comment=$(echo "${comment}" | sed "s/${file_key}/${file_content}/g") - echo ${comment} + if [ -f "${file_name}" ]; then + file_content=$(cat | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' -e 's/[\/&]/\\&/g' "${file_name}") + comment=$(echo "${comment}" | sed "s/${file_key}/${file_content}/g") + fi done fi elif [[ (! -z "${comment_file}") ]]; then