Skip to content

Add Sonatype Nexus repository integration module #262

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 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e32a0b7
feat: add Sonatype Nexus repository integration module
MAVRICK-1 Jul 29, 2025
e2d8aad
Update registry/mavrickrishi/modules/nexus/main.tf
MAVRICK-1 Jul 29, 2025
2a892ad
Update registry/mavrickrishi/modules/nexus/main.tf
MAVRICK-1 Jul 29, 2025
20e9a32
Update registry/mavrickrishi/modules/nexus/main.tf
MAVRICK-1 Jul 29, 2025
af94e5b
fix: apply code formatting
MAVRICK-1 Jul 29, 2025
db7afc8
fixed changes
MAVRICK-1 Jul 30, 2025
09905c3
Update registry/mavrickrishi/modules/nexus/README.md
MAVRICK-1 Jul 30, 2025
56f5990
Update registry/mavrickrishi/modules/nexus/main.tf
MAVRICK-1 Jul 30, 2025
3c890d0
Update registry/mavrickrishi/modules/nexus/main.tf
MAVRICK-1 Jul 30, 2025
88f8284
fix: update Nexus module configurations and README details
MAVRICK-1 Jul 30, 2025
f375e5f
feat: add support for Go package manager in Nexus module and update R…
MAVRICK-1 Jul 30, 2025
97d144b
feat: add test for configuring Go module proxy in Nexus module
MAVRICK-1 Jul 30, 2025
1bd0085
feat: Add Nexus Repository module and related configurations
MAVRICK-1 Jul 30, 2025
1b01b37
Merge branch 'main' into feat/nexus-repository-module
MAVRICK-1 Jul 30, 2025
5534564
Delete .icons/nexus.svg
MAVRICK-1 Jul 30, 2025
0854c5e
fix: remove false positive entries from typos.toml and adjust usernam…
MAVRICK-1 Jul 30, 2025
c520a19
fix: correct username entry for mavrickrishi in typos.toml
MAVRICK-1 Jul 30, 2025
f42da8f
Merge branch 'main' into feat/nexus-repository-module
MAVRICK-1 Aug 1, 2025
9f2fe38
Merge branch 'main' into feat/nexus-repository-module
MAVRICK-1 Aug 4, 2025
0a10b4d
Merge branch 'main' into feat/nexus-repository-module
MAVRICK-1 Aug 4, 2025
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
2 changes: 2 additions & 0 deletions .github/typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
muc = "muc" # For Munich location code
Hashi = "Hashi"
HashiCorp = "HashiCorp"
mavrickrishi = "mavrickrishi" # Username
mavrick = "mavrick" # Username

[files]
extend-exclude = ["registry/coder/templates/aws-devcontainer/architecture.svg"] #False positive
84 changes: 84 additions & 0 deletions .icons/nexus-repository.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions registry/mavrickrishi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
display_name: mavrickrishi
bio: Coder module contributor
github: mavrick-1
status: community
---

# mavrickrishi

This directory contains Coder modules and templates created by mavrickrishi.

## Modules

- [nexus-repository](./modules/nexus-repository/) - Configure package managers to use Sonatype Nexus Repository
149 changes: 149 additions & 0 deletions registry/mavrickrishi/modules/nexus-repository/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
display_name: Sonatype Nexus Repository
description: Configure package managers to use Sonatype Nexus Repository for Maven, npm, PyPI, and Docker registries.
icon: ../../../../.icons/nexus-repository.svg
verified: true
tags: [integration, nexus-repository, maven, npm, pypi, docker]
---

# Sonatype Nexus Repository

Configure package managers (Maven, npm, Go, PyPI, Docker) to use [Sonatype Nexus Repository](https://help.sonatype.com/en/sonatype-nexus-repository.html) with API token authentication. This module provides secure credential handling, multiple repository support per package manager, and flexible username configuration.

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
maven = ["maven-public", "maven-releases"]
npm = ["npm-public", "@scoped:npm-private"]
go = ["go-public", "go-private"]
pypi = ["pypi-public", "pypi-private"]
docker = ["docker-public", "docker-private"]
}
}
```

## Requirements

- Nexus Repository Manager 3.x
- Valid API token or user credentials
- Package managers installed on the workspace (Maven, npm, Go, pip, Docker as needed)

> [!NOTE]
> This module configures package managers but does not install them. You need to handle the installation of Maven, npm, Go, Python pip, and Docker yourself.

## Examples

### Configure Maven to use Nexus repositories

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
maven = ["maven-public", "maven-releases", "maven-snapshots"]
}
}
```

### Configure npm with scoped packages

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
npm = ["npm-public", "@mycompany:npm-private"]
}
}
```

### Configure Go module proxy

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
go = ["go-public", "go-private"]
}
}
```

### Configure Python PyPI repositories

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
pypi = ["pypi-public", "pypi-private"]
}
}
```

### Configure Docker registries

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
docker = ["docker-public", "docker-private"]
}
}
```

### Use custom username

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_username = "custom-user"
nexus_password = var.nexus_api_token
package_managers = {
maven = ["maven-public"]
}
}
```

### Complete configuration for all package managers

```tf
module "nexus_repository" {
source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
nexus_url = "https://nexus.example.com"
nexus_password = var.nexus_api_token
package_managers = {
maven = ["maven-public", "maven-releases"]
npm = ["npm-public", "@company:npm-private"]
go = ["go-public", "go-private"]
pypi = ["pypi-public", "pypi-private"]
docker = ["docker-public", "docker-private"]
}
}
```
135 changes: 135 additions & 0 deletions registry/mavrickrishi/modules/nexus-repository/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { describe, expect, it } from "bun:test";
import {
executeScriptInContainer,
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "~test";

describe("nexus-repository", async () => {
await runTerraformInit(import.meta.dir);

testRequiredVariables(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-password"
});

it("configures Maven settings", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
package_managers: JSON.stringify({
maven: ["maven-public"]
})
});

const output = await executeScriptInContainer(state, "ubuntu:20.04");
expect(output.stdout.join("\n")).toContain("☕ Configuring Maven...");
expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
});

it("configures npm registry", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
package_managers: JSON.stringify({
npm: ["npm-public"]
})
});

const output = await executeScriptInContainer(state, "ubuntu:20.04");
expect(output.stdout.join("\n")).toContain("📦 Configuring npm...");
expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
});

it("configures PyPI repository", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
package_managers: JSON.stringify({
pypi: ["pypi-public"]
})
});

const output = await executeScriptInContainer(state, "ubuntu:20.04");
expect(output.stdout.join("\n")).toContain("🐍 Configuring pip...");
expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
});

it("configures multiple package managers", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
package_managers: JSON.stringify({
maven: ["maven-public"],
npm: ["npm-public"],
pypi: ["pypi-public"]
})
});

const output = await executeScriptInContainer(state, "ubuntu:20.04");
expect(output.stdout.join("\n")).toContain("☕ Configuring Maven...");
expect(output.stdout.join("\n")).toContain("📦 Configuring npm...");
expect(output.stdout.join("\n")).toContain("🐍 Configuring pip...");
expect(output.stdout.join("\n")).toContain("✅ Nexus repository configuration completed!");
});

it("handles empty package managers", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
package_managers: JSON.stringify({})
});

const output = await executeScriptInContainer(state, "ubuntu:20.04");
expect(output.stdout.join("\n")).toContain("🤔 no maven repository is set, skipping maven configuration.");
expect(output.stdout.join("\n")).toContain("🤔 no npm repository is set, skipping npm configuration.");
expect(output.stdout.join("\n")).toContain("🤔 no pypi repository is set, skipping pypi configuration.");
expect(output.stdout.join("\n")).toContain("🤔 no docker repository is set, skipping docker configuration.");
});

it("configures Go module proxy", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
package_managers: JSON.stringify({
go: ["go-public", "go-private"]
})
});

const output = await executeScriptInContainer(state, "ubuntu:20.04");
expect(output.stdout.join("\n")).toContain("🐹 Configuring Go...");
expect(output.stdout.join("\n")).toContain("Go proxy configured via GOPROXY environment variable");
expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
});

it("validates nexus_url format", async () => {
await expect(
runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "invalid-url",
nexus_password: "test-token",
package_managers: JSON.stringify({})
})
).rejects.toThrow();
});

it("validates username_field values", async () => {
await expect(
runTerraformApply(import.meta.dir, {
agent_id: "test-agent",
nexus_url: "https://nexus.example.com",
nexus_password: "test-token",
username_field: "invalid",
package_managers: JSON.stringify({})
})
).rejects.toThrow();
});
});
Loading