diff --git a/registry/coder/modules/jfrog-oauth/README.md b/registry/coder/modules/jfrog-oauth/README.md index 56a9fc3b8..eaddfee6a 100644 --- a/registry/coder/modules/jfrog-oauth/README.md +++ b/registry/coder/modules/jfrog-oauth/README.md @@ -16,7 +16,7 @@ Install the JF CLI and authenticate package managers with Artifactory using OAut module "jfrog" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/jfrog-oauth/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://example.jfrog.io" username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username" @@ -27,6 +27,7 @@ module "jfrog" { pypi = ["pypi", "extra-index-pypi"] docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"] conda = ["conda", "conda-local"] + maven = ["maven", "maven-local"] } } ``` @@ -46,7 +47,7 @@ Configure the Python pip package manager to fetch packages from Artifactory whil module "jfrog" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/jfrog-oauth/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://example.jfrog.io" username_field = "email" @@ -75,7 +76,7 @@ The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extensio module "jfrog" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/jfrog-oauth/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://example.jfrog.io" username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username" diff --git a/registry/coder/modules/jfrog-oauth/main.test.ts b/registry/coder/modules/jfrog-oauth/main.test.ts index 093f34c36..0a8e62c09 100644 --- a/registry/coder/modules/jfrog-oauth/main.test.ts +++ b/registry/coder/modules/jfrog-oauth/main.test.ts @@ -150,4 +150,38 @@ EOF`; 'if [ -z "YES" ]; then\n not_configured conda', ); }); + it("generates a maven settings.xml with multiple repos", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "some-agent-id", + jfrog_url: fakeFrogUrl, + package_managers: JSON.stringify({ + maven: ["central", "snapshots", "local"], + }), + }); + + const coderScript = findResourceInstance(state, "coder_script"); + + expect(coderScript.script).toContain( + 'jf mvnc --global --repo-resolve "central"', + ); + + expect(coderScript.script).toContain(""); + expect(coderScript.script).toContain("central"); + expect(coderScript.script).toContain("snapshots"); + expect(coderScript.script).toContain("local"); + + expect(coderScript.script).toContain( + "http://localhost:8081/artifactory/central", + ); + expect(coderScript.script).toContain( + "http://localhost:8081/artifactory/snapshots", + ); + expect(coderScript.script).toContain( + "http://localhost:8081/artifactory/local", + ); + + expect(coderScript.script).toContain( + 'if [ -z "YES" ]; then\n not_configured maven', + ); + }); }); diff --git a/registry/coder/modules/jfrog-oauth/main.tf b/registry/coder/modules/jfrog-oauth/main.tf index ad7dbfdb1..922f64421 100644 --- a/registry/coder/modules/jfrog-oauth/main.tf +++ b/registry/coder/modules/jfrog-oauth/main.tf @@ -59,6 +59,7 @@ variable "package_managers" { pypi = optional(list(string), []) docker = optional(list(string), []) conda = optional(list(string), []) + maven = optional(list(string), []) }) description = <<-EOF A map of package manager names to their respective artifactory repositories. Unused package managers can be omitted. @@ -69,6 +70,7 @@ variable "package_managers" { pypi = ["YOUR_PYPI_REPO_KEY", "ANOTHER_PYPI_REPO_KEY"] docker = ["YOUR_DOCKER_REPO_KEY", "ANOTHER_DOCKER_REPO_KEY"] conda = ["YOUR_CONDA_REPO_KEY", "ANOTHER_CONDA_REPO_KEY"] + maven = ["YOUR_MAVEN_REPO_KEY", "ANOTHER_MAVEN_REPO_KEY"] } EOF } @@ -103,6 +105,9 @@ locals { conda_conf = templatefile( "${path.module}/conda.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.conda }) ) + maven_settings = templatefile( + "${path.module}/settings.xml.tftpl", merge(local.common_values, { REPOS = var.package_managers.maven }) + ) } data "coder_workspace" "me" {} @@ -133,6 +138,9 @@ resource "coder_script" "jfrog" { HAS_CONDA = length(var.package_managers.conda) == 0 ? "" : "YES" CONDA_CONF = local.conda_conf REPOSITORY_CONDA = try(element(var.package_managers.conda, 0), "") + HAS_MAVEN = length(var.package_managers.maven) == 0 ? "" : "YES" + MAVEN_SETTINGS = local.maven_settings + REPOSITORY_MAVEN = try(element(var.package_managers.maven, 0), "") } )) run_on_start = true diff --git a/registry/coder/modules/jfrog-oauth/run.sh b/registry/coder/modules/jfrog-oauth/run.sh index 38b041885..6e4e06425 100644 --- a/registry/coder/modules/jfrog-oauth/run.sh +++ b/registry/coder/modules/jfrog-oauth/run.sh @@ -94,6 +94,20 @@ EOF config_complete fi +# Configure Maven to use the Artifactory "maven" repository. +if [ -z "${HAS_MAVEN}" ]; then + not_configured maven +else + echo "☕ Configuring maven..." + jf mvnc --global --repo-resolve "${REPOSITORY_MAVEN}" + # Create Maven config directory if it doesn't exist + mkdir -p ~/.m2 + cat << EOF > ~/.m2/settings.xml +${MAVEN_SETTINGS} +EOF + config_complete +fi + # Install the JFrog vscode extension for code-server. if [ "${CONFIGURE_CODE_SERVER}" == "true" ]; then while ! [ -x /tmp/code-server/bin/code-server ]; do diff --git a/registry/coder/modules/jfrog-oauth/settings.xml.tftpl b/registry/coder/modules/jfrog-oauth/settings.xml.tftpl new file mode 100644 index 000000000..18da11123 --- /dev/null +++ b/registry/coder/modules/jfrog-oauth/settings.xml.tftpl @@ -0,0 +1,55 @@ + + + + +%{ for REPO in REPOS ~} + + ${REPO} + ${ARTIFACTORY_USERNAME} + ${ARTIFACTORY_ACCESS_TOKEN} + +%{ endfor ~} + + + + + artifactory + +%{ for REPO in REPOS ~} + + ${REPO} + ${JFROG_URL}/artifactory/${REPO} + + true + + + true + + +%{ endfor ~} + + +%{ for REPO in REPOS ~} + + ${REPO} + ${JFROG_URL}/artifactory/${REPO} + + true + + + true + + +%{ endfor ~} + + + + + + artifactory + + + diff --git a/registry/coder/modules/jfrog-token/README.md b/registry/coder/modules/jfrog-token/README.md index da7461066..065d7e8ea 100644 --- a/registry/coder/modules/jfrog-token/README.md +++ b/registry/coder/modules/jfrog-token/README.md @@ -13,7 +13,7 @@ Install the JF CLI and authenticate package managers with Artifactory using Arti ```tf module "jfrog" { source = "registry.coder.com/coder/jfrog-token/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://XXXX.jfrog.io" artifactory_access_token = var.artifactory_access_token @@ -23,6 +23,7 @@ module "jfrog" { pypi = ["pypi", "extra-index-pypi"] docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"] conda = ["conda", "conda-local"] + maven = ["maven", "maven-local"] } } ``` @@ -41,7 +42,7 @@ For detailed instructions, please see this [guide](https://coder.com/docs/v2/lat ```tf module "jfrog" { source = "registry.coder.com/coder/jfrog-token/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://YYYY.jfrog.io" artifactory_access_token = var.artifactory_access_token # An admin access token @@ -50,17 +51,19 @@ module "jfrog" { go = ["go-local"] pypi = ["pypi-local"] conda = ["conda-local"] + maven = ["maven-local"] } } ``` -You should now be able to install packages from Artifactory using both the `jf npm`, `jf go`, `jf pip` and `npm`, `go`, `pip`, `conda` commands. +You should now be able to install packages from Artifactory using both the `jf npm`, `jf go`, `jf pip` and `npm`, `go`, `pip`, `conda`, `maven` commands. ```shell jf npm install prettier jf go get github.com/golang/example/hello jf pip install requests conda install numpy +mvn clean install ``` ```shell @@ -68,6 +71,7 @@ npm install prettier go get github.com/golang/example/hello pip install requests conda install numpy +mvn clean install ``` ### Configure code-server with JFrog extension @@ -77,7 +81,7 @@ The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extensio ```tf module "jfrog" { source = "registry.coder.com/coder/jfrog-token/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://XXXX.jfrog.io" artifactory_access_token = var.artifactory_access_token @@ -97,7 +101,7 @@ data "coder_workspace" "me" {} module "jfrog" { source = "registry.coder.com/coder/jfrog-token/coder" - version = "1.1.0" + version = "1.2.0" agent_id = coder_agent.example.id jfrog_url = "https://XXXX.jfrog.io" artifactory_access_token = var.artifactory_access_token diff --git a/registry/coder/modules/jfrog-token/main.test.ts b/registry/coder/modules/jfrog-token/main.test.ts index 58d32a055..9e3097b0f 100644 --- a/registry/coder/modules/jfrog-token/main.test.ts +++ b/registry/coder/modules/jfrog-token/main.test.ts @@ -187,4 +187,39 @@ EOF`; 'if [ -z "YES" ]; then\n not_configured conda', ); }); + it("generates a maven settings.xml with multiple repos", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "some-agent-id", + jfrog_url: fakeFrogUrl, + artifactory_access_token: "XXXX", + package_managers: JSON.stringify({ + maven: ["central", "snapshots", "local"], + }), + }); + + const coderScript = findResourceInstance(state, "coder_script"); + + expect(coderScript.script).toContain( + 'jf mvnc --global --repo-resolve "central"', + ); + + expect(coderScript.script).toContain(""); + expect(coderScript.script).toContain("central"); + expect(coderScript.script).toContain("snapshots"); + expect(coderScript.script).toContain("local"); + + expect(coderScript.script).toContain( + `${fakeFrogUrl}/artifactory/central`, + ); + expect(coderScript.script).toContain( + `${fakeFrogUrl}/artifactory/snapshots`, + ); + expect(coderScript.script).toContain( + `${fakeFrogUrl}/artifactory/local`, + ); + + expect(coderScript.script).toContain( + 'if [ -z "YES" ]; then\n not_configured maven', + ); + }); }); diff --git a/registry/coder/modules/jfrog-token/main.tf b/registry/coder/modules/jfrog-token/main.tf index 227220772..4de91da5a 100644 --- a/registry/coder/modules/jfrog-token/main.tf +++ b/registry/coder/modules/jfrog-token/main.tf @@ -92,6 +92,7 @@ variable "package_managers" { pypi = optional(list(string), []) docker = optional(list(string), []) conda = optional(list(string), []) + maven = optional(list(string), []) }) description = <<-EOF A map of package manager names to their respective artifactory repositories. Unused package managers can be omitted. @@ -102,6 +103,7 @@ variable "package_managers" { pypi = ["YOUR_PYPI_REPO_KEY", "ANOTHER_PYPI_REPO_KEY"] docker = ["YOUR_DOCKER_REPO_KEY", "ANOTHER_DOCKER_REPO_KEY"] conda = ["YOUR_CONDA_REPO_KEY", "ANOTHER_CONDA_REPO_KEY"] + maven = ["YOUR_MAVEN_REPO_KEY", "ANOTHER_MAVEN_REPO_KEY"] } EOF } @@ -136,6 +138,9 @@ locals { conda_conf = templatefile( "${path.module}/conda.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.conda }) ) + maven_settings = templatefile( + "${path.module}/settings.xml.tftpl", merge(local.common_values, { REPOS = var.package_managers.maven }) + ) } # Configure the Artifactory provider @@ -179,6 +184,9 @@ resource "coder_script" "jfrog" { HAS_CONDA = length(var.package_managers.conda) == 0 ? "" : "YES" CONDA_CONF = local.conda_conf REPOSITORY_CONDA = try(element(var.package_managers.conda, 0), "") + HAS_MAVEN = length(var.package_managers.maven) == 0 ? "" : "YES" + MAVEN_SETTINGS = local.maven_settings + REPOSITORY_MAVEN = try(element(var.package_managers.maven, 0), "") } )) run_on_start = true diff --git a/registry/coder/modules/jfrog-token/run.sh b/registry/coder/modules/jfrog-token/run.sh index 5f6e59c4a..7f53da00a 100644 --- a/registry/coder/modules/jfrog-token/run.sh +++ b/registry/coder/modules/jfrog-token/run.sh @@ -93,6 +93,20 @@ EOF config_complete fi +# Configure Maven to use the Artifactory "maven" repository. +if [ -z "${HAS_MAVEN}" ]; then + not_configured maven +else + echo "☕ Configuring maven..." + jf mvnc --global --repo-resolve "${REPOSITORY_MAVEN}" + # Create Maven config directory if it doesn't exist + mkdir -p ~/.m2 + cat << EOF > ~/.m2/settings.xml +${MAVEN_SETTINGS} +EOF + config_complete +fi + # Install the JFrog vscode extension for code-server. if [ "${CONFIGURE_CODE_SERVER}" == "true" ]; then while ! [ -x /tmp/code-server/bin/code-server ]; do diff --git a/registry/coder/modules/jfrog-token/settings.xml.tftpl b/registry/coder/modules/jfrog-token/settings.xml.tftpl new file mode 100644 index 000000000..18da11123 --- /dev/null +++ b/registry/coder/modules/jfrog-token/settings.xml.tftpl @@ -0,0 +1,55 @@ + + + + +%{ for REPO in REPOS ~} + + ${REPO} + ${ARTIFACTORY_USERNAME} + ${ARTIFACTORY_ACCESS_TOKEN} + +%{ endfor ~} + + + + + artifactory + +%{ for REPO in REPOS ~} + + ${REPO} + ${JFROG_URL}/artifactory/${REPO} + + true + + + true + + +%{ endfor ~} + + +%{ for REPO in REPOS ~} + + ${REPO} + ${JFROG_URL}/artifactory/${REPO} + + true + + + true + + +%{ endfor ~} + + + + + + artifactory + + +