Skip to content

Add maven package manager support to JFrog modules #214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions registry/coder/modules/jfrog-oauth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ module "jfrog" {
go = ["go", "another-go-repo"]
pypi = ["pypi", "extra-index-pypi"]
docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"]
maven = ["maven-local", "maven-central"]
}
}
```

> Note
> This module does not install `npm`, `go`, `pip`, etc but only configure them. You need to handle the installation of these tools yourself.
> This module does not install `npm`, `go`, `pip`, `maven`, etc but only configure them. You need to handle the installation of these tools yourself.

## Prerequisites

Expand Down Expand Up @@ -68,6 +69,35 @@ jf pip install requests
pip install requests
```

### Configure Maven package manager

Configure Maven to fetch packages from Artifactory repositories.

```tf
module "jfrog" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jfrog-oauth/coder"
version = "1.0.19"
agent_id = coder_agent.example.id
jfrog_url = "https://example.jfrog.io"
username_field = "username"

package_managers = {
maven = ["maven-local", "maven-central"]
}
}
```

You should now be able to install packages from Artifactory using both the `jf mvn` and `mvn` command.

```shell
jf mvn install
```

```shell
mvn install
```

### Configure code-server with JFrog extension

The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extension) for VS Code allows you to interact with Artifactory from within the IDE.
Expand All @@ -82,9 +112,10 @@ module "jfrog" {
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"
configure_code_server = true # Add JFrog extension configuration for code-server
package_managers = {
npm = ["npm"]
go = ["go"]
pypi = ["pypi"]
npm = ["npm"]
go = ["go"]
pypi = ["pypi"]
maven = ["maven-local"]
}
}
```
Expand Down
94 changes: 94 additions & 0 deletions registry/coder/modules/jfrog-oauth/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,98 @@ EOF`;
'if [ -z "YES" ]; then\n not_configured go',
);
});

it("generates maven settings with multiple repos", async () => {
const state = await runTerraformApply<TestVariables>(import.meta.dir, {
agent_id: "some-agent-id",
jfrog_url: fakeFrogUrl,
package_managers: JSON.stringify({
maven: ["maven-local", "maven-central"],
}),
});
const coderScript = findResourceInstance(state, "coder_script");
const mavenStanza = `cat << EOF > ~/.m2/settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>maven-local</id>
<username>${user}</username>
<password></password>
</server>
<server>
<id>maven-central</id>
<username>${user}</username>
<password></password>
</server>
</servers>
<profiles>
<profile>
<id>artifactory</id>
<repositories>
<repository>
<id>maven-local</id>
<name>maven-local</name>
<url>http://localhost:8081/artifactory/maven-local</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>maven-central</id>
<name>maven-central</name>
<url>http://localhost:8081/artifactory/maven-central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven-local</id>
<name>maven-local</name>
<url>http://localhost:8081/artifactory/maven-local</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>maven-central</id>
<name>maven-central</name>
<url>http://localhost:8081/artifactory/maven-central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>
EOF`;
expect(coderScript.script).toContain(mavenStanza);
expect(coderScript.script).toContain(
'jf mvnc --global --repo-resolve "maven-local" --repo-deploy "maven-local"',
);
expect(coderScript.script).toContain(
'if [ -z "YES" ]; then\n not_configured maven',
);
});
});
10 changes: 9 additions & 1 deletion registry/coder/modules/jfrog-oauth/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ variable "package_managers" {
go = optional(list(string), [])
pypi = optional(list(string), [])
docker = 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.
Expand All @@ -67,6 +68,7 @@ variable "package_managers" {
go = ["YOUR_GO_REPO_KEY", "ANOTHER_GO_REPO_KEY"]
pypi = ["YOUR_PYPI_REPO_KEY", "ANOTHER_PYPI_REPO_KEY"]
docker = ["YOUR_DOCKER_REPO_KEY", "ANOTHER_DOCKER_REPO_KEY"]
maven = ["YOUR_MAVEN_REPO_KEY", "ANOTHER_MAVEN_REPO_KEY"]
}
EOF
}
Expand All @@ -90,14 +92,17 @@ locals {
{
REPOS = [
for r in var.package_managers.npm :
strcontains(r, ":") ? zipmap(["SCOPE", "NAME"], ["${split(":", r)[0]}:", split(":", r)[1]]) : { SCOPE = "", NAME = r }
length(split(":", r)) > 1 ? zipmap(["SCOPE", "NAME"], ["${split(":", r)[0]}:", split(":", r)[1]]) : { SCOPE = "", NAME = r }
]
}
)
)
pip_conf = templatefile(
"${path.module}/pip.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.pypi })
)
maven_settings = templatefile(
"${path.module}/settings.xml.tftpl", merge(local.common_values, { REPOS = var.package_managers.maven })
)
}

data "coder_workspace" "me" {}
Expand Down Expand Up @@ -125,6 +130,9 @@ resource "coder_script" "jfrog" {
REPOSITORY_PYPI = try(element(var.package_managers.pypi, 0), "")
HAS_DOCKER = length(var.package_managers.docker) == 0 ? "" : "YES"
REGISTER_DOCKER = join("\n", formatlist("register_docker \"%s\"", var.package_managers.docker))
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
Expand Down
13 changes: 13 additions & 0 deletions registry/coder/modules/jfrog-oauth/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ else
fi
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}" --repo-deploy "${REPOSITORY_MAVEN}"
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
Expand Down
53 changes: 53 additions & 0 deletions registry/coder/modules/jfrog-oauth/settings.xml.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
%{ for REPO in REPOS ~}
<server>
<id>${REPO}</id>
<username>${ARTIFACTORY_USERNAME}</username>
<password>${ARTIFACTORY_ACCESS_TOKEN}</password>
</server>
%{ endfor ~}
</servers>
<profiles>
<profile>
<id>artifactory</id>
<repositories>
%{ for REPO in REPOS ~}
<repository>
<id>${REPO}</id>
<name>${REPO}</name>
<url>${JFROG_URL}/artifactory/${REPO}</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
%{ endfor ~}
</repositories>
<pluginRepositories>
%{ for REPO in REPOS ~}
<pluginRepository>
<id>${REPO}</id>
<name>${REPO}</name>
<url>${JFROG_URL}/artifactory/${REPO}</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
%{ endfor ~}
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>
23 changes: 14 additions & 9 deletions registry/coder/modules/jfrog-token/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,21 @@ module "jfrog" {
go = ["go", "another-go-repo"]
pypi = ["pypi", "extra-index-pypi"]
docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"]
maven = ["maven-local", "maven-central"]
}
}
```

For detailed instructions, please see this [guide](https://coder.com/docs/v2/latest/guides/artifactory-integration#jfrog-token) on the Coder documentation.

> Note
> This module does not install `npm`, `go`, `pip`, etc but only configure them. You need to handle the installation of these tools yourself.
> This module does not install `npm`, `go`, `pip`, `maven`, etc but only configure them. You need to handle the installation of these tools yourself.

![JFrog](../../.images/jfrog.png)

## Examples

### Configure npm, go, and pypi to use Artifactory local repositories
### Configure npm, go, pypi, and maven to use Artifactory local repositories

```tf
module "jfrog" {
Expand All @@ -47,25 +48,28 @@ module "jfrog" {
jfrog_url = "https://YYYY.jfrog.io"
artifactory_access_token = var.artifactory_access_token # An admin access token
package_managers = {
npm = ["npm-local"]
go = ["go-local"]
pypi = ["pypi-local"]
npm = ["npm-local"]
go = ["go-local"]
pypi = ["pypi-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` commands.
You should now be able to install packages from Artifactory using both the `jf npm`, `jf go`, `jf pip`, `jf mvn` and `npm`, `go`, `pip`, `mvn` commands.

```shell
jf npm install prettier
jf go get github.com/golang/example/hello
jf pip install requests
jf mvn install
```

```shell
npm install prettier
go get github.com/golang/example/hello
pip install requests
mvn install
```

### Configure code-server with JFrog extension
Expand All @@ -81,9 +85,10 @@ module "jfrog" {
artifactory_access_token = var.artifactory_access_token
configure_code_server = true # Add JFrog extension configuration for code-server
package_managers = {
npm = ["npm"]
go = ["go"]
pypi = ["pypi"]
npm = ["npm"]
go = ["go"]
pypi = ["pypi"]
maven = ["maven-local"]
}
}
```
Expand Down
10 changes: 9 additions & 1 deletion registry/coder/modules/jfrog-token/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ variable "package_managers" {
go = optional(list(string), [])
pypi = optional(list(string), [])
docker = 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.
Expand All @@ -100,6 +101,7 @@ variable "package_managers" {
go = ["YOUR_GO_REPO_KEY", "ANOTHER_GO_REPO_KEY"]
pypi = ["YOUR_PYPI_REPO_KEY", "ANOTHER_PYPI_REPO_KEY"]
docker = ["YOUR_DOCKER_REPO_KEY", "ANOTHER_DOCKER_REPO_KEY"]
maven = ["YOUR_MAVEN_REPO_KEY", "ANOTHER_MAVEN_REPO_KEY"]
}
EOF
}
Expand All @@ -123,14 +125,17 @@ locals {
{
REPOS = [
for r in var.package_managers.npm :
strcontains(r, ":") ? zipmap(["SCOPE", "NAME"], ["${split(":", r)[0]}:", split(":", r)[1]]) : { SCOPE = "", NAME = r }
length(split(":", r)) > 1 ? zipmap(["SCOPE", "NAME"], ["${split(":", r)[0]}:", split(":", r)[1]]) : { SCOPE = "", NAME = r }
]
}
)
)
pip_conf = templatefile(
"${path.module}/pip.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.pypi })
)
maven_settings = templatefile(
"${path.module}/settings.xml.tftpl", merge(local.common_values, { REPOS = var.package_managers.maven })
)
}

# Configure the Artifactory provider
Expand Down Expand Up @@ -171,6 +176,9 @@ resource "coder_script" "jfrog" {
REPOSITORY_PYPI = try(element(var.package_managers.pypi, 0), "")
HAS_DOCKER = length(var.package_managers.docker) == 0 ? "" : "YES"
REGISTER_DOCKER = join("\n", formatlist("register_docker \"%s\"", var.package_managers.docker))
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
Expand Down
Loading