From 8683ee9cfe0919bd83f273a9b90a76e68255534f Mon Sep 17 00:00:00 2001 From: Colin Alworth Date: Fri, 10 Dec 2021 15:14:47 -0600 Subject: [PATCH] Provide docker-web project for gradle, restructure web static content --- build.gradle | 5 +- buildSrc/src/main/groovy/GwtTools.groovy | 34 ----------- docker/web/build.gradle | 37 ++++++++++++ docker/web/src/main/docker/Dockerfile | 10 ++++ .../main/docker}/nginx/99-init-notebooks.sh | 0 .../web/src/main/docker}/nginx/default.conf | 0 .../web/src/main/docker}/nginx/nginx.conf | 0 proto/raw-js-openapi/build.gradle | 16 +++++- settings.gradle | 4 ++ web/client-ide/client-ide.gradle | 56 ++++++------------- web/client-ide/docker/Dockerfile | 15 ----- web/client-ui/client-ui.gradle | 15 ++++- web/web.gradle | 24 ++++++++ 13 files changed, 122 insertions(+), 94 deletions(-) create mode 100644 docker/web/build.gradle create mode 100644 docker/web/src/main/docker/Dockerfile rename {web/client-ide => docker/web/src/main/docker}/nginx/99-init-notebooks.sh (100%) rename {web/client-ide => docker/web/src/main/docker}/nginx/default.conf (100%) rename {web/client-ide => docker/web/src/main/docker}/nginx/nginx.conf (100%) delete mode 100644 web/client-ide/docker/Dockerfile create mode 100644 web/web.gradle diff --git a/build.gradle b/build.gradle index 59d2f3abdd0..e3dda0a1805 100644 --- a/build.gradle +++ b/build.gradle @@ -98,6 +98,7 @@ Set modsAreBasic = subprojects.findAll {it.name in [ 'deephaven2-wheel', 'envoy', 'grpc-proxy', + 'web', 'web-client-ui', 'pyclient', 'sphinx', @@ -480,7 +481,7 @@ tasks.register('prepareCompose') { it.description 'A lifecycle task that prepares prerequisites for local docker-compose builds' it.dependsOn project(':docker-server-slim').tasks.findByName('buildDocker'), project(':docker-server').tasks.findByName('buildDocker-server'), - project(':web-client-ide').tasks.findByName('buildDocker'), + project(':docker-web').tasks.findByName('buildDocker'), project(':envoy').tasks.findByName('buildDocker'), project(':grpc-proxy').tasks.findByName('buildDocker') } @@ -496,7 +497,7 @@ tasks.register('smoke') { it.dependsOn project(':grpc-api').tasks.findByName(LifecycleBasePlugin.CHECK_TASK_NAME) it.dependsOn project(':docker-server-slim').tasks.findByName('prepareDocker') it.dependsOn project(':docker-server').tasks.findByName('prepareDocker') - it.dependsOn project(':web-client-ide').tasks.findByName('prepareDocker') + it.dependsOn project(':web').tasks.findByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME) it.dependsOn project(':Generators').tasks.findByName(LifecycleBasePlugin.CHECK_TASK_NAME) } diff --git a/buildSrc/src/main/groovy/GwtTools.groovy b/buildSrc/src/main/groovy/GwtTools.groovy index 7a8a7115e85..db5fbe69ae6 100644 --- a/buildSrc/src/main/groovy/GwtTools.groovy +++ b/buildSrc/src/main/groovy/GwtTools.groovy @@ -6,10 +6,7 @@ import groovy.transform.CompileStatic import org.gradle.api.Project import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.CopySpec import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.tasks.TaskOutputs -import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.compile.JavaCompile /** @@ -72,37 +69,6 @@ class GwtTools { gwtc.logger.quiet('Running in gwt dev mode; saving source to {}/dh/src', extras) } - // Add a jar task to create an artifact containing our compiled application - p.tasks.register "jsJar", Jar, { - Jar j -> - j.group = '~Deephaven' - j.description = description - // make a task dependency, AND make sure we rebuild this jar if the gwtc task output files change. - j.inputs.files gwtc.outputs.files - j.from("$gwt.compile.war/dhapi") { - CopySpec c-> - c.exclude '**/extra' // don't put our source files in exported jar, thx - c.into 'dhapi' - } - // let's also pull in the ide client's build output - TaskOutputs uiOutputs = p.project(':web-client-ui').tasks.getByName('ideClient').outputs - j.from(uiOutputs.files) { - CopySpec c -> - c.into 'dhide' - } - - TaskOutputs internalOpenapiOutputs = p.project(':proto:raw-js-openapi').tasks.getByName('webpackSources').outputs - j.from(internalOpenapiOutputs.files) { - CopySpec c -> - c.into 'dhapi' - } - - j.classifier = 'js' - j.doFirst { - j.logger.info "Merging $gwt.compile.war and $uiOutputs into $j.archivePath" - } - } - p.tasks.findByName('gwtCheck')?.enabled = false } diff --git a/docker/web/build.gradle b/docker/web/build.gradle new file mode 100644 index 00000000000..823e6829bc5 --- /dev/null +++ b/docker/web/build.gradle @@ -0,0 +1,37 @@ +import io.deephaven.tools.License + +plugins { + id 'com.bmuschko.docker-remote-api' +} + +configurations { + js +} +dependencies { + js project(path: ':web', targetConfiguration: 'js') +} + +evaluationDependsOn Docker.registryProject('nginx-base') + +def dockerLicenses = License.createFrom(project).syncDockerLicense() + +def syncDir = layout.buildDirectory.dir('docker') +def prepareDocker = project.tasks.register('prepareDocker', Sync) { + from layout.projectDirectory.dir('src/main/docker') + from(configurations.js) { + into 'static' + } + from (dockerLicenses.get().outputs) { + into 'licenses' + } + into syncDir +} + +Docker.registerDockerImage(project, 'buildDocker') { + inputDir.set syncDir + inputs.files Docker.registryFiles(project, 'nginx-base') + inputs.files prepareDocker.get().outputs.files + images.add('deephaven/web:local-build') +} + +assemble.dependsOn buildDocker diff --git a/docker/web/src/main/docker/Dockerfile b/docker/web/src/main/docker/Dockerfile new file mode 100644 index 00000000000..a8da545ddd3 --- /dev/null +++ b/docker/web/src/main/docker/Dockerfile @@ -0,0 +1,10 @@ +FROM deephaven/nginx-base:local-build + +COPY licenses/ / +COPY nginx/default.conf /etc/nginx/conf.d/ +COPY nginx/nginx.conf /etc/nginx/ +COPY nginx/99-init-notebooks.sh /docker-entrypoint.d + +COPY static/ /usr/share/nginx/html + +VOLUME /tmp diff --git a/web/client-ide/nginx/99-init-notebooks.sh b/docker/web/src/main/docker/nginx/99-init-notebooks.sh similarity index 100% rename from web/client-ide/nginx/99-init-notebooks.sh rename to docker/web/src/main/docker/nginx/99-init-notebooks.sh diff --git a/web/client-ide/nginx/default.conf b/docker/web/src/main/docker/nginx/default.conf similarity index 100% rename from web/client-ide/nginx/default.conf rename to docker/web/src/main/docker/nginx/default.conf diff --git a/web/client-ide/nginx/nginx.conf b/docker/web/src/main/docker/nginx/nginx.conf similarity index 100% rename from web/client-ide/nginx/nginx.conf rename to docker/web/src/main/docker/nginx/nginx.conf diff --git a/proto/raw-js-openapi/build.gradle b/proto/raw-js-openapi/build.gradle index 12cc8b52e3b..cde0fdb7f33 100644 --- a/proto/raw-js-openapi/build.gradle +++ b/proto/raw-js-openapi/build.gradle @@ -7,7 +7,7 @@ evaluationDependsOn ':proto:proto-backplane-grpc' evaluationDependsOn Docker.registryProject('node') def backplaneProject = project(':proto:proto-backplane-grpc') -def webpackSourcesLocation = "${buildDir}/dhapi" +def webpackSourcesLocation = layout.buildDirectory.dir("${buildDir}/dhapi") Docker.registerDockerTask(project, 'webpackSources') { copyIn { @@ -30,12 +30,22 @@ Docker.registerDockerTask(project, 'webpackSources') { from ('Dockerfile') from ('../package.json') from ('../package-lock.json') - } parentContainers = [ Docker.registryTask(project, 'node') ] imageName = 'deephaven/js-out:local-build' containerOutPath = '/usr/src/app/raw-js-openapi/build/js-out' copyOut { - into(webpackSourcesLocation) + include 'dh-internal.js' + into(webpackSourcesLocation.get().dir('jsapi')) + } +} + +configurations { + js +} + +artifacts { + js(webpackSourcesLocation) { + builtBy webpackSources } } diff --git a/settings.gradle b/settings.gradle index a1c152583e5..c01fb821954 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,6 +17,7 @@ String[] mods = [ 'Util', 'Numerics', 'TableLogger', 'Plot', // new web projects; these modules are intended to form a complete, modular web application, // with heavy dependency isolation that should enable very fast rebuilds. String[] webMods = [ + 'web', 'web-client-api', // compiled javascript api client 'web-client-ide', // IDE-only additions to open-api javascript client 'web-client-ui', // React IDE client app @@ -245,6 +246,9 @@ project(':docker-runtime-base').projectDir = file('docker/runtime-base') include(':docker-server') project(':docker-server').projectDir = file('docker/server') +include(':docker-web') +project(':docker-web').projectDir = file('docker/web') + include(':docker-server-slim') project(':docker-server-slim').projectDir = file('docker/server-slim') diff --git a/web/client-ide/client-ide.gradle b/web/client-ide/client-ide.gradle index c6c82646546..07e70372112 100644 --- a/web/client-ide/client-ide.gradle +++ b/web/client-ide/client-ide.gradle @@ -1,57 +1,37 @@ -import io.deephaven.tools.License - plugins { id 'com.bmuschko.docker-remote-api' } -evaluationDependsOn ':web-client-ui' -evaluationDependsOn ':proto:raw-js-openapi' evaluationDependsOn Docker.registryProject('nginx-base') apply from: "$rootDir/gradle/web-client.gradle" +configurations { + js +} + dependencies { compile project(':web-client-api') compile project(':open-api-lang-parser') + + js project(path: ':proto:raw-js-openapi', configuration: 'js') } GwtTools.gwtCompile project, 'io.deephaven.ide.DeephavenIde', 'Create a jar of javascript for web IDE' -// deephaven/dhide -Task dhide = project(':web-client-ui').tasks.findByName('ideClientMakeImage') - -// deephaven/js-out -Task jsOut = project(':proto:raw-js-openapi').tasks.findByName('webpackSourcesMakeImage') - -Task gwtc = tasks.getByName('gwtCompile') - -def dockerLicenses = License.createFrom(project).syncDockerLicense() - -def prepareDocker = project.tasks.register('prepareDocker', Sync) { - // TODO(deephaven-core#1596): Remove extra dependencies for build-ci.yml - // Note: GH actions currently prepares docker via gradle, but does its own building via - // a native GH action. As such, we need to make sure that the prepare also invokes the - // necessarily build pre-reqs. If GH actions eventually calls buildDocker instead, we - // can remove these dependencies. - inputs.files([dhide, jsOut].each { t -> t.outputs.files }) - inputs.files Docker.registryFiles(project, 'nginx-base') - - into "${buildDir}/docker" - from(gwtc.outputs.files) { - include("dhapi/**") +def jsOutput = layout.buildDirectory.dir('js') +def gwtOutput = tasks.register('gwtOutput', Sync) { + includeEmptyDirs = false + from(tasks.getByName('gwtCompile').outputs.files) { + // only copy the dhapi module, and don't give it a wrapper directory + include 'dhapi/**' + eachFile { it.path = 'jsapi/' + it.path.substring('dhapi/'.length()) } } - from (dockerLicenses.get().outputs) { - into 'licenses' - } - from 'docker/Dockerfile' - from 'nginx/default.conf' - from 'nginx/nginx.conf' - from 'nginx/99-init-notebooks.sh' + into jsOutput } -Docker.registerDockerImage(project, 'buildDocker') { - inputs.files([prepareDocker.get(), dhide, jsOut].each { t -> t.outputs.files }) - inputs.files Docker.registryFiles(project, 'nginx-base') - //buildArgs.put('DEEPHAVEN_VERSION', "${project.version}") - images.add('deephaven/web:local-build') +artifacts { + js(jsOutput) { + builtBy gwtOutput + } } diff --git a/web/client-ide/docker/Dockerfile b/web/client-ide/docker/Dockerfile deleted file mode 100644 index 14459fd4564..00000000000 --- a/web/client-ide/docker/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM deephaven/dhide:local-build as dhide - -FROM deephaven/js-out:local-build as js-out - -FROM deephaven/nginx-base:local-build - -COPY --from=dhide /usr/src/app/package/build /usr/share/nginx/html/ide -COPY --from=js-out /usr/src/app/raw-js-openapi/build/js-out /usr/share/nginx/html/jsapi -COPY licenses/ / -COPY dhapi /usr/share/nginx/html/jsapi -COPY default.conf /etc/nginx/conf.d/ -COPY nginx.conf /etc/nginx/ -COPY 99-init-notebooks.sh /docker-entrypoint.d - -VOLUME /tmp \ No newline at end of file diff --git a/web/client-ui/client-ui.gradle b/web/client-ui/client-ui.gradle index 99aab5c764b..8847ebcbcd4 100644 --- a/web/client-ui/client-ui.gradle +++ b/web/client-ui/client-ui.gradle @@ -4,7 +4,8 @@ plugins { evaluationDependsOn Docker.registryProject('node') -Docker.registerDockerTask(project, 'ideClient') { +def dhUi = layout.buildDirectory.dir('dhide') +def ui = Docker.registerDockerTask(project, 'ui') { copyIn { from file('Dockerfile') } @@ -12,6 +13,16 @@ Docker.registerDockerTask(project, 'ideClient') { containerOutPath = '/usr/src/app/package/build' imageName = 'deephaven/dhide:local-build' copyOut { - into "${buildDir}/dhide" + into dhUi.get().dir('ide') + } +} + +configurations { + js +} + +artifacts { + js(dhUi) { + builtBy ui } } diff --git a/web/web.gradle b/web/web.gradle new file mode 100644 index 00000000000..0515657d273 --- /dev/null +++ b/web/web.gradle @@ -0,0 +1,24 @@ +configurations { + js + jsJar { + transitive = false + } +} + +dependencies { + js project(path: ':web-client-ui', configuration: 'js') + js project(path: ':web-client-ide', configuration: 'js') +} + +/** + * Provides a jar full of static js/html/css that can be served from jetty + */ +def ideClientJsJar = tasks.register('ideClientJsJar', Jar) { + archivesBaseName = "deephaven-web" + from configurations.js +} + +artifacts { + jsJar ideClientJsJar + js layout.buildDirectory.dir('empty') +}