From 62c9f13f20d0df01fbb9fd38a1e940f27b58d6e8 Mon Sep 17 00:00:00 2001 From: Matthew Boedicker Date: Mon, 19 Mar 2018 20:35:23 -0700 Subject: [PATCH 01/23] Add fork explanation to README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c9518d..5c36bc1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -> This resource is no longer actively maintained. +This resource is a fork of +https://github.com/laurentverbruggen/concourse-bitbucket-pullrequest-resource. + +That resource is no longer maintained but this one will continue to be +developed. # Concourse Bitbucket Pull Request Resource From e148fc83a5d22e84a3494591e10fd3044af8dee6 Mon Sep 17 00:00:00 2001 From: Matthew Boedicker Date: Mon, 19 Mar 2018 21:46:44 -0700 Subject: [PATCH 02/23] Add create_comments option to source to disable creating comments --- README.md | 2 ++ assets/out | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5c36bc1..4dc1532 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ It will accept a regular expression as determined by [egrep](http://linuxcommand * `rebuild_phrase`: *Optional (default: test this please).* Regular expression as determined by [egrep](http://linuxcommand.org/man_pages/egrep1.html) will match all comments in pull request overview. If a match is found the pull request will be rebuilt. +* `create_comments`: *Optional (default: false).* If true write comments with build status to pull requests. + ## Behavior ### `check`: Search for pull requests to build. diff --git a/assets/out b/assets/out index 864ce29..88e4558 100755 --- a/assets/out +++ b/assets/out @@ -38,6 +38,7 @@ uri=$(jq -r '.source.uri // ""' < "$payload") git_config_payload=$(jq -r '.source.git_config // []' < "$payload") rebuild_when_target_changed=$(jq -r '.source.rebuild_when_target_changed // "false"' < "$payload") rebuild_phrase=$(jq -r '.source.rebuild_phrase // "test this please"' < "$payload") +create_comments=$(jq -r '.source.create_comments // "false"' < "$payload") path=$(jq -r '.params.path // ""' < "$payload") status=$(jq -r '.params.status // ""' < "$payload") @@ -156,7 +157,7 @@ if [ -n "$comments" ]; then # check for progress messages => if pull request number matches then edit comment (instead of creating a new one) if [ -z "$commented" ]; then - if bitbucket_pullrequest_progress_commit_match "$text" "$prq_hash" "Started"; then + if bitbucket_pullrequest_progress_commit_match "$text" "$prq_hash" "Started" && [ "$create_comments" == "true" ]; then bitbucket_pullrequest_update_comment_status "$repo_host" "$repo_project" "$repo_name" "$prq_number" "$comment_message" "$id" "$version" "" "$skip_ssl_verification" >/dev/null commented=true fi @@ -176,7 +177,7 @@ if [ -n "$comments" ]; then done <<< "$comments" fi -if [ -z "$commented" ]; then +if [ -z "$commented" ] && [ "$create_comments" == "true" ]; then bitbucket_pullrequest_add_comment_status "$repo_host" "$repo_project" "$repo_name" "$prq_number" "$comment_message" "" "$skip_ssl_verification" >/dev/null fi From 27bfda7d6053ab332d4efa875ce134cfae9c671c Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Sat, 24 Mar 2018 17:58:17 -0700 Subject: [PATCH 03/23] Use pull request updatedDate for version check emits all pull requests that have been updated since the last version. This should simplify things and handle forces pushes to pull requests that are not the latest. Fixes #1. --- assets/check | 23 +++++++++++++++++------ assets/out | 24 +++++------------------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/assets/check b/assets/check index f691df3..19940e6 100755 --- a/assets/check +++ b/assets/check @@ -39,6 +39,7 @@ only_when_mergeable=$(jq -r '.source.only_when_mergeable // "false"' < "$payload only_when_asked=$(jq -r '.source.only_when_asked // "false"' < "$payload") rebuild_when_target_changed=$(jq -r '.source.rebuild_when_target_changed // "false"' < "$payload") rebuild_phrase=$(jq -r '.source.rebuild_phrase // "test this please"' < "$payload") +CURRENT_VERSION_DATE=$(jq -r '.version.date // "0"' < "$payload") configure_git_ssl_verification "$skip_ssl_verification" configure_git_global "${git_config_payload}" @@ -84,6 +85,8 @@ if [ -n "$pull_requests" ]; then continue fi + PULL_REQUEST_DATE=$(echo "$prq" | jq -r '.updatedDate') + log "Pull request #${prq_number}" prq_to_branch=$(echo "$prq" | jq -r '.toRef.displayId') @@ -102,7 +105,6 @@ if [ -n "$pull_requests" ]; then fi # edit timestamp to version to force new build when rebuild_phrase is included in comments - prq_verify_date=$(echo "$prq" | jq -r '.createdDate') skip_build=false comments=$(bitbucket_pullrequest_overview_comments "$repo_host" "$repo_project" "$repo_name" "$prq_number" "" "$skip_ssl_verification" | jq -c '.[]') if [ -n "$comments" ]; then @@ -118,20 +120,29 @@ if [ -n "$pull_requests" ]; then # edit timestamp to force new build when rebuild_phrase is included in comments if echo "$text" | grep -Ec "$rebuild_phrase" > /dev/null; then - prq_verify_date=$(echo "$comment" | jq -r '.createdDate') + PULL_REQUEST_DATE=$(echo "$comment" | jq -r '.createdDate') break fi done <<< "$comments" fi + if [ "$PULL_REQUEST_DATE" -lt "$CURRENT_VERSION_DATE" ]; then + continue + fi + # add prq to versions if [ "$skip_build" == "false" ]; then - pretty_date=$(date_from_epoch_seconds "$(( ($prq_verify_date + 500) / 1000))") - versions+=" + [{ id: \"$prq_number\", hash: \"$prq_hash\", date: \"$pretty_date\", change: $prq_verify_date }]" + versions+=" + [{ id: \"$prq_number\", hash: \"$prq_hash\", date: \"$PULL_REQUEST_DATE\" }]" fi - fi done <<< "$pull_requests" fi -jq -n "$versions | sort_by(.change) | map(del(.change))" >&3 +# On the first request return only the current version. +if [ "$CURRENT_VERSION_DATE" -eq "0" ]; then + jq -n "$versions | sort_by((.date | tonumber), (.id | tonumber), .hash) | .[-1]" > /tmp/check_result +else + jq -n "$versions | sort_by((.date | tonumber), (.id | tonumber), .hash)" > /tmp/check_result +fi + +cat /tmp/check_result >&3 diff --git a/assets/out b/assets/out index 88e4558..d6f6fd1 100755 --- a/assets/out +++ b/assets/out @@ -142,13 +142,12 @@ data=$(jq -cn "{ bitbucket_pullrequest_commit_status "$repo_host" "$source_commit" "$data" "" "" "$skip_ssl_verification" # use the pullrequest date stored in git config in get -prq_verify_date=$(git config --get pullrequest.date | cat) +PULL_REQUEST_DATE=$(git config --get pullrequest.date | cat) # add comment to pull request to track if build was started/finished comment_message=$(bitbucket_pullrequest_progress_comment "$status" "$prq_hash" "$source_commit" "$target_commit") comments=$(bitbucket_pullrequest_overview_comments "$repo_host" "$repo_project" "$repo_name" "$prq_number" "" "$skip_ssl_verification" | jq -c '.[]') commented="" -skip_verify=false if [ -n "$comments" ]; then while read -r comment; do id=$(echo "$comment" | jq -r '.id') @@ -156,22 +155,9 @@ if [ -n "$comments" ]; then version=$(echo "$comment" | jq -r '.version') # check for progress messages => if pull request number matches then edit comment (instead of creating a new one) - if [ -z "$commented" ]; then - if bitbucket_pullrequest_progress_commit_match "$text" "$prq_hash" "Started" && [ "$create_comments" == "true" ]; then - bitbucket_pullrequest_update_comment_status "$repo_host" "$repo_project" "$repo_name" "$prq_number" "$comment_message" "$id" "$version" "" "$skip_ssl_verification" >/dev/null - commented=true - fi - fi - - # edit timestamp to force new build when rebuild_phrase is included in comments - if [ "$skip_verify" != "true" ]; then - if echo "$text" | grep -Ec "$rebuild_phrase" > /dev/null; then - prq_verify_date=$(date_from_epoch_seconds $(( ($(echo "$comment" | jq -r '.createdDate') + 500) / 1000))) - skip_verify=true - fi - fi - - if [ "$skip_verify" == "true" -a "$commented" == "true" ]; then + if bitbucket_pullrequest_progress_commit_match "$text" "$prq_hash" "Started" && [ "$create_comments" == "true" ]; then + bitbucket_pullrequest_update_comment_status "$repo_host" "$repo_project" "$repo_name" "$prq_number" "$comment_message" "$id" "$version" "" "$skip_ssl_verification" >/dev/null + commented=true break fi done <<< "$comments" @@ -185,7 +171,7 @@ jq -n "{ version: { id: \"$prq_number\", hash: \"$prq_hash\", - date: \"$prq_verify_date\" + date: \"$PULL_REQUEST_DATE\" }, metadata: $(pullrequest_metadata "$prq_number" "$uri" "$skip_ssl_verification") }" >&3 From b44b8a66727e2d0764bd69f29af4a477e4ec0805 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Wed, 28 Mar 2018 16:37:55 -0700 Subject: [PATCH 04/23] When there are no versions return empty list instead of null version: null breaks Concourse. --- assets/check | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/check b/assets/check index 19940e6..4c2c858 100755 --- a/assets/check +++ b/assets/check @@ -140,7 +140,7 @@ fi # On the first request return only the current version. if [ "$CURRENT_VERSION_DATE" -eq "0" ]; then - jq -n "$versions | sort_by((.date | tonumber), (.id | tonumber), .hash) | .[-1]" > /tmp/check_result + jq -n "$versions | sort_by((.date | tonumber), (.id | tonumber), .hash) | .[-1:]" > /tmp/check_result else jq -n "$versions | sort_by((.date | tonumber), (.id | tonumber), .hash)" > /tmp/check_result fi From c38e8a0038d27c0dbb69c33bfc10620bfd4a1971 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 30 Mar 2018 22:47:08 -0700 Subject: [PATCH 05/23] Fix Concourse docs links --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4dc1532..52d226e 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ resource_types: repository: laurentverbruggen/concourse-bitbucket-pullrequest-resource ``` -See [concourse docs](http://concourse.ci/configuring-resource-types.html) for more details on adding `resource_types` to a pipeline config. +See [concourse docs](https://concourse-ci.org/resource-types.html) for more details on adding `resource_types` to a pipeline config. ## Source Configuration @@ -85,7 +85,7 @@ Check will return a version for every pull request that matches the criteria def Clones the repository to the destination, and locks it down to a given ref. ** IMPORTANT ** -It is essential that you set the [version](https://concourse.ci/get-step.html#get-version) to `every` on the get step of your job configuration. +It is essential that you set the [version](https://concourse-ci.org/get-step.html#get-step-version) to `every` on the get step of your job configuration. It will allow you to build all versions instead of only the latest. Submodules are initialized and updated recursively. @@ -113,7 +113,7 @@ Set the status message on specified pull request. * `status`: *Required.* The status of success, failure or pending. - * [`on_success`](https://concourse.ci/on-success-step.html) and [`on_failure`](https://concourse.ci/on-failure-step.html) triggers may be useful for you when you wanted to reflect build result to the pull request (see the example below). + * [`on_success`](https://concourse-ci.org/on-success-step-hook.html) and [`on_failure`](https://concourse-ci.org/on-failure-step-hook.html) triggers may be useful for you when you wanted to reflect build result to the pull request (see the example below). ## Example pipeline From d75905a2263317be5226e9a8699744b674e7b2d2 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 30 Mar 2018 22:55:03 -0700 Subject: [PATCH 06/23] Fix resource repository and example uri --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 52d226e..74a187e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ resource_types: - name: concourse-bitbucket-pullrequest type: docker-image source: - repository: laurentverbruggen/concourse-bitbucket-pullrequest-resource + repository: mm62/concourse-bitbucket-pullrequest-resource ``` See [concourse docs](https://concourse-ci.org/resource-types.html) for more details on adding `resource_types` to a pipeline config. @@ -122,7 +122,7 @@ resource_types: - name: concourse-bitbucket-pullrequest type: docker-image source: - repository: laurentverbruggen/concourse-bitbucket-pullrequest-resource + repository: mm62/concourse-bitbucket-pullrequest-resource resources: - name: pullrequest @@ -130,7 +130,7 @@ resources: source: username: {{bitbucket-username}} password: {{bitbucket-password}} - uri: laurentverbruggen/concourse-bitbucket-pullrequest-resource + uri: https://your-bitbucket.com/project/repo jobs: - name: test pull request From 3d8dbd9ef34cab4cee4997ee5e46e04f6c257ad7 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 30 Mar 2018 22:56:39 -0700 Subject: [PATCH 07/23] README yaml formatting --- README.md | 84 +++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 74a187e..6ba9f34 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ Use this resource by adding the following to the `resource_types` section of a p ```yaml --- resource_types: -- name: concourse-bitbucket-pullrequest - type: docker-image - source: - repository: mm62/concourse-bitbucket-pullrequest-resource + - name: concourse-bitbucket-pullrequest + type: docker-image + source: + repository: mm62/concourse-bitbucket-pullrequest-resource ``` See [concourse docs](https://concourse-ci.org/resource-types.html) for more details on adding `resource_types` to a pipeline config. @@ -119,46 +119,46 @@ Set the status message on specified pull request. ```yaml resource_types: -- name: concourse-bitbucket-pullrequest - type: docker-image - source: - repository: mm62/concourse-bitbucket-pullrequest-resource + - name: concourse-bitbucket-pullrequest + type: docker-image + source: + repository: mm62/concourse-bitbucket-pullrequest-resource resources: -- name: pullrequest - type: concourse-bitbucket-pullrequest - source: - username: {{bitbucket-username}} - password: {{bitbucket-password}} - uri: https://your-bitbucket.com/project/repo + - name: pullrequest + type: concourse-bitbucket-pullrequest + source: + username: {{bitbucket-username}} + password: {{bitbucket-password}} + uri: https://your-bitbucket.com/project/repo jobs: -- name: test pull request - plan: - - get: pullrequest - trigger: true - version: every - - put: pullrequest - params: - path: pullrequest - status: pending - - task: test - config: - platform: linux - - inputs: - - name: pullrequest - - ... - - on_success: - put: pullrequest - params: - path: pullrequest - status: success - on_failure: - put: pullrequest - params: - path: pullrequest - status: failure + - name: test pull request + plan: + - get: pullrequest + trigger: true + version: every + - put: pullrequest + params: + path: pullrequest + status: pending + - task: test + config: + platform: linux + + inputs: + - name: pullrequest + + ... + + on_success: + put: pullrequest + params: + path: pullrequest + status: success + on_failure: + put: pullrequest + params: + path: pullrequest + status: failure ``` From fd1fe2355b702c989f86978ed3817bf3184af13a Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 30 Mar 2018 23:20:19 -0700 Subject: [PATCH 08/23] Add test script and travis build --- .travis.yml | 6 ++++++ scripts/test | 37 +++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 20 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f63ba9e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +sudo: required + +services: + - docker + +script: scripts/test diff --git a/scripts/test b/scripts/test index 85cec78..0d75847 100755 --- a/scripts/test +++ b/scripts/test @@ -1,24 +1,21 @@ #!/bin/bash -set -e - -not_installed() { - ! command -v $1 > /dev/null 2>&1 -} +set -eu -bitbucket_pullrequest_dir=$(cd $(dirname $0)/.. && pwd) - -if not_installed docker; then - echo "# docker is not installed! run the following commands:" - echo " brew install docker" - echo " brew cask install docker-machine" - echo " docker-machine create dev --driver virtualbox" - echo ' eval $(docker-machine env dev)' - echo " docker login" - exit 1 -fi +set +e +docker run --interactive --rm hadolint/hadolint < Dockerfile +docker run --interactive --rm --volume "$PWD:/mnt" koalaman/shellcheck \ + --color=always \ + /mnt/assets/check \ + /mnt/assets/helpers/askpass.sh \ + /mnt/assets/helpers/bitbucket.sh \ + /mnt/assets/helpers/git.sh \ + /mnt/assets/helpers/utils.sh \ + /mnt/assets/in \ + /mnt/assets/out \ + /mnt/install_git_lfs.sh \ + /mnt/scripts/test +set -e -name=laurentverbruggen/concourse-bitbucket-pullrequest-resource -cd $bitbucket_pullrequest_dir -docker build --rm . -t $name -docker push $name +docker build --rm --tag mm62/concourse-bitbucket-pullrequest-resource-test . +docker rmi mm62/concourse-bitbucket-pullrequest-resource-test From 64c2f51914ee04f0d94f54c68dd23661bb51b7d3 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 30 Mar 2018 23:27:35 -0700 Subject: [PATCH 09/23] Add Travis badge to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6ba9f34..d54e2ab 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/mmb/concourse-bitbucket-pullrequest-resource.svg?branch=master)](https://travis-ci.org/mmb/concourse-bitbucket-pullrequest-resource) + This resource is a fork of https://github.com/laurentverbruggen/concourse-bitbucket-pullrequest-resource. From bb0435ddf8db19cb046b16d760edb1f4b55b355a Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Wed, 4 Apr 2018 21:55:35 -0700 Subject: [PATCH 10/23] Update Dockerfile with hadolint recommendations --- Dockerfile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index a0e34ce..bef09d9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,18 @@ FROM gliderlabs/alpine:edge -RUN apk --update add \ - ca-certificates \ - bash \ - jq \ - curl \ - git \ - openssh-client +RUN apk --no-cache add \ + bash=4.4.19-r1 \ + ca-certificates=20171114-r0 \ + curl=7.59.0-r0 \ + git=2.16.3-r0 \ + jq=1.5-r5 \ + openssh-client=7.6_p1-r1 # can't `git pull` unless we set these RUN git config --global user.email "git@localhost" && \ git config --global user.name "git" -ADD scripts/install_git_lfs.sh install_git_lfs.sh +COPY scripts/install_git_lfs.sh install_git_lfs.sh RUN ./install_git_lfs.sh -ADD assets/ /opt/resource/ -RUN chmod +x /opt/resource/* +COPY assets /opt/resource From 6d93140ffd2d580e292bb7810476a51e88ae1433 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Wed, 4 Apr 2018 22:08:58 -0700 Subject: [PATCH 11/23] Add hashbangs and shellcheck directives First steps toward making shellcheck pass. --- assets/helpers/git.sh | 2 ++ assets/helpers/utils.sh | 2 ++ assets/out | 3 +++ 3 files changed, 7 insertions(+) diff --git a/assets/helpers/git.sh b/assets/helpers/git.sh index 6e3d661..92213f5 100644 --- a/assets/helpers/git.sh +++ b/assets/helpers/git.sh @@ -1,3 +1,5 @@ +#!/bin/bash + load_pubkey() { local private_key_path=$TMPDIR/git-resource-private-key diff --git a/assets/helpers/utils.sh b/assets/helpers/utils.sh index 3b37d85..ef82608 100755 --- a/assets/helpers/utils.sh +++ b/assets/helpers/utils.sh @@ -1,3 +1,5 @@ +#!/bin/bash + export TMPDIR=${TMPDIR:-/tmp} hash() { diff --git a/assets/out b/assets/out index d6f6fd1..e7c245e 100755 --- a/assets/out +++ b/assets/out @@ -7,8 +7,11 @@ exec 3>&1 # make stdout available as fd 3 for the result exec 1>&2 # redirect all output to stderr for logging ASSETS=$(cd "$(dirname "$0")" && pwd) +# shellcheck source=helpers/git.sh source $ASSETS/helpers/git.sh +# shellcheck source=helpers/utils.sh source $ASSETS/helpers/utils.sh +# shellcheck source=helpers/bitbucket.sh source $ASSETS/helpers/bitbucket.sh # for all temporary files in 'out' From 524462d09df8fe333681347bdf399ff30492ef07 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Thu, 5 Apr 2018 21:17:39 -0700 Subject: [PATCH 12/23] Check should error if git ls-remote uri fails Fixes #2 --- assets/check | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/assets/check b/assets/check index 4c2c858..1ebca29 100755 --- a/assets/check +++ b/assets/check @@ -56,10 +56,13 @@ if [ "$rebuild_when_target_changed" == "true" ]; then fi # collect all pull requests from uri -pull_requests=$(git ls-remote "$uri" | grep -E "/pull\-requests/[0-9]+/${prq_branch}" | cat) +REMOTES=$(git ls-remote "$uri") +set +e +PULL_REQUESTS=$(echo "$REMOTES" | grep -E "/pull\\-requests/[0-9]+/${prq_branch}") +set -e versions="[]" -if [ -n "$pull_requests" ]; then +if [ -n "$PULL_REQUESTS" ]; then log "Calculating repository specifics" # determine repository name for calling REST api repo_name=$(basename "$uri" | sed "s/.git$//") @@ -135,7 +138,7 @@ if [ -n "$pull_requests" ]; then versions+=" + [{ id: \"$prq_number\", hash: \"$prq_hash\", date: \"$PULL_REQUEST_DATE\" }]" fi fi - done <<< "$pull_requests" + done <<< "$PULL_REQUESTS" fi # On the first request return only the current version. From 8ccdfa3463d4638d342bc2a3b7ad90d383ac137d Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Thu, 5 Apr 2018 21:26:29 -0700 Subject: [PATCH 13/23] Bump openssh-client version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index bef09d9..bb4e964 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ RUN apk --no-cache add \ curl=7.59.0-r0 \ git=2.16.3-r0 \ jq=1.5-r5 \ - openssh-client=7.6_p1-r1 + openssh-client=7.7_p1-r0 # can't `git pull` unless we set these RUN git config --global user.email "git@localhost" && \ From 4e4ee828292226dc4f1440b2c76fecc6b7521559 Mon Sep 17 00:00:00 2001 From: Thomas Detoux Date: Tue, 17 Apr 2018 16:31:19 -0400 Subject: [PATCH 14/23] Add the original branch name as a git config value to be used later in the pipeline --- README.md | 2 ++ assets/in | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/README.md b/README.md index d54e2ab..1a1264d 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ It will allow you to build all versions instead of only the latest. Submodules are initialized and updated recursively. +Note: the name of the branch from which the pull request has been created is stored in the special git config `pullrequest.branch` so that you can use it as reference in your pipeline. + #### Parameters * `depth`: *Optional.* If a positive integer is given, *shallow* clone the repository using the `--depth` option. Using this flag voids your warranty. diff --git a/assets/in b/assets/in index 4e21009..1e4968d 100755 --- a/assets/in +++ b/assets/in @@ -132,12 +132,30 @@ if [ -z "$target_commit" ]; then exit 1 fi +# parse uri and retrieve host +uri_parser "$uri" +repo_host="${uri_schema}://${uri_address}" +repo_host=${repo_host}$(getBasePathOfBitbucket) + +# determine repository name for calling REST api +repo_name=$(basename "$uri" | sed "s/.git$//") +repo_project=$(basename $(dirname "$uri")) + +# verify target branch of prq +prq=$(bitbucket_pullrequest "$repo_host" "$repo_project" "$repo_name" "$prq_id" "" "$skip_ssl_verification") + +if [ "$prq" != "ERROR" ]; then + branch=$(echo "$prq" | jq -r '.fromRef.displayId') +fi + + # expose configuration of pull request that can be used in container git config --add pullrequest.id $prq_id git config --add pullrequest.source $source_commit git config --add pullrequest.target $target_commit git config --add pullrequest.merge $ref git config --add pullrequest.date "$prq_date" +git config --add pullrequest.branch "$branch" jq -n "{ version: $(jq '.version' < "$payload"), From 74a1190babf5753eb144c663b3aa3537c54a8c71 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 11 May 2018 23:21:24 -0700 Subject: [PATCH 15/23] Fix error on pull requests that are already merged The refs/pull-requests/nn refs remain for some merged and closed pull requests. They return IllegalPullRequestStateException when the merge is requested. The check for NoSuchPullRequestException was checking the file name and not the contents of the file. Update Dockerfile apk dependencies. --- Dockerfile | 10 +++++----- assets/check | 6 +++++- assets/helpers/bitbucket.sh | 7 +++++-- scripts/test | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index bb4e964..daa3f20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,11 @@ FROM gliderlabs/alpine:edge RUN apk --no-cache add \ bash=4.4.19-r1 \ - ca-certificates=20171114-r0 \ - curl=7.59.0-r0 \ - git=2.16.3-r0 \ - jq=1.5-r5 \ - openssh-client=7.7_p1-r0 + ca-certificates=20171114-r3 \ + curl=7.59.0-r1 \ + git=2.17.0-r0 \ + jq=1.6_rc1-r1 \ + openssh-client=7.7_p1-r2 # can't `git pull` unless we set these RUN git config --global user.email "git@localhost" && \ diff --git a/assets/check b/assets/check index 1ebca29..31285c5 100755 --- a/assets/check +++ b/assets/check @@ -84,7 +84,7 @@ if [ -n "$PULL_REQUESTS" ]; then # verify target branch of prq prq=$(bitbucket_pullrequest "$repo_host" "$repo_project" "$repo_name" "$prq_number" "" "$skip_ssl_verification") - if [ "$prq" = "ERROR" ]; then + if [ "$prq" = "NO_SUCH_PULL_REQUEST" ]; then continue fi @@ -98,6 +98,10 @@ if [ -n "$PULL_REQUESTS" ]; then if [ "$only_when_mergeable" == "true" -o "$only_without_conflicts" == "true" ]; then prq_merge=$(bitbucket_pullrequest_merge "$repo_host" "$repo_project" "$repo_name" "$prq_number" "" "$skip_ssl_verification") + if [ "$prq_merge" = "ALREADY_MERGED" ]; then + continue + fi + # verify if prq has merge conflicts conflicted=$(echo "$prq_merge" | jq -r '.conflicted') if [ "$conflicted" == "true" -a "$only_without_conflicts" == "true" ]; then continue; fi diff --git a/assets/helpers/bitbucket.sh b/assets/helpers/bitbucket.sh index c28ed69..751dd3b 100755 --- a/assets/helpers/bitbucket.sh +++ b/assets/helpers/bitbucket.sh @@ -72,8 +72,11 @@ bitbucket_request() { jq -c '.values' < "$request_result" elif [ "$(jq -c '.errors' < "$request_result")" == "null" ]; then jq '.' < "$request_result" - elif [ "${request_result/NoSuchPullRequestException}" = "${request_result}" ]; then - printf "ERROR" + elif grep -q NoSuchPullRequestException "$request_result"; then + printf "NO_SUCH_PULL_REQUEST" + return + elif grep -q 'This pull request has already been merged' "$request_result"; then + printf "ALREADY_MERGED" return else log "Bitbucket request ($request_url) failed: $(cat $request_result)" diff --git a/scripts/test b/scripts/test index 0d75847..3b0020d 100755 --- a/scripts/test +++ b/scripts/test @@ -17,5 +17,5 @@ docker run --interactive --rm --volume "$PWD:/mnt" koalaman/shellcheck \ /mnt/scripts/test set -e -docker build --rm --tag mm62/concourse-bitbucket-pullrequest-resource-test . +docker build --pull --rm --tag mm62/concourse-bitbucket-pullrequest-resource-test . docker rmi mm62/concourse-bitbucket-pullrequest-resource-test From 7a583196531c6f7786ce5250201818cbf7388c51 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Mon, 14 May 2018 14:42:26 -0700 Subject: [PATCH 16/23] Fix error on pull requests that are declined The refs/pull-requests/nn refs remain for some declined pull requests. They return IllegalPullRequestStateException when the merge is requested. --- assets/check | 2 +- assets/helpers/bitbucket.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/check b/assets/check index 31285c5..b191f97 100755 --- a/assets/check +++ b/assets/check @@ -98,7 +98,7 @@ if [ -n "$PULL_REQUESTS" ]; then if [ "$only_when_mergeable" == "true" -o "$only_without_conflicts" == "true" ]; then prq_merge=$(bitbucket_pullrequest_merge "$repo_host" "$repo_project" "$repo_name" "$prq_number" "" "$skip_ssl_verification") - if [ "$prq_merge" = "ALREADY_MERGED" ]; then + if [ "$prq_merge" = "ALREADY_MERGED" ] || [ "$prq_merge" = "DECLINED" ]; then continue fi diff --git a/assets/helpers/bitbucket.sh b/assets/helpers/bitbucket.sh index 751dd3b..34c2dfa 100755 --- a/assets/helpers/bitbucket.sh +++ b/assets/helpers/bitbucket.sh @@ -78,6 +78,9 @@ bitbucket_request() { elif grep -q 'This pull request has already been merged' "$request_result"; then printf "ALREADY_MERGED" return + elif grep -q 'This pull request has been declined and must be reopened before it can be merged' "$request_result"; then + printf "DECLINED" + return else log "Bitbucket request ($request_url) failed: $(cat $request_result)" exit 1 From 70ef703727523419d42b001180f65dfaf0489929 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 25 May 2018 22:10:32 -0700 Subject: [PATCH 17/23] Switch from gliderlabs/alpine to official alpine for docker base For more stable package versions. --- Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index daa3f20..4a37cc4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ -FROM gliderlabs/alpine:edge +FROM alpine:3.7 RUN apk --no-cache add \ bash=4.4.19-r1 \ - ca-certificates=20171114-r3 \ - curl=7.59.0-r1 \ - git=2.17.0-r0 \ - jq=1.6_rc1-r1 \ - openssh-client=7.7_p1-r2 + ca-certificates=20171114-r0 \ + curl=7.60.0-r1 \ + git=2.15.0-r1 \ + jq=1.5-r5 \ + openssh-client=7.5_p1-r8 # can't `git pull` unless we set these RUN git config --global user.email "git@localhost" && \ From 88d67abf13da5352ae2f35bb421e91bccd0398b4 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Fri, 25 May 2018 22:32:47 -0700 Subject: [PATCH 18/23] Update pullrequest.branch setting with more specific errors --- assets/in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/in b/assets/in index 1e4968d..869e5f5 100755 --- a/assets/in +++ b/assets/in @@ -144,7 +144,9 @@ repo_project=$(basename $(dirname "$uri")) # verify target branch of prq prq=$(bitbucket_pullrequest "$repo_host" "$repo_project" "$repo_name" "$prq_id" "" "$skip_ssl_verification") -if [ "$prq" != "ERROR" ]; then +if [ "$prq" != "NO_SUCH_PULL_REQUEST" ] && \ + [ "$prq" != "ALREADY_MERGED" ] && \ + [ "$prq" != "DECLINED" ]; then branch=$(echo "$prq" | jq -r '.fromRef.displayId') fi From 4232a80916fd39274126dc65b5eecb45c914c442 Mon Sep 17 00:00:00 2001 From: Thomas Detoux Date: Wed, 25 Apr 2018 10:55:43 -0400 Subject: [PATCH 19/23] Add a custom comment after the comment made by the resource --- README.md | 7 +++++++ assets/helpers/bitbucket.sh | 13 ++++++++++--- assets/out | 17 +++++++++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dbd358e..3ccaec4 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,13 @@ Set the status message on specified pull request. * [`on_success`](https://concourse-ci.org/on-success-step-hook.html) and [`on_failure`](https://concourse-ci.org/on-failure-step-hook.html) triggers may be useful for you when you wanted to reflect build result to the pull request (see the example below). +* `comment`: *Optional.* A custom comment that you want added to the status message. + Any occurence of `[[BRANCH]]` will be replace by the actual branch name form the + pull request. + +* `commentFile`: *Optional.* The path to a file that contains a custom comment to + add to the message. This allow the comment to be built by a previous task in the job. + ## Example pipeline ```yaml diff --git a/assets/helpers/bitbucket.sh b/assets/helpers/bitbucket.sh index e8d0f8c..e97f84a 100755 --- a/assets/helpers/bitbucket.sh +++ b/assets/helpers/bitbucket.sh @@ -164,26 +164,33 @@ bitbucket_pullrequest_progress_comment() { # $2: hash of merge commit # $3: hash of source commit # $4: hash of target commit + # $5: custom comment local hash="$2" local progress_msg_end="" + local custom_comment="" + if [ "$hash" == "$3" ]; then progress_msg_end+=" into $4]" else progress_msg_end="] $3 into $4" fi + if [ -n "$5" ]; then + custom_comment="\n\n$5" + fi + local build_url="$ATC_EXTERNAL_URL/teams/$(rawurlencode "$BUILD_TEAM_NAME")/pipelines/$(rawurlencode "$BUILD_PIPELINE_NAME")/jobs/$(rawurlencode "$BUILD_JOB_NAME")/builds/$(rawurlencode "$BUILD_NAME")" local build_result_pre=" \n\n **[" local build_result_post="]($build_url)** - Build #$BUILD_NAME" case "$1" in success) - echo "$(bitbucket_pullrequest_progress_msg_start "$hash" "Finished")${progress_msg_end}${build_result_pre}✓ BUILD SUCCESS${build_result_post}" ;; + echo "$(bitbucket_pullrequest_progress_msg_start "$hash" "Finished")${progress_msg_end}${build_result_pre}✓ BUILD SUCCESS${build_result_post}${custom_comment}" ;; failure) - echo "$(bitbucket_pullrequest_progress_msg_start "$hash" "Finished")${progress_msg_end}${build_result_pre}✕ BUILD FAILED${build_result_post}" ;; + echo "$(bitbucket_pullrequest_progress_msg_start "$hash" "Finished")${progress_msg_end}${build_result_pre}✕ BUILD FAILED${build_result_post}${custom_comment}" ;; pending) - echo "$(bitbucket_pullrequest_progress_msg_start "$hash" "Started")${progress_msg_end}${build_result_pre}⌛ BUILD IN PROGRESS${build_result_post}" ;; + echo "$(bitbucket_pullrequest_progress_msg_start "$hash" "Started")${progress_msg_end}${build_result_pre}⌛ BUILD IN PROGRESS${build_result_post}${custom_comment}" ;; esac } diff --git a/assets/out b/assets/out index e7c245e..d8db180 100755 --- a/assets/out +++ b/assets/out @@ -45,6 +45,8 @@ create_comments=$(jq -r '.source.create_comments // "false"' < "$payload") path=$(jq -r '.params.path // ""' < "$payload") status=$(jq -r '.params.status // ""' < "$payload") +additionnal_comment=$(jq -r '.params.comment // ""' < "$payload") +additionnal_comment_file=$(jq -r '.params.commentFile // ""' < "$payload") configure_git_ssl_verification "$skip_ssl_verification" configure_git_global "${git_config_payload}" @@ -65,14 +67,20 @@ if [ -z "$status" ]; then fi cd "$source" + +if [ -n "$additionnal_comment_file" ]; then + additionnal_comment="$(<${additionnal_comment_file})" +fi + cd "$path" merge_commit=$(git rev-parse HEAD) ls_remote=$(git ls-remote "$uri") -# collect prq id from git config stored in git config (during get step) +# collect prq id and branch name from git config stored in git config (during get step) # included cat to catch error prq_number=$(git config --get pullrequest.id | cat) +branch=$(git config --get pullrequest.branch | cat) if [ -z "$prq_number" ]; then prqs=$(echo "$ls_remote" | grep -E "/pull\-requests/[0-9]+" | grep "$merge_commit" | cat) @@ -147,8 +155,13 @@ bitbucket_pullrequest_commit_status "$repo_host" "$source_commit" "$data" "" "" # use the pullrequest date stored in git config in get PULL_REQUEST_DATE=$(git config --get pullrequest.date | cat) +# Add branch name to additional comment +if [ -n "$additionnal_comment" ]; then + additionnal_comment="${additionnal_comment//\[\[BRANCH\]\]/$branch}" +fi + # add comment to pull request to track if build was started/finished -comment_message=$(bitbucket_pullrequest_progress_comment "$status" "$prq_hash" "$source_commit" "$target_commit") +comment_message=$(bitbucket_pullrequest_progress_comment "$status" "$prq_hash" "$source_commit" "$target_commit", "$additionnal_comment") comments=$(bitbucket_pullrequest_overview_comments "$repo_host" "$repo_project" "$repo_name" "$prq_number" "" "$skip_ssl_verification" | jq -c '.[]') commented="" if [ -n "$comments" ]; then From 537818674c8a194b6a507086bdf63ffd8ee2712e Mon Sep 17 00:00:00 2001 From: Yansheng Wei Date: Mon, 16 Mar 2020 13:48:21 -0500 Subject: [PATCH 20/23] - Add optional sleep_between_fetches to avoid overloading bitBucket server, default "0" means no sleep. - Update Dockerfile with new packages so it can build successfully. --- Dockerfile | 8 ++++---- README.md | 2 ++ assets/check | 4 ++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4a37cc4..3cc1300 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,11 @@ FROM alpine:3.7 RUN apk --no-cache add \ bash=4.4.19-r1 \ - ca-certificates=20171114-r0 \ - curl=7.60.0-r1 \ - git=2.15.0-r1 \ + ca-certificates=20190108-r0 \ + curl=7.61.1-r3 \ + git=2.15.4-r0 \ jq=1.5-r5 \ - openssh-client=7.5_p1-r8 + openssh-client=7.5_p1-r10 # can't `git pull` unless we set these RUN git config --global user.email "git@localhost" && \ diff --git a/README.md b/README.md index 3ccaec4..c393f49 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,8 @@ See [concourse docs](https://concourse-ci.org/resource-types.html) for more deta * `only_for_branch`: *Optional.* If specified only pull requests which target those branches will be considered. It will accept a regular expression as determined by [egrep](http://linuxcommand.org/man_pages/egrep1.html). +* `sleep_between_fetches`: *Optional (default: 0).* Number of seconds to sleep between checking pull requests, avoiding too frequent fetches for check method. + * `only_without_conflicts`: *Optional (default: true).* If enabled only pull requests which are not in a conflicted state will be built. * `only_when_mergeable`: *Optional (default: false).* If enabled only pull requests which are mergeable (all tasks done, required number of approvers reached, ...) will be built. diff --git a/assets/check b/assets/check index b191f97..3f6788c 100755 --- a/assets/check +++ b/assets/check @@ -37,6 +37,8 @@ only_for_branch=$(jq -r '.source.only_for_branch // "."' < "$payload") only_without_conflicts=$(jq -r '.source.only_without_conflicts // "true"' < "$payload") only_when_mergeable=$(jq -r '.source.only_when_mergeable // "false"' < "$payload") only_when_asked=$(jq -r '.source.only_when_asked // "false"' < "$payload") +sleep_between_fetches=$(jq -r '.source.sleep_between_fetches // "0"' < "$payload") + sleep_between_fetches=$(echo "$sleep_between_fetches" | sed 's/[^0-9\.]//g') rebuild_when_target_changed=$(jq -r '.source.rebuild_when_target_changed // "false"' < "$payload") rebuild_phrase=$(jq -r '.source.rebuild_phrase // "test this please"' < "$payload") CURRENT_VERSION_DATE=$(jq -r '.version.date // "0"' < "$payload") @@ -61,6 +63,7 @@ set +e PULL_REQUESTS=$(echo "$REMOTES" | grep -E "/pull\\-requests/[0-9]+/${prq_branch}") set -e + versions="[]" if [ -n "$PULL_REQUESTS" ]; then log "Calculating repository specifics" @@ -76,6 +79,7 @@ if [ -n "$PULL_REQUESTS" ]; then versions="[]" while read pull_request ; do + sleep $sleep_between_fetches # throttle requests to avoid excessive load to server log "Verifying pull request" # determine hash and prq number from grep prq_number=$(echo "$pull_request" | sed -E "s/^.*\/pull-requests\/([0-9]+)\/.*$/\\1/") From ed38e9c08230d54bff5c12590f5f3577f3c5f899 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Mon, 11 May 2020 19:05:19 -0700 Subject: [PATCH 21/23] Add global cleanup function On puts to a resource that has a private key the bitbucket bash exit trap was overwriting the exit trap to kill the ssh-agent. This resulted in the put containers getting stuck because ssh-agent was not killed. Move all cleanup to a single global cleanup function. --- assets/helpers/bitbucket.sh | 3 --- assets/helpers/git.sh | 1 - assets/helpers/utils.sh | 7 +++++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/assets/helpers/bitbucket.sh b/assets/helpers/bitbucket.sh index e97f84a..5fddd3a 100755 --- a/assets/helpers/bitbucket.sh +++ b/assets/helpers/bitbucket.sh @@ -35,9 +35,6 @@ bitbucket_request() { rm -f "$request_data" } - # register the cleanup function to be called on the EXIT signal - trap request_result_cleanup EXIT - local extra_options="" if [ -n "$data" ]; then method=${method:-POST} diff --git a/assets/helpers/git.sh b/assets/helpers/git.sh index d598fca..ee4496f 100644 --- a/assets/helpers/git.sh +++ b/assets/helpers/git.sh @@ -9,7 +9,6 @@ load_pubkey() { chmod 0600 $private_key_path eval $(ssh-agent) >/dev/null 2>&1 - trap "kill $SSH_AGENT_PID" 0 SSH_ASKPASS=$ASSETS/helpers/askpass.sh DISPLAY= ssh-add $private_key_path >/dev/null diff --git a/assets/helpers/utils.sh b/assets/helpers/utils.sh index ef82608..70a5ee5 100755 --- a/assets/helpers/utils.sh +++ b/assets/helpers/utils.sh @@ -164,3 +164,10 @@ getBasePathOfBitbucket() { echo ${base_path} } + +cleanup() { + rm -rf "$TMPDIR/bitbucket-pullrequest-resource-*" + killall ssh-agent +} + +trap cleanup EXIT From ad45c83adb1fc538e78836d8769d63f625e81342 Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Mon, 11 May 2020 19:38:19 -0700 Subject: [PATCH 22/23] Check if ssh-agent is running before killall If it's not running killall returns 1 and causes failure exit due to set -e. --- assets/helpers/utils.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/helpers/utils.sh b/assets/helpers/utils.sh index 70a5ee5..1e3fc0b 100755 --- a/assets/helpers/utils.sh +++ b/assets/helpers/utils.sh @@ -167,7 +167,9 @@ getBasePathOfBitbucket() { cleanup() { rm -rf "$TMPDIR/bitbucket-pullrequest-resource-*" - killall ssh-agent + if pgrep ssh-agent; then + killall ssh-agent + fi } trap cleanup EXIT From d28370100891e330c57da1f93333a51a7181cf7c Mon Sep 17 00:00:00 2001 From: "Matthew M. Boedicker" Date: Mon, 11 May 2020 21:09:06 -0700 Subject: [PATCH 23/23] Only clean up temp files created by bitbucket_request Hide output of pgrep and killall so they don't interfere with the response. --- assets/helpers/utils.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/assets/helpers/utils.sh b/assets/helpers/utils.sh index 1e3fc0b..06b841c 100755 --- a/assets/helpers/utils.sh +++ b/assets/helpers/utils.sh @@ -166,9 +166,10 @@ getBasePathOfBitbucket() { } cleanup() { - rm -rf "$TMPDIR/bitbucket-pullrequest-resource-*" - if pgrep ssh-agent; then - killall ssh-agent + rm -rf "$TMPDIR/bitbucket-pullrequest-resource-bitbucket-request*" + rm -rf "$TMPDIR/bitbucket-pullrequest-resource-bitbucket-request-data*" + if pgrep ssh-agent > /dev/null 2>&1; then + killall ssh-agent > /dev/null 2>&1 fi }