From 0dc864fd96431e61285534d977e8f3bd42c6c3bb Mon Sep 17 00:00:00 2001 From: Jacob Barrett Date: Wed, 24 Feb 2021 22:59:47 -0800 Subject: [PATCH 1/4] Replaces xmllint with xqilla for XPath 2. Adds version filter. --- Dockerfile | 10 ++++------ README.md | 2 ++ assets/check | 40 +++++++++++++++++----------------------- test/check.sh | 26 ++++++++++++++++++++++++++ test/helpers.sh | 24 ++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 29 deletions(-) diff --git a/Dockerfile b/Dockerfile index d5e4dcf..11f9b9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,8 @@ -FROM openjdk:8u151-jdk-alpine +FROM adoptopenjdk/openjdk8:latest -RUN apk add --no-cache curl tar bash jq libxml2-utils - -# https://github.com/concourse/concourse/issues/2042 -RUN unlink $JAVA_HOME/jre/lib/security/cacerts && \ - cp /etc/ssl/certs/java/cacerts $JAVA_HOME/jre/lib/security/cacerts +RUN apt-get update \ + && apt-get install -y curl tar bash jq xqilla \ + && rm -rf /var/lib/apt/lists/* ADD assets/ /opt/resource/ ADD test/ /opt/resource/test/ diff --git a/README.md b/README.md index 1d1a9fd..12f1067 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Deploys and retrieve artifacts from a Maven Repository Manager. * `artifact`: *Required.* The artifact coordinates in the form of _groupId:artifactId:type[:classifier]_ +* `version`: *Optional.* A regular expression matching the entire version of an artifact. If specified only versions matching the regex will be considered. For example `1.0.0-.*` would match all version like `1.0.0-build.123` but not `1.0.0` or `21.0.0-build.123`. Can be used to pin to latest of a major or minor release without bumping to the absolute latest release. + * `username`: *Optional.* Username for accessing an authenticated repository. * `password`: *Optional.* Password for accessing an authenticated repository. diff --git a/assets/check b/assets/check index 26f9ddc..a3dfb91 100755 --- a/assets/check +++ b/assets/check @@ -1,7 +1,7 @@ #!/bin/bash # vim: set ft=sh -set -eu +set -eux set -o pipefail exec 3>&1 # make stdout available as fd 3 for the result @@ -28,6 +28,7 @@ fi release_url=$(jq -r '.source.url //empty' < $payload) snapshot_url=$(jq -r '.source.snapshot_url //empty' < $payload) artifact=$(jq -r '.source.artifact //empty' < $payload) +version_filter=$(jq -r '.source.version //".*"' < $payload) version=$(jq -r '.version.version //empty' < $payload) username=$(jq -r '.source.username //empty' < $payload) password=$(jq -r '.source.password //empty' < $payload) @@ -72,38 +73,31 @@ else metadataUrl="$url/${groupId//.//}/$artifactId/maven-metadata.xml" fi +metadata=$(mktemp) set +e -metadata=$(curl --fail --silent --show-error $cert $auth $metadataUrl 2>&1) +curl -o $metadata --fail --silent --show-error $cert $auth $metadataUrl 2>&1 if [ $? -ne 0 ]; then - printf '\e[91m[ERROR]\e[0m %s\n' "$metadata" + printf '\e[91m[ERROR]\e[0m %s\n' "$(cat $metadata)" printf '\e[91m[ERROR]\e[0m failed to download maven-metadata.xml from: %s\n' "$metadataUrl" exit 2 fi set -e -declare -a versions=( ) if [[ "$version" = *-SNAPSHOT ]]; then - if [[ -z "$classifier" ]]; then - versions[1]=$(echo $metadata | xmllint --xpath "/metadata/versioning/snapshotVersions/snapshotVersion[extension='$packaging' and not(classifier)]/value/text()" - 2>/dev/null) + if [[ -z "$classifier" ]]; then + versions=$(echo "/metadata/versioning/snapshotVersions/snapshotVersion[extension='$packaging' and not(classifier)]/value/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) else - versions[1]=$(echo $metadata | xmllint --xpath "/metadata/versioning/snapshotVersions/snapshotVersion[extension='$packaging' and classifier='$classifier']/value/text()" - 2>/dev/null) + versions=$(echo "/metadata/versioning/snapshotVersions/snapshotVersion[extension='$packaging' and classifier='$classifier']/value/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) fi -elif [ "$version" = "latest" ] || [ -z "$version" ]; then - versions[1]=$(echo $metadata | xmllint --xpath "/metadata/versioning/versions/version[last()]/text()" - 2>/dev/null) else - itemsCount=$(echo $metadata | xmllint --xpath 'count(/metadata/versioning/versions/version)' - 2>/dev/null) - found=false - for (( i=1; i <= $itemsCount; i++ )); do - - current=$(echo $metadata | xmllint --xpath "/metadata/versioning/versions/version[$i]/text()" - 2>/dev/null) - if [ "$found" = false ] && [ "$current" = "$version" ]; then - found=true - fi - - if [ "$found" = true ]; then - versions[$i]=$current - fi - done + match_version_filter="matches(text(), '^$version_filter\$')" + if [ "$version" = "latest" ] || [ -z "$version" ]; then + versions=$(echo "/metadata/versioning/versions/version[$match_version_filter][last()]/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) + else + versions=$(echo "/metadata/versioning/versions/version[text()='$version']/(self::version|following-sibling::version[$match_version_filter])/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) + fi fi -printf "%s\n" "${versions[@]}" | sed 's/.*/{ "version": "&" }/' | jq --slurp . >&3 +rm -f $metadata + +echo "$versions" | sed 's/.*/{ "version": "&" }/' | jq --slurp . >&3 diff --git a/test/check.sh b/test/check.sh index a4da733..0a8142b 100755 --- a/test/check.sh +++ b/test/check.sh @@ -95,7 +95,33 @@ it_can_check_latest_from_three_versions() { ' } +it_can_check_filtered_version_from_four_versions() { + + local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) + + local repository=$src/remote-repository + mkdir -p $repository + + local url=file://$repository + local artifact=ci.concourse.maven:maven-resource:jar:standalone + + local version1=$(deploy_artifact $url $artifact '1.0.0-rc.1' $src) + local version2=$(deploy_artifact $url $artifact '1.0.0-rc.2' $src) + local version3=$(deploy_artifact $url $artifact '2.0.0-rc.1' $src) + local version4=$(deploy_artifact $url $artifact '21.0.0-rc.1' $src) + + check_artifact_filtered $url $artifact 'latest' $src '1.0.0-.*' | \ + jq -e \ + --arg version $version2 \ + ' + . == [ + {version: $version} + ] + ' +} + run it_can_check_from_one_version run it_can_check_from_three_versions run it_can_check_latest_from_one_version run it_can_check_latest_from_three_versions +run it_can_check_filtered_version_from_four_versions diff --git a/test/helpers.sh b/test/helpers.sh index f5afa8b..0940bea 100755 --- a/test/helpers.sh +++ b/test/helpers.sh @@ -154,6 +154,30 @@ check_artifact() { }' | $resource_dir/check "$src" | tee /dev/stderr } +check_artifact_filtered() { + local url=$1 + local artifact=$2 + local version=$3 + local src=$4 + local filter=$5 + + jq -n \ + --arg url "$url" \ + --arg artifact "$artifact" \ + --arg version "$version" \ + --arg filter "$filter" \ + '{ + source: { + url: $url, + artifact: $artifact, + version: $filter + }, + version: { + version: $version + } + }' | $resource_dir/check "$src" | tee /dev/stderr +} + check_artifact_from_manager() { local version=$1 From 058ac920ce63bd52e7bd2b968725daa1c574960a Mon Sep 17 00:00:00 2001 From: Jacob Barrett Date: Thu, 25 Feb 2021 10:49:17 -0800 Subject: [PATCH 2/4] Produces a version file on in. --- README.md | 7 ++++++- assets/check | 10 +++++----- assets/in | 2 ++ test/check.sh | 2 +- test/get.sh | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 12f1067..ac80e15 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Deploys and retrieve artifacts from a Maven Repository Manager. * `artifact`: *Required.* The artifact coordinates in the form of _groupId:artifactId:type[:classifier]_ -* `version`: *Optional.* A regular expression matching the entire version of an artifact. If specified only versions matching the regex will be considered. For example `1.0.0-.*` would match all version like `1.0.0-build.123` but not `1.0.0` or `21.0.0-build.123`. Can be used to pin to latest of a major or minor release without bumping to the absolute latest release. +* `version`: *Optional.* A regular expression matching the entire version of an artifact. If specified only versions matching the regex will be considered. For example `1\.\0\.0-.*` would match all version like `1.0.0-build.123` but not `1.0.0` or `21.0.0-build.123`. Can be used to pin to latest of a major or minor release without bumping to the absolute latest release. * `username`: *Optional.* Username for accessing an authenticated repository. @@ -49,6 +49,11 @@ the repository. Download the artifact from the repository. +### Files + + * [artifact]: Named artifact file. + + * version: File containing the version of the artifact. ### `out`: Deploy artifact to a repository. diff --git a/assets/check b/assets/check index a3dfb91..fc9888f 100755 --- a/assets/check +++ b/assets/check @@ -1,7 +1,7 @@ #!/bin/bash # vim: set ft=sh -set -eux +set -eu set -o pipefail exec 3>&1 # make stdout available as fd 3 for the result @@ -28,7 +28,7 @@ fi release_url=$(jq -r '.source.url //empty' < $payload) snapshot_url=$(jq -r '.source.snapshot_url //empty' < $payload) artifact=$(jq -r '.source.artifact //empty' < $payload) -version_filter=$(jq -r '.source.version //".*"' < $payload) +version_pattern=$(jq -r '.source.version //".*"' < $payload) version=$(jq -r '.version.version //empty' < $payload) username=$(jq -r '.source.username //empty' < $payload) password=$(jq -r '.source.password //empty' < $payload) @@ -90,11 +90,11 @@ if [[ "$version" = *-SNAPSHOT ]]; then versions=$(echo "/metadata/versioning/snapshotVersions/snapshotVersion[extension='$packaging' and classifier='$classifier']/value/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) fi else - match_version_filter="matches(text(), '^$version_filter\$')" + match_version_pattern="matches(text(), '^$version_pattern\$')" if [ "$version" = "latest" ] || [ -z "$version" ]; then - versions=$(echo "/metadata/versioning/versions/version[$match_version_filter][last()]/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) + versions=$(echo "/metadata/versioning/versions/version[$match_version_pattern][last()]/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) else - versions=$(echo "/metadata/versioning/versions/version[text()='$version']/(self::version|following-sibling::version[$match_version_filter])/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) + versions=$(echo "/metadata/versioning/versions/version[text()='$version']/(self::version|following-sibling::version[$match_version_pattern])/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) fi fi diff --git a/assets/in b/assets/in index 1327a49..9f6d7c2 100755 --- a/assets/in +++ b/assets/in @@ -101,6 +101,8 @@ args="$args -Drepository.url=$url" $resource_dir/mvnw dependency:copy $args +echo $version > $destination/version + jq -n \ --arg version "$version" \ '{ diff --git a/test/check.sh b/test/check.sh index 0a8142b..3317b53 100755 --- a/test/check.sh +++ b/test/check.sh @@ -110,7 +110,7 @@ it_can_check_filtered_version_from_four_versions() { local version3=$(deploy_artifact $url $artifact '2.0.0-rc.1' $src) local version4=$(deploy_artifact $url $artifact '21.0.0-rc.1' $src) - check_artifact_filtered $url $artifact 'latest' $src '1.0.0-.*' | \ + check_artifact_filtered $url $artifact 'latest' $src '1\.0\.0-.*' | \ jq -e \ --arg version $version2 \ ' diff --git a/test/get.sh b/test/get.sh index 1327e14..a2c656f 100755 --- a/test/get.sh +++ b/test/get.sh @@ -22,6 +22,8 @@ it_can_get_artifact() { ' .version == {version: $version} ' + local actual_version=$(cat $src/version) + [ "$version" == "$actual_version" ] } run it_can_get_artifact From 1558f26e08ecbe5f3ec2f5ae650a5b06b34f27e8 Mon Sep 17 00:00:00 2001 From: Jacob Barrett Date: Wed, 3 Mar 2021 11:51:21 -0800 Subject: [PATCH 3/4] Fixes issue with returning empty version. Asserts correct behavior for versions after previous checked version. --- README.md | 2 +- assets/check | 6 ++++- test/check.sh | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac80e15..a67e914 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Download the artifact from the repository. ### Files - * [artifact]: Named artifact file. + * (artifact): Named artifact file. * version: File containing the version of the artifact. diff --git a/assets/check b/assets/check index fc9888f..3fd12f4 100755 --- a/assets/check +++ b/assets/check @@ -100,4 +100,8 @@ fi rm -f $metadata -echo "$versions" | sed 's/.*/{ "version": "&" }/' | jq --slurp . >&3 +if [ -z "${versions}" ]; then + echo "[]" >&3 +else + echo "$versions" | sed 's/.*/{ "version": "&" }/' | jq --slurp . >&3 +fi diff --git a/test/check.sh b/test/check.sh index 3317b53..782e32a 100755 --- a/test/check.sh +++ b/test/check.sh @@ -120,8 +120,83 @@ it_can_check_filtered_version_from_four_versions() { ' } +it_can_check_filtered_out_all_version() { + + local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) + + local repository=$src/remote-repository + mkdir -p $repository + + local url=file://$repository + local artifact=ci.concourse.maven:maven-resource:jar:standalone + + local version1=$(deploy_artifact $url $artifact '1.0.0-rc.1' $src) + local version2=$(deploy_artifact $url $artifact '1.0.0-rc.2' $src) + + check_artifact_filtered $url $artifact 'latest' $src '2\.0\.0-.*' | \ + jq -e \ + ' + . == [ + ] + ' +} + +it_can_check_provided_version_is_not_latest_version_when_filtering() { + + local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) + + local repository=$src/remote-repository + mkdir -p $repository + + local url=file://$repository + local artifact=ci.concourse.maven:maven-resource:jar:standalone + + local version1=$(deploy_artifact $url $artifact '1.0.0-rc.1' $src) + local version2=$(deploy_artifact $url $artifact '1.0.0-rc.2' $src) + local version3=$(deploy_artifact $url $artifact '1.0.0-rc.3' $src) + + check_artifact_filtered $url $artifact $version2 $src '1\.0\.0-.*' | \ + jq -e \ + --arg version1 $version1 \ + --arg version2 $version2 \ + --arg version3 $version3 \ + ' + . == [ + {version: $version2}, + {version: $version3} + ] + ' +} + +it_can_check_provided_version_is_latest_version_when_filtering() { + + local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) + + local repository=$src/remote-repository + mkdir -p $repository + + local url=file://$repository + local artifact=ci.concourse.maven:maven-resource:jar:standalone + + local version1=$(deploy_artifact $url $artifact '1.0.0-rc.1' $src) + local version2=$(deploy_artifact $url $artifact '1.0.0-rc.2' $src) + + check_artifact_filtered $url $artifact $version2 $src '1\.0\.0-.*' | \ + jq -e \ + --arg version1 $version1 \ + --arg version2 $version2 \ + ' + . == [ + {version: $version2} + ] + ' +} + run it_can_check_from_one_version run it_can_check_from_three_versions run it_can_check_latest_from_one_version run it_can_check_latest_from_three_versions run it_can_check_filtered_version_from_four_versions +run it_can_check_filtered_out_all_version +run it_can_check_provided_version_is_not_latest_version_when_filtering +run it_can_check_provided_version_is_latest_version_when_filtering From 7697a568b1ae571a9bad9b0313187462ff78b0ac Mon Sep 17 00:00:00 2001 From: Jacob Barrett Date: Wed, 22 Sep 2021 14:44:53 -0700 Subject: [PATCH 4/4] Fixes issues with missing input version on check. --- assets/check | 6 +----- test/check.sh | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/assets/check b/assets/check index 3fd12f4..44c0fb8 100755 --- a/assets/check +++ b/assets/check @@ -91,11 +91,7 @@ if [[ "$version" = *-SNAPSHOT ]]; then fi else match_version_pattern="matches(text(), '^$version_pattern\$')" - if [ "$version" = "latest" ] || [ -z "$version" ]; then - versions=$(echo "/metadata/versioning/versions/version[$match_version_pattern][last()]/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) - else - versions=$(echo "/metadata/versioning/versions/version[text()='$version']/(self::version|following-sibling::version[$match_version_pattern])/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) - fi + versions=$(echo "/metadata/versioning/versions/((version[text()='$version']/(self::version|following-sibling::version)[$match_version_pattern])|(version[$match_version_pattern][last()]))/text()" | xqilla -i $metadata /dev/stdin 2>/dev/null) fi rm -f $metadata diff --git a/test/check.sh b/test/check.sh index 782e32a..62c7778 100755 --- a/test/check.sh +++ b/test/check.sh @@ -120,6 +120,32 @@ it_can_check_filtered_version_from_four_versions() { ' } +it_can_check_filtered_version_from_five_versions_interleaved() { + + local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) + + local repository=$src/remote-repository + mkdir -p $repository + + local url=file://$repository + local artifact=ci.concourse.maven:maven-resource:jar:standalone + + local version1=$(deploy_artifact $url $artifact '1.0.0-rc.1' $src) + local version2=$(deploy_artifact $url $artifact '1.0.0-rc.2' $src) + local version3=$(deploy_artifact $url $artifact '2.0.0-rc.1' $src) + local version4=$(deploy_artifact $url $artifact '21.0.0-rc.1' $src) + local version5=$(deploy_artifact $url $artifact '1.0.0-rc.3' $src) + + check_artifact_filtered $url $artifact 'latest' $src '1\.0\.0-.*' | \ + jq -e \ + --arg version $version5 \ + ' + . == [ + {version: $version} + ] + ' +} + it_can_check_filtered_out_all_version() { local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) @@ -192,11 +218,39 @@ it_can_check_provided_version_is_latest_version_when_filtering() { ' } +it_can_check_filtered_version_gets_latest_version_if_input_version_is_missing() { + + local src=$(mktemp -d $TMPDIR/check-src.XXXXXX) + + local repository=$src/remote-repository + mkdir -p $repository + + local url=file://$repository + local artifact=ci.concourse.maven:maven-resource:jar:standalone + + local version1=$(deploy_artifact $url $artifact '1.0.0-rc.1' $src) + local version2=$(deploy_artifact $url $artifact '1.0.0-rc.2' $src) + local version3=$(deploy_artifact $url $artifact '2.0.0-rc.1' $src) + local version4=$(deploy_artifact $url $artifact '21.0.0-rc.1' $src) + local version5=$(deploy_artifact $url $artifact '1.0.0-rc.4' $src) + + check_artifact_filtered $url $artifact '1.0.0-rc.3' $src '1\.0\.0-.*' | \ + jq -e \ + --arg version $version5 \ + ' + . == [ + {version: $version} + ] + ' +} + run it_can_check_from_one_version run it_can_check_from_three_versions run it_can_check_latest_from_one_version run it_can_check_latest_from_three_versions run it_can_check_filtered_version_from_four_versions +run it_can_check_filtered_version_from_five_versions_interleaved run it_can_check_filtered_out_all_version run it_can_check_provided_version_is_not_latest_version_when_filtering run it_can_check_provided_version_is_latest_version_when_filtering +run it_can_check_filtered_version_gets_latest_version_if_input_version_is_missing