From 531a9a8554fb5bba2103b12b0cf67b35450ced32 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Thu, 25 Feb 2021 12:02:08 -0700 Subject: [PATCH] package: use a central verification-metadata file This lets us have better control over which dependencies are verified, as changes to runelite-client's dependencies cause all Hub plugins with pinned deps to fail, as the new transitive deps aren't pinned. Moving this file into this repo not only lets us update it in these situations, but also means individual plugin authors don't need to touch Gradle's verification and all of it's associated pains. This also allows plugins to pull a dependency that another plugin pulls already with no extra work. --- .github/workflows/build.yml | 5 +- README.md | 29 +- package/package/build.gradle | 6 + .../runelite/pluginhub/packager/Packager.java | 7 +- .../runelite/pluginhub/packager/Plugin.java | 9 + .../pluginhub/packager/PluginTest.java | 20 + package/travis.sh | 1 + package/verification-template/README.md | 5 + package/verification-template/build.gradle | 72 +++ .../gradle/verification-metadata.xml | 587 ++++++++++++++++++ package/verification-template/settings.gradle | 1 + 11 files changed, 713 insertions(+), 29 deletions(-) create mode 100644 package/verification-template/README.md create mode 100644 package/verification-template/build.gradle create mode 100644 package/verification-template/gradle/verification-metadata.xml create mode 100644 package/verification-template/settings.gradle diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 047dc83a6..398b07c92 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,11 +28,12 @@ jobs: path: | ~/.gradle/caches/ ~/.gradle/wrapper/ - key: package-2.0.3 + key: package-2.0.4 - name: prepare run: | pushd package ./gradlew --build-cache prep + ./gradlew --build-cache --project-dir verification-template :verifyCore popd - name: build env: @@ -79,7 +80,7 @@ jobs: path: | ~/.gradle/caches/ ~/.gradle/wrapper/ - key: upload-2.0.3 + key: upload-2.0.4 - uses: actions/download-artifact@v2 with: name: manifest_diff diff --git a/README.md b/README.md index 5f172a97a..992d319b9 100644 --- a/README.md +++ b/README.md @@ -118,29 +118,6 @@ will not merge it__. We require any dependencies that are not a transitive dependency of runelite-client to be have their cryptographic hash verified during the build to prevent [supply chain attacks](https://en.wikipedia.org/wiki/Supply_chain_attack) and ensure build reproducability. To do this we rely on [Gradle's dependency verification](https://docs.gradle.org/nightly/userguide/dependency_verification.html). - -Create `gradle/verification-metadata.xml` with the following contents - -```xml - - - - true - false - - - - - - - - - -``` - -And finally run: -``` -./gradlew --write-verification-metadata sha256 -``` -Then commit the files to your repository. You will have to run this final command anytime you -add/remove/update dependencies that are not part of RuneLite. \ No newline at end of file +To add a new dependency, add it to the `thirdParty` configuration in [`package/verification-template/build.gradle`](https://github.com/runelite/plugin-hub/blob/master/package/verification-template/build.gradle), +then run `../gradlew --write-verification-metadata sha256` to update the metadata file. A maintainer must then verify +the dependencies manually before your pull request will be merged. \ No newline at end of file diff --git a/package/package/build.gradle b/package/package/build.gradle index fca319c10..172689f9e 100644 --- a/package/package/build.gradle +++ b/package/package/build.gradle @@ -49,6 +49,12 @@ dependencies { testImplementation "com.squareup.okhttp3:mockwebserver:3.14.9" } +processResources { + from("../verification-template/gradle/verification-metadata.xml") { + into "net/runelite/pluginhub/packager" + } +} + jar { manifest { attributes "Main-Class": "net.runelite.pluginhub.packager.Packager" diff --git a/package/package/src/main/java/net/runelite/pluginhub/packager/Packager.java b/package/package/src/main/java/net/runelite/pluginhub/packager/Packager.java index 99b59d1b8..e0dbb5f5e 100644 --- a/package/package/src/main/java/net/runelite/pluginhub/packager/Packager.java +++ b/package/package/src/main/java/net/runelite/pluginhub/packager/Packager.java @@ -337,11 +337,16 @@ public class Packager implements Closeable if (doPackageTests) { - testFailure = new ProcessBuilder(new File(PACKAGE_ROOT, "gradlew").getAbsolutePath(), "--console=plain", "test") + testFailure |= new ProcessBuilder(new File(PACKAGE_ROOT, "gradlew").getAbsolutePath(), "--console=plain", "test") .directory(PACKAGE_ROOT) .inheritIO() .start() .waitFor() != 0; + testFailure |= new ProcessBuilder(new File(PACKAGE_ROOT, "gradlew").getAbsolutePath(), "--console=plain", ":verifyAll") + .directory(new File(PACKAGE_ROOT, "verification-template")) + .inheritIO() + .start() + .waitFor() != 0; } if (doAll) diff --git a/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java b/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java index b8bd35bbe..a53e56eb2 100644 --- a/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java +++ b/package/package/src/main/java/net/runelite/pluginhub/packager/Plugin.java @@ -40,6 +40,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; @@ -51,6 +52,7 @@ import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Comparator; @@ -369,6 +371,13 @@ public class Plugin implements Closeable } } + try (InputStream is = Plugin.class.getResourceAsStream("verification-metadata.xml")) + { + File metadataFile = new File(repositoryDirectory, "gradle/verification-metadata.xml"); + metadataFile.getParentFile().mkdir(); + Files.copy(is, metadataFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + try (ProjectConnection con = GradleConnector.newConnector() .forProjectDirectory(repositoryDirectory) .useInstallation(GRADLE_HOME) diff --git a/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java b/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java index c036b00c2..830cbfa1a 100644 --- a/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java +++ b/package/package/src/test/java/net/runelite/pluginhub/packager/PluginTest.java @@ -100,6 +100,26 @@ public class PluginTest } } + @Test + public void testUnverifiedDependency() throws InterruptedException, DisabledPluginException, PluginBuildException, IOException + { + try (Plugin p = createExamplePlugin("unverified-dependency")) + { + File buildFile = new File(p.repositoryDirectory, "build.gradle"); + String buildSrc = Files.asCharSource(buildFile, StandardCharsets.UTF_8).read(); + buildSrc = buildSrc.replace("dependencies {", "dependencies {\n" + + " implementation 'org.apache.httpcomponents:httpclient:4.5.13'"); + Files.asCharSink(buildFile, StandardCharsets.UTF_8).write(buildSrc); + p.build(Util.readRLVersion()); + p.assembleManifest(); + Assert.fail(); + } + catch (PluginBuildException e) + { + log.info("ok: ", e); + } + } + private static void writeProperties(Properties props, File fi) throws IOException { try (FileOutputStream fos = new FileOutputStream(fi)) diff --git a/package/travis.sh b/package/travis.sh index 6bdac43c1..07d381d41 100755 --- a/package/travis.sh +++ b/package/travis.sh @@ -31,6 +31,7 @@ env: ' pushd "$(dirname "$0")" ./gradlew --console=plain --build-cache prep +./gradlew --console=plain --build-cache --project-dir verification-template :verifyCore popd PACKAGE_IS_PR="$TRAVIS_PULL_REQUEST" \ diff --git a/package/verification-template/README.md b/package/verification-template/README.md new file mode 100644 index 000000000..b14b2bade --- /dev/null +++ b/package/verification-template/README.md @@ -0,0 +1,5 @@ +This project includes the dependency verification hashes used by all Plugin Hub plugins. +At the start of every build `core` dependencies are verified, but `thirdParty` deps are not. +To add a new dependency for a plugin add a new dep to the `thirdParty` configuration in this +`build.gradle` and run `../gradlew --write-verification-metadata sha256`. The maintainer MUST +then verify the hashes match Maven Central and that the library in question is reasonable. \ No newline at end of file diff --git a/package/verification-template/build.gradle b/package/verification-template/build.gradle new file mode 100644 index 000000000..7986832a6 --- /dev/null +++ b/package/verification-template/build.gradle @@ -0,0 +1,72 @@ +plugins { + id "base" +} + +repositories { + maven { + url = "https://repo.runelite.net" + } + mavenCentral() + gradlePluginPortal() +} + +configurations { + core + thirdParty.extendsFrom core +} + +dependencies { + core group: "net.runelite", name:"client", version: file("../../runelite.version").text.trim() + core "org.projectlombok:lombok:1.18.4" + + thirdParty("org.zeromq:jnacl:0.1.0") { + because "keepass-xc" + } + thirdParty("org.mongodb:mongodb-driver-sync:4.2.0") { + because "afterdark-pvm-loot-tracker" + } + thirdParty("jfree:jfreechart:1.0.13") { + because "bank-value-tracker" + } + thirdParty("net.sourceforge.jdatepicker:jdatepicker:1.3.2") { + because "bank-value-tracker" + } + thirdParty("io.freefair.lombok:io.freefair.lombok.gradle.plugin:5.3.0") { + because "discord-rare-drop-notifier" + } + thirdParty("org.projectlombok:lombok:1.18.16") { + because "discord-rare-drop-notifier" + } + thirdParty("org.json:json:20200518") { + because "discord-rare-drop-notifier" + } + thirdParty("org.jsoup:jsoup:1.13.1") { + because "discord-rare-drop-notifier, drop-simulator, fire-beats, loot-table" + } + thirdParty("com.miglayout:miglayout-swing:5.2") { + because "drop-simulator" + } + thirdParty("org.apache.commons:commons-io:1.3.2") { + because "emojiscape" + } + thirdParty("org.influxdb:influxdb-java:2.5") { + because "influxdb-stats" + } + thirdParty("com.diffplug.spotless:spotless-plugin-gradle:5.2.0") { + because "ring-of-recoil-notifier" + } +} + +task verifyCore { + doLast { + // This causes resolution (and therefore verification) of the configuration + configurations.core.asPath + } +} + +task verifyAll { + doLast { + // This causes resolution (and therefore verification) of the configuration + configurations.thirdParty.asPath + } +} \ No newline at end of file diff --git a/package/verification-template/gradle/verification-metadata.xml b/package/verification-template/gradle/verification-metadata.xml new file mode 100644 index 000000000..1114083c7 --- /dev/null +++ b/package/verification-template/gradle/verification-metadata.xml @@ -0,0 +1,587 @@ + + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package/verification-template/settings.gradle b/package/verification-template/settings.gradle new file mode 100644 index 000000000..ff5477128 --- /dev/null +++ b/package/verification-template/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "verification-template" \ No newline at end of file