From 33eed15faa956a5d713e7946d539c9e671595edb Mon Sep 17 00:00:00 2001 From: Roberto Perez Alcolea Date: Fri, 5 Mar 2021 05:58:18 -0800 Subject: [PATCH] Upgrade nebula.netflixoss to replace bintray publication and update TravisCI Secrets (#920) --- .gitignore | 4 ++++ .travis.yml | 16 +++++++++------- build.gradle | 4 ++-- buildViaTravis.sh | 11 ++++++----- gradle/wrapper/gradle-wrapper.properties | 2 +- installViaTravis.sh | 15 +++------------ priam/build.gradle | 9 ++++++++- .../priam/backupv2/SnapshotMetaTask.java | 2 +- .../identity/token/TokenRetrieverUtils.java | 2 -- secrets/signing-key.enc | Bin 0 -> 6800 bytes 10 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 secrets/signing-key.enc diff --git a/.gitignore b/.gitignore index 8163af2a8..c1862c52c 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ Thumbs.db .gradle .m2 + # Build output directies /target */target @@ -67,3 +68,6 @@ atlassian-ide-plugin.xml # NetBeans specific files/directories .nbattrs >>>>>>> build/multi-project + +# publishing secrets +secrets/signing-key diff --git a/.travis.yml b/.travis.yml index 29dbc1298..9e6b9926a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,14 +4,16 @@ jdk: sudo: false git: depth: 100 -install: ./installViaTravis.sh -script: ./buildViaTravis.sh +install: "./installViaTravis.sh" +script: "./buildViaTravis.sh" cache: directories: - - $HOME/.gradle + - "$HOME/.gradle" env: global: - - secure: p81PYYYYhjhp1uJHOoT9EfUia8qPMphdykCxQannWMVvIFKXF5ibi/Qd52OUIYuJT9Q5MN9GhlwCtolxmCZu44YMLi99LsoITAv6n08LAFEux1oAOXmGt3ZBllvBFtlW+jlQ5lKmbuuPue3RVbTaWzL3KCCaYQ4uKW/sP31bXic= - - secure: AYWrIC/1JqAVyLhzlDhL163LypPpq7AliDltfey9emxzS73vB5VrGTHG45Em7xdkHN0kc1vED+UFsYks7ym1olXZPsbW29R0Gfd+p1VxCE3Cbhj7x690xNC3wIlSgWGpbgiPs7vhVN80OuNgnpz9/+WRFpKAVrYrcisbvugsDqk= - - secure: Ai75crFDh3imkmxzNQDXIwK49appZuZTrsmdZzgH1Zl/nD33RoZPWUWeeHP0yJoicNqZlU6aEXJnk8JGDWtPIT3VNO7Rsey+yrw041rHNV6bFGpwGdQgKv5CUhRHK+gShgFgnME5THCPKvK51+li1feIoByoYVmEn0gmvcxL0yM= - - secure: ZqBsyaFMBz3cqM7UHq0IRotTPaoBNUHrC7buiAqqhZ5JNM48a2m7ORuu/SENPFfr6xOT5KylCrvT6eD1bkQi5S2jT9Qyoju/9H/hXaAUG89dhwKOxqEE11ZGKF8DlNO/jcmchVnIkgWfEjVKc7vCAww1Y8lgxhyj4gRtnln+F+o= + - secure: bXzjPA0Ec3NBIN25knd9UYzGtxxmlhoLkO0LwI87iRSeCLzvbT+qBl/chvaXCk3DC2JnSq6GGWw2r0R6pjR4UezZx72KP+dm19cy606e7np1mHZmzziSkyjaBd84HPgOz8L4jh5G9qQBG8VhkjikIabAgsbiWG3oX6a/rOadobg= + - secure: COIxG87u7BSBAD0s8g0E9PTq4XLompgW/PL55bnIxuVkIo3tXXqShAxMzsJ0C++q5AbofNUICqTbGqN0ozk9GpMC78d5pgWS1O4hpdWsouK8Fxcju+KkKC5MUDC478G/zW0uSa0uZsZGaDy3Gx17jpvq2CdVCgHmaHmGGOxfDbA= + - secure: LMyJ2v4kN+07Gz5pPHkYLOvbQOAI05bHFGUVfaAbofyiR1DqKpKqB4hYaKSgb0kB/3YI6u9dLQ5AWzAqfx3HY0+p2iTmgseIxbHGrFfOH7bt2xusYNUtYPn1JXOAz1Nzxq/a+4rCgqD9lFI19XetrI5SNrRIRErDIZnWdXyhW/M= + - secure: dxJVfXpC/yORQWg2oaw+Q2UjeoAHiqf5hyLVSdGbIJYVrSu/fyFCuUNjQffikjleoyuaPeIHxaGQZoQZE3+9Cf3d7s1lXzugO3UOxmKR9UYi8tz6sLUFeLPjVhR6Etx603A8oCg659RhD2VyOCZvq1/R2gUa34tUtnVyoFyUzDA= + - secure: tl59nbZhOzWqW/PLp91+Paugond4Lwwj/qT1Tq4EFJ9Q2nNMFW3twlWzmUOcgn7GaJZTgfoDx2HGYFg1N3rrBtZIY/Wtzz9eWrGY4ywHfoXz/8lQGtbciDjiNePByuvSLOPWeTIGncOLGNUcCPNFOO9+kC4BzUGr9CjtTc+qnWg= + - secure: AZoBLO43P+GVjQq+vsT8mekOUNqifi+tRYukz19GLN2vv2vsgY4ejhXjeer1kwqm0l/1bXtfqo0uHyD+CFn2yINV20oKHScYNS4fwKnJ8aC60MZqAj6zddfe2VvEeDIKDiejpz4AfRJwgqpl9B0FrNtZ/1oU5n8oneTKpVFryTs= diff --git a/build.gradle b/build.gradle index c3f6b6b02..591a397c3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'nebula.netflixoss' version '7.1.3' + id 'nebula.netflixoss' version '9.1.0' id 'com.github.sherter.google-java-format' version '0.8' } @@ -78,7 +78,7 @@ allprojects { compile 'com.google.http-client:google-http-client-jackson2:1.28.0' compile 'com.netflix.spectator:spectator-api:0.96.0' compileOnly 'javax.servlet:javax.servlet-api:3.1.0' - testCompile 'org.jmockit:jmockit:1.31' + testCompile 'org.jmockit:jmockit:1.38' testCompile "org.spockframework:spock-core:1.1-groovy-2.4" testCompile "com.google.truth:truth:1.0.1" testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1' diff --git a/buildViaTravis.sh b/buildViaTravis.sh index 812026d7a..c3ddb674c 100755 --- a/buildViaTravis.sh +++ b/buildViaTravis.sh @@ -3,21 +3,22 @@ if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then echo -e "Build Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]" - ./gradlew build --stacktrace + ./gradlew build elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then echo -e 'Build Branch with Snapshot => Branch ['$TRAVIS_BRANCH']' - ./gradlew -Prelease.travisci=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" build snapshot --stacktrace + ./gradlew -Prelease.travisci=true -PnetflixOss.username="$NETFLIX_OSS_REPO_USERNAME" -PnetflixOss.password="$NETFLIX_OSS_REPO_PASSWORD" -Psonatype.signingPassword="$NETFLIX_OSS_SIGNING_PASSWORD" build snapshot elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then echo -e 'Build Branch for Release => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG']' case "$TRAVIS_TAG" in *-rc\.*) - ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" candidate --stacktrace + ./gradlew -Prelease.travisci=true -PnetflixOss.username="$NETFLIX_OSS_REPO_USERNAME" -PnetflixOss.password="$NETFLIX_OSS_REPO_PASSWORD" -Psonatype.signingPassword="$NETFLIX_OSS_SIGNING_PASSWORD" -Prelease.useLastTag=true candidate ;; *) - ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" final --stacktrace + ./gradlew -Prelease.travisci=true -PnetflixOss.username="$NETFLIX_OSS_REPO_USERNAME" -PnetflixOss.password="$NETFLIX_OSS_REPO_PASSWORD" -Psonatype.username="$NETFLIX_OSS_SONATYPE_USERNAME" -Psonatype.password="$NETFLIX_OSS_SONATYPE_PASSWORD" -Psonatype.signingPassword="$NETFLIX_OSS_SIGNING_PASSWORD" -Prelease.useLastTag=true final ;; esac else echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG'] Pull Request ['$TRAVIS_PULL_REQUEST']' - ./gradlew build --stacktrace + ./gradlew build fi + diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 717f03890..68ca99ac4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip diff --git a/installViaTravis.sh b/installViaTravis.sh index 06a86291c..82cf1b880 100755 --- a/installViaTravis.sh +++ b/installViaTravis.sh @@ -1,16 +1,7 @@ #!/bin/bash # This script will build the project. -if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then - echo -e "Assemble Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]" - ./gradlew assemble --stacktrace -elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then - echo -e 'Assemble Branch with Snapshot => Branch ['$TRAVIS_BRANCH']' - ./gradlew -Prelease.travisci=true assemble --stacktrace -elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then - echo -e 'Assemble Branch for Release => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG']' - ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true assemble --stacktrace -else - echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG'] Pull Request ['$TRAVIS_PULL_REQUEST']' - ./gradlew assemble --stacktrace +if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then + echo "Decrypting publishing credentials" + openssl aes-256-cbc -k "$NETFLIX_OSS_SIGNING_FILE_PASSWORD" -in secrets/signing-key.enc -out secrets/signing-key -d fi diff --git a/priam/build.gradle b/priam/build.gradle index 723f3d03d..bbafaa0aa 100644 --- a/priam/build.gradle +++ b/priam/build.gradle @@ -1 +1,8 @@ -apply plugin: 'groovy' \ No newline at end of file +apply plugin: 'groovy' + +/** + * This is from https://jmockit.github.io/tutorial/Introduction.html#runningTests + */ +test { + jvmArgs "-javaagent:${classpath.find { it.name.contains("jmockit") }.absolutePath}" +} diff --git a/priam/src/main/java/com/netflix/priam/backupv2/SnapshotMetaTask.java b/priam/src/main/java/com/netflix/priam/backupv2/SnapshotMetaTask.java index 5ac26dc8f..871f021e2 100644 --- a/priam/src/main/java/com/netflix/priam/backupv2/SnapshotMetaTask.java +++ b/priam/src/main/java/com/netflix/priam/backupv2/SnapshotMetaTask.java @@ -415,7 +415,7 @@ ImmutableSetMultimap getFileUploadResults( * Gives the prefix (common name) of the sstable components. Returns an empty Optional if it is * not an sstable component or a manifest or schema file. * - *

For example: mc-3-big-Data.db --> mc-3-big ks-cf-ka-7213-Index.db --> ks-cf-ka-7213 + *

For example: mc-3-big-Data.db -- mc-3-big ks-cf-ka-7213-Index.db -- ks-cf-ka-7213 * * @param file the file from which to extract a common prefix. * @return common prefix of the file, or empty, diff --git a/priam/src/main/java/com/netflix/priam/identity/token/TokenRetrieverUtils.java b/priam/src/main/java/com/netflix/priam/identity/token/TokenRetrieverUtils.java index 700f3ef92..1fd35b7ec 100644 --- a/priam/src/main/java/com/netflix/priam/identity/token/TokenRetrieverUtils.java +++ b/priam/src/main/java/com/netflix/priam/identity/token/TokenRetrieverUtils.java @@ -30,8 +30,6 @@ public class TokenRetrieverUtils { * @param dc * @return IP of the token owner based on gossip information or null if C* status doesn't * converge. - * @throws GossipParseException when required number of instances are not available to fetch the - * gossip info. */ public static InferredTokenOwnership inferTokenOwnerFromGossip( List allIds, String token, String dc) { diff --git a/secrets/signing-key.enc b/secrets/signing-key.enc new file mode 100644 index 0000000000000000000000000000000000000000..ce0833210e7c7d67f8e1ce477f263c20886463b7 GIT binary patch literal 6800 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