Skip to content

feat: add Forgejo module#3556

Merged
mdelapenya merged 9 commits intotestcontainers:mainfrom
s04:feat/add-forgejo-module
Mar 9, 2026
Merged

feat: add Forgejo module#3556
mdelapenya merged 9 commits intotestcontainers:mainfrom
s04:feat/add-forgejo-module

Conversation

@s04
Copy link
Copy Markdown
Contributor

@s04 s04 commented Feb 20, 2026

Summary

  • Add a new testcontainers module for Forgejo, a self-hosted Git forge (community-driven fork of Gitea)
  • The module scaffolded with modulegen and enhanced with Forgejo-specific configuration
  • Container starts with SQLite and INSTALL_LOCK=true pre-configured for immediate test use

Features

  • Automatic admin user creation via PostReadies lifecycle hook (runs forgejo admin user create as git user)
  • ConnectionString() returns the HTTP URL for the Forgejo instance
  • SSHConnectionString() returns the SSH endpoint for Git operations
  • WithAdminCredentials(username, password, email) option to customize the admin user
  • WithConfig(section, key, value) option for arbitrary Forgejo configuration via FORGEJO__section__key env vars
  • Health check via /api/healthz endpoint

Test plan

  • TestForgejo - Container starts, health endpoint returns 200, connection string works, default admin creds set
  • TestForgejoWithAdminCredentials - Custom admin credentials work, API authentication succeeds
  • TestForgejoSSHEndpoint - SSH endpoint is available
  • ExampleRun - Example test passes
  • make lint passes with 0 issues
  • go vet passes

🤖 Generated with Claude Code

Add a new testcontainers module for Forgejo, a self-hosted Git forge.

The module provides:
- Container startup with SQLite and INSTALL_LOCK pre-configured
- Automatic admin user creation via PostReadies lifecycle hook
- ConnectionString() and SSHConnectionString() helper methods
- WithAdminCredentials() option for custom admin setup
- WithConfig() option for arbitrary Forgejo configuration via
  FORGEJO__section__key environment variables
- Health check via /api/healthz endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@s04 s04 requested a review from a team as a code owner February 20, 2026 00:45
@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 20, 2026

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 5dc7000
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/69aeb8f307a3e90008aa6893
😎 Deploy Preview https://deploy-preview-3556--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new Forgejo testcontainers module with implementation, docs, tests, example, workspace and CI/config updates, module-local go.mod, and a Makefile; exposes a Container type, Run function, connection helpers, and options for admin credentials and config.

Changes

Cohort / File(s) Summary
Repository config & IDE workspace
\.github/dependabot.yml, .vscode/.testcontainers-go.code-workspace, mkdocs.yml
Enable Dependabot for modules/forgejo, add VS Code workspace folder entry for modules/forgejo, and add docs/modules/forgejo.md to site navigation.
Documentation
docs/modules/forgejo.md
Add module documentation covering usage, Run signature, options (admin creds, config), container methods and examples.
Module implementation
modules/forgejo/forgejo.go
New package implementing Container (embeds testcontainers.Container and stores admin creds), Run (starts container, config via env, attaches post-readies hook to create admin user), ConnectionString/SSHConnectionString, and option helpers WithAdminCredentials and WithConfig.
Tests & examples
modules/forgejo/forgejo_test.go, modules/forgejo/examples_test.go
Add integration tests and example verifying startup, health/API access, default and overridden admin credentials, SSH endpoint, and proper cleanup.
Module build & deps
modules/forgejo/Makefile, modules/forgejo/go.mod
Add module-local go.mod (Go 1.24, test deps, local replace) and Makefile delegating to shared tests target.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Run as "forgejo.Run()"
    participant TC as "testcontainers"
    participant Env as "Container Env"
    participant PostReady as "Post-Readies Hook"
    participant CLI as "forgejo CLI"

    Client->>Run: Run(ctx, image, opts...)
    Run->>TC: Create & start container with env/options
    TC->>TC: Container becomes ready
    TC->>PostReady: Trigger post-readies hooks
    PostReady->>Env: Read admin creds / config from env
    PostReady->>CLI: Exec forgejo CLI to create admin user
    CLI-->>PostReady: Command result
    PostReady-->>Run: Hook completes
    Run-->>Client: Return *forgejo.Container (with AdminUsername/AdminPassword)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

enhancement

Suggested reviewers

  • mdelapenya

Poem

🐰 I hopped a patch into the tree,
Forgejo buds for testing, fresh and free.
Containers hum and admins appear,
Docs and examples bring them near.
A rabbit cheers — the build is clear!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add Forgejo module' clearly and concisely summarizes the main change: adding a new Forgejo module to the testcontainers project.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the module's features, configuration, connection helpers, options, health checks, and test plan.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
modules/forgejo/forgejo.go (2)

56-73: Duplicated credential-extraction logic — extract a helper.

The pattern of scanning inspect.Config.Env to parse FORGEJO_ADMIN_USERNAME, FORGEJO_ADMIN_PASSWORD, and FORGEJO_ADMIN_EMAIL appears verbatim in both the PostReadies hook (lines 62–73) and the post-startup block of Run (lines 113–125). Consider extracting it into a small private helper:

// extractAdminCredentials returns the first matching values for the three
// FORGEJO_ADMIN_* env vars, falling back to the supplied defaults.
func extractAdminCredentials(env []string) (username, password, email string) {
    username, password, email = defaultUser, defaultPassword, defaultEmail
    for _, e := range env {
        if v, ok := strings.CutPrefix(e, "FORGEJO_ADMIN_USERNAME="); ok {
            username = v
        }
        if v, ok := strings.CutPrefix(e, "FORGEJO_ADMIN_PASSWORD="); ok {
            password = v
        }
        if v, ok := strings.CutPrefix(e, "FORGEJO_ADMIN_EMAIL="); ok {
            email = v
        }
    }
    return
}

Both call sites can then simply call extractAdminCredentials(inspect.Config.Env).

Also applies to: 113-125

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo.go` around lines 56 - 73, Extract the duplicated
env-parsing logic into a small private helper named extractAdminCredentials that
accepts []string and returns (username, password, email) defaulting to
defaultUser/defaultPassword/defaultEmail; replace the loop in the PostReadies
anonymous hook (the func(ctx context.Context, container
testcontainers.Container) error block) and the similar loop in Run's
post-startup block with calls to extractAdminCredentials(inspect.Config.Env) so
both sites reuse the single function.

30-128: Double container.Inspect call — consider reusing the result.

container.Inspect(ctx) is called once inside the PostReadies hook (line 57) and again immediately after testcontainers.Run returns (line 108). Since both calls happen on the same, fully-started container, the second inspect could be avoided by storing the credentials in a closure variable that the hook populates, then reading them after Run returns.

This isn't a correctness problem (two inspect calls are cheap and idempotent), but it does avoid an unnecessary round-trip to the Docker daemon.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo.go` around lines 30 - 128, The code calls
container.Inspect both inside the PostReadies hook (adminHook) and again after
testcontainers.Run in Run; create closure variables (e.g., hookAdminUser,
hookAdminPass, hookAdminEmail and a boolean like hookCredsSet) in Run, have the
adminHook (PostReadies) populate those instead of only reading local inspect,
then after testcontainers.Run use those closure values to set
Container.AdminUsername/AdminPassword if hookCredsSet is true; keep a fallback
to call ctr.Inspect only if the hook did not populate the credentials. This
updates adminHook/PostReadies and the post-Run credential retrieval logic in Run
to avoid the redundant container.Inspect call.
modules/forgejo/forgejo_test.go (3)

72-74: TestForgejoSSHEndpoint — consider asserting the SSH endpoint format.

require.NotEmpty confirms a non-blank string but won't catch a malformed value (e.g., wrong scheme, missing port). A lightweight prefix/regex check would make the test more meaningful without significant overhead.

♻️ Example assertion
 	require.NotEmpty(t, sshStr)
+	require.True(t, strings.HasPrefix(sshStr, "ssh://"), "SSH connection string should start with ssh://")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo_test.go` around lines 72 - 74, The test currently
only checks sshStr is non-empty; strengthen it by asserting the SSH endpoint
format returned by ctr.SSHConnectionString(ctx). After require.NoError and
require.NotEmpty, add an assertion that sshStr matches the expected pattern (for
example starts with "ssh://" or "git@" and includes a hostname and port like
":22", or use a simple regexp matching "^ssh://[^/:]+(:[0-9]+)?$" depending on
your desired canonical form). Update TestForgejoSSHEndpoint to validate this
format so malformed endpoints are caught early.

27-27: Use http.NewRequestWithContext for consistency.

http.Get on this line ignores the test context, while TestForgejoWithAdminCredentials correctly uses http.NewRequestWithContext(ctx, ...). Although context.Background() never cancels, the inconsistency makes the intent unclear and will complicate any future timeout/cancellation wiring.

♻️ Proposed refactor
-	resp, err := http.Get(connStr + "/api/healthz")
-	require.NoError(t, err)
-	defer resp.Body.Close()
+	req, err := http.NewRequestWithContext(ctx, http.MethodGet, connStr+"/api/healthz", nil)
+	require.NoError(t, err)
+	resp, err := http.DefaultClient.Do(req)
+	require.NoError(t, err)
+	defer resp.Body.Close()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo_test.go` at line 27, The test uses http.Get which
ignores the test context—replace the call with creating a request via
http.NewRequestWithContext(ctx, http.MethodGet, connStr+"/api/healthz", nil) and
execute it with an http.Client (client.Do(req)) so the request uses the same ctx
as TestForgejoWithAdminCredentials; update the variable names (resp, err)
accordingly and ensure response.Body is closed as before. Use the existing ctx
variable in this test to keep behavior consistent with
TestForgejoWithAdminCredentials and support future cancellation/timeouts.

17-17: Consider pinning the image to a specific minor/patch version.

All three tests use codeberg.org/forgejo/forgejo:11, a floating major-version tag. As Forgejo releases new 11.x patches, the pulled image can silently change, potentially causing flaky or breaking tests unrelated to code changes.

Also applies to: 41-41, 68-68

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo_test.go` at line 17, Tests currently pull the
floating image tag "codeberg.org/forgejo/forgejo:11" via forgejo.Run which can
change as new 11.x patches are released; update each call (the forgejo.Run
invocations in modules/forgejo/forgejo_test.go) to use a pinned minor/patch tag
(e.g., "codeberg.org/forgejo/forgejo:11.<minor>.<patch>") or better, introduce a
single test-level constant (e.g., forgejoImage) and replace the three inline
literal usages with that constant so all tests use the same pinned version.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/modules/forgejo.md`:
- Around line 13-15: The fenced code block containing the command "go get
github.com/testcontainers/testcontainers-go/modules/forgejo" lacks a language
specifier (MD040); update the opening fence from ``` to ```sh (or ```bash) so
the block becomes a shell-highlighted code fence, ensuring the markdownlint rule
passes.

In `@modules/forgejo/forgejo.go`:
- Around line 142-159: WithAdminCredentials and WithConfig assume req.Env is
initialized and will panic on a nil map when a caller passes a
GenericContainerRequest{} directly; update both functions (WithAdminCredentials
and WithConfig) to check if req.Env == nil and initialize it to
make(map[string]string) before writing entries so they safely set
FORGEJO_ADMIN_* and FORGEJO__<section>__<key> environment variables even when
testcontainers.WithEnv was not applied.

---

Nitpick comments:
In `@modules/forgejo/forgejo_test.go`:
- Around line 72-74: The test currently only checks sshStr is non-empty;
strengthen it by asserting the SSH endpoint format returned by
ctr.SSHConnectionString(ctx). After require.NoError and require.NotEmpty, add an
assertion that sshStr matches the expected pattern (for example starts with
"ssh://" or "git@" and includes a hostname and port like ":22", or use a simple
regexp matching "^ssh://[^/:]+(:[0-9]+)?$" depending on your desired canonical
form). Update TestForgejoSSHEndpoint to validate this format so malformed
endpoints are caught early.
- Line 27: The test uses http.Get which ignores the test context—replace the
call with creating a request via http.NewRequestWithContext(ctx, http.MethodGet,
connStr+"/api/healthz", nil) and execute it with an http.Client (client.Do(req))
so the request uses the same ctx as TestForgejoWithAdminCredentials; update the
variable names (resp, err) accordingly and ensure response.Body is closed as
before. Use the existing ctx variable in this test to keep behavior consistent
with TestForgejoWithAdminCredentials and support future cancellation/timeouts.
- Line 17: Tests currently pull the floating image tag
"codeberg.org/forgejo/forgejo:11" via forgejo.Run which can change as new 11.x
patches are released; update each call (the forgejo.Run invocations in
modules/forgejo/forgejo_test.go) to use a pinned minor/patch tag (e.g.,
"codeberg.org/forgejo/forgejo:11.<minor>.<patch>") or better, introduce a single
test-level constant (e.g., forgejoImage) and replace the three inline literal
usages with that constant so all tests use the same pinned version.

In `@modules/forgejo/forgejo.go`:
- Around line 56-73: Extract the duplicated env-parsing logic into a small
private helper named extractAdminCredentials that accepts []string and returns
(username, password, email) defaulting to
defaultUser/defaultPassword/defaultEmail; replace the loop in the PostReadies
anonymous hook (the func(ctx context.Context, container
testcontainers.Container) error block) and the similar loop in Run's
post-startup block with calls to extractAdminCredentials(inspect.Config.Env) so
both sites reuse the single function.
- Around line 30-128: The code calls container.Inspect both inside the
PostReadies hook (adminHook) and again after testcontainers.Run in Run; create
closure variables (e.g., hookAdminUser, hookAdminPass, hookAdminEmail and a
boolean like hookCredsSet) in Run, have the adminHook (PostReadies) populate
those instead of only reading local inspect, then after testcontainers.Run use
those closure values to set Container.AdminUsername/AdminPassword if
hookCredsSet is true; keep a fallback to call ctr.Inspect only if the hook did
not populate the credentials. This updates adminHook/PostReadies and the
post-Run credential retrieval logic in Run to avoid the redundant
container.Inspect call.

Comment thread docs/modules/forgejo.md Outdated
Comment thread modules/forgejo/forgejo.go
- Extract extractAdminCredentials helper to deduplicate env parsing
- Use closure variables in PostReadies hook to avoid redundant Inspect call
- Add nil-map guards in WithAdminCredentials and WithConfig
- Use http.NewRequestWithContext instead of http.Get in tests
- Assert SSH connection string format in TestForgejoSSHEndpoint
- Add language specifier to markdown code block (MD040)
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
modules/forgejo/forgejo.go (2)

141-151: Consider validating empty credentials in WithAdminCredentials.

If any of username, password, or email is empty, the forgejo admin user create CLI call in the PostReadies hook will fail with an opaque error after the container has already started. An early check in the option func gives a clearer failure message.

🛡️ Proposed guard
 func WithAdminCredentials(username, password, email string) testcontainers.CustomizeRequestOption {
 	return func(req *testcontainers.GenericContainerRequest) error {
+		if username == "" || password == "" || email == "" {
+			return fmt.Errorf("WithAdminCredentials: username, password, and email must not be empty")
+		}
 		if req.Env == nil {
 			req.Env = make(map[string]string)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo.go` around lines 141 - 151, WithAdminCredentials
currently sets environment vars without validating inputs; add an early guard
inside WithAdminCredentials (the returned testcontainers.CustomizeRequestOption)
to check that username, password, and email are non-empty and return a
descriptive error if any are empty so the caller fails fast before container
startup; update the function to validate these three parameters and return an
error (e.g. fmt.Errorf with which field is missing) instead of proceeding to set
req.Env when a value is missing.

156-165: WithConfig silently accepts __ in section/key, producing ambiguous env-var names.

Forgejo splits config env vars on __ to derive section and key. If a caller passes a section or key string that itself contains __, the resulting FORGEJO__<section>__<key> will be misparse by Forgejo's config layer.

🛡️ Proposed guard
 func WithConfig(section, key, value string) testcontainers.CustomizeRequestOption {
 	return func(req *testcontainers.GenericContainerRequest) error {
+		if strings.Contains(section, "__") || strings.Contains(key, "__") {
+			return fmt.Errorf("WithConfig: section and key must not contain \"__\" (got section=%q, key=%q)", section, key)
+		}
 		if req.Env == nil {
 			req.Env = make(map[string]string)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo.go` around lines 156 - 165, WithConfig currently
builds env var names like envKey := fmt.Sprintf("FORGEJO__%s__%s", section, key)
but accepts section/key containing "__", which breaks Forgejo's split logic;
modify WithConfig to validate that neither section nor key contain the substring
"__" (e.g. using strings.Contains(section, "__") || strings.Contains(key, "__"))
and return a non-nil error from the returned
testcontainers.CustomizeRequestOption when validation fails, so callers get
immediate feedback instead of producing ambiguous env var names; update imports
if needed and keep the existing map initialization and env assignment logic
intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@modules/forgejo/forgejo.go`:
- Around line 141-164: The nil-map panic was fixed by ensuring both
WithAdminCredentials and WithConfig initialize req.Env when nil; confirm the
pattern in WithAdminCredentials and WithConfig (check the nil guard and
make(map[string]string) assignment) is present and consistent, and apply the
same guard to any other CustomContainerRequest mutators if they write to req.Env
to prevent future nil-map writes.

---

Nitpick comments:
In `@modules/forgejo/forgejo.go`:
- Around line 141-151: WithAdminCredentials currently sets environment vars
without validating inputs; add an early guard inside WithAdminCredentials (the
returned testcontainers.CustomizeRequestOption) to check that username,
password, and email are non-empty and return a descriptive error if any are
empty so the caller fails fast before container startup; update the function to
validate these three parameters and return an error (e.g. fmt.Errorf with which
field is missing) instead of proceeding to set req.Env when a value is missing.
- Around line 156-165: WithConfig currently builds env var names like envKey :=
fmt.Sprintf("FORGEJO__%s__%s", section, key) but accepts section/key containing
"__", which breaks Forgejo's split logic; modify WithConfig to validate that
neither section nor key contain the substring "__" (e.g. using
strings.Contains(section, "__") || strings.Contains(key, "__")) and return a
non-nil error from the returned testcontainers.CustomizeRequestOption when
validation fails, so callers get immediate feedback instead of producing
ambiguous env var names; update imports if needed and keep the existing map
initialization and env assignment logic intact.

- Validate that username, password, and email are non-empty in
  WithAdminCredentials to fail fast before container startup
- Validate that section and key don't contain "__" in WithConfig to
  prevent ambiguous env var names that break Forgejo's config parsing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@modules/forgejo/forgejo.go`:
- Around line 159-170: The WithConfig function currently allows empty section or
key which produces malformed env vars (e.g., FORGEJO____key or
FORGEJO__section__)—update WithConfig to validate that both section and key are
non-empty in addition to the existing "__" checks and return a clear error
(including the offending section/key) if either is empty; ensure this validation
occurs before constructing envKey and before mutating req.Env so req.Env and
envKey remain consistent on failure.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d33ba4f and e3cb125.

📒 Files selected for processing (1)
  • modules/forgejo/forgejo.go

Comment thread modules/forgejo/forgejo.go
Copy link
Copy Markdown
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @s04 thanks for adding this module. I left just a comment regarding the container fields being public.

Other than that, LGTM.

BTW, could you describe the interest in having this module in the project? We also have community modules that can be hosted in user repos, but linked in our modules catalog. I'm not against adding this here, but you know, you could iterate faster if hosting it yourself.

Comment thread modules/forgejo/forgejo.go Outdated
Make AdminUsername and AdminPassword private with getter methods,
matching the convention used by other modules (postgres, mysql, mssql).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
modules/forgejo/forgejo.go (1)

169-178: Empty section / key still not validated.

This is the same concern previously noted: empty values yield malformed env vars (e.g., FORGEJO____key). Consider rejecting empty strings before constructing the env key.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/forgejo/forgejo.go` around lines 169 - 178, The WithConfig function
builds env keys but doesn't validate that section and key are non-empty; update
WithConfig to check that section != "" and key != "" (in addition to the
existing "__" checks) and return a clear error (e.g., "section and key must not
be empty") when either is empty before constructing envKey and assigning to
req.Env; this change should be made inside the WithConfig closure so calls to
WithConfig with empty values fail early.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@modules/forgejo/forgejo.go`:
- Around line 65-67: The wait strategy currently hardcodes "3000" in
wait.ForHTTP(...).WithPort("3000"); change it to derive the port from the
module's defaultHTTPPort constant (defined at top of file) to keep consistency
with exposed ports. Replace the literal with a trimmed form of defaultHTTPPort
(e.g., strings.TrimSuffix(defaultHTTPPort, "/tcp")) or convert defaultHTTPPort
to a nat.Port and pass its Port() string into WithPort; update imports (add
"strings" if using TrimSuffix) and adjust the call in
testcontainers.WithWaitStrategy(wait.ForHTTP("/api/healthz").WithPort(...)) to
use that derived value instead of the hardcoded "3000".

---

Duplicate comments:
In `@modules/forgejo/forgejo.go`:
- Around line 169-178: The WithConfig function builds env keys but doesn't
validate that section and key are non-empty; update WithConfig to check that
section != "" and key != "" (in addition to the existing "__" checks) and return
a clear error (e.g., "section and key must not be empty") when either is empty
before constructing envKey and assigning to req.Env; this change should be made
inside the WithConfig closure so calls to WithConfig with empty values fail
early.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3cb125 and 1ed8388.

📒 Files selected for processing (2)
  • modules/forgejo/forgejo.go
  • modules/forgejo/forgejo_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • modules/forgejo/forgejo_test.go

Comment thread modules/forgejo/forgejo.go
s04 and others added 2 commits February 24, 2026 18:24
Reject empty section or key before constructing the env var name,
preventing malformed keys like FORGEJO____key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded "3000" with defaultHTTPPort to stay consistent
with the exposed ports declaration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mdelapenya
Copy link
Copy Markdown
Member

@s04 as you are building with Claude, are you using the SKILL from https://github.com/testcontainers/claude-skills? If so, what's your experience with it?

@mdelapenya
Copy link
Copy Markdown
Member

@s04 I added a few commits on top of your fixing the lint, also bump the Go version to 1.25 (recently updated in main)

Thanks!

@mdelapenya mdelapenya self-assigned this Mar 9, 2026
@mdelapenya mdelapenya added the feature New functionality or new behaviors on the existing one label Mar 9, 2026
Copy link
Copy Markdown
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for adding this module!

@mdelapenya mdelapenya merged commit 6f68717 into testcontainers:main Mar 9, 2026
17 checks passed
@s04
Copy link
Copy Markdown
Contributor Author

s04 commented Mar 9, 2026

@mdelapenya Thanks!

Regarding your question about https://github.com/testcontainers/claude-skills I have not used it partly because

However locally for other projects I've built custom skills for knowledge base and context refreshers and found them quite good so I think I'll give it a shot next time.

Appreciate the collab and the push over the finish line. Looking forward to using it, will try and keep an eye on this and extended it as needed.

Have a good start to your week.

mdelapenya added a commit that referenced this pull request Mar 9, 2026
…m-v2

* upstream/main: (269 commits)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/grafana-lgtm (#3563)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/toxiproxy (#3564)
  feat(azure): add lowkey vault container (#3542)
  feat(chroma): update to chroma 1.x (#3552)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3547)
  chore(deps): bump tj-actions/changed-files from 47.0.0 to 47.0.1 (#3546)
  chore(deps): bump actions/upload-artifact from 4.6.2 to 6.0.0 (#3545)
  ...
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…archive-temp

* upstream/main:
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/grafana-lgtm (#3563)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/toxiproxy (#3564)
mdelapenya added a commit that referenced this pull request Mar 10, 2026
…-action

* upstream/main: (22 commits)
  chore(deps): bump golang.org/x/mod in /modules/localstack (#3587)
  chore(deps): bump golang.org/x/mod in /modules/elasticsearch (#3585)
  chore(deps): bump golang.org/x/mod in /modules/redpanda (#3588)
  chore(deps): bump golang.org/x/mod in /modules/kafka (#3586)
  chore(deps): bump github.com/shirou/gopsutil/v4 from 4.25.12 to 4.26.2 (#3576)
  chore(deps): bump github.com/moby/go-archive from 0.1.0 to 0.2.0 (#3548)
  chore(deps): bump github.com/moby/term from 0.5.0 to 0.5.2 (#3081)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New functionality or new behaviors on the existing one

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants