mpetuska/npm-publish

Support user-specified node binary location

Closed this issue · 4 comments

I'm trying to avoid downloading Node.js on our CI builds and use the version provided by our build image.

So I configured the Kotlin MPP Gradle plugin in my root build.gradle.kts as follows:

// On CI, use NodeJs and Yarn provided by the build image
if (System.getenv("CI") == "true") {
    rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
        rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().download = false
    }
    rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
        rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().download = false
    }
}

Now npm-publish fails:

* What went wrong:
Some problems were found with the configuration of task ':project-xxx:publishJsPackageToXXXRegistry' (type 'NpmPublishTask').
  - In plugin 'dev.petuska.npm.publish' type 'dev.petuska.npm.publish.task.NpmPublishTask' property 'node' specifies file '/builds/devxxx/project-xxx/.gradle/nodejs/node-v16.13.0-linux-x64/bin/node' which doesn't exist.
    
    Reason: An input file was expected to be present but it doesn't exist.
    
    Possible solutions:
      1. Make sure the file exists before the task is called.
      2. Make sure that the task which produces the file is declared as an input.
    
    Please refer to https://docs.gradle.org/7.5.1/userguide/validation_problems.html#input_file_does_not_exist for more details about this problem.
  - In plugin 'dev.petuska.npm.publish' type 'dev.petuska.npm.publish.task.NpmPublishTask' property 'nodeHome' specifies directory '/builds/devxxx/project-xxx/.gradle/nodejs/node-v16.13.0-linux-x64' which doesn't exist.
    
    Reason: An input file was expected to be present but it doesn't exist.
    
    Possible solutions:
      1. Make sure the directory exists before the task is called.
      2. Make sure that the task which produces the directory is declared as an input.
    
    Please refer to https://docs.gradle.org/7.5.1/userguide/validation_problems.html#input_file_does_not_exist for more details about this problem.
  - In plugin 'dev.petuska.npm.publish' type 'dev.petuska.npm.publish.task.NpmPublishTask' property 'npm' specifies file '/builds/devxxx/project-xxx/.gradle/nodejs/node-v16.13.0-linux-x64/lib/node_modules/npm/bin/npm-cli.js' which doesn't exist.
    
    Reason: An input file was expected to be present but it doesn't exist.
    
    Possible solutions:
      1. Make sure the file exists before the task is called.
      2. Make sure that the task which produces the file is declared as an input.
    
    Please refer to https://docs.gradle.org/7.5.1/userguide/validation_problems.html#input_file_does_not_exist for more details about this problem.

I tried to do:

npmPublish {
    if (System.getenv("CI") == "true") nodeHome.set(File("/usr"))
    // ...
}

tasks.withType<NpmPublishTask> {
    if (System.getenv("CI") == "true") nodeHome.set(File("/usr"))
}

But this fails with the same errors.

I suspect that this is due to this assignment that occurs after project evaluation:
https://github.com/mpetuska/npm-publish/blob/master/npm-publish-gradle-plugin/src/main/kotlin/NpmPublishPlugin.kt#L54
Shouldn't this be done at convention time?

OK, I may have spoke too soon.

It seems that this works:

tasks.withType<NpmPublishTask> {
    if (System.getenv("CI") == "true") nodeHome.set(File("/usr"))
}

But this does not:

npmPublish {
    if (System.getenv("CI") == "true") nodeHome.set(File("/usr"))
    // ...
}

Still a bug as both should work! Thanks for reporting this, I'll fix it next release.

NODE_HOME env variable is also supported, but only when not using kotlin plugin.

FYI, you might want to use withType<NodeExecTask> instead to capture all plugin's tasks that depend on node (like pack).

Thanks a lot @mpetuska !