Skip to content

Conversation

@otaviof
Copy link
Collaborator

@otaviof otaviof commented Jan 5, 2026

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

    • Centralized application context and modular integration registration for richer CLI and installer behavior.
    • Standard MCP tools builder enables dynamic assembly of runtime tooling.
  • Chores

    • Broadened and standardized linting/formatting rules and exclusions.
    • Moved template reference to installer root; adjusted build metadata embedding.
    • Renamed Helm annotation keys across charts for a consistent prefix.
  • Documentation

    • README and topology docs updated to reflect path and annotation changes.

✏️ Tip: You can customize this high-level summary in your review settings.

- Moved `pkg/subcmd/interface.go` to `pkg/api/subcommand.go`
- Renamed Interface to SubCommand for clarity
- Merged Runner and NewRunner into `pkg/api/subcommand.go`
- Updated all subcommand implementations to use the new `api` package
- Deleted `pkg/subcmd/runner.go`

Assisted-by: Gemini
Decoupling the installer from hardcoded paths and enabling support for
generic filesystems.

- Add `pkg/framework/tarfs.go` with `NewTarFS` to create an `fs.FS` from
  embedded tarball bytes.
- Introduce `pkg/chartfs/overlay.go` with `OverlayFS` to support
  prioritized file lookups between "Embedded" and "Local" layers.
- Refactor `ChartFS` in `pkg/chartfs/chartfs.go` to wrap a single
  `fs.FS`, removing former constructors and hardcoded installer
  directory constants.
- Update `pkg/config`, `pkg/mcptools`, and `pkg/subcmd` to use
  dependency injection for `ChartFS`.
- Align all unit tests with the new API using `os.DirFS` for test
  fixtures.

Assisted-by: Gemini
Migrating `.golangci.yaml` to support v3 schema.
It decouples the core logic from hardcoded directory structures by
establishing the provided `fs.FS` as the installer root and centralizing
asset filename conventions.

- Established a Framework Contract by moving key assets to the installer
  root:
    - Moved 'values.yaml.tpl' to 'installer/values.yaml.tpl'.
    - Moved 'instructions.md' to 'installer/instructions.md'.
- Introduced 'pkg/api/types.go' to hold centralized constants
- Refactored the codebase to eliminate hardcoded filename strings.
- Decoupled MCP Server from 'go:embed'.
Implements the core framework entrypoint in `pkg/framework` including
the `App` structure. It introduces `NewTarFS` to handle embedded assets
and refactors ChartFS to accept any generic filesystem.

The `main` application is updated to bootstrap via the new framework
using an `OverlayFS` to merge embedded and local files.

Assisted-by: Gemini
Decouple integration logic from the core installer framework by
introducing a registry-based management system.

- Move integration lifecycle management to `pkg/framework/app.go`.
- Introduce `api.IntegrationModule` for pluggable integrations.
- Refactor `integrations.Manager` to be a generic registry, removing
  hardcoded integration instances.
- Use dependency injection to provide the Manager to Deploy and
  Integration subcommands.

Assisted-by: Gemini
Refactor MCP tools and server to use a dynamic application name instead
of `constants.AppName`.

Assisted-by: Gemini
Relocate MCP server implementation to framework package to:
- Avoid naming collision with mark3labs/mcp-go/mcp
- Establish as part of public framework API
- Align with installer framework architecture plan

File history preserved via git mv.
Introduces `MCPToolsBuilder` and `MCPToolsContext` to decouple tool
instantiation from the `mcpserver` subcommand. This allows injecting
custom tool sets and simplifies the main server logic.

- Move standard tool creation to `pkg/subcmd/mcptools.go`.
- Update `framework.App` to support custom tool builders and MCP image
  config.
- Ensure `MCPToolsContext` enforces `io.Discard` for logging to protect
  the MCP STDIO protocol.

Assisted-by: Gemini
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 5, 2026

@otaviof: This pull request references RHTAP-6067 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6067). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot requested review from Roming22 and jkopriva January 5, 2026 14:35
@openshift-ci openshift-ci bot added the approved label Jan 5, 2026
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 5, 2026

@otaviof: This pull request references RHTAP-6067 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6067). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai
Copy link

coderabbitai bot commented Jan 5, 2026

📝 Walkthrough
📝 Walkthrough

Walkthrough

Replaces root/cmd wiring with a framework App driven by AppContext; introduces AppContext and SubCommand API; layers filesystems via OverlayFS/ChartFS; centralizes annotations/constants; rewires MCP tools, integrations, and subcommands to use the new app/integration/module model; updates linter/formatter config and Helm annotation keys.

Changes

Cohort / File(s) Change summary (attention)
Linters & format
.golangci.yaml
Upgrade schema, replace granular linter toggles with enable list, add many linters, add exclusions and formatter config. Review new linter set and path exclusions.
CLI entrypoint & build
cmd/tssc/main.go, Makefile, .goreleaser.yaml
New main uses embedded tar FS and framework.NewApp; link-time version/commit moved to main.version/main.commitID. Verify build LDFlags and app init wiring.
Framework & app runtime
pkg/framework/app.go, pkg/framework/options.go, pkg/framework/tarfs.go, pkg/framework/mcpserver/mcpserver.go
New App type, options, tar->fs helper, and app-scoped MCP server constructors; App wires subcommands, integrations, and MCP image. Review lifecycle, flag propagation, and MCP image validation.
Filesystem & chartfs
pkg/chartfs/chartfs.go, pkg/chartfs/overlay.go, pkg/chartfs/chartfs_test.go
Replace dual FS with overlay fs.FS; add OverlayFS layering, new constructors, and adjust tests to use os.DirFS. Check path semantics and WithBaseDir behavior.
API surface & types
pkg/api/appcontext.go, pkg/api/subcommand.go, pkg/api/types.go
New AppContext, SubCommand interface and IntegrationModule type. Review public contracts and option semantics.
Subcommand model & modules
pkg/subcmd/* (many files), pkg/subcmd/modules.go, pkg/subcmd/mcptools.go, pkg/subcmd/mcptools.go, pkg/subcmd/mcptools.go
Replace local subcmd Interface with api.SubCommand; constructors now accept AppContext; introduce modules registry and standard modules; add standard MCP tools builder. High churn—verify signatures and wiring for every integration subcommand.
Integrations manager
pkg/integrations/manager.go
New modules map, Register, LoadModules, GetModules and changed constructor. Review module initialization, secret creation and registration flow.
MCP tools & context
pkg/mcptools/*.go (context, configtools, deploytools, integrationtools, notestool, statustool, topology, utils)
Tools now app-scoped (appName/appCtx), builder/context pattern added, constructors/signatures changed, many suffix-based names introduced. Review public tool names, constructors, and error messages.
Config & ConfigMap manager
pkg/config/*.go, hack/deploy.sh, integration-tests/scripts/install.sh, README.md
New NewConfigDefault requires ChartFS param; ConfigMapManager gains name/Selector and NewConfigMapManager signature changed to accept appName. Also values template path moved to installer/values.yaml.tpl. Check config retrieval, selector usage, and deploy script updates.
Constants & annotations
pkg/constants/constants.go removed/changed, pkg/annotations/annotations.go, pkg/resolver/annotations.go (removed)
Metadata constants moved: new pkg/annotations added, old constants removed; many files updated to use annotations.*. Validate annotation keys and RepoURI.
Resolver & topology
pkg/resolver/* (collection.go, topologybuilder.go, dependency.go, tests)
New NewCollection signature includes AppContext; NewTopologyBuilder accepts appCtx; dependency annotation keys switched to annotations package. Review tests and collection construction.
Installer charts & docs
installer/charts/**/Chart.yaml, installer/charts/_common/_helpers.tpl, docs/topology.md
Chart annotation keys renamed from tssc.redhat-appstudio.github.com/... to helmet.redhat-appstudio.github.com/...; docs updated. Ensure external consumers expect new keys.
Flags & version printing
pkg/flags/flags.go, pkg/flags/installer.go
ShowVersion now accepts appName/version/commitID; default values updated to use constants.ValuesFilename. Verify version plumbing from main into flags.
Misc tests & small updates
multiple *_test.go files, pkg/installer/job.go, pkg/k8s/delete_resources.go
Tests updated to use os.DirFS and new signatures; Job label selector moved to method; post-deploy selector uses annotations.PostDeploy. Check tests and label selector behavior.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Main
  participant TarFS
  participant App
  participant ChartFS
  participant IntegrManager as Integrations.Manager
  participant MCPBuilder as MCPToolsBuilder
  participant MCPServer

  User->>Main: run CLI
  Main->>TarFS: NewTarFS(embedded tarball)
  TarFS-->>Main: fs.FS
  Main->>ChartFS: New(overlay fs)
  Main->>App: NewApp(AppContext, ChartFS, options...)
  App->>IntegrManager: LoadModules(...)
  IntegrManager-->>App: modules registered
  App->>MCPBuilder: StandardMCPToolsBuilder()
  MCPBuilder-->>App: []mcptools.Interface
  App->>MCPServer: NewMCPServer(appCtx, builder, image)
  App->>MCPServer: Start / Run()
  MCPServer-->>User: expose MCP API / tools
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • Roming22
  • lcarva
  • dperaza4dustbit
  • jkopriva
  • lingyzhuang

"I hopped through code, a jaunty chap 🐇
New contexts, modules, and an overlay map.
Charts renamed, tools align,
Subcommands stitch, the app's design.
A carrot for reviewers — cheers! 🥕"

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.38% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'RHTAP-6103: Core Installer Framework' directly reflects the main architectural change—introducing a reusable installer framework—which is the primary focus of this large refactor affecting multiple subsystems.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 5, 2026

@otaviof: This pull request references RHTAP-6067 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6067). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Introduced a modular plugin system for integrations, allowing dynamic integration loading and management.

  • Enhanced MCP tools architecture with application-name parameterization for better tool organization.

  • Refactoring

  • Restructured application initialization to support a centralized plugin-based command framework.

  • Consolidated configuration file paths and references for consistency.

  • Chores

  • Updated linting configuration schema and expanded linter coverage.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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: 4

Fix all issues with AI Agents 🤖
In @.golangci.yaml:
- Around line 69-79: The golangci-lint config incorrectly uses a top-level
"formatters" section; remove that "formatters" block entirely and add the
formatters as linters under the existing "linters.enable" list (add gofmt,
gofumpt, goimports to linters.enable). Also move or merge any relevant exclusion
rules (generated/paths) into the appropriate golangci-lint "exclude" or
"linters-settings" sections if needed, ensuring only supported top-level keys
remain and that gofmt/gofumpt/goimports are enabled via "linters.enable".
- Around line 51-65: The current "exclusions" block is not valid golangci-lint
syntax; replace it with standard keys: move conditional rules under
"issues.exclude-rules" (translate your revive file-pattern rule into an
exclude-rule matching path: (.+)_test.go and linter: revive), move path globs
into "run.skip-dirs" or "run.skip-files" (e.g., third_party$, builtin$,
examples$), and put linter-specific options under "linters-settings" if needed;
ensure you remove the invalid "exclusions" top-level key and validate the YAML
with golangci-lint config parser.

In @cmd/tssc/main.go:
- Around line 31-35: The call to cfs.WithBaseDir("installer") silently ignores
errors (bcfs, err := cfs.WithBaseDir("installer"); err == nil { cfs = bcfs })
which can hide misconfiguration; change this to explicitly handle the error by
checking if err != nil and then return or exit with a clear error message that
includes err (or use process logger / fmt.Errorf) so the program fails fast
instead of continuing with the wrong cfs; update the block around WithBaseDir,
bcfs, and err to log/return the wrapped error (or call log.Fatalf/os.Exit(1))
rather than swallowing it.

In @pkg/framework/tarfs.go:
- Around line 10-13: NewTarFS currently returns the raw error from tarfs.New
with no context; change it to call tarfs.New(bytes.NewReader(tarball)), check
the returned err, and if non-nil wrap it with contextual text (e.g. "creating
tar fs" or "NewTarFS: failed to create tar fs") using fmt.Errorf("%s: %w", ...)
before returning; keep the function signature the same and return the wrapped
error and the fs on success.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/subcmd/integration_github.go (1)

78-90: panic for unimplemented --update could crash production usage.

Using panic for an unimplemented code path is risky if users accidentally invoke it. Consider returning an error instead:

🔎 Proposed fix
 func (g *IntegrationGitHub) Run() error {
 	if g.create {
 		return g.integration.Create(g.cmd.Context(), g.cfg)
 	}
 	if g.update {
-		// TODO: implement update.
-		panic(fmt.Sprintf(
-			"TODO: '%s integration github --update'", constants.AppName,
-		))
+		return fmt.Errorf("'%s integration github --update' is not yet implemented", constants.AppName)
 	}
 	return nil
 }
🧹 Nitpick comments (8)
pkg/integrations/manager.go (2)

93-109: LoadModules always returns nil - consider removing error return or using it.

The function signature returns an error but always returns nil. If error handling is planned for future validation (e.g., duplicate module names), that's fine. Otherwise, simplify the signature:

🔎 Option 1: Add duplicate detection
 func (m *Manager) LoadModules(
 	appName string,
 	logger *slog.Logger,
 	kube *k8s.Kube,
 	modules []api.IntegrationModule,
 ) error {
 	for _, mod := range modules {
+		if _, exists := m.modules[IntegrationName(mod.Name)]; exists {
+			return fmt.Errorf("duplicate integration module: %q", mod.Name)
+		}
 		impl := mod.Init(logger, kube)
 
 		secretName := fmt.Sprintf("%s-%s-integration", appName, mod.Name)
 		wrapper := integration.NewSecret(logger, kube, secretName, impl)
 
 		m.Register(mod, wrapper)
 	}
 	return nil
 }

57-64: Non-deterministic iteration order for GetModules.

Map iteration order in Go is randomized. If consumers depend on consistent ordering (e.g., for CLI help output or deterministic testing), consider sorting or using a slice to preserve insertion order.

pkg/subcmd/integration_jenkins.go (1)

3-12: Import ordering: standard library imports should precede third-party imports.

The api package import appears before log/slog. Go convention and most linters expect standard library imports first:

🔎 Suggested import ordering
 import (
+	"log/slog"
+
 	"github.com/redhat-appstudio/tssc-cli/pkg/api"
-	"log/slog"
 
 	"github.com/redhat-appstudio/tssc-cli/pkg/config"
 	"github.com/redhat-appstudio/tssc-cli/pkg/integration"
 	"github.com/redhat-appstudio/tssc-cli/pkg/k8s"
 
 	"github.com/spf13/cobra"
 )
pkg/subcmd/integration_github.go (1)

3-14: Import ordering: standard library imports should precede third-party imports.

Same issue as other files - api appears before fmt and log/slog:

🔎 Suggested import ordering
 import (
-	"github.com/redhat-appstudio/tssc-cli/pkg/api"
 	"fmt"
 	"log/slog"
 
+	"github.com/redhat-appstudio/tssc-cli/pkg/api"
 	"github.com/redhat-appstudio/tssc-cli/pkg/config"
 	"github.com/redhat-appstudio/tssc-cli/pkg/constants"
 	"github.com/redhat-appstudio/tssc-cli/pkg/integration"
 	"github.com/redhat-appstudio/tssc-cli/pkg/k8s"
 
 	"github.com/spf13/cobra"
 )
pkg/subcmd/integration_artifactory.go (1)

3-12: Import ordering: standard library imports should precede third-party imports.

The api package import appears before log/slog:

🔎 Suggested import ordering
 import (
-	"github.com/redhat-appstudio/tssc-cli/pkg/api"
 	"log/slog"
 
+	"github.com/redhat-appstudio/tssc-cli/pkg/api"
 	"github.com/redhat-appstudio/tssc-cli/pkg/config"
 	"github.com/redhat-appstudio/tssc-cli/pkg/integration"
 	"github.com/redhat-appstudio/tssc-cli/pkg/k8s"
 
 	"github.com/spf13/cobra"
 )
pkg/chartfs/overlay.go (1)

17-25: Consider adding nil safety checks for robustness.

The Open method assumes both Embedded and Local are non-nil. If either is nil, this will cause a panic at runtime.

🔎 Proposed defensive check
 func (o *OverlayFS) Open(name string) (fs.File, error) {
+	if o.Embedded == nil && o.Local == nil {
+		return nil, fs.ErrNotExist
+	}
+	if o.Embedded == nil {
+		return o.Local.Open(name)
+	}
 	f, err := o.Embedded.Open(name)
 	if err == nil {
 		return f, nil
 	}
 	if !errors.Is(err, fs.ErrNotExist) {
 		return nil, err
 	}
+	if o.Local == nil {
+		return nil, err
+	}
 	return o.Local.Open(name)
 }
pkg/subcmd/deploy.go (1)

115-127: Consider using dynamic appName in error messages.

The error message on lines 117-123 uses constants.AppName three times, while other parts of this PR (MCP tools, framework) use dynamic appName. This creates an inconsistency where the integration hint will always show the hardcoded app name regardless of how the framework is configured.

If dynamic naming should be fully consistent, consider passing appName to NewDeploy and storing it for use in these messages.

pkg/chartfs/chartfs.go (1)

19-27: LGTM!

The ReadFile and Open methods correctly delegate to the underlying fs.FS, implementing the fs.FS interface properly. The comment on line 24 has a trailing backtick that appears to be a typo.

🔎 Minor typo fix in comment
-// Open opens the named file. Implements "fs.FS" interface.`
+// Open opens the named file. Implements "fs.FS" interface.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f19c089 and 42d4c5b.

📒 Files selected for processing (60)
  • .golangci.yaml
  • README.md
  • cmd/tssc/main.go
  • hack/deploy.sh
  • installer/instructions.md
  • installer/values.yaml.tpl
  • integration-tests/scripts/install.sh
  • pkg/api/subcommand.go
  • pkg/api/types.go
  • pkg/chartfs/chartfs.go
  • pkg/chartfs/chartfs_test.go
  • pkg/chartfs/overlay.go
  • pkg/cmd/root.go
  • pkg/config/config.go
  • pkg/config/config_test.go
  • pkg/config/manager.go
  • pkg/constants/constants.go
  • pkg/engine/engine.go
  • pkg/engine/engine_test.go
  • pkg/flags/installer.go
  • pkg/framework/app.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/framework/options.go
  • pkg/framework/tarfs.go
  • pkg/hooks/hooks_test.go
  • pkg/integrations/manager.go
  • pkg/mcptools/configtools.go
  • pkg/mcptools/context.go
  • pkg/mcptools/deploytools.go
  • pkg/mcptools/integrationtools.go
  • pkg/mcptools/notestool.go
  • pkg/mcptools/statustool.go
  • pkg/mcptools/topology.go
  • pkg/mcptools/utils.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/resolver_test.go
  • pkg/resolver/topology_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/interface.go
  • pkg/subcmd/mcpserver.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/runner.go
  • pkg/subcmd/template.go
  • pkg/subcmd/topology.go
💤 Files with no reviewable changes (3)
  • pkg/subcmd/runner.go
  • pkg/cmd/root.go
  • pkg/subcmd/interface.go
🧰 Additional context used
📓 Path-based instructions (7)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • hack/deploy.sh
  • pkg/engine/engine.go
  • pkg/mcptools/utils.go
  • pkg/subcmd/integration_github.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/flags/installer.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • README.md
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/engine/engine_test.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/statustool.go
  • pkg/mcptools/context.go
  • cmd/tssc/main.go
  • pkg/config/manager.go
  • pkg/api/types.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • integration-tests/scripts/install.sh
  • pkg/api/subcommand.go
  • pkg/resolver/topology_test.go
  • pkg/constants/constants.go
  • pkg/framework/tarfs.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/chartfs/chartfs_test.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/chartfs/chartfs.go
  • pkg/resolver/resolver_test.go
  • pkg/integrations/manager.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_azure.go
  • pkg/mcptools/deploytools.go
  • pkg/config/config_test.go
  • pkg/mcptools/configtools.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/hooks/hooks_test.go
  • pkg/resolver/collection_test.go
  • pkg/chartfs/overlay.go
  • pkg/framework/app.go
  • pkg/mcptools/integrationtools.go
  • pkg/framework/options.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/dependency_test.go
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/engine/engine.go
  • pkg/mcptools/utils.go
  • pkg/subcmd/integration_github.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/flags/installer.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/engine/engine_test.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/statustool.go
  • pkg/mcptools/context.go
  • cmd/tssc/main.go
  • pkg/config/manager.go
  • pkg/api/types.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • pkg/api/subcommand.go
  • pkg/resolver/topology_test.go
  • pkg/constants/constants.go
  • pkg/framework/tarfs.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/chartfs/chartfs_test.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/chartfs/chartfs.go
  • pkg/resolver/resolver_test.go
  • pkg/integrations/manager.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_azure.go
  • pkg/mcptools/deploytools.go
  • pkg/config/config_test.go
  • pkg/mcptools/configtools.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/hooks/hooks_test.go
  • pkg/resolver/collection_test.go
  • pkg/chartfs/overlay.go
  • pkg/framework/app.go
  • pkg/mcptools/integrationtools.go
  • pkg/framework/options.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/dependency_test.go
pkg/engine/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use Helm SDK in pkg/engine for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Files:

  • pkg/engine/engine.go
  • pkg/engine/engine_test.go
pkg/subcmd/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

pkg/subcmd/**/*.go: Use cobra library for CLI command structure in the tssc-cli project
Define commands as structs in pkg/subcmd that implement a common interface
Use specific validateFlags() methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators
Inject dependencies like k8s.Kube and chartfs.ChartFS via constructors in command structs

Files:

  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/mcpserver.go
**/*_test.go

📄 CodeRabbit inference engine (GEMINI.md)

Use the standard testing package with github.com/onsi/gomega assertion library for tests

Files:

  • pkg/engine/engine_test.go
  • pkg/resolver/topology_test.go
  • pkg/chartfs/chartfs_test.go
  • pkg/resolver/resolver_test.go
  • pkg/config/config_test.go
  • pkg/hooks/hooks_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
pkg/resolver/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use pkg/resolver to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Files:

  • pkg/resolver/topology_test.go
  • pkg/resolver/resolver_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
pkg/chartfs/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Implement io.FS compatible abstraction in pkg/chartfs to provide access to embedded installer directory resources

Files:

  • pkg/chartfs/chartfs_test.go
  • pkg/chartfs/chartfs.go
  • pkg/chartfs/overlay.go
🧠 Learnings (25)
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/engine/**/*.go : Use Helm SDK in `pkg/engine` for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Applied to files:

  • pkg/engine/engine.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/engine/engine_test.go
  • pkg/subcmd/template.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/mcptools/notestool.go
  • pkg/mcptools/configtools.go
  • pkg/hooks/hooks_test.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • pkg/engine/engine.go
  • pkg/mcptools/utils.go
  • pkg/subcmd/integration_github.go
  • pkg/flags/installer.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/statustool.go
  • cmd/tssc/main.go
  • pkg/config/manager.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • pkg/api/subcommand.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_azure.go
  • pkg/mcptools/configtools.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/mcptools/integrationtools.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use specific `validateFlags()` methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators

Applied to files:

  • pkg/mcptools/utils.go
  • pkg/subcmd/integration_github.go
  • pkg/flags/installer.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_quay.go
  • pkg/api/subcommand.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_artifactory.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Define commands as structs in `pkg/subcmd` that implement a common interface

Applied to files:

  • pkg/mcptools/utils.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/statustool.go
  • cmd/tssc/main.go
  • pkg/api/types.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • pkg/api/subcommand.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/mcptools/integrationtools.go
📚 Learning: 2025-09-29T14:49:45.227Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/mcptools/configtools.go:0-0
Timestamp: 2025-09-29T14:49:45.227Z
Learning: In pkg/mcptools/configtools.go, the SettingsArg and ProductsArg constants are used for Gemini input generation, where Gemini uses these parameter names to generate input and the system reads the input content by these argument names.

Applied to files:

  • pkg/mcptools/utils.go
  • pkg/mcptools/statustool.go
  • pkg/mcptools/topology.go
  • pkg/mcptools/configtools.go
  • pkg/mcptools/integrationtools.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/mcptools/utils.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/mcptools/statustool.go
  • pkg/config/manager.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/subcmd/deploy.go
  • pkg/mcptools/notestool.go
  • .golangci.yaml
  • pkg/mcptools/integrationtools.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • pkg/mcptools/utils.go
  • pkg/subcmd/integration_github.go
  • pkg/flags/installer.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/engine/engine_test.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/statustool.go
  • pkg/mcptools/context.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • pkg/api/subcommand.go
  • pkg/resolver/topology_test.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/chartfs/chartfs_test.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/chartfs/chartfs.go
  • pkg/resolver/resolver_test.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_azure.go
  • pkg/config/config_test.go
  • pkg/mcptools/configtools.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/hooks/hooks_test.go
  • pkg/resolver/collection_test.go
  • pkg/framework/app.go
  • pkg/mcptools/integrationtools.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/dependency_test.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/integration/**/*.go : Define integrations in `pkg/integration` to connect to external services like GitHub, Quay, etc.

Applied to files:

  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/statustool.go
  • pkg/api/types.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_trustification.go
  • pkg/integrations/manager.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/mcptools/integrationtools.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Define interface definition at the top of service files, followed by service struct and implementation

Applied to files:

  • pkg/subcmd/integration_github.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_artifactory.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Regenerate mocks after modifying existing interfaces

Applied to files:

  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_artifactory.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `interface{}`, use the `any` alias instead

Applied to files:

  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_azure.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*.go : Use `go:embed` directive to embed `installer` directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Applied to files:

  • pkg/flags/installer.go
  • README.md
  • pkg/subcmd/installer.go
  • pkg/mcptools/statustool.go
  • cmd/tssc/main.go
  • pkg/config/config.go
  • pkg/chartfs/chartfs.go
  • pkg/mcptools/notestool.go
  • pkg/framework/app.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/chartfs/**/*.go : Implement `io.FS` compatible abstraction in `pkg/chartfs` to provide access to embedded installer directory resources

Applied to files:

  • pkg/flags/installer.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/engine/engine_test.go
  • pkg/subcmd/template.go
  • pkg/mcptools/statustool.go
  • cmd/tssc/main.go
  • pkg/resolver/topology_test.go
  • pkg/framework/tarfs.go
  • pkg/subcmd/integration.go
  • pkg/config/config.go
  • pkg/chartfs/chartfs_test.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/chartfs/chartfs.go
  • pkg/resolver/resolver_test.go
  • pkg/config/config_test.go
  • pkg/mcptools/configtools.go
  • pkg/hooks/hooks_test.go
  • pkg/resolver/collection_test.go
  • pkg/chartfs/overlay.go
  • pkg/framework/app.go
  • pkg/resolver/dependency_test.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/resolver/**/*.go : Use `pkg/resolver` to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Applied to files:

  • pkg/flags/installer.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/template.go
  • pkg/resolver/topology_test.go
  • pkg/config/config.go
  • pkg/mcptools/topology.go
  • pkg/subcmd/deploy.go
  • pkg/resolver/resolver_test.go
  • pkg/mcptools/configtools.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : All tests must use the `testing` package with `testify/assert` library

Applied to files:

  • pkg/subcmd/topology.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/chartfs/chartfs_test.go
  • pkg/config/config_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Use the `any` type alias instead of `interface{}` for generic types

Applied to files:

  • pkg/subcmd/integration_gitlab.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_service.go : Regenerate mocks after adding new service interfaces

Applied to files:

  • pkg/subcmd/integration_gitlab.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*_test.go : Use the standard `testing` package with `github.com/onsi/gomega` assertion library for tests

Applied to files:

  • pkg/chartfs/chartfs_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/testdata/** : Store test data in `testdata/` directory

Applied to files:

  • pkg/chartfs/chartfs_test.go
📚 Learning: 2025-08-27T18:30:02.411Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1190
File: pkg/resolver/resolver_test.go:52-67
Timestamp: 2025-08-27T18:30:02.411Z
Learning: In tssc-cli, there is a distinction between deployment namespace (where resources are deployed, referenced in values.yaml.tpl) and chart registration namespace (where Helm charts are registered, tested in resolver tests). These are different concepts and may use different namespace values.

Applied to files:

  • pkg/subcmd/deploy.go
📚 Learning: 2025-09-29T15:10:13.650Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/config/config.go:159-185
Timestamp: 2025-09-29T15:10:13.650Z
Learning: In the tssc-cli project, the UpdateMappingValue method in pkg/config/config.go should only update existing configuration keys and not create new ones. Adding new config entries is not allowed, so silent return when key is not found is the desired behavior.

Applied to files:

  • pkg/mcptools/configtools.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Check `.golangci.yml` for specific linter rule configurations

Applied to files:

  • .golangci.yaml
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Run all linters using 'make lint' with golangci-lint and custom configuration in .golangci.yml

Applied to files:

  • .golangci.yaml
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Format all Go files using `gofumpt` with 'make fmt'

Applied to files:

  • .golangci.yaml
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : All API methods should accept `options ...RequestOptionFunc` parameter

Applied to files:

  • pkg/framework/options.go
🧬 Code graph analysis (32)
pkg/subcmd/integration_github.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/flags/installer.go (1)
pkg/constants/constants.go (1)
  • ValuesFilename (22-22)
pkg/subcmd/integration_nexus.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_jenkins.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/installer.go (2)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/installer/installer.go (1)
  • Installer (24-32)
pkg/subcmd/config.go (2)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/config/config.go (1)
  • Config (30-36)
pkg/engine/engine_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/subcmd/template.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_acs.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/mcptools/context.go (5)
pkg/constants/constants.go (1)
  • AppName (7-7)
pkg/flags/flags.go (1)
  • Flags (18-25)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/integrations/manager.go (1)
  • Manager (20-23)
cmd/tssc/main.go (8)
pkg/framework/tarfs.go (1)
  • NewTarFS (11-13)
installer/embed.go (1)
  • InstallerTarball (9-9)
pkg/chartfs/overlay.go (1)
  • OverlayFS (10-13)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/framework/app.go (1)
  • NewApp (132-151)
pkg/constants/constants.go (1)
  • AppName (7-7)
pkg/framework/options.go (2)
  • WithShortDescription (19-23)
  • WithIntegrations (33-37)
pkg/subcmd/modules.go (1)
  • StandardModules (125-139)
pkg/config/manager.go (1)
pkg/constants/constants.go (1)
  • ConfigFilename (19-19)
pkg/api/types.go (3)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/integration/integration.go (1)
  • Integration (19-26)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/topology_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/framework/tarfs.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/subcmd/integration_gitlab.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_bitbucket.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_trustedartifactsigner.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration.go (2)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • IntegrationName (15-15)
pkg/api/subcommand.go (1)
  • NewRunner (36-47)
pkg/config/config.go (3)
pkg/constants/constants.go (1)
  • ConfigFilename (19-19)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/subcmd/config.go (1)
  • Config (21-36)
pkg/subcmd/deploy.go (3)
pkg/integrations/manager.go (1)
  • Manager (20-23)
pkg/resolver/topologybuilder.go (1)
  • TopologyBuilder (14-18)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_trustification.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/resolver_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/mcptools/notestool.go (1)
pkg/installer/job.go (2)
  • Job (22-26)
  • NewJob (298-304)
pkg/subcmd/integration_azure.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/config/config_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/subcmd/integration_artifactory.go (1)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/hooks/hooks_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/resolver/collection_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/framework/app.go (13)
pkg/constants/constants.go (1)
  • CommitID (37-37)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/api/types.go (1)
  • IntegrationModule (13-23)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • NewManager (112-117)
pkg/k8s/kube.go (2)
  • Kube (21-23)
  • NewKube (143-145)
pkg/mcptools/context.go (1)
  • MCPToolsBuilder (52-52)
pkg/subcmd/integration.go (1)
  • NewIntegration (16-83)
pkg/subcmd/mcptools.go (1)
  • StandardMCPToolsBuilder (13-15)
pkg/api/subcommand.go (2)
  • SubCommand (9-22)
  • NewRunner (36-47)
pkg/subcmd/config.go (1)
  • NewConfig (284-307)
pkg/subcmd/deploy.go (1)
  • NewDeploy (193-216)
pkg/subcmd/mcpserver.go (1)
  • NewMCPServer (89-115)
pkg/framework/options.go (1)
  • Option (9-9)
pkg/framework/options.go (4)
pkg/framework/app.go (1)
  • App (20-35)
pkg/constants/constants.go (1)
  • Version (33-33)
pkg/api/types.go (1)
  • IntegrationModule (13-23)
pkg/mcptools/context.go (1)
  • MCPToolsBuilder (52-52)
pkg/resolver/dependency_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)

@otaviof
Copy link
Collaborator Author

otaviof commented Jan 5, 2026

/retest

1 similar comment
@otaviof
Copy link
Collaborator Author

otaviof commented Jan 5, 2026

/retest

@otaviof otaviof changed the title RHTAP-6067: Core Installer Framework RHTAP-6103: Core Installer Framework Jan 5, 2026
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 5, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6067). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Introduced a modular plugin system for integrations, allowing dynamic integration loading and management.

  • Enhanced MCP tools architecture with application-name parameterization for better tool organization.

  • Refactoring

  • Restructured application initialization to support a centralized plugin-based command framework.

  • Consolidated configuration file paths and references for consistency.

  • Chores

  • Updated linting configuration schema and expanded linter coverage.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 5, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Introduced a modular plugin system for integrations, allowing dynamic integration loading and management.

  • Enhanced MCP tools architecture with application-name parameterization for better tool organization.

  • Refactoring

  • Restructured application initialization to support a centralized plugin-based command framework.

  • Consolidated configuration file paths and references for consistency.

  • Chores

  • Updated linting configuration schema and expanded linter coverage.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@otaviof
Copy link
Collaborator Author

otaviof commented Jan 6, 2026

/retest

Fixes bug where local file arguments required double "installer/" prefix
when using `tssc config --create installer/config.yaml`. Also used in
the `install.sh` CI script.
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 6, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Modular integration plugins with dynamic loading.

  • Installer app now exposes a cohesive application entry and configurable MCP tools (app-name driven).

  • Refactoring

  • Reworked command/subcommand wiring for a plugin-based CLI and layered filesystem support.

  • Consolidated template/config resolution to use centralized filename constants.

  • Chores

  • Upgraded linting/formatting config and expanded linter coverage.

  • Documentation

  • Updated README and deployment script references to new template path.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Moves MCP image configuration and version, commit-ID, and container
image from the framework to `main.go`.

Assisted-by: Claude
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 6, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Modular integration plugins with dynamic loading and a unified application entry (app-level Run/Command).

  • Standard MCP tools builder and installer app options for configurable MCP tooling.

  • Refactoring

  • Reworked CLI wiring to a plugin-based subcommand model and introduced an overlay filesystem approach.

  • Consolidated template/config filenames into centralized constants and updated callers.

  • Chores

  • Upgraded linting/formatting config and expanded lint coverage.

  • Documentation

  • Updated README and deployment scripts to the new template path.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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: 0

🧹 Nitpick comments (1)
cmd/tssc/main.go (1)

37-43: Consider extracting the image registry base path as a constant.

The hardcoded registry path quay.io/redhat-user-workloads/rhtap-shared-team-tenant/tssc-cli is specific to the tssc-cli project. While this is appropriate for cmd/tssc/main.go, if other binaries will reuse the framework with different images, consider defining this as a constant or making it configurable via environment variable for easier maintenance.

🔎 Optional refactor
+const mcpImageBase = "quay.io/redhat-user-workloads/rhtap-shared-team-tenant/tssc-cli"
+
 func main() {
     // ...
-    mcpImage := "quay.io/redhat-user-workloads/rhtap-shared-team-tenant/tssc-cli"
+    mcpImage := mcpImageBase
     if commitID == "" {
         mcpImage = fmt.Sprintf("%s:latest", mcpImage)
     } else {
         mcpImage = fmt.Sprintf("%s:%s", mcpImage, commitID)
     }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7eff5d and d8f8f12.

📒 Files selected for processing (7)
  • .goreleaser.yaml
  • Makefile
  • cmd/tssc/main.go
  • pkg/constants/constants.go
  • pkg/flags/flags.go
  • pkg/framework/app.go
  • pkg/framework/options.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/framework/options.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • pkg/constants/constants.go
  • cmd/tssc/main.go
  • pkg/flags/flags.go
  • Makefile
  • pkg/framework/app.go
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/constants/constants.go
  • cmd/tssc/main.go
  • pkg/flags/flags.go
  • pkg/framework/app.go
🧠 Learnings (14)
📓 Common learnings
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/chartfs/**/*.go : Implement `io.FS` compatible abstraction in `pkg/chartfs` to provide access to embedded installer directory resources

Applied to files:

  • cmd/tssc/main.go
  • pkg/framework/app.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • cmd/tssc/main.go
  • pkg/flags/flags.go
  • pkg/framework/app.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • cmd/tssc/main.go
  • pkg/flags/flags.go
📚 Learning: 2025-08-20T15:48:01.881Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.

Applied to files:

  • cmd/tssc/main.go
📚 Learning: 2025-09-29T15:10:13.650Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/config/config.go:159-185
Timestamp: 2025-09-29T15:10:13.650Z
Learning: In the tssc-cli project, the UpdateMappingValue method in pkg/config/config.go should only update existing configuration keys and not create new ones. Adding new config entries is not allowed, so silent return when key is not found is the desired behavior.

Applied to files:

  • cmd/tssc/main.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*.go : Use `go:embed` directive to embed `installer` directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Applied to files:

  • cmd/tssc/main.go
  • Makefile
  • pkg/framework/app.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Define commands as structs in `pkg/subcmd` that implement a common interface

Applied to files:

  • cmd/tssc/main.go
  • pkg/flags/flags.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/engine/**/*.go : Use Helm SDK in `pkg/engine` for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Applied to files:

  • cmd/tssc/main.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use specific `validateFlags()` methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators

Applied to files:

  • pkg/flags/flags.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/flags/flags.go
📚 Learning: 2025-09-29T14:49:45.227Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/mcptools/configtools.go:0-0
Timestamp: 2025-09-29T14:49:45.227Z
Learning: In pkg/mcptools/configtools.go, the SettingsArg and ProductsArg constants are used for Gemini input generation, where Gemini uses these parameter names to generate input and the system reads the input content by these argument names.

Applied to files:

  • pkg/flags/flags.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Use `make build` or `make` (default target) to build the application executable, rather than running plain `go build` manually

Applied to files:

  • Makefile
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Do not run plain `go build` or `go test` manually as you might miss build-time injections or prerequisites

Applied to files:

  • Makefile
🧬 Code graph analysis (1)
cmd/tssc/main.go (8)
pkg/framework/tarfs.go (1)
  • NewTarFS (11-13)
installer/embed.go (1)
  • InstallerTarball (9-9)
pkg/chartfs/overlay.go (1)
  • NewOverlayFS (17-22)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/framework/app.go (1)
  • NewApp (126-145)
pkg/constants/constants.go (1)
  • AppName (7-7)
pkg/framework/options.go (5)
  • WithVersion (12-16)
  • WithCommitID (19-23)
  • WithShortDescription (26-30)
  • WithIntegrations (40-44)
  • WithMCPImage (47-51)
pkg/subcmd/modules.go (1)
  • StandardModules (125-139)
🔇 Additional comments (11)
pkg/flags/flags.go (1)

66-69: LGTM! Clean parameterization of version display.

The signature change from using internal constants to accepting explicit parameters supports the framework's dynamic branding goals and improves testability.

Makefile (1)

80-80: LGTM! Linker flags correctly updated to target main package variables.

The ldflags now inject version and commitID into the main package, consistent with the new build-time variable declarations in cmd/tssc/main.go.

.goreleaser.yaml (1)

21-22: LGTM! GoReleaser ldflags aligned with Makefile and main.go.

The ldflags correctly inject version and commit metadata into the main package using GoReleaser's template variables.

pkg/constants/constants.go (1)

17-25: LGTM! Well-organized centralized filename constants.

Adding ConfigFilename, ValuesFilename, and InstructionsFilename constants eliminates hardcoded strings across the codebase and improves maintainability. The removal of Version and CommitID correctly aligns with relocating build-time metadata to the main package.

cmd/tssc/main.go (3)

14-18: LGTM! Build-time variables with sensible defaults.

The package-level variables with "v0.0.0-SNAPSHOT" and "" defaults ensure the application works during development even without linker injection, while being overridden during release builds.


21-35: LGTM! Clean overlay filesystem initialization.

The approach of creating an overlay filesystem with the embedded tarball as the base layer and the current working directory as the local overlay is well-structured. Error handling is properly implemented for both NewTarFS and os.Getwd().


47-63: LGTM! Well-structured application initialization.

The framework.NewApp call with functional options provides clean dependency injection. The use of constants.AppName, subcmd.StandardModules(), and explicit version/commit configuration aligns with the framework's design goals.

pkg/framework/app.go (4)

18-35: LGTM! Well-designed App struct with clear separation of concerns.

The struct cleanly separates public metadata fields (Name, Version, CommitID, Short, Long, ChartFS) from private implementation details. This design supports the framework's goal of exposing a public API while encapsulating internals.


96-99: Good defensive validation for required MCP image configuration.

The explicit error message clearly guides users to use WithMCPImage() when configuring the app, preventing cryptic failures downstream.


124-145: LGTM! Clean constructor with functional options pattern.

The NewApp constructor properly applies options before initializing dependencies that require them (Kube client, root command setup). The error propagation from setupRootCmd ensures configuration failures are surfaced to the caller.


74-74: The logger implementation already respects user-specified log levels correctly. The LogLevel field is passed as a pointer (*slog.Level) to slog.HandlerOptions, and the slog handler evaluates this level dynamically for each log statement. When command-line flags are parsed during Execute(), the pointer is updated via LogLevelValue.Set(), and subsequent logging operations will respect the user-specified log level. If module loading during initialization needs to respect user-specified levels, the logger will reflect those changes for any logging that occurs after flag parsing.

Likely an incorrect or invalid review comment.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 7, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Modular integration plugins with dynamic loading and a unified application runtime; MCP tools builder for configurable toolchains and installer image flag.

  • Refactoring

  • CLI reworked to a plugin-based subcommand model; installer assets accessed via an overlay filesystem; application metadata (name/version/namespace) now drives tool names and messages.

  • Chores

  • Upgraded linting and formatting configuration (expanded linters and formatters).

  • Documentation

  • Updated README and deployment scripts to the new template path.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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: 4

🤖 Fix all issues with AI agents
In @pkg/resolver/dependency.go:
- Around line 108-110: The constructors NewDependency and
NewDependencyWithNamespace currently accept appCtx without validation which can
lead to panics later; add an explicit nil check at the start of both functions
and handle it immediately (e.g., panic or call log.Fatalf) with a clear message
like "appCtx is required and must not be nil" so the failure surfaces at
construction time; update both NewDependency(hc *chart.Chart, appCtx
*api.AppContext) and NewDependencyWithNamespace(...) to include this check and
message, or alternatively document in their comments that appCtx is required and
must never be nil if you prefer not to change runtime behavior.

In @pkg/subcmd/mcpserver.go:
- Around line 89-117: The constructor NewMCPServer fails to initialize the
MCPServer.appName field, so Run() ends up passing an empty appName to
mcpserver.NewMCPServer; update NewMCPServer to set the appName field on the
returned MCPServer by reading it from the provided app context (e.g.,
appCtx.AppName or the appropriate getter on api.AppContext) so that
MCPServer.appName is populated before PersistentFlags and return.
🧹 Nitpick comments (9)
pkg/framework/constants.go (1)

3-15: Duplicate constant definitions across packages.

These three constants (ConfigFilename, ValuesFilename, InstructionsFilename) are identically defined in:

  • pkg/framework/constants.go (this file)
  • pkg/api/constants.go
  • pkg/constants/constants.go

This duplication violates DRY and risks divergence during maintenance. Consider consolidating to a single source of truth (likely pkg/api/constants.go since it's the shared API package) and having other packages import from there.

pkg/api/constants.go (1)

1-15: Consider making this the single source of truth.

Since pkg/api is the shared API package for external consumers, this is the appropriate location for these framework contract constants. However, identical definitions exist in pkg/framework/constants.go and pkg/constants/constants.go.

Recommend keeping this file and having the other packages import from here, or removing duplicates entirely if they're not needed.

pkg/resolver/annotations.go (1)

21-23: Nil pointer dereference risk: Consider adding validation if appCtx is passed directly to annotation functions outside this resolver package.

The annotation helper functions call appCtx.RepoURI() without nil-checking. While the current usage pattern (within Dependency methods) ensures appCtx is always non-nil, consider adding a defensive guard if these functions are or will be part of a public API:

♻️ Suggested defensive check
 func AnnotationProductName(appCtx *api.AppContext) string {
+	if appCtx == nil {
+		return ""
+	}
 	return fmt.Sprintf("%s/%s", appCtx.RepoURI(), suffixProductName)
 }

Alternatively, document the precondition that appCtx must not be nil.

pkg/subcmd/installer.go (1)

217-225: Consider whether unused appCtx parameter should be stored.

The appCtx parameter is accepted by NewInstaller but is not stored in the struct or used anywhere. While this maintains a consistent constructor signature across subcommands, consider whether Installer might benefit from accessing app metadata (e.g., for display in --list output).

If intentionally unused for consistency, this is acceptable. If it should be used, add an appCtx field to the struct.

cmd/tssc/main.go (1)

45-51: Consider using a constant for the MCP image base URL.

The MCP image base URL is hardcoded as a string. Consider extracting it to a constant for maintainability and to avoid typos in future modifications.

♻️ Suggested refactor
+const mcpImageBase = "quay.io/redhat-user-workloads/rhtap-shared-team-tenant/tssc-cli"
+
 // TSSC-specific MCP server image based on build-time commit ID.
-mcpImage := "quay.io/redhat-user-workloads/rhtap-shared-team-tenant/tssc-cli"
 if commitID == "" {
-    mcpImage = fmt.Sprintf("%s:latest", mcpImage)
+    mcpImage := fmt.Sprintf("%s:latest", mcpImageBase)
 } else {
-    mcpImage = fmt.Sprintf("%s:%s", mcpImage, commitID)
+    mcpImage := fmt.Sprintf("%s:%s", mcpImageBase, commitID)
 }
pkg/subcmd/integration_gitlab.go (1)

6-7: Minor: Blank line in import block.

There's a blank line between the api import and subsequent imports. While not incorrect, Go convention typically groups standard library imports separately from third-party imports without extra blank lines within groups.

♻️ Suggested import grouping
 import (
 	"log/slog"
 
 	"github.com/redhat-appstudio/tssc-cli/pkg/api"
-
 	"github.com/redhat-appstudio/tssc-cli/pkg/config"
 	"github.com/redhat-appstudio/tssc-cli/pkg/integration"
 	"github.com/redhat-appstudio/tssc-cli/pkg/k8s"
pkg/subcmd/integration_azure.go (1)

6-7: Minor: Same import formatting as GitLab integration.

Same observation as integration_gitlab.go — the blank line between imports is inconsistent with typical Go style.

pkg/subcmd/mcptools.go (1)

83-91: Tool ordering in return slice.

The tools are returned in a specific order. If this ordering has semantic meaning (e.g., initialization order), consider documenting it.

pkg/framework/app.go (1)

95-98: Consider validating required MCP image earlier in initialization.

The MCP image is validated late in setupRootCmd(), which means NewApp() could successfully return an App instance that will fail when setupRootCmd() is called internally. Since the error message states the image is required via WithMCPImage(), consider either:

  1. Validating immediately after applying functional options in NewApp() (line 169)
  2. Documenting in the NewApp() godoc that WithMCPImage() is mandatory

This would fail faster and provide clearer error messages to framework consumers.

♻️ Option 1: Validate after applying options in NewApp
 	for _, opt := range opts {
 		opt(app)
 	}
+
+	// Validate MCP image is configured.
+	if app.mcpImage == "" {
+		return nil, fmt.Errorf(
+			"MCP server image not configured: use WithMCPImage() option")
+	}

 	// Initialize Kube client with flags
 	app.kube = k8s.NewKube(app.flags)

Then remove the validation from setupRootCmd() (lines 95-98).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8f8f12 and 7675e7e.

📒 Files selected for processing (43)
  • cmd/tssc/main.go
  • pkg/api/appcontext.go
  • pkg/api/constants.go
  • pkg/api/types.go
  • pkg/chartfs/chartfs_test.go
  • pkg/constants/constants.go
  • pkg/framework/app.go
  • pkg/framework/constants.go
  • pkg/framework/options.go
  • pkg/hooks/hooks_test.go
  • pkg/installer/job.go
  • pkg/mcptools/configtools.go
  • pkg/mcptools/context.go
  • pkg/mcptools/notestool.go
  • pkg/resolver/annotations.go
  • pkg/resolver/collection.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/resolver_test.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/subcmd/config.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/mcpserver.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/template.go
  • pkg/subcmd/topology.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • pkg/subcmd/integration_bitbucket.go
  • pkg/framework/options.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/modules.go
  • pkg/resolver/resolver_test.go
  • pkg/hooks/hooks_test.go
🧰 Additional context used
📓 Path-based instructions (6)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • pkg/framework/constants.go
  • pkg/resolver/annotations.go
  • pkg/api/constants.go
  • pkg/constants/constants.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/config_helper.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_artifactory.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/api/appcontext.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/chartfs/chartfs_test.go
  • pkg/framework/app.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/context.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/subcmd/mcptools.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/mcptools/configtools.go
  • pkg/api/types.go
  • pkg/resolver/topologybuilder.go
  • pkg/installer/job.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/framework/constants.go
  • pkg/resolver/annotations.go
  • pkg/api/constants.go
  • pkg/constants/constants.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/config_helper.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_artifactory.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/api/appcontext.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/chartfs/chartfs_test.go
  • pkg/framework/app.go
  • pkg/subcmd/integration_acs.go
  • pkg/mcptools/context.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/subcmd/mcptools.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/mcptools/configtools.go
  • pkg/api/types.go
  • pkg/resolver/topologybuilder.go
  • pkg/installer/job.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
pkg/resolver/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use pkg/resolver to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Files:

  • pkg/resolver/annotations.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topologybuilder.go
pkg/subcmd/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

pkg/subcmd/**/*.go: Use cobra library for CLI command structure in the tssc-cli project
Define commands as structs in pkg/subcmd that implement a common interface
Use specific validateFlags() methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators
Inject dependencies like k8s.Kube and chartfs.ChartFS via constructors in command structs

Files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/mcpserver.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
**/*_test.go

📄 CodeRabbit inference engine (GEMINI.md)

Use the standard testing package with github.com/onsi/gomega assertion library for tests

Files:

  • pkg/chartfs/chartfs_test.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
pkg/chartfs/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Implement io.FS compatible abstraction in pkg/chartfs to provide access to embedded installer directory resources

Files:

  • pkg/chartfs/chartfs_test.go
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.
📚 Learning: 2025-09-29T14:49:45.227Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/mcptools/configtools.go:0-0
Timestamp: 2025-09-29T14:49:45.227Z
Learning: In pkg/mcptools/configtools.go, the SettingsArg and ProductsArg constants are used for Gemini input generation, where Gemini uses these parameter names to generate input and the system reads the input content by these argument names.

Applied to files:

  • pkg/api/constants.go
  • pkg/constants/constants.go
  • pkg/mcptools/configtools.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/integration/**/*.go : Define integrations in `pkg/integration` to connect to external services like GitHub, Quay, etc.

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_trustification.go
  • pkg/api/appcontext.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/api/types.go
  • pkg/resolver/topologybuilder.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/config_helper.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_artifactory.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/chartfs/chartfs_test.go
  • pkg/framework/app.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/subcmd/mcptools.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/installer/job.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Define commands as structs in `pkg/subcmd` that implement a common interface

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_artifactory.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/mcpserver.go
  • pkg/api/types.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/config_helper.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_artifactory.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/subcmd/mcptools.go
  • pkg/resolver/topologybuilder.go
  • pkg/installer/job.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Define interface definition at the top of service files, followed by service struct and implementation

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/resolver/topologybuilder.go
  • pkg/installer/job.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/config.go
  • pkg/resolver/topologybuilder.go
  • pkg/installer/job.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/engine/**/*.go : Use Helm SDK in `pkg/engine` for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Applied to files:

  • pkg/subcmd/template.go
  • pkg/resolver/collection.go
  • cmd/tssc/main.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/framework/app.go
  • pkg/subcmd/config.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/topology.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/chartfs/**/*.go : Implement `io.FS` compatible abstraction in `pkg/chartfs` to provide access to embedded installer directory resources

Applied to files:

  • pkg/subcmd/template.go
  • pkg/resolver/collection.go
  • cmd/tssc/main.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/chartfs/chartfs_test.go
  • pkg/framework/app.go
  • pkg/subcmd/config.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/subcmd/topology.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : All tests must use the `testing` package with `testify/assert` library

Applied to files:

  • pkg/subcmd/template.go
  • pkg/subcmd/integration_github.go
  • pkg/chartfs/chartfs_test.go
  • pkg/subcmd/config.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/subcmd/topology.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/resolver/**/*.go : Use `pkg/resolver` to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Applied to files:

  • pkg/subcmd/template.go
  • pkg/resolver/collection.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/config.go
  • pkg/resolver/dependency.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/subcmd/topology.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Regenerate mocks after modifying existing interfaces

Applied to files:

  • pkg/subcmd/integration_gitlab.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Struct fields and methods should be ordered to match the GitLab API documentation

Applied to files:

  • pkg/subcmd/integration_gitlab.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `interface{}`, use the `any` alias instead

Applied to files:

  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
📚 Learning: 2025-08-20T15:48:01.881Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.

Applied to files:

  • cmd/tssc/main.go
📚 Learning: 2025-09-29T15:10:13.650Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/config/config.go:159-185
Timestamp: 2025-09-29T15:10:13.650Z
Learning: In the tssc-cli project, the UpdateMappingValue method in pkg/config/config.go should only update existing configuration keys and not create new ones. Adding new config entries is not allowed, so silent return when key is not found is the desired behavior.

Applied to files:

  • cmd/tssc/main.go
  • pkg/mcptools/configtools.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*.go : Use `go:embed` directive to embed `installer` directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Applied to files:

  • cmd/tssc/main.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/deploy.go
  • pkg/framework/app.go
  • pkg/mcptools/notestool.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use specific `validateFlags()` methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators

Applied to files:

  • pkg/subcmd/installer.go
📚 Learning: 2025-08-27T18:30:02.411Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1190
File: pkg/resolver/resolver_test.go:52-67
Timestamp: 2025-08-27T18:30:02.411Z
Learning: In tssc-cli, there is a distinction between deployment namespace (where resources are deployed, referenced in values.yaml.tpl) and chart registration namespace (where Helm charts are registered, tested in resolver tests). These are different concepts and may use different namespace values.

Applied to files:

  • pkg/subcmd/deploy.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*_test.go : Use the standard `testing` package with `github.com/onsi/gomega` assertion library for tests

Applied to files:

  • pkg/chartfs/chartfs_test.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : When fixing bugs or creating new features, ensure new test scenarios are added to cover the new logic

Applied to files:

  • pkg/resolver/collection_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `int`, use `int64` instead (applies to both slices and maps)

Applied to files:

  • pkg/installer/job.go
🧬 Code graph analysis (22)
pkg/resolver/annotations.go (1)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/integration_nexus.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/template.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/dependency.go (1)
  • NewDependencyWithNamespace (114-118)
pkg/subcmd/config_helper.go (1)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/integration_artifactory.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_trustification.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/deploy.go (6)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/integrations/manager.go (1)
  • Manager (20-23)
pkg/resolver/topologybuilder.go (1)
  • TopologyBuilder (15-19)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration.go (4)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • IntegrationName (15-15)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/api/subcommand.go (1)
  • NewRunner (36-47)
pkg/chartfs/chartfs_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/subcmd/integration_acs.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/mcptools/context.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/flags/flags.go (1)
  • Flags (17-24)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/integrations/manager.go (1)
  • Manager (20-23)
pkg/subcmd/integration_azure.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/integration/integration.go (1)
  • Integration (19-26)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/config.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/subcmd/mcpserver.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/mcptools/context.go (2)
  • MCPToolsBuilder (53-53)
  • NewMCPToolsContext (31-49)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/framework/mcpserver/mcpserver.go (2)
  • MCPServer (9-11)
  • NewMCPServer (23-32)
pkg/constants/constants.go (1)
  • InstructionsFilename (14-14)
pkg/resolver/collection_test.go (3)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/api/appcontext.go (1)
  • NewAppContext (84-99)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/resolver/dependency_test.go (3)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/api/appcontext.go (1)
  • NewAppContext (84-99)
pkg/resolver/dependency.go (1)
  • NewDependency (108-110)
pkg/mcptools/configtools.go (6)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/config/manager.go (2)
  • ConfigMapManager (17-19)
  • Name (25-25)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/config/config.go (2)
  • Config (30-36)
  • NewConfigDefault (305-307)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/types.go (4)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/integration/integration.go (1)
  • Integration (19-26)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/topologybuilder.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/mcptools/notestool.go (5)
pkg/flags/flags.go (1)
  • Flags (17-24)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/config/manager.go (1)
  • ConfigMapManager (17-19)
pkg/resolver/topologybuilder.go (1)
  • TopologyBuilder (15-19)
pkg/installer/job.go (1)
  • Job (22-27)
pkg/subcmd/topology.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/resolver/collection.go (2)
  • Collection (14-16)
  • NewCollection (100-130)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_quay.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
🔇 Additional comments (59)
pkg/resolver/annotations.go (1)

9-17: LGTM on suffix constants.

The unexported suffix constants provide good encapsulation while enabling consistent annotation key construction.

pkg/subcmd/config_helper.go (1)

14-30: LGTM on AppContext integration.

The signature update properly injects appCtx as a dependency, and the dynamic appCtx.Name usage in error messages enables proper branding for different installer consumers. This aligns with the coding guidelines for dependency injection in pkg/subcmd.

Note: Consider adding a nil-check for appCtx to prevent panics if called incorrectly, consistent with defensive patterns elsewhere.

pkg/subcmd/integration_nexus.go (2)

17-26: LGTM on struct and interface update.

The struct correctly adds appCtx field and implements api.SubCommand. Dependencies (appCtx, logger, kube, integration) are properly injected via the constructor, following the coding guidelines for pkg/subcmd.


60-81: LGTM on constructor.

The constructor properly accepts and wires appCtx through to the struct instance. The pattern aligns with the broader refactoring to AppContext-driven architecture and follows dependency injection guidelines.

pkg/resolver/collection.go (1)

100-106: LGTM on AppContext propagation.

The signature change correctly threads appCtx through to NewDependency for annotation key construction. Since the Collection doesn't need to retain appCtx after construction, not storing it is appropriate.

One consideration: if appCtx is nil, it will propagate to NewDependency and eventually cause panics in the annotation functions. Ensure callers always provide a valid AppContext.

pkg/subcmd/config.go (4)

20-26: LGTM! AppContext integration follows the dependency injection pattern.

The Config struct correctly adds appCtx field and the interface assertion is updated to api.SubCommand. This aligns with the coding guidelines for injecting dependencies via constructors.

Also applies to: 38-38


84-86: Good use of AppContext for namespace default.

Using c.appCtx.Namespace as the default value for the namespace flag properly centralizes configuration, replacing the previous hardcoded constant.


178-182: Correct propagation of appCtx to resolver.NewCollection.

The appCtx is properly passed through to resolver.NewCollection, maintaining the context-aware architecture throughout the dependency resolution flow.


284-308: Constructor properly injects all dependencies including appCtx.

The NewConfig function follows the established pattern of dependency injection via constructors and correctly returns api.SubCommand. As per coding guidelines, dependencies like k8s.Kube and chartfs.ChartFS are injected via the constructor.

pkg/mcptools/context.go (3)

14-27: Well-designed context struct with clear documentation.

The MCPToolsContext struct properly encapsulates all dependencies needed for MCP tool creation. The documentation clearly explains the critical constraint about STDIO protocol compatibility.


29-49: Constructor correctly enforces MCP STDIO protocol safety.

The use of f.GetLogger(io.Discard) ensures logs don't corrupt MCP protocol messages. The inline comment on line 41 reinforces this critical requirement for future maintainers.


51-53: Clean builder pattern type definition.

The MCPToolsBuilder function type enables consumers to provide custom tool builders while maintaining a consistent interface.

pkg/resolver/dependency_test.go (1)

16-22: Test correctly updated for new API signatures.

The test properly adapts to:

  1. The new chartfs.New(fs.FS) constructor that returns *ChartFS directly
  2. The api.NewAppContext constructor for creating app context
  3. The updated NewDependency signature requiring appCtx

As per coding guidelines, the test uses the standard testing package with gomega assertion library.

pkg/subcmd/installer.go (1)

29-29: Interface implementation updated correctly.

The Installer struct now properly implements api.SubCommand with the correct method signatures.

Also applies to: 60-63

pkg/chartfs/chartfs_test.go (2)

13-14: Test correctly updated for new ChartFS API.

The test properly uses the new New(fs.FS) constructor. The direct return of *ChartFS (without error) simplifies test setup.


16-20: Path correctly adjusted for new filesystem root.

The path change from "installer/values.yaml.tpl" to "values.yaml.tpl" is correct since os.DirFS("../../installer") already roots the filesystem at the installer directory. As per coding guidelines, this implements an io.FS compatible abstraction.

pkg/resolver/collection_test.go (1)

16-24: Test correctly updated for new API signatures.

The test properly adapts to:

  1. The new chartfs.New(fs.FS) constructor
  2. The api.NewAppContext constructor
  3. The updated NewCollection(appCtx, charts) signature

As per coding guidelines, this test correctly uses pkg/resolver for dependency topology and the standard testing package with gomega.

cmd/tssc/main.go (3)

21-35: Proper error handling for filesystem initialization.

Good error handling for both NewTarFS and os.Getwd() operations. The overlay filesystem creation cleanly combines embedded tarball contents with the local filesystem for customization support.


37-43: AppContext properly configured with build-time metadata.

The api.NewAppContext usage correctly injects build-time variables (version, commitID) and provides a meaningful short description for CLI help text.


53-67: Clean application lifecycle with proper error handling.

The framework.NewApp call properly injects all dependencies and the error handling paths are explicit. The application runs cleanly with appropriate exit codes on failure.

pkg/subcmd/integration_artifactory.go (1)

6-7: LGTM! Consistent migration to AppContext-driven architecture.

The changes correctly:

  • Add the api package import and appCtx field
  • Update the interface assertion to api.SubCommand
  • Wire appCtx through the constructor and into bootstrapConfig

This aligns with the PR's goal of centralizing application metadata in AppContext. Based on learnings, the dependency injection pattern via constructor is correctly followed.

Also applies to: 19-19, 29-29, 47-47, 64-64, 77-77

pkg/resolver/topology_test.go (1)

16-19: LGTM! Test correctly updated for new API signatures.

The test properly:

  • Uses os.DirFS with the chartfs.New constructor
  • Creates an AppContext via api.NewAppContext("tssc")
  • Passes appCtx to all NewDependencyWithNamespace calls

As per coding guidelines, the test uses the standard testing package with github.com/onsi/gomega assertion library.

pkg/resolver/topologybuilder.go (1)

56-76: LGTM! AppContext correctly propagated to collection creation.

The TopologyBuilder constructor correctly:

  • Accepts appCtx as a parameter
  • Passes it through to NewCollection(appCtx, charts) during initialization

The design choice to not store appCtx in the struct is appropriate since it's only needed during collection creation. As per coding guidelines, this file correctly defines the dependency topology.

pkg/subcmd/integration_acs.go (1)

6-7: LGTM! Consistent with other integration subcommand migrations.

The changes mirror the pattern established in integration_artifactory.go and other integration commands:

  • Import api package and add appCtx field
  • Assert api.SubCommand interface compliance
  • Wire appCtx through constructor and bootstrapConfig

Based on learnings, dependencies are correctly injected via the constructor.

Also applies to: 19-19, 26-26, 44-44, 61-61, 74-74

pkg/subcmd/template.go (1)

7-7: LGTM! AppContext correctly integrated into template subcommand.

The Template subcommand properly:

  • Adds appCtx field and imports the api package
  • Updates interface assertion to api.SubCommand
  • Propagates appCtx to both resolver.NewDependencyWithNamespace and bootstrapConfig
  • Accepts appCtx in the constructor and wires it to the struct

Based on learnings, dependencies like chartfs.ChartFS and the new AppContext are correctly injected via the constructor.

Also applies to: 23-23, 38-38, 87-87, 89-89, 151-151, 166-166

pkg/subcmd/integration_quay.go (1)

6-7: LGTM! Consistent migration pattern for Quay integration.

The changes follow the same pattern as other integration subcommands, correctly implementing the api.SubCommand interface and wiring appCtx through the constructor and bootstrapConfig.

Also applies to: 19-19, 26-26, 56-56, 73-73, 86-86

pkg/subcmd/integration_trustification.go (1)

6-7: LGTM! Completes the consistent migration across integration subcommands.

The Trustification integration follows the same pattern as all other integration subcommands in this PR. The api.SubCommand interface is correctly implemented, and appCtx is properly wired through the constructor and bootstrapConfig.

Also applies to: 19-19, 26-26, 44-44, 62-62, 75-75

pkg/resolver/dependency.go (1)

15-19: AppContext integration looks correct.

The struct now properly carries the application context for dynamic annotation key resolution. The field ordering is logical with related Helm chart data grouped together.

pkg/subcmd/topology.go (3)

18-27: Struct changes align with framework architecture.

The addition of appCtx and compliance with api.SubCommand is consistent with the broader refactoring. Dependencies (cfs, kube) are properly injected via the constructor as per coding guidelines.


50-65: AppContext propagation is correctly implemented.

The Complete method properly passes appCtx to both resolver.NewCollection and bootstrapConfig, aligning with the new signatures defined in the relevant code snippets.


86-105: Constructor follows dependency injection pattern.

The constructor correctly accepts all dependencies including the new appCtx parameter and initializes all struct fields. This aligns with the coding guidelines for pkg/subcmd/**/*.go. Based on learnings, dependencies like k8s.Kube and chartfs.ChartFS are injected via constructors.

pkg/subcmd/integration.go (3)

16-22: Dynamic module-based integration registration.

The function now accepts a manager parameter enabling dynamic registration of integration modules. This is a cleaner architecture than hardcoded integration lists.


26-40: AppContext propagation in PersistentPostRunE.

The bootstrapConfig and resolver.NewCollection calls correctly receive appCtx, ensuring consistent application context throughout the post-run configuration update flow.


76-80: No action needed. The mod.Command() function returns only SubCommand (not an error tuple), as defined in pkg/api/types.go. The code correctly handles the single return value.

Likely an incorrect or invalid review comment.

pkg/subcmd/integration_gitlab.go (2)

17-26: Struct and interface changes are consistent.

The IntegrationGitLab struct now includes appCtx and implements api.SubCommand. This aligns with the centralized SubCommand interface pattern established in the PR.


60-81: Constructor follows the established pattern.

Dependencies are properly injected via constructor parameters, and appCtx is correctly assigned to the struct field. This matches the coding guidelines for pkg/subcmd/**/*.go.

pkg/subcmd/integration_azure.go (1)

17-26: Changes are consistent with the integration pattern.

The Azure integration follows the same pattern as GitLab and other integration subcommands. The appCtx is properly stored and passed to bootstrapConfig. Constructor injects dependencies correctly per coding guidelines.

Also applies to: 40-45, 59-80

pkg/subcmd/mcptools.go (3)

10-15: Clean builder pattern for MCP tools.

The StandardMCPToolsBuilder function returns the internal builder, providing a nice separation between the public API and implementation.


18-44: Shared dependencies created efficiently.

The builder creates shared dependencies (cm, tb) once and reuses them across multiple tools, avoiding redundant instantiations. Error handling for NewConfigTools and NewTopologyBuilder is correctly implemented.


52-62: Integration tools construction.

The NewIntegration call creates a cobra.Command for metadata introspection. This pattern works, though it's creating a command primarily to extract metadata rather than execute it.

pkg/installer/job.go (3)

22-27: Repository-aware labeling improves isolation.

Adding repoURI enables per-repository job isolation, which is essential when multiple installations might coexist in a cluster.


56-58: Consistent use of LabelSelector throughout.

All label usages now consistently call j.LabelSelector(), ensuring label consistency across job creation, lookup, and log following. This is a good refactoring that centralizes the label logic.

Also applies to: 224-224, 229-229, 260-260


301-308: Constructor properly extracts values from AppContext.

The constructor correctly sources appName and repoURI from appCtx, aligning with the centralized metadata approach of this PR.

pkg/subcmd/integration_github.go (1)

7-7: LGTM! AppContext integration is clean and consistent.

The refactoring properly threads AppContext through the struct, constructor, and methods. The interface change from Interface to api.SubCommand aligns with the broader API refactoring, and bootstrapConfig now correctly receives appCtx for context-aware configuration loading.

Based on learnings, dependencies are properly injected via the constructor.

Also applies to: 20-20, 30-30, 53-53, 87-87, 96-110

pkg/api/types.go (1)

10-28: Well-designed integration module contract.

The IntegrationModule type cleanly separates business logic initialization (Init) from CLI command creation (Command), enabling the pluggable integration pattern described in the PR objectives. The function-field approach provides flexibility for dynamic module registration while maintaining type safety.

pkg/subcmd/deploy.go (1)

9-9: LGTM! Refactoring to AppContext and integration manager is consistent.

The changes properly integrate AppContext and the new integrations.Manager throughout the deploy command. Dependencies are correctly injected via the constructor, and the topology builder and config bootstrap now receive appCtx for context-aware operation. Error messages dynamically use appCtx.Name for better branding flexibility.

Based on learnings, dependencies like k8s.Kube and chartfs.ChartFS are properly injected via the constructor.

Also applies to: 27-27, 32-32, 38-38, 79-79, 84-84, 124-124, 195-214

pkg/api/appcontext.go (1)

7-22: Excellent use of functional options pattern for immutable context.

The AppContext design follows best practices:

  • Immutable metadata holder separates "what the app is" from "how it runs"
  • Functional options enable flexible configuration with sensible defaults
  • The RepoURI() method provides a consistent repository identifier format
  • Default values align with the Red Hat AppStudio project context

The centralization of application metadata enables the dynamic branding and framework reusability goals outlined in the PR objectives.

Also applies to: 24-27, 81-99

pkg/mcptools/notestool.go (1)

22-22: LGTM! Parameterization enables framework reusability.

The refactoring properly introduces per-instance appName instead of hardcoded constants, enabling the MCP tool to be rebranded for different applications. The suffix-based naming convention (appName + notesSuffix) is clean and the constructor properly injects dependencies including the job parameter.

pkg/framework/app.go (4)

18-33: LGTM! Clean encapsulation with appropriate field visibility.

The struct design correctly exposes AppCtx and ChartFS as public fields for external access while keeping implementation details (integrations, rootCmd, flags, kube, mcpToolsBuilder, mcpImage) private. The comments clearly document the purpose of each field.


35-43: LGTM! Clean public API surface.

These methods provide a clean interface for external callers to access the Cobra command and execute the application without exposing internal details.


100-148: LGTM! Consistent subcommand registration pattern.

All subcommands are correctly instantiated with AppCtx as the first parameter, promoting consistent application metadata propagation. The use of the api.SubCommand interface and api.NewRunner wrapper creates a uniform command registration pattern across the framework.


150-179: LGTM! Well-structured constructor with functional options pattern.

The constructor properly applies functional options before initializing dependencies and calls setupRootCmd() with appropriate error handling. The godoc clearly documents the parameters and usage pattern.

pkg/subcmd/mcpserver.go (3)

18-32: LGTM! Updated struct definition aligns with framework refactor.

The struct correctly implements api.SubCommand and includes all necessary fields for the builder pattern (appCtx, manager, mcpToolsBuilder, image). The appName field enables dynamic branding across the MCP server.


38-57: LGTM! Standard api.SubCommand implementation.

The implementation correctly satisfies the api.SubCommand interface with appropriate flag handling and stub implementations for Complete() and Validate().


59-87: LGTM! Clean builder-based tool initialization flow.

The Run method correctly uses the MCPToolsBuilder pattern with NewMCPToolsContext constructor, ensuring the logger uses io.Discard for MCP STDIO protocol compatibility (as noted in the comment on line 61). The flow is clear: build tools → read instructions → create server → add tools → start server.

pkg/mcptools/configtools.go (4)

19-47: LGTM! Struct and constants updated for dynamic naming.

The addition of appName and cfs fields, along with the refactoring of tool name constants to suffix-based identifiers (e.g., configGetSuffix), correctly enables dynamic branding where each tool name is prefixed with the application name. This aligns with the broader framework refactor.


62-167: LGTM! Handlers correctly use appName for dynamic messaging.

The getHandler and initHandler methods properly interpolate c.appName into user-facing messages and tool references (e.g., line 115: c.appName+configGetSuffix), ensuring consistent dynamic branding. The use of c.cfs for configuration access (line 82) aligns with the new ChartFS integration.


444-569: LGTM! Consistent dynamic tool registration throughout.

All six MCP tools are registered with consistent suffix-based naming (e.g., c.appName+configGetSuffix) and their descriptions properly interpolate c.appName to provide context-aware help text. This ensures the tools are dynamically branded per application instance.


571-594: LGTM! Constructor correctly wires appCtx and cfs dependencies.

The updated NewConfigTools signature properly accepts appCtx and cfs, initializes the default configuration with config.NewConfigDefault(cfs, appCtx.Namespace) (line 580), and sets the appName field from appCtx.Name (line 586). All new struct fields are correctly initialized.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 7, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Modular integration plugins, unified application runtime, and a standard MCP tools builder; installer image flag added.

  • Refactoring

  • CLI reworked to a plugin/subcommand model with application context driving names/messages; installer assets served via an overlay filesystem; tooling and job labels now use application context.

  • Chores

  • Expanded linting/formatting configuration and numerous tooling cleanups.

  • Documentation

  • README and deployment scripts updated to the new template path.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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

🤖 Fix all issues with AI agents
In @pkg/subcmd/mcptools.go:
- Around line 17-47: MCPServer.Validate() currently returns nil without checking
required dependencies which can lead to nil dereferences later in
standardMCPTools; update MCPServer.Validate() to explicitly check that m.appCtx,
m.flags, m.cfs, m.kube, and m.manager are non-nil and return descriptive errors
(e.g., "application context is nil", "flags are nil", "chart filesystem is nil",
"kubernetes client is nil", "integrations manager is nil") when any are missing
so callers like standardMCPTools fail fast and predictably.
🧹 Nitpick comments (4)
pkg/installer/job.go (1)

301-307: Consider adding nil checks for defensive programming.

If appCtx is nil, calling appCtx.Name or appCtx.RepoURI() will panic. While the codebase pattern appears to assume valid arguments, adding a simple guard could prevent runtime panics:

🛡️ Optional defensive nil check
 func NewJob(appCtx *api.AppContext, kube *k8s.Kube) *Job {
+	if appCtx == nil || kube == nil {
+		panic("NewJob: appCtx and kube must not be nil")
+	}
 	return &Job{
 		kube:    kube,
 		appName: appCtx.Name,
 		repoURI: appCtx.RepoURI(),
 		retries: 0,
 	}
 }
pkg/subcmd/integration_github.go (1)

84-91: Dynamic app name in error message supports rebranding.

Using g.appCtx.Name instead of a hardcoded constant aligns with the framework's goal of making the CLI reusable. The TODO for the update path is acknowledged.

The --update flag triggers a panic. Would you like me to open an issue to track implementing the update functionality?

pkg/resolver/annotations.go (1)

21-52: Consider extracting a helper to reduce repetition.

All six functions follow the same pattern: fmt.Sprintf("%s/%s", appCtx.RepoURI(), suffix). A private helper could reduce duplication while keeping the public API unchanged.

♻️ Optional refactor
+// makeAnnotation builds an annotation key from the app context and suffix.
+func makeAnnotation(appCtx *api.AppContext, suffix string) string {
+	return fmt.Sprintf("%s/%s", appCtx.RepoURI(), suffix)
+}
+
 // AnnotationProductName returns the product-name annotation key for the given app
 // context.
 func AnnotationProductName(appCtx *api.AppContext) string {
-	return fmt.Sprintf("%s/%s", appCtx.RepoURI(), suffixProductName)
+	return makeAnnotation(appCtx, suffixProductName)
 }
 
 // (Apply same pattern to other functions...)
pkg/subcmd/mcptools.go (1)

52-62: Optional: Consider clarifying the "metadata introspection" comment.

The comment states that IntegrationTools "creates its own instance for metadata introspection," but it's not immediately clear why this differs from other tools or what metadata introspection means in this context.

If metadata introspection refers to the Integration command's use of reflection or dynamic discovery of available integrations, consider elaborating:

-// Integration tools, creates its own instance for metadata introspection.
+// Integration tools. NewIntegration creates a command instance that
+// introspects available integrations via the IntegrationManager.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7675e7e and 05c6c25.

📒 Files selected for processing (44)
  • cmd/tssc/main.go
  • pkg/api/appcontext.go
  • pkg/api/constants.go
  • pkg/api/types.go
  • pkg/chartfs/chartfs_test.go
  • pkg/constants/constants.go
  • pkg/framework/app.go
  • pkg/framework/constants.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/framework/options.go
  • pkg/hooks/hooks_test.go
  • pkg/installer/job.go
  • pkg/mcptools/configtools.go
  • pkg/mcptools/context.go
  • pkg/mcptools/notestool.go
  • pkg/resolver/annotations.go
  • pkg/resolver/collection.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/resolver_test.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/subcmd/config.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/mcpserver.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/template.go
  • pkg/subcmd/topology.go
🚧 Files skipped from review as they are similar to previous changes (11)
  • pkg/resolver/dependency.go
  • pkg/framework/constants.go
  • pkg/subcmd/installer.go
  • pkg/framework/options.go
  • pkg/api/appcontext.go
  • pkg/subcmd/topology.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/resolver/resolver_test.go
  • pkg/api/types.go
  • pkg/mcptools/configtools.go
🧰 Additional context used
📓 Path-based instructions (6)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • pkg/chartfs/chartfs_test.go
  • pkg/constants/constants.go
  • cmd/tssc/main.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/resolver/collection_test.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/subcmd/integration_acs.go
  • pkg/framework/app.go
  • pkg/mcptools/context.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/installer/job.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/annotations.go
  • pkg/hooks/hooks_test.go
  • pkg/api/constants.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
**/*_test.go

📄 CodeRabbit inference engine (GEMINI.md)

Use the standard testing package with github.com/onsi/gomega assertion library for tests

Files:

  • pkg/chartfs/chartfs_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/hooks/hooks_test.go
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/chartfs/chartfs_test.go
  • pkg/constants/constants.go
  • cmd/tssc/main.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/resolver/collection_test.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/subcmd/integration_acs.go
  • pkg/framework/app.go
  • pkg/mcptools/context.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/installer/job.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/mcpserver.go
  • pkg/resolver/annotations.go
  • pkg/hooks/hooks_test.go
  • pkg/api/constants.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
pkg/chartfs/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Implement io.FS compatible abstraction in pkg/chartfs to provide access to embedded installer directory resources

Files:

  • pkg/chartfs/chartfs_test.go
pkg/subcmd/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

pkg/subcmd/**/*.go: Use cobra library for CLI command structure in the tssc-cli project
Define commands as structs in pkg/subcmd that implement a common interface
Use specific validateFlags() methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators
Inject dependencies like k8s.Kube and chartfs.ChartFS via constructors in command structs

Files:

  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/mcpserver.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
pkg/resolver/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use pkg/resolver to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Files:

  • pkg/resolver/collection_test.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/annotations.go
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/chartfs/**/*.go : Implement `io.FS` compatible abstraction in `pkg/chartfs` to provide access to embedded installer directory resources

Applied to files:

  • pkg/chartfs/chartfs_test.go
  • cmd/tssc/main.go
  • pkg/subcmd/template.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/framework/app.go
  • pkg/subcmd/deploy.go
  • pkg/hooks/hooks_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • pkg/chartfs/chartfs_test.go
  • cmd/tssc/main.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/resolver/collection_test.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/integration_acs.go
  • pkg/framework/app.go
  • pkg/mcptools/context.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/installer/job.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/mcpserver.go
  • pkg/hooks/hooks_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*_test.go : Use the standard `testing` package with `github.com/onsi/gomega` assertion library for tests

Applied to files:

  • pkg/chartfs/chartfs_test.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/hooks/hooks_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : All tests must use the `testing` package with `testify/assert` library

Applied to files:

  • pkg/chartfs/chartfs_test.go
  • pkg/subcmd/template.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/integration_github.go
  • pkg/hooks/hooks_test.go
  • pkg/subcmd/config.go
📚 Learning: 2025-08-13T14:29:50.296Z
Learnt from: dperaza4dustbit
Repo: redhat-appstudio/tssc-cli PR: 1133
File: installer/charts/tssc-infrastructure/values.yaml:26-26
Timestamp: 2025-08-13T14:29:50.296Z
Learning: The tssc-cli team uses "__OVERWRITE_ME__" as a placeholder convention in Helm chart values.yaml files, even when the field will be used in templates with range operations. This is their established team convention and should not be flagged as an issue.

Applied to files:

  • pkg/constants/constants.go
📚 Learning: 2025-09-29T14:49:45.227Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/mcptools/configtools.go:0-0
Timestamp: 2025-09-29T14:49:45.227Z
Learning: In pkg/mcptools/configtools.go, the SettingsArg and ProductsArg constants are used for Gemini input generation, where Gemini uses these parameter names to generate input and the system reads the input content by these argument names.

Applied to files:

  • pkg/constants/constants.go
  • pkg/subcmd/mcptools.go
  • pkg/api/constants.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • cmd/tssc/main.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/installer/job.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-09-29T15:10:13.650Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/config/config.go:159-185
Timestamp: 2025-09-29T15:10:13.650Z
Learning: In the tssc-cli project, the UpdateMappingValue method in pkg/config/config.go should only update existing configuration keys and not create new ones. Adding new config entries is not allowed, so silent return when key is not found is the desired behavior.

Applied to files:

  • cmd/tssc/main.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Define commands as structs in `pkg/subcmd` that implement a common interface

Applied to files:

  • cmd/tssc/main.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*.go : Use `go:embed` directive to embed `installer` directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Applied to files:

  • cmd/tssc/main.go
  • pkg/framework/app.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/deploy.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/engine/**/*.go : Use Helm SDK in `pkg/engine` for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Applied to files:

  • cmd/tssc/main.go
  • pkg/subcmd/template.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/framework/app.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_github.go
  • pkg/hooks/hooks_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/integration/**/*.go : Define integrations in `pkg/integration` to connect to external services like GitHub, Quay, etc.

Applied to files:

  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Define interface definition at the top of service files, followed by service struct and implementation

Applied to files:

  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/installer/job.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/resolver/collection.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_nexus.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/installer/job.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Regenerate mocks after modifying existing interfaces

Applied to files:

  • pkg/subcmd/integration_gitlab.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/resolver/**/*.go : Use `pkg/resolver` to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Applied to files:

  • pkg/subcmd/template.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/deploy.go
  • pkg/resolver/annotations.go
  • pkg/hooks/hooks_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : When fixing bugs or creating new features, ensure new test scenarios are added to cover the new logic

Applied to files:

  • pkg/resolver/collection_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `int`, use `int64` instead (applies to both slices and maps)

Applied to files:

  • pkg/installer/job.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `interface{}`, use the `any` alias instead

Applied to files:

  • pkg/installer/job.go
📚 Learning: 2025-08-27T18:30:02.411Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1190
File: pkg/resolver/resolver_test.go:52-67
Timestamp: 2025-08-27T18:30:02.411Z
Learning: In tssc-cli, there is a distinction between deployment namespace (where resources are deployed, referenced in values.yaml.tpl) and chart registration namespace (where Helm charts are registered, tested in resolver tests). These are different concepts and may use different namespace values.

Applied to files:

  • pkg/subcmd/deploy.go
  • pkg/hooks/hooks_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : Tests must be parallelized using `t.Parallel()`

Applied to files:

  • pkg/hooks/hooks_test.go
🧬 Code graph analysis (24)
pkg/chartfs/chartfs_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/subcmd/config_helper.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/config/manager.go (2)
  • NewConfigMapManager (176-180)
  • Name (25-25)
pkg/subcmd/integration_jenkins.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/config/config.go (1)
  • Config (30-36)
pkg/integration/integration.go (1)
  • Integration (19-26)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_gitlab.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/config/config.go (1)
  • Config (30-36)
pkg/integration/integration.go (1)
  • Integration (19-26)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/modules.go (3)
pkg/api/types.go (1)
  • IntegrationModule (13-28)
pkg/integrations/manager.go (11)
  • ACS (26-26)
  • Artifactory (27-27)
  • Azure (28-28)
  • BitBucket (29-29)
  • GitHub (30-30)
  • GitLab (31-31)
  • Jenkins (32-32)
  • Nexus (33-33)
  • Quay (34-34)
  • TrustedArtifactSigner (35-35)
  • Trustification (36-36)
pkg/integration/imageregistry.go (2)
  • NewContainerRegistry (105-107)
  • QuayURL (27-27)
pkg/resolver/collection.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/resolver/dependency.go (2)
  • Dependency (15-19)
  • NewDependency (108-110)
pkg/resolver/dependency_test.go (3)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/api/appcontext.go (1)
  • NewAppContext (84-99)
pkg/resolver/dependency.go (1)
  • NewDependency (108-110)
pkg/framework/mcpserver/mcpserver.go (1)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/integration_acs.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/mcptools/context.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/flags/flags.go (1)
  • Flags (17-24)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/integrations/manager.go (1)
  • Manager (20-23)
pkg/subcmd/integration_trustification.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_nexus.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/mcptools/notestool.go (5)
pkg/flags/flags.go (1)
  • Flags (17-24)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/config/manager.go (1)
  • ConfigMapManager (17-19)
pkg/resolver/topologybuilder.go (1)
  • TopologyBuilder (15-19)
pkg/installer/job.go (1)
  • Job (22-27)
pkg/subcmd/integration_trustedartifactsigner.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/installer/job.go (2)
pkg/subcmd/template.go (1)
  • Template (19-36)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/deploy.go (4)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/integrations/manager.go (1)
  • Manager (20-23)
pkg/resolver/topologybuilder.go (1)
  • TopologyBuilder (15-19)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_azure.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_github.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/config/manager.go (1)
  • Name (25-25)
pkg/subcmd/integration_quay.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/mcpserver.go (6)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/mcptools/context.go (2)
  • MCPToolsBuilder (53-53)
  • NewMCPToolsContext (31-49)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/framework/mcpserver/mcpserver.go (2)
  • MCPServer (10-12)
  • NewMCPServer (24-33)
pkg/resolver/annotations.go (1)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/hooks/hooks_test.go (4)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/api/appcontext.go (1)
  • NewAppContext (84-99)
pkg/hooks/hooks.go (1)
  • NewHooks (89-99)
pkg/resolver/dependency.go (1)
  • NewDependencyWithNamespace (114-118)
pkg/subcmd/config.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/subcmd/integration.go (4)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • IntegrationName (15-15)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/api/subcommand.go (1)
  • NewRunner (36-47)
🔇 Additional comments (66)
pkg/hooks/hooks_test.go (3)

5-5: LGTM: Import changes align with new API surface.

The addition of os for os.DirFS and the switch from constants to api for NewAppContext are necessary and correct for the framework refactor.

Also applies to: 8-8


20-20: LGTM: Filesystem creation correctly updated for new API.

The change from chartfs.NewChartFS to chartfs.New(os.DirFS(...)) correctly reflects the new API signature where chartfs.New no longer returns an error. The test will still fail appropriately if the path is invalid when GetChartFiles is called.


25-27: LGTM: AppContext integration correctly implemented.

The introduction of api.NewAppContext("tssc") and passing both appCtx.Namespace and appCtx to NewDependencyWithNamespace correctly implements the centralized application metadata pattern described in the PR objectives.

pkg/installer/job.go (2)

8-8: LGTM: Import and field changes support the AppContext refactoring.

The switch from constants to the api package and the addition of the repoURI field align with the framework's goal of dynamic, per-instance labeling based on application context.

Also applies to: 25-25


57-57: LGTM: Consistent use of instance-based label selector.

All call sites correctly use j.LabelSelector() for queries, resource labels, and command generation, replacing the previous constant-based approach with dynamic, per-instance labeling.

Also applies to: 224-224, 229-229, 260-260

pkg/subcmd/integration_artifactory.go (2)

6-7: LGTM – AppContext integration follows the established pattern.

The import, field addition, and interface assertion update align with the broader refactor to centralize application metadata via AppContext. Dependencies are correctly injected via the constructor as per coding guidelines.

Also applies to: 17-27, 29-29


44-48: Constructor and Complete method correctly propagate appCtx.

The constructor signature and initialization properly wire appCtx, and Complete correctly passes it to bootstrapConfig. This follows the consistent pattern across integration subcommands.

Also applies to: 63-81

pkg/subcmd/integration_quay.go (2)

6-7: LGTM – Consistent AppContext refactor pattern.

The changes mirror the established pattern across integration subcommands: import addition, field inclusion, and interface assertion update to api.SubCommand.

Also applies to: 17-24, 26-26


54-57: Constructor and Complete wiring is correct.

The appCtx is properly injected via the constructor and propagated to bootstrapConfig in the Complete method, maintaining consistency with other integration subcommands.

Also applies to: 72-93

pkg/subcmd/integration_nexus.go (2)

6-7: LGTM – Follows established refactor pattern.

Import, struct field, and interface assertion changes are consistent with the broader AppContext migration across integration subcommands.

Also applies to: 17-24, 26-26


42-46: Constructor and Complete correctly wired.

The appCtx propagation through the constructor and into bootstrapConfig is correctly implemented.

Also applies to: 60-81

pkg/subcmd/integration_jenkins.go (2)

6-7: LGTM – Consistent with the integration subcommand refactor.

The api import, appCtx field addition, and api.SubCommand interface assertion follow the established pattern.

Also applies to: 17-24, 26-26


42-46: Constructor and Complete method correctly implemented.

appCtx is properly accepted, stored, and forwarded to bootstrapConfig, consistent with sibling integration subcommands.

Also applies to: 60-81

pkg/subcmd/integration_trustification.go (2)

6-7: LGTM – Follows established integration subcommand pattern.

The api import, appCtx field, and api.SubCommand interface assertion are correctly added, maintaining consistency across integration subcommands.

Also applies to: 17-24, 26-26


42-46: Constructor and Complete wiring is correct.

appCtx is properly injected and propagated to bootstrapConfig, completing the refactor pattern.

Also applies to: 61-82

pkg/api/constants.go (1)

3-15: Duplicate constant definitions detected.

These constants (ConfigFilename, ValuesFilename, InstructionsFilename) are identically defined in pkg/constants/constants.go. This violates DRY principles. Consider consolidating to a single source of truth—either here in pkg/api (if it's the public API surface) or in pkg/constants, then import where needed.

Likely an incorrect or invalid review comment.

pkg/constants/constants.go (1)

3-15: Duplicate constants – consolidation needed.

As noted in a previous review, these constants are duplicated in pkg/api/constants.go. The AI summary states this file should be "the singular source," but identical definitions exist elsewhere. Consider having one package own these constants and having others import from it.

Likely an incorrect or invalid review comment.

pkg/subcmd/integration_bitbucket.go (2)

17-26: LGTM! Clean integration of AppContext into the subcommand struct.

The addition of appCtx field and the interface assertion change to api.SubCommand align well with the broader framework refactoring. The pattern follows project conventions for dependency injection via constructors.


60-78: Constructor signature change is consistent with other integration modules.

The updated NewIntegrationBitBucket properly accepts and stores appCtx, and the Complete method correctly propagates it to bootstrapConfig. This follows the established pattern across other integration subcommands.

pkg/subcmd/config.go (4)

20-38: LGTM! AppContext integration follows the established pattern.

The struct field addition and interface assertion change to api.SubCommand are consistent with the broader refactoring. Dependencies continue to be injected via the constructor as per project guidelines.


81-87: Good use of appCtx.Namespace for dynamic default value.

Using c.appCtx.Namespace instead of a hardcoded constant enables the framework to support different applications with their own default namespaces.


176-182: Correctly updated resolver.NewCollection call with appCtx.

The call signature now matches the updated NewCollection function that requires appCtx for dependency construction, as shown in the relevant code snippets.


283-308: Constructor properly wires AppContext and returns the interface type.

The updated signature accepting appCtx and returning api.SubCommand aligns with the framework's plugin architecture. The appCtx is correctly stored and used in flag defaults.

pkg/chartfs/chartfs_test.go (1)

10-20: LGTM! Test updated to use the new fs.FS-based constructor.

The change from NewChartFS to New(os.DirFS("../../installer")) correctly aligns with the refactored ChartFS API that accepts any fs.FS. The path adjustment for ReadFile to "values.yaml.tpl" is appropriate since the filesystem is now rooted at the installer directory. This follows the coding guidelines for implementing an io.FS compatible abstraction in pkg/chartfs.

pkg/framework/mcpserver/mcpserver.go (1)

24-32: LGTM! Constructor now supports dynamic app metadata and instructions.

The refactored NewMCPServer properly uses appCtx.Name and appCtx.Version for server identification, enabling the framework to support different applications with their own branding. Passing instructions as a parameter instead of embedding them improves flexibility for reuse.

pkg/subcmd/config_helper.go (1)

13-30: LGTM! Dynamic application naming in error messages.

The updated bootstrapConfig function properly uses appCtx.Name to generate contextual error messages. This enables the framework to display appropriate subcommand paths (e.g., tssc config) for different applications built on this framework.

pkg/resolver/collection.go (1)

98-106: LGTM! AppContext propagation to dependencies enables dynamic annotation keys.

The updated NewCollection properly passes appCtx to each NewDependency call, allowing dependencies to use application-specific annotation keys. This aligns with the Dependency struct that stores appCtx for annotation key resolution, as shown in the relevant code snippets from pkg/resolver/dependency.go.

cmd/tssc/main.go (3)

20-35: LGTM! Clean initialization flow with proper error handling.

The initialization sequence properly creates a tarball-based filesystem, overlays it with the local working directory, and wraps it with ChartFS. Error handling is explicit, addressing the concern from previous reviews about silent error handling. The overlay pattern cleanly combines embedded resources with local overrides.


53-67: LGTM! Unified app lifecycle with framework.NewApp.

The application creation and execution flow is clean. Dependencies are wired through functional options (WithIntegrations, WithMCPImage), and error handling properly exits with status code 1 on failures.


37-51: Application context and MCP image configuration look correct.

The TSSC-specific context is properly initialized with build-time metadata. The MCP image tagging logic using commitID provides a reasonable strategy: latest for development builds (empty commitID) and specific commit tags for release builds. The go:embed directive is correctly implemented in installer/embed.go for embedding installer resources, and no hardcoded API keys or sensitive credentials are present in the file.

pkg/resolver/collection_test.go (1)

4-22: LGTM! Clean test adaptation to new API.

The test correctly adapts to the refactored APIs:

  • Uses os.DirFS with chartfs.New(fs.FS) instead of NewChartFS(path string)
  • Creates AppContext via api.NewAppContext("tssc") and passes it to NewCollection
  • Maintains existing test assertions while adapting to new constructor signatures

These changes align with the PR's goal of making the framework more generic and reusable.

pkg/resolver/dependency_test.go (1)

4-22: LGTM! Consistent test migration.

The test adapts to the new API surface consistently with other resolver tests:

  • Replaces NewChartFS with chartfs.New(os.DirFS(...))
  • Threads AppContext through to NewDependency
  • Preserves all existing test assertions

The changes align with the dependency injection pattern established across the PR.

pkg/subcmd/integration_acs.go (2)

6-26: LGTM! Proper AppContext integration.

The struct correctly:

  • Adds appCtx *api.AppContext field for application context
  • Migrates from local Interface to api.SubCommand (enabling external framework use)
  • Follows the established pattern across integration subcommands

44-74: LGTM! AppContext properly threaded through.

The changes correctly:

  • Pass appCtx to bootstrapConfig in the Complete method
  • Extend the constructor to accept appCtx parameter
  • Assign appCtx during struct initialization

The dependency injection pattern is consistent with coding guidelines and other subcommands in this PR.

pkg/subcmd/template.go (2)

7-38: LGTM! Consistent struct refactoring.

The struct changes follow the established pattern:

  • Adds appCtx *api.AppContext for application context
  • Migrates to api.SubCommand interface
  • Maintains proper field ordering and documentation

87-166: LGTM! AppContext properly propagated.

The changes correctly thread AppContext through the template workflow:

  • Passes appCtx to NewDependencyWithNamespace for dependency initialization
  • Passes appCtx to bootstrapConfig for configuration loading
  • Extends constructor to accept and assign appCtx

The dependency injection follows the established pattern per coding guidelines.

pkg/subcmd/integration_gitlab.go (1)

6-74: LGTM! Consistent integration command refactoring.

The changes mirror the pattern established in integration_acs.go:

  • Adds appCtx *api.AppContext field to the struct
  • Migrates from local Interface to api.SubCommand
  • Threads appCtx through bootstrapConfig in Complete
  • Extends constructor to accept and assign appCtx

All changes align with the framework refactoring objectives and maintain consistency across integration subcommands.

pkg/subcmd/integration_trustedartifactsigner.go (2)

17-27: Consistent AppContext wiring aligns with the framework refactor.

The struct correctly holds appCtx and implements api.SubCommand. Dependencies are properly injected via the constructor, following the project's established patterns. Based on learnings, this follows the guideline to inject dependencies like k8s.Kube via constructors in command structs.


59-80: Constructor properly wires AppContext and dependencies.

The constructor follows the established pattern of accepting all dependencies as parameters and initializing the struct fields correctly.

pkg/subcmd/integration_azure.go (1)

17-27: Consistent with the AppContext refactor pattern.

The changes mirror the pattern used in other integration subcommands, properly implementing api.SubCommand and injecting dependencies via the constructor.

pkg/mcptools/context.go (2)

14-27: Well-designed context struct with clear documentation.

The MCPToolsContext struct properly encapsulates all dependencies needed for MCP tools. The documentation clearly explains the io.Discard requirement for the logger to protect MCP STDIO protocol integrity.


29-53: Builder pattern enables flexible tool registration.

The NewMCPToolsContext constructor and MCPToolsBuilder type provide a clean API for consumers to customize MCP tool creation. The critical comment at line 41 appropriately warns about the logger requirement.

pkg/subcmd/integration.go (2)

16-22: Constructor signature properly updated for modular integration loading.

The function now accepts appCtx and manager parameters, enabling dynamic integration wiring via the manager's module registry.


76-80: Dynamic module registration enables extensibility.

The loop iterates over registered modules from the manager, creates subcommands via the module's Command factory, and wires them through api.NewRunner. This pattern enables consumers to customize which integrations are included.

pkg/subcmd/integration_github.go (1)

18-31: Consistent AppContext integration with dynamic naming.

The struct properly holds appCtx and implements api.SubCommand. The interface assertion is correctly updated.

pkg/subcmd/deploy.go (4)

23-38: Struct properly extended with AppContext and integration manager.

The Deploy struct now holds appCtx and manager as fields, with the interface assertion correctly updated to api.SubCommand. Dependencies are injected via the constructor as per project guidelines.


76-92: Complete method properly initializes topology with AppContext.

The TopologyBuilder and bootstrapConfig calls correctly receive appCtx, centralizing application metadata throughout the command lifecycle.


116-128: Dynamic app name in user-facing error messages.

Using d.appCtx.Name instead of hardcoded strings enables the CLI to be rebranded while maintaining helpful error messages that guide users to the correct subcommands.


193-218: Constructor signature and return type properly updated.

The NewDeploy function now accepts appCtx and manager, returning api.SubCommand for consistent interface compliance across subcommands.

pkg/subcmd/modules.go (2)

12-122: Well-structured module definitions following the IntegrationModule contract.

Each module correctly implements the api.IntegrationModule contract with Name, Init, and Command fields. The use of integrations.XXX constants for names ensures consistency with the manager's integration registry.


124-139: StandardModules provides sensible defaults for common use cases.

The function returns all standard integration modules in a defined order. As confirmed in past review comments, consumers can customize which modules to include via the WithIntegrations functional option, making this a sensible default rather than a mandatory set.

pkg/mcptools/notestool.go (3)

21-29: LGTM! Clean struct with proper field documentation and dependency injection.

The struct fields are well-documented, and the refactoring to accept appName and job via the constructor aligns with the dependency injection pattern. Based on learnings, injecting dependencies like k8s.Kube and related components via constructors is the recommended approach.


116-133: Dynamic tool naming correctly implemented.

The Init method properly uses the per-instance name n.appName+notesSuffix for MCP tool registration, enabling dynamic branding as intended by the PR objectives.


135-153: Constructor properly initializes all fields.

The constructor signature correctly accepts all dependencies including the new appName and job parameters, and initializes all struct fields. This follows the dependency injection pattern recommended for this codebase.

pkg/subcmd/mcpserver.go (3)

19-31: Struct properly refactored with api.SubCommand compliance.

The struct now correctly includes appCtx which resolves the previous issue where appName was not initialized. The interface assertion var _ api.SubCommand = &MCPServer{} ensures compile-time verification of interface compliance.


59-86: Well-structured Run method with proper error handling.

The method correctly:

  1. Creates MCPToolsContext using the constructor (ensuring logger uses io.Discard for MCP STDIO protocol compatibility as noted in the context)
  2. Uses the builder pattern to create tools
  3. Reads instructions from the embedded filesystem using standardized constants
  4. Properly wraps errors with context using fmt.Errorf

98-116: Constructor properly initializes all fields including appCtx.

The previous review issue about missing appName initialization is resolved. The constructor now correctly sets appCtx at line 105, which is used in Run() to create the MCP server with proper application metadata.

pkg/framework/app.go (5)

21-33: Well-documented App struct with clear field organization.

The struct separates public fields (AppCtx, ChartFS) from internal runtime state. The comment clearly states that AppCtx is the single source of truth for application metadata, aligning with the PR objective to centralize application metadata.


47-58: Good defensive programming with fallback for empty short description.

The check at lines 49-51 provides a sensible default (appCtx.Name + " installer") when Short is not provided, preventing empty CLI descriptions.


88-98: Appropriate validation for required MCP configuration.

The validation at lines 95-98 ensures mcpImage is configured before proceeding, providing a clear error message directing users to use WithMCPImage(). This fail-fast approach prevents cryptic runtime errors.


156-179: Constructor follows functional options pattern correctly.

The constructor properly:

  1. Initializes core required fields first
  2. Applies functional options to allow customization
  3. Creates the Kubernetes client after options (allowing flags to be modified by options if needed)
  4. Calls setupRootCmd() and propagates errors

This follows the established pattern for configurable constructors in Go.


83-86: The pattern difference is intentional. NewIntegration returns *cobra.Command directly because it is a parent command that groups integration-specific subcommands (github, gitlab, quay, etc.). The other subcommands (config, deploy, template, etc.) implement the SubCommand interface and are wrapped with api.NewRunner() to enable lifecycle management (Complete, Validate, Run). The different registration patterns correctly reflect their architectural roles: NewIntegration is a command container, while the others are leaf commands with business logic.

pkg/resolver/annotations.go (2)

9-17: Clean constant definitions for annotation suffixes.

The unexported suffix constants are well-organized and follow a consistent naming pattern. This approach keeps the implementation details private while exposing only the necessary functions.


19-52: RepoURI() method is correctly defined on api.AppContext.

The RepoURI() method exists at pkg/api/appcontext.go:25 with the correct signature func (a *AppContext) RepoURI() string. All annotation functions in lines 19-52 correctly call this method to build annotation keys.

pkg/subcmd/mcptools.go (2)

10-15: LGTM! Clean delegation pattern.

The public entry point correctly exposes the builder function while keeping the implementation private.


83-90: LGTM! All standard MCP tools properly constructed.

The tools are returned in a consistent order with all necessary dependencies injected. The construction pattern follows the builder approach correctly.

Migrating from hardcoded constants to a context-driven architecture
where `AppContext` serves as the single source of truth for application
metadata.

Assisted-by: Claude
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 7, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

Release Notes

  • Chores
  • Restructured internal application framework for improved modularity and extensibility
  • Updated Go linter configuration to enforce additional code quality standards
  • Refactored configuration and filesystem handling for streamlined setup
  • Moved template configuration file location to root installer directory for simpler access
  • Enhanced build process to embed version and commit information at compile time

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/mcptools/configtools.go (1)

287-329: Critical: Product data loss when toggling enabled status.

Line 318 updates spec.Enabled, but line 320 creates a new config.Product{Enabled: enabled} and passes it to setProduct, discarding the original spec. This causes the product's namespace, properties, and other fields to be lost.

🐛 Fix to preserve existing product fields
 	// Toggle the product status.
 	spec.Enabled = enabled
 
-	if res = c.setProduct(ctx, cfg, name, config.Product{Enabled: enabled}); res != nil {
+	if res = c.setProduct(ctx, cfg, name, *spec); res != nil {
 		return res, nil
 	}
🧹 Nitpick comments (3)
cmd/tssc/main.go (1)

45-51: Consider documenting the MCP image tagging strategy.

The logic using commitID to select between :latest and :<commitID> tags is sound for development/release workflows. A brief inline comment explaining the rationale (e.g., "latest for local builds, commit-specific for CI builds") would help future maintainers.

pkg/framework/app.go (1)

156-179: Consider adding nil-safety checks for required parameters.

The constructor accepts appCtx and cfs without validation. If either is nil, downstream code (e.g., appCtx.RepoURI() in annotations, cfs.ReadFile() in deploy) will panic. Consider adding early validation:

if appCtx == nil {
    return nil, fmt.Errorf("appCtx is required")
}
if cfs == nil {
    return nil, fmt.Errorf("chartfs is required")
}
pkg/subcmd/mcpserver.go (1)

53-56: Consider adding defensive validation for required dependencies.

While the framework likely guarantees non-nil dependencies, Validate() could defensively check that mcpToolsBuilder is not nil to prevent potential panics in Run() at line 71.

♻️ Suggested validation
 func (m *MCPServer) Validate() error {
+	if m.mcpToolsBuilder == nil {
+		return fmt.Errorf("MCPToolsBuilder is required")
+	}
 	return nil
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05c6c25 and 5c77acc.

📒 Files selected for processing (42)
  • cmd/tssc/main.go
  • pkg/api/appcontext.go
  • pkg/api/types.go
  • pkg/chartfs/chartfs_test.go
  • pkg/constants/constants.go
  • pkg/framework/app.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/framework/options.go
  • pkg/hooks/hooks_test.go
  • pkg/installer/job.go
  • pkg/mcptools/configtools.go
  • pkg/mcptools/context.go
  • pkg/mcptools/notestool.go
  • pkg/resolver/annotations.go
  • pkg/resolver/collection.go
  • pkg/resolver/collection_test.go
  • pkg/resolver/dependency.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/resolver_test.go
  • pkg/resolver/topology_test.go
  • pkg/resolver/topologybuilder.go
  • pkg/subcmd/config.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/integration_azure.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/mcpserver.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/template.go
  • pkg/subcmd/topology.go
🚧 Files skipped from review as they are similar to previous changes (16)
  • pkg/resolver/topologybuilder.go
  • pkg/framework/options.go
  • pkg/subcmd/integration_jenkins.go
  • pkg/resolver/resolver_test.go
  • pkg/api/types.go
  • pkg/subcmd/integration_acs.go
  • pkg/subcmd/mcptools.go
  • pkg/constants/constants.go
  • pkg/resolver/dependency_test.go
  • pkg/api/appcontext.go
  • pkg/hooks/hooks_test.go
  • pkg/mcptools/notestool.go
  • pkg/subcmd/installer.go
  • pkg/subcmd/integration_azure.go
  • pkg/resolver/collection_test.go
  • pkg/chartfs/chartfs_test.go
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • pkg/resolver/collection.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/mcptools/context.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/resolver/annotations.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/resolver/topology_test.go
  • pkg/subcmd/integration_quay.go
  • pkg/framework/app.go
  • pkg/mcptools/configtools.go
  • pkg/subcmd/mcpserver.go
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/resolver/collection.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/mcptools/context.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/framework/mcpserver/mcpserver.go
  • pkg/resolver/annotations.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/resolver/topology_test.go
  • pkg/subcmd/integration_quay.go
  • pkg/framework/app.go
  • pkg/mcptools/configtools.go
  • pkg/subcmd/mcpserver.go
pkg/resolver/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use pkg/resolver to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Files:

  • pkg/resolver/collection.go
  • pkg/resolver/dependency.go
  • pkg/resolver/annotations.go
  • pkg/resolver/topology_test.go
pkg/subcmd/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

pkg/subcmd/**/*.go: Use cobra library for CLI command structure in the tssc-cli project
Define commands as structs in pkg/subcmd that implement a common interface
Use specific validateFlags() methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators
Inject dependencies like k8s.Kube and chartfs.ChartFS via constructors in command structs

Files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_quay.go
  • pkg/subcmd/mcpserver.go
**/*_test.go

📄 CodeRabbit inference engine (GEMINI.md)

Use the standard testing package with github.com/onsi/gomega assertion library for tests

Files:

  • pkg/resolver/topology_test.go
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/resolver/**/*.go : Use `pkg/resolver` to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Applied to files:

  • pkg/resolver/collection.go
  • pkg/subcmd/config.go
  • pkg/subcmd/deploy.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/resolver/annotations.go
  • pkg/subcmd/template.go
  • pkg/resolver/topology_test.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • pkg/resolver/collection.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/mcptools/context.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/resolver/dependency.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/resolver/topology_test.go
  • pkg/subcmd/integration_quay.go
  • pkg/framework/app.go
  • pkg/subcmd/mcpserver.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/engine/**/*.go : Use Helm SDK in `pkg/engine` for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Applied to files:

  • pkg/resolver/collection.go
  • pkg/subcmd/config.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/template.go
  • pkg/resolver/topology_test.go
  • pkg/framework/app.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/chartfs/**/*.go : Implement `io.FS` compatible abstraction in `pkg/chartfs` to provide access to embedded installer directory resources

Applied to files:

  • pkg/resolver/collection.go
  • pkg/subcmd/config.go
  • cmd/tssc/main.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/template.go
  • pkg/resolver/topology_test.go
  • pkg/framework/app.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • pkg/resolver/collection.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/resolver/collection.go
  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/integration/**/*.go : Define integrations in `pkg/integration` to connect to external services like GitHub, Quay, etc.

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Define commands as structs in `pkg/subcmd` that implement a common interface

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • cmd/tssc/main.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/modules.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Define interface definition at the top of service files, followed by service struct and implementation

Applied to files:

  • pkg/subcmd/integration_nexus.go
  • pkg/subcmd/config.go
  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
  • pkg/subcmd/integration_trustedartifactsigner.go
  • pkg/subcmd/deploy.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/integration_artifactory.go
  • pkg/subcmd/template.go
  • pkg/subcmd/integration_bitbucket.go
  • pkg/subcmd/integration_trustification.go
  • pkg/subcmd/integration_gitlab.go
  • pkg/subcmd/integration_quay.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : All tests must use the `testing` package with `testify/assert` library

Applied to files:

  • pkg/subcmd/config.go
  • pkg/subcmd/integration_github.go
  • pkg/subcmd/topology.go
  • pkg/subcmd/template.go
  • pkg/resolver/topology_test.go
📚 Learning: 2025-08-20T15:48:01.881Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.

Applied to files:

  • cmd/tssc/main.go
📚 Learning: 2025-09-29T15:10:13.650Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/config/config.go:159-185
Timestamp: 2025-09-29T15:10:13.650Z
Learning: In the tssc-cli project, the UpdateMappingValue method in pkg/config/config.go should only update existing configuration keys and not create new ones. Adding new config entries is not allowed, so silent return when key is not found is the desired behavior.

Applied to files:

  • cmd/tssc/main.go
  • pkg/mcptools/configtools.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*.go : Use `go:embed` directive to embed `installer` directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Applied to files:

  • cmd/tssc/main.go
  • pkg/subcmd/deploy.go
  • pkg/framework/app.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `interface{}`, use the `any` alias instead

Applied to files:

  • pkg/subcmd/integration_github.go
  • pkg/installer/job.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `int`, use `int64` instead (applies to both slices and maps)

Applied to files:

  • pkg/installer/job.go
📚 Learning: 2025-08-27T18:30:02.411Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1190
File: pkg/resolver/resolver_test.go:52-67
Timestamp: 2025-08-27T18:30:02.411Z
Learning: In tssc-cli, there is a distinction between deployment namespace (where resources are deployed, referenced in values.yaml.tpl) and chart registration namespace (where Helm charts are registered, tested in resolver tests). These are different concepts and may use different namespace values.

Applied to files:

  • pkg/subcmd/deploy.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*_test.go : Use the standard `testing` package with `github.com/onsi/gomega` assertion library for tests

Applied to files:

  • pkg/resolver/topology_test.go
📚 Learning: 2025-09-29T14:49:45.227Z
Learnt from: lingyzhuang
Repo: redhat-appstudio/tssc-cli PR: 1276
File: pkg/mcptools/configtools.go:0-0
Timestamp: 2025-09-29T14:49:45.227Z
Learning: In pkg/mcptools/configtools.go, the SettingsArg and ProductsArg constants are used for Gemini input generation, where Gemini uses these parameter names to generate input and the system reads the input content by these argument names.

Applied to files:

  • pkg/mcptools/configtools.go
🧬 Code graph analysis (19)
pkg/resolver/collection.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/resolver/dependency.go (2)
  • Dependency (15-19)
  • NewDependency (108-110)
pkg/mcptools/context.go (5)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/flags/flags.go (1)
  • Flags (17-24)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/integrations/manager.go (1)
  • Manager (20-23)
cmd/tssc/main.go (8)
pkg/framework/tarfs.go (1)
  • NewTarFS (11-13)
installer/embed.go (1)
  • InstallerTarball (9-9)
pkg/chartfs/overlay.go (1)
  • NewOverlayFS (17-22)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/api/appcontext.go (4)
  • NewAppContext (84-99)
  • WithVersion (54-58)
  • WithCommitID (61-65)
  • WithShortDescription (68-72)
pkg/framework/app.go (1)
  • NewApp (156-179)
pkg/framework/options.go (2)
  • WithIntegrations (14-18)
  • WithMCPImage (21-25)
pkg/subcmd/modules.go (1)
  • StandardModules (125-139)
pkg/subcmd/integration_github.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/config/manager.go (1)
  • Name (25-25)
pkg/installer/job.go (1)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/deploy.go (4)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/integrations/manager.go (1)
  • Manager (20-23)
pkg/resolver/topologybuilder.go (1)
  • TopologyBuilder (15-19)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/dependency.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/resolver/annotations.go (6)
  • AnnotationDependsOn (27-29)
  • AnnotationWeight (32-34)
  • AnnotationProductName (21-23)
  • AnnotationUseProductNamespace (38-40)
  • AnnotationIntegrationsProvided (44-46)
  • AnnotationIntegrationsRequired (50-52)
pkg/subcmd/config_helper.go (4)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/k8s/kube.go (1)
  • Kube (21-23)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/config/manager.go (2)
  • NewConfigMapManager (176-180)
  • Name (25-25)
pkg/subcmd/integration.go (4)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • IntegrationName (15-15)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/api/subcommand.go (1)
  • NewRunner (36-47)
pkg/subcmd/integration_artifactory.go (2)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/framework/mcpserver/mcpserver.go (2)
pkg/subcmd/mcpserver.go (2)
  • NewMCPServer (89-116)
  • MCPServer (19-29)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/resolver/annotations.go (1)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/template.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/dependency.go (1)
  • NewDependencyWithNamespace (114-118)
pkg/subcmd/integration_bitbucket.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_trustification.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/subcmd/integration_gitlab.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/resolver/topology_test.go (3)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/api/appcontext.go (1)
  • NewAppContext (84-99)
pkg/resolver/dependency.go (1)
  • NewDependencyWithNamespace (114-118)
pkg/subcmd/integration_quay.go (3)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/subcmd/config.go (1)
  • Config (20-36)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
pkg/framework/app.go (15)
pkg/api/appcontext.go (1)
  • AppContext (13-22)
pkg/chartfs/chartfs.go (1)
  • ChartFS (15-17)
pkg/api/types.go (1)
  • IntegrationModule (13-28)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • NewManager (112-117)
pkg/flags/flags.go (2)
  • Flags (17-24)
  • NewFlags (72-93)
pkg/k8s/kube.go (2)
  • Kube (21-23)
  • NewKube (143-145)
pkg/subcmd/integration.go (1)
  • NewIntegration (16-83)
pkg/subcmd/mcptools.go (1)
  • StandardMCPToolsBuilder (13-15)
pkg/api/subcommand.go (2)
  • SubCommand (9-22)
  • NewRunner (36-47)
pkg/subcmd/config.go (1)
  • NewConfig (284-309)
pkg/subcmd/deploy.go (1)
  • NewDeploy (194-219)
pkg/subcmd/installer.go (1)
  • NewInstaller (217-236)
pkg/subcmd/mcpserver.go (1)
  • NewMCPServer (89-116)
pkg/subcmd/template.go (1)
  • NewTemplate (150-186)
pkg/subcmd/topology.go (1)
  • NewTopology (86-105)
🔇 Additional comments (55)
pkg/mcptools/context.go (2)

14-27: LGTM! Well-designed context struct for MCP tools.

The MCPToolsContext follows a clean dependency injection pattern with all necessary components for MCP tool creation. The public fields are appropriate for a context struct that serves as a parameter object.


31-49: Excellent enforcement of MCP STDIO protocol requirements.

The constructor correctly forces io.Discard for the logger (line 42), preventing any stdout/stderr output that would corrupt the MCP protocol. The inline documentation (lines 16-18 and 41) clearly explains this critical requirement.

pkg/resolver/topology_test.go (2)

16-19: LGTM! Test properly updated for new ChartFS and AppContext APIs.

The migration from chartfs.NewChartFS("../../installer") to chartfs.New(os.DirFS("../../installer")) aligns with the refactoring to use fs.FS interface. The addition of appCtx initialization (line 19) correctly provides the required context for dependency construction.


23-35: Consistent AppContext propagation in test.

All NewDependencyWithNamespace calls have been properly updated to include the appCtx parameter, maintaining consistency throughout the test.

pkg/subcmd/config_helper.go (1)

14-31: Verify all callers of bootstrapConfig have been updated.

The function signature changed from bootstrapConfig(ctx context.Context, kube *k8s.Kube) to bootstrapConfig(ctx context.Context, appCtx *api.AppContext, kube *k8s.Kube). This is a breaking API change that requires the new appCtx parameter. The dynamic error messaging using appCtx.Name is a good improvement over hardcoded constants.

pkg/resolver/collection.go (1)

100-106: All callers of NewCollection have been properly updated.

Verification confirms all 6 call sites across the codebase pass the new appCtx parameter as the first argument (topology.go, integration.go, config.go, topologybuilder.go, and both test files). No outdated calls remain.

pkg/framework/mcpserver/mcpserver.go (1)

24-33: All callers properly provide required parameters.

Verification confirms that the only caller of NewMCPServer (at pkg/subcmd/mcpserver.go:82) correctly provides both the appCtx with Name and Version fields and the instructions string. Instructions are dynamically loaded from file storage, not hardcoded, ensuring proper separation of configuration and code.

cmd/tssc/main.go (2)

20-35: LGTM! Clean initialization with proper error handling.

The filesystem setup correctly handles errors for both tarball reading and working directory retrieval. The overlay filesystem composition (embedded tarball + local cwd) follows the expected pattern for the framework refactor.


53-67: LGTM! Framework wiring follows the new architecture.

The application is properly constructed with AppContext, ChartFS, integrations, and MCP image. Error handling paths are appropriate. Dependencies are correctly injected via constructors as per coding guidelines.

pkg/subcmd/integration_bitbucket.go (2)

17-26: LGTM! AppContext integration follows the established pattern.

The struct correctly adds appCtx field and implements api.SubCommand. This aligns with the PR's goal of centralizing application metadata and follows the coding guideline to inject dependencies via constructors.


60-81: LGTM! Constructor properly injects all dependencies.

The constructor signature correctly accepts appCtx as the first parameter, consistent with other integration subcommands. Dependencies (logger, kube, integration) are properly injected as per coding guidelines.

pkg/subcmd/template.go (2)

18-38: LGTM! Template struct properly extended with AppContext.

The struct correctly incorporates appCtx and implements api.SubCommand. The field ordering is consistent with other subcommands in the package.


74-93: LGTM! Complete method properly propagates AppContext.

Both NewDependencyWithNamespace and bootstrapConfig correctly receive appCtx, enabling app-scoped naming and configuration throughout the dependency resolution and bootstrap flows.

pkg/subcmd/integration.go (2)

16-22: LGTM! Function signature properly expanded for framework wiring.

The constructor now accepts appCtx and manager, enabling dynamic integration loading. This aligns with the PR's goal of a modular plugin system.


76-80: The concern is unfounded; manager.Integration() cannot return nil.

The Integration() method in pkg/integrations/manager.go (lines 40-45) either returns a valid *integration.Integration or panics if the integration is not found. It explicitly checks the map and calls panic() if the integration instance doesn't exist, making it impossible for nil to be returned.

pkg/subcmd/integration_artifactory.go (2)

15-29: LGTM! Consistent with the integration subcommand pattern.

The struct properly adds appCtx and implements api.SubCommand, matching the pattern established across other integration files.


63-84: LGTM! Constructor follows dependency injection guidelines.

Dependencies are properly injected via the constructor, consistent with coding guidelines for pkg/subcmd/**/*.go.

pkg/installer/job.go (2)

300-308: LGTM! Constructor properly derives instance-specific values from AppContext.

The constructor correctly extracts appName and repoURI from the provided AppContext, enabling per-instance resource naming and labeling. This supports the framework's goal of running multiple installations.


29-32: Label value validation still missing.

The LabelSelector() returns "installer-job." + j.repoURI where repoURI is derived from appCtx.RepoURI(). Kubernetes label values must not exceed 63 characters and must match ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$. There's no validation to ensure the combined label value conforms to these constraints.

Consider adding validation in NewJob or in AppContext construction to prevent runtime failures when applying labels.

Likely an incorrect or invalid review comment.

pkg/subcmd/integration_gitlab.go (2)

15-26: LGTM! Consistent AppContext integration.

The struct correctly adds appCtx and implements api.SubCommand, following the same pattern as other integration subcommands.


60-81: LGTM! Constructor properly wired with AppContext.

Dependencies are correctly injected via the constructor, and appCtx is properly stored for use in Complete. This follows the established pattern and coding guidelines.

pkg/subcmd/integration_quay.go (1)

6-7: LGTM! Clean refactoring to centralize AppContext.

The changes consistently propagate appCtx through the constructor, struct fields, and bootstrapConfig invocation, aligning with the framework-wide migration to api.SubCommand. The dependency injection pattern follows coding guidelines.

Also applies to: 19-19, 26-26, 56-56, 73-73, 86-86

pkg/subcmd/integration_trustification.go (1)

6-7: LGTM! Consistent with the AppContext refactoring pattern.

The changes mirror the pattern in integration_quay.go and other subcommands, ensuring uniform propagation of appCtx throughout the integration commands.

Also applies to: 19-19, 26-26, 44-44, 62-62, 75-75

pkg/subcmd/config.go (1)

7-7: LGTM! Excellent migration to centralized AppContext.

Key improvements:

  • Line 85: Replacing hardcoded constants.Namespace with c.appCtx.Namespace improves configurability
  • Line 178: Passing appCtx to resolver.NewCollection aligns with the new collection signature
  • Lines 285,290: Return type changed to api.SubCommand enables framework-level abstractions

The refactoring is systematic and preserves the existing logic while adding the centralized context.

Also applies to: 26-26, 38-38, 85-85, 178-178, 285-285, 290-290, 302-302

pkg/subcmd/integration_trustedartifactsigner.go (1)

6-7: LGTM! Consistent AppContext integration.

The refactoring follows the established pattern across all integration subcommands, maintaining consistency in how appCtx is threaded through constructors and bootstrap flows.

Also applies to: 19-19, 26-26, 42-42, 60-60, 73-73

pkg/subcmd/topology.go (1)

7-7: LGTM! Well-integrated AppContext refactoring.

The changes properly thread appCtx through both resolver.NewCollection (line 57) and bootstrapConfig (line 61), ensuring the topology command has consistent access to application metadata throughout its lifecycle.

Also applies to: 21-21, 29-29, 57-57, 61-61, 87-87, 100-100

pkg/resolver/dependency.go (2)

15-19: LGTM!

The Dependency struct properly includes the appCtx field with clear comments. The field ordering is logical and the integration with the annotation lookup methods is consistent.


62-104: LGTM!

All annotation lookup methods consistently use the appCtx-aware annotation functions. The error message in Weight() correctly references the dynamic annotation key.

pkg/subcmd/integration_github.go (3)

18-28: LGTM!

The struct properly includes appCtx field and follows the coding guideline of defining commands as structs that implement a common interface. Dependencies are correctly injected via the constructor.


51-91: LGTM!

The Complete method properly passes appCtx to bootstrapConfig, and Run correctly uses g.appCtx.Name for dynamic application branding in the panic message.


95-123: LGTM!

The constructor properly injects dependencies including appCtx, logger, kube, and integration. This follows the coding guideline of injecting dependencies via constructors in command structs. Based on learnings, this is the expected pattern.

pkg/subcmd/integration_nexus.go (2)

17-26: LGTM!

The struct properly includes the appCtx field and implements api.SubCommand. Consistent with the pattern used across other integration subcommands.


60-81: LGTM!

The constructor correctly injects appCtx and other dependencies following the established pattern. The Complete method properly passes appCtx to bootstrapConfig.

pkg/subcmd/deploy.go (4)

22-36: LGTM!

The Deploy struct properly includes appCtx and manager fields with appropriate comments. The struct follows the coding guideline of defining commands that implement a common interface.


76-92: LGTM!

The Complete method correctly passes appCtx and manager to NewTopologyBuilder and appCtx to bootstrapConfig. The integration with the new architecture is properly wired.


114-128: LGTM!

The error message correctly uses d.appCtx.Name for dynamic application branding, enabling the framework to be reused across different installer applications.


193-218: LGTM!

The constructor properly injects all dependencies (appCtx, logger, flags, cfs, kube, manager) and returns api.SubCommand. This follows the coding guideline of injecting dependencies via constructors in command structs. Based on learnings, this is the expected pattern.

pkg/subcmd/modules.go (3)

1-10: LGTM!

The imports are well-organized and the file establishes a clean module registry pattern for integration modules.


12-122: LGTM!

The module definitions follow a consistent pattern with Name, Init, and Command fields. Each module properly wires its integration logic and CLI subcommand. The varying signatures in Init functions (some using logger/kube, others not) appropriately reflect the different initialization requirements of each integration.


124-139: LGTM!

StandardModules() provides a clean aggregation of all standard integration modules. The fixed ordering ensures consistent behavior across the CLI.

pkg/framework/app.go (3)

18-33: LGTM!

The App struct is well-designed as the central entry point for the installer framework. Public fields (AppCtx, ChartFS) expose necessary metadata while private fields encapsulate runtime dependencies. The comment clearly explains the struct's purpose.


35-43: LGTM!

The Command() and Run() methods provide clean access to Cobra functionality, following the established pattern in the codebase.


45-148: LGTM!

The setupRootCmd method is well-structured:

  • Properly handles short description fallback (lines 48-51)
  • Configures version and help handling (lines 64-71)
  • Creates logger after flags are applied (line 73)
  • Loads integrations with proper error handling (lines 76-81)
  • Validates MCP image configuration (lines 95-98)
  • Registers all subcommands via api.Runner (lines 144-146)

The subcommand wiring follows the coding guideline of using the cobra library for CLI structure.

pkg/resolver/annotations.go (2)

9-17: LGTM!

The suffix constants are well-named and clearly document the annotation key structure. Using unexported constants keeps the implementation details encapsulated.


19-52: LGTM!

The annotation functions follow a consistent pattern and properly delegate to appCtx.RepoURI() for dynamic key generation. The documentation clearly explains each function's purpose. This refactoring enables the framework to support multiple applications with different annotation prefixes.

Note: Nil-safety for appCtx should be enforced at construction time (in NewDependency) rather than in each annotation function to avoid redundant checks.

pkg/subcmd/mcpserver.go (3)

31-31: LGTM: Compile-time interface verification.

Good use of compile-time assertion to ensure MCPServer correctly implements api.SubCommand.


58-86: LGTM: Well-structured MCP server initialization.

The Run() method follows a clear, logical flow:

  1. Creates tools context with io.Discard logger (critical for MCP STDIO protocol)
  2. Builds tools via the injected builder
  3. Reads embedded instructions
  4. Constructs and starts the server

Error handling is appropriate, and passing appCtx to mcpserver.NewMCPServer (line 82) correctly addresses the previous critical issue about dynamic branding.


88-116: LGTM: Correct dependency injection pattern.

The constructor properly injects all dependencies (k8s.Kube, chartfs.ChartFS, integrations.Manager, builder, etc.) and initializes all struct fields. This follows the established pattern for command structs in this codebase.

Based on learnings, this correctly implements the dependency injection approach for command constructors.

pkg/mcptools/configtools.go (7)

9-10: LGTM! Imports support the framework refactoring.

The new imports for api.AppContext and chartfs.ChartFS correctly support the architectural changes to enable dynamic application naming and filesystem abstraction.


19-32: LGTM! Struct changes support framework architecture.

The addition of appName and cfs fields enables dynamic application naming and filesystem abstraction, aligning with the PR's goal to create a reusable installer framework.

Based on learnings, dependencies are properly structured for constructor injection.


34-47: LGTM! Suffix-based naming enables framework reusability.

The refactoring from full tool names to suffix constants enables dynamic tool naming across different applications, which is essential for the framework architecture.


104-167: LGTM! Dynamic naming integrated correctly.

The initHandler correctly uses c.appName for dynamic messaging and tool references, supporting the framework's reusability goal.


445-569: LGTM! Tool registration properly implements dynamic naming.

All MCP tools are correctly registered with dynamic names (appName + suffix) and descriptions that reference the application name, enabling framework reusability across different applications.


571-594: LGTM! Constructor follows dependency injection pattern.

The updated constructor properly accepts appCtx and cfs parameters, extracting application metadata and storing injected dependencies. This follows the established pattern for dependency injection via constructors.

Based on learnings, this approach correctly injects dependencies like chartfs.ChartFS and k8s.Kube via constructors in command structs.


82-84: Remove the unnecessary config.NewConfigDefault call at line 82.

The cfg variable is assigned but never used. The function immediately uses c.defaultCfg (initialized at line 580 with the proper namespace) instead. This assignment is redundant dead code.

@otaviof
Copy link
Collaborator Author

otaviof commented Jan 7, 2026

/retest

@otaviof otaviof requested a review from Roming22 January 8, 2026 09:14
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 8, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • App now uses a centralized application context and modular integration registration for richer CLI and installer tooling.

  • Installer exposes a standard MCP tools builder to assemble runtime tools dynamically.

  • Chores

  • Expanded and simplified linter/formatter configuration to broaden checks and standardize exclusions.

  • Refined filesystem/config handling and moved template reference to the root installer path.

  • Build metadata (version/commit) embedding adjusted.

  • Documentation

  • README updated to reflect new template path.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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: 3

🤖 Fix all issues with AI agents
In @installer/charts/tssc-app-namespaces/Chart.yaml:
- Around line 7-8: Update all remaining references to the old annotation
namespace to the new helmet namespace: in docs/topology.md replace occurrences
of "tssc.redhat-appstudio.github.com" with "helmet.redhat-appstudio.github.com"
to keep documentation consistent, and in Go source update constants/strings
where they reference the old annotations—change
"tssc.redhat-appstudio.github.com/config" in pkg/config/manager.go and
"tssc.redhat-appstudio.github.com/post-deploy=delete" in
pkg/k8s/delete_resources.go to use "helmet.redhat-appstudio.github.com/config"
and "helmet.redhat-appstudio.github.com/post-deploy=delete" respectively; run
tests and linting to ensure no remaining usages of the old namespace.

In @installer/charts/tssc-integrations/Chart.yaml:
- Around line 7-8: The repo was partially migrated to the new annotation
namespace but critical consumers still reference the old
tssc.redhat-appstudio.github.com; update all occurrences to
helmet.redhat-appstudio.github.com: change the label/annotation selectors in
pkg/k8s/delete_resources.go (label selector used for post-deploy deletion),
pkg/config/manager.go (label selector for config lookup), the Helm helper in
installer/charts/_common/_helpers.tpl (template generating post-deploy labels),
the selector in hack/deploy.sh, and all example annotations in docs/topology.md
to use helmet.redhat-appstudio.github.com so runtime lookups and generated
labels match the Chart.yaml annotations.

In @pkg/resolver/dependency.go:
- Line 18: Remove the unused appCtx field from the Dependency struct and drop
any constructor parameters or assignments that accept an *api.AppContext for it
(search for struct type Dependency and its constructor/new function); update any
code that constructs Dependency (e.g., NewDependency or similar factory
functions) to stop passing or storing appCtx, and remove related comments
referencing "annotation keys" from that struct to avoid stale documentation;
ensure no other references to appCtx remain in the resolver package and run
tests/build to confirm cleanup.
🧹 Nitpick comments (1)
pkg/installer/job.go (1)

29-32: Consider making this a package-level function or constant.

The LabelSelector() method doesn't access any instance fields and only uses the static resolver.RepoURI constant. This could be simplified to a package-level function or constant for clarity.

However, if the instance method pattern is intentional for future extensibility or API consistency, the current implementation is acceptable.

♻️ Alternative implementation as package-level function
-// LabelSelector returns the label selector for installer jobs.
-func (j *Job) LabelSelector() string {
-	return fmt.Sprintf("installer-job.%s", resolver.RepoURI)
-}
+// jobLabelSelector returns the label selector value for installer jobs.
+func jobLabelSelector() string {
+	return fmt.Sprintf("installer-job.%s", resolver.RepoURI)
+}

Or as a package constant if the value is truly static:

+// jobLabelSelector is the label selector value for installer jobs.
+const jobLabelSelector = "installer-job." + resolver.RepoURI

Then update all usages from j.LabelSelector() to jobLabelSelector() or jobLabelSelector.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c77acc and d9ddc97.

📒 Files selected for processing (15)
  • installer/charts/tssc-acs-test/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
  • installer/charts/tssc-app-namespaces/Chart.yaml
  • installer/charts/tssc-dh/Chart.yaml
  • installer/charts/tssc-gitops/Chart.yaml
  • installer/charts/tssc-iam/Chart.yaml
  • installer/charts/tssc-infrastructure/Chart.yaml
  • installer/charts/tssc-integrations/Chart.yaml
  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-tpa/Chart.yaml
  • pkg/api/appcontext.go
  • pkg/installer/job.go
  • pkg/resolver/annotations.go
  • pkg/resolver/dependency.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/api/appcontext.go
  • pkg/resolver/annotations.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • pkg/resolver/dependency.go
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-infrastructure/Chart.yaml
  • installer/charts/tssc-tpa/Chart.yaml
  • installer/charts/tssc-iam/Chart.yaml
  • installer/charts/tssc-acs-test/Chart.yaml
  • installer/charts/tssc-gitops/Chart.yaml
  • installer/charts/tssc-dh/Chart.yaml
  • pkg/installer/job.go
  • installer/charts/tssc-acs/Chart.yaml
  • installer/charts/tssc-app-namespaces/Chart.yaml
  • installer/charts/tssc-integrations/Chart.yaml
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/resolver/dependency.go
  • pkg/installer/job.go
pkg/resolver/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use pkg/resolver to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Files:

  • pkg/resolver/dependency.go
🧠 Learnings (8)
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • pkg/resolver/dependency.go
  • pkg/installer/job.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/resolver/**/*.go : Use `pkg/resolver` to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Applied to files:

  • pkg/resolver/dependency.go
  • pkg/installer/job.go
📚 Learning: 2025-08-20T15:48:01.881Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.

Applied to files:

  • installer/charts/tssc-iam/Chart.yaml
📚 Learning: 2025-08-27T18:30:02.411Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1190
File: pkg/resolver/resolver_test.go:52-67
Timestamp: 2025-08-27T18:30:02.411Z
Learning: In tssc-cli, there is a distinction between deployment namespace (where resources are deployed, referenced in values.yaml.tpl) and chart registration namespace (where Helm charts are registered, tested in resolver tests). These are different concepts and may use different namespace values.

Applied to files:

  • installer/charts/tssc-iam/Chart.yaml
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • pkg/installer/job.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Define interface definition at the top of service files, followed by service struct and implementation

Applied to files:

  • pkg/installer/job.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/installer/job.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Do not use `interface{}`, use the `any` alias instead

Applied to files:

  • pkg/installer/job.go
🧬 Code graph analysis (1)
pkg/installer/job.go (3)
pkg/resolver/annotations.go (1)
  • RepoURI (5-5)
pkg/subcmd/template.go (1)
  • Template (19-36)
pkg/api/appcontext.go (1)
  • AppContext (9-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Red Hat Konflux / pr-e2e-tests / tssc-cli
🔇 Additional comments (10)
installer/charts/tssc-gitops/Chart.yaml (1)

9-10: LGTM!

Annotation namespace migration from tssc.redhat-appstudio.github.com/* to helmet.redhat-appstudio.github.com/* is consistent with the framework rebranding. Values are preserved correctly.

installer/charts/tssc-infrastructure/Chart.yaml (1)

8-8: LGTM!

Annotation namespace migration is consistent with the broader refactoring effort.

installer/charts/tssc-tpa/Chart.yaml (1)

9-11: LGTM!

Annotation namespace migration is consistent across all three annotation keys. Values are preserved correctly.

installer/charts/tssc-acs/Chart.yaml (1)

9-11: LGTM!

Annotation namespace migration is consistent with the framework rebranding. All annotation values are preserved correctly.

installer/charts/tssc-tas/Chart.yaml (1)

9-11: LGTM!

Annotation namespace migration is consistent with the other charts in this PR. Values are preserved correctly.

pkg/installer/job.go (3)

8-10: LGTM: Import additions support the refactor.

The new imports for pkg/api and pkg/resolver correctly support the AppContext-based parameterization and static RepoURI usage introduced in this refactor.


57-57: LGTM: Consistent label selector usage.

The LabelSelector() method is used consistently across all relevant contexts: listing jobs, creating job metadata, pod template labels, and generating the log-follow command. This ensures uniform job identification and filtering.

Also applies to: 224-224, 229-229, 260-260


301-307: NewJob signature change has been properly addressed.

The signature change to accept *api.AppContext is correctly implemented, and the one call site in pkg/subcmd/mcptools.go:47 has been properly updated to pass the new parameters. No additional action is needed.

pkg/resolver/dependency.go (2)

107-117: Constructor signatures properly updated to accept and propagate appCtx.

The constructors correctly accept appCtx and wire it through the dependency chain. However, the value of this change depends on whether appCtx is actually utilized in the annotation accessor methods (see previous comment on line 18).


63-103: All annotation constants are properly defined and framework-aligned.

The constants AnnotationDependsOn, AnnotationWeight, AnnotationProductName, AnnotationUseProductNamespace, AnnotationIntegrationsProvided, and AnnotationIntegrationsRequired are defined in pkg/resolver/annotations.go (lines 9-14) and properly exported. They all follow a consistent pattern using RepoURI + "/annotation-name" where RepoURI = "helmet.redhat-appstudio.github.com". The helper function commaSeparatedToSlice is also correctly defined in pkg/resolver/helper.go. No issues found.

Replace the dynamic `AppContext.RepoURI()` method with static constants
to ensure every Helm chart will rely on framework's annotations and
repository URI.

Assisted-by: Claude
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 9, 2026

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Jan 9, 2026

@otaviof: This pull request references RHTAP-6103 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR implements the core architectural changes required to transform tssc-cli into a reusable installer framework (RHTAP-6103). It decouples the specific TSSC logic from the underlying machinery, allowing other projects to consume this codebase to build custom installers with their own branding, Helm charts, and tools.

Key Changes:

  • Public Framework API (pkg/framework):

    • Introduced NewApp as the main entry point for creating installer applications.
    • Added Functional Options (WithIntegrations, WithMCPToolsBuilder, WithMCPImage) for flexible configuration.
    • Moved pkg/mcpserver to pkg/framework/mcpserver to serve as the generic server wrapper.
  • Generic Filesystem (pkg/chartfs):

    • Refactored ChartFS to accept any standard fs.FS interface.
    • Removed hardcoded references to the local installer/ directory.
    • Added NewTarFS utility to support creating filesystems from embedded tarballs (overcoming go:embed symlink limitations).
    • Standardized asset discovery (Convention over Configuration) for config.yaml, values.yaml.tpl, and instructions.md.
  • MCP Server Refactoring:

    • Builder Pattern: Introduced MCPToolsBuilder and MCPToolsContext to decouple tool creation from the server, allowing consumers to inject custom tools.
    • Dynamic Branding: Parametrized AppName across the MCP stack so tools reflect the consumer's application name.
    • Safety: Enforced io.Discard for tool loggers to protect the MCP STDIO protocol.
  • Dynamic Integrations (pkg/integrations):

    • Refactored the integration manager to use a Registry Pattern.
    • Added api.IntegrationModule to encapsulate integration logic and CLI commands, enabling dynamic registration via WithIntegrations.
  • Shared API (pkg/api):

    • Moved SubCommand interface and Runner to pkg/api to break circular dependencies and expose them for external use.

Summary by CodeRabbit

  • New Features

  • Centralized application context and modular integration registration for richer CLI and installer behavior.

  • Standard MCP tools builder enables dynamic assembly of runtime tooling.

  • Chores

  • Broadened and standardized linting/formatting rules and exclusions.

  • Moved template reference to installer root; adjusted build metadata embedding.

  • Renamed Helm annotation keys across charts for a consistent prefix.

  • Documentation

  • README and topology docs updated to reflect path and annotation changes.

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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: 0

🧹 Nitpick comments (4)
pkg/resolver/dependency_test.go (2)

12-19: Avoid cwd-sensitive ../../installer in tests (can be flaky in some runners).
Consider resolving the installer directory relative to this test file instead of the process working directory.

Proposed change
 import (
 	"os"
+	"path/filepath"
+	"runtime"
 	"testing"

 	"github.com/redhat-appstudio/tssc-cli/pkg/chartfs"

 	o "github.com/onsi/gomega"
 )

 func TestNewDependency(t *testing.T) {
 	g := o.NewWithT(t)

-	cfs := chartfs.New(os.DirFS("../../installer"))
+	_, thisFile, _, _ := runtime.Caller(0)
+	installerDir := filepath.Clean(filepath.Join(filepath.Dir(thisFile), "../../installer"))
+	cfs := chartfs.New(os.DirFS(installerDir))

 	developerHub, err := cfs.GetChartFiles("charts/tssc-dh")
 	g.Expect(err).To(o.Succeed())

22-46: Optional: create a fresh Gomega g per subtest for cleaner failure attribution.
Right now assertions in t.Run(...) still report through the parent t.

Example pattern
 	t.Run("Chart", func(t *testing.T) {
+		g := o.NewWithT(t)
 		g.Expect(d.Chart()).NotTo(o.BeNil())
 	})
pkg/subcmd/mcptools.go (1)

17-91: Builder implementation follows good dependency injection pattern.

The function properly injects dependencies from toolsCtx and handles errors from constructors that can fail. This aligns with the coding guidelines for dependency injection in command structs.

Optional: Consider defensive nil-checks.

The builder doesn't validate that required toolsCtx fields (e.g., Kube, ChartFS, IntegrationManager) are non-nil before use. If validation is the builder's responsibility rather than the caller's, consider adding checks to provide clearer error messages.

Note: Coupling to Integration subcommand.

Lines 53-59 create an Integration subcommand instance directly. This couples the MCP tools builder to the specific subcommand implementation, which may be intentional for the framework's design but reduces modularity if other consumers want different integration tooling.

Based on learnings, the dependency injection pattern is correctly applied.

pkg/api/appcontext.go (1)

9-16: Consider validating the Name parameter.

The Name field is foundational for application identity (used for namespace defaults, ConfigMap naming, etc.), but NewAppContext accepts an empty string without validation. An empty name could propagate downstream issues.

💡 Optional validation in NewAppContext
 func NewAppContext(name string, opts ...ContextOption) *AppContext {
+	if name == "" {
+		panic("appcontext: name is required")
+	}
 	appCtx := &AppContext{
 		Name:      name,
 		Namespace: name,
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9ddc97 and a16367e.

📒 Files selected for processing (30)
  • docs/topology.md
  • hack/deploy.sh
  • installer/charts/_common/_helpers.tpl
  • installer/charts/tssc-acs-test/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
  • installer/charts/tssc-app-namespaces/Chart.yaml
  • installer/charts/tssc-dh/Chart.yaml
  • installer/charts/tssc-gitops/Chart.yaml
  • installer/charts/tssc-iam/Chart.yaml
  • installer/charts/tssc-infrastructure/Chart.yaml
  • installer/charts/tssc-integrations/Chart.yaml
  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-tpa/Chart.yaml
  • pkg/annotations/annotations.go
  • pkg/api/appcontext.go
  • pkg/config/manager.go
  • pkg/hooks/hooks_test.go
  • pkg/installer/job.go
  • pkg/k8s/delete_resources.go
  • pkg/resolver/annotations.go
  • pkg/resolver/collection.go
  • pkg/resolver/dependency.go
  • pkg/resolver/dependency_test.go
  • pkg/resolver/topology_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/mcptools.go
  • pkg/subcmd/template.go
💤 Files with no reviewable changes (1)
  • pkg/resolver/annotations.go
🚧 Files skipped from review as they are similar to previous changes (11)
  • installer/charts/tssc-acs-test/Chart.yaml
  • hack/deploy.sh
  • pkg/resolver/dependency.go
  • installer/charts/tssc-integrations/Chart.yaml
  • pkg/resolver/collection.go
  • installer/charts/tssc-dh/Chart.yaml
  • pkg/resolver/topology_test.go
  • installer/charts/tssc-gitops/Chart.yaml
  • pkg/installer/job.go
  • installer/charts/tssc-tpa/Chart.yaml
  • installer/charts/tssc-app-namespaces/Chart.yaml
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode Gemini API keys in source code; use environment variables or secure configuration management

Files:

  • pkg/subcmd/mcptools.go
  • pkg/k8s/delete_resources.go
  • pkg/subcmd/integration.go
  • pkg/api/appcontext.go
  • pkg/config/manager.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/config_helper.go
  • installer/charts/tssc-iam/Chart.yaml
  • docs/topology.md
  • installer/charts/tssc-pipelines/Chart.yaml
  • pkg/subcmd/config.go
  • installer/charts/tssc-infrastructure/Chart.yaml
  • installer/charts/_common/_helpers.tpl
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
  • pkg/annotations/annotations.go
pkg/subcmd/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

pkg/subcmd/**/*.go: Use cobra library for CLI command structure in the tssc-cli project
Define commands as structs in pkg/subcmd that implement a common interface
Use specific validateFlags() methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators
Inject dependencies like k8s.Kube and chartfs.ChartFS via constructors in command structs

Files:

  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use go:embed directive to embed installer directory resources (Helm charts, configurations, values.yaml.tpl) in the executable

Files:

  • pkg/subcmd/mcptools.go
  • pkg/k8s/delete_resources.go
  • pkg/subcmd/integration.go
  • pkg/api/appcontext.go
  • pkg/config/manager.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
  • pkg/annotations/annotations.go
**/*_test.go

📄 CodeRabbit inference engine (GEMINI.md)

Use the standard testing package with github.com/onsi/gomega assertion library for tests

Files:

  • pkg/resolver/dependency_test.go
  • pkg/hooks/hooks_test.go
pkg/resolver/**/*.go

📄 CodeRabbit inference engine (GEMINI.md)

Use pkg/resolver to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Files:

  • pkg/resolver/dependency_test.go
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Inject dependencies like `k8s.Kube` and `chartfs.ChartFS` via constructors in command structs

Applied to files:

  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration.go
  • pkg/config/manager.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
  • pkg/annotations/annotations.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Define commands as structs in `pkg/subcmd` that implement a common interface

Applied to files:

  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use `cobra` library for CLI command structure in the tssc-cli project

Applied to files:

  • pkg/subcmd/mcptools.go
  • pkg/subcmd/integration.go
  • pkg/config/manager.go
  • pkg/subcmd/config_helper.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/subcmd/**/*.go : Use specific `validateFlags()` methods for flag logic (e.g., mutual exclusion) rather than relying only on Cobra's built-in validators

Applied to files:

  • pkg/subcmd/mcptools.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Validate required parameters before making API calls

Applied to files:

  • pkg/subcmd/mcptools.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/integration/**/*.go : Define integrations in `pkg/integration` to connect to external services like GitHub, Quay, etc.

Applied to files:

  • pkg/subcmd/integration.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/resolver/**/*.go : Use `pkg/resolver` to define the dependency topology, including the sequence of Helm Charts and relationships between them and required integrations

Applied to files:

  • pkg/subcmd/integration.go
  • pkg/resolver/dependency_test.go
  • docs/topology.md
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
  • pkg/annotations/annotations.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/chartfs/**/*.go : Implement `io.FS` compatible abstraction in `pkg/chartfs` to provide access to embedded installer directory resources

Applied to files:

  • pkg/subcmd/integration.go
  • pkg/resolver/dependency_test.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to pkg/engine/**/*.go : Use Helm SDK in `pkg/engine` for Helm engine implementation, chart installation, templating functions, and installation lifecycle management

Applied to files:

  • pkg/subcmd/integration.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
  • pkg/annotations/annotations.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Enable and follow linters: asciicheck, dogsled, dupword, errorlint, goconst, misspell, nakedret, nolintlint, revive, staticcheck, testifylint, unconvert, usestdlibvars, whitespace

Applied to files:

  • pkg/subcmd/integration.go
  • pkg/config/manager.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*.go : Define interface definition at the top of service files, followed by service struct and implementation

Applied to files:

  • pkg/subcmd/integration.go
  • pkg/config/manager.go
  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
📚 Learning: 2025-08-20T15:48:01.881Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1159
File: installer/charts/tssc-dh/Chart.yaml:5-6
Timestamp: 2025-08-20T15:48:01.881Z
Learning: In the tssc-cli project, chart version bumps in Chart.yaml files are handled at code freeze rather than immediately when appVersion changes, as part of their coordinated release process.

Applied to files:

  • installer/charts/tssc-iam/Chart.yaml
  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-infrastructure/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
📚 Learning: 2025-08-27T18:30:02.411Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1190
File: pkg/resolver/resolver_test.go:52-67
Timestamp: 2025-08-27T18:30:02.411Z
Learning: In tssc-cli, there is a distinction between deployment namespace (where resources are deployed, referenced in values.yaml.tpl) and chart registration namespace (where Helm charts are registered, tested in resolver tests). These are different concepts and may use different namespace values.

Applied to files:

  • installer/charts/tssc-iam/Chart.yaml
  • docs/topology.md
  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-infrastructure/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
📚 Learning: 2025-09-29T21:21:23.787Z
Learnt from: Roming22
Repo: redhat-appstudio/tssc-cli PR: 1297
File: installer/charts/tssc-pipelines/templates/NOTES.txt:1-14
Timestamp: 2025-09-29T21:21:23.787Z
Learning: In the tssc-cli project's Helm NOTES templates, displaying sensitive values like webhook secrets in plain text is intentional behavior to help users with their configuration, as confirmed by the maintainer Roming22.

Applied to files:

  • installer/charts/tssc-iam/Chart.yaml
  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
📚 Learning: 2025-08-13T14:29:50.296Z
Learnt from: dperaza4dustbit
Repo: redhat-appstudio/tssc-cli PR: 1133
File: installer/charts/tssc-infrastructure/values.yaml:26-26
Timestamp: 2025-08-13T14:29:50.296Z
Learning: The tssc-cli team uses "__OVERWRITE_ME__" as a placeholder convention in Helm chart values.yaml files, even when the field will be used in templates with range operations. This is their established team convention and should not be flagged as an issue.

Applied to files:

  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
  • installer/charts/tssc-acs/Chart.yaml
📚 Learning: 2025-08-11T16:40:25.369Z
Learnt from: dperaza4dustbit
Repo: redhat-appstudio/tssc-cli PR: 1129
File: installer/charts/tssc-infrastructure/values.yaml:11-15
Timestamp: 2025-08-11T16:40:25.369Z
Learning: The team prefers using specific version tags instead of "latest" for container images to ensure stability and reproducibility in production environments.

Applied to files:

  • installer/charts/tssc-pipelines/Chart.yaml
  • installer/charts/tssc-tas/Chart.yaml
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : All tests must use the `testing` package with `testify/assert` library

Applied to files:

  • pkg/subcmd/config.go
  • pkg/subcmd/template.go
  • pkg/hooks/hooks_test.go
📚 Learning: 2025-12-10T16:04:55.706Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-10T16:04:55.706Z
Learning: Applies to **/*_test.go : Use the standard `testing` package with `github.com/onsi/gomega` assertion library for tests

Applied to files:

  • pkg/hooks/hooks_test.go
📚 Learning: 2025-11-24T19:55:52.646Z
Learnt from: CR
Repo: redhat-appstudio/tssc-cli PR: 0
File: vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md:0-0
Timestamp: 2025-11-24T19:55:52.646Z
Learning: Applies to vendor/gitlab.com/gitlab-org/api/client-go/**/*_test.go : Tests must be parallelized using `t.Parallel()`

Applied to files:

  • pkg/hooks/hooks_test.go
🧬 Code graph analysis (5)
pkg/subcmd/integration.go (5)
pkg/api/appcontext.go (1)
  • AppContext (9-16)
pkg/integrations/manager.go (2)
  • Manager (20-23)
  • IntegrationName (15-15)
pkg/resolver/collection.go (1)
  • NewCollection (100-130)
pkg/config/manager.go (1)
  • NewConfigMapManager (175-180)
pkg/api/subcommand.go (1)
  • NewRunner (36-47)
pkg/config/manager.go (2)
pkg/annotations/annotations.go (1)
  • Config (16-16)
pkg/constants/constants.go (1)
  • ConfigFilename (6-6)
pkg/resolver/dependency_test.go (1)
pkg/chartfs/chartfs.go (1)
  • New (98-100)
pkg/subcmd/config_helper.go (2)
pkg/api/appcontext.go (1)
  • AppContext (9-16)
pkg/config/manager.go (1)
  • NewConfigMapManager (175-180)
pkg/subcmd/template.go (2)
pkg/api/appcontext.go (1)
  • AppContext (9-16)
pkg/api/subcommand.go (1)
  • SubCommand (9-22)
🪛 LanguageTool
docs/topology.md

[uncategorized] ~76-~76: The official name of this software platform is spelled with a capital “H”.
Context: ...Example*: If the chart requires both github and trustification integrations: ``...

(GITHUB)

🪛 markdownlint-cli2 (0.18.1)
docs/topology.md

18-18: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


28-28: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


39-39: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


50-50: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


61-61: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


72-72: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Red Hat Konflux / tssc-cli-on-pull-request
🔇 Additional comments (38)
pkg/resolver/dependency_test.go (1)

3-10: Import change is fine.
No concerns with adding os for os.DirFS.

pkg/subcmd/mcptools.go (2)

10-15: LGTM!

Clean factory function with clear documentation. The separation between public entry point and internal implementation follows good Go practices.


47-47: No action needed. installer.NewJob is explicitly designed to return only *Job without an error return type, unlike NewConfigTools and NewTopologyBuilder which return errors. This design difference is intentional; NewJob does not require error handling.

Likely an incorrect or invalid review comment.

pkg/subcmd/integration.go (3)

16-22: LGTM!

The updated signature correctly follows the dependency injection pattern, accepting appCtx for application context and manager for the integration registry. This aligns with the framework refactor objectives.

Based on coding guidelines, dependencies are properly injected via constructor parameters.


69-70: LGTM!

The ConfigMapManager instantiation correctly uses appCtx.Name to derive the ConfigMap name dynamically, aligning with the refactored signature in pkg/config/manager.go (lines 174-179).


77-81: Type conversion is correct and necessary.

The explicit conversion integrations.IntegrationName(mod.Name) on line 78 is required by Go's type system. Although IntegrationName is a type alias for string, Go treats named types distinctly from their underlying types. The manager.Integration() method expects an IntegrationName parameter, so the conversion is necessary and follows the pattern already established in the codebase (e.g., in Manager.Register()).

pkg/config/manager.go (6)

26-29: LGTM!

The Name() getter provides external access to the dynamically derived ConfigMap name, supporting the framework's parameterization goals.


108-123: LGTM!

The refactored configMapForConfig method correctly uses:

  • m.name for dynamic ConfigMap naming (line 113)
  • annotations.Config for standardized labels (line 116)
  • constants.ConfigFilename for the data key (line 120)

This eliminates hardcoded values and aligns with the framework parameterization objectives.


174-179: LGTM!

The updated signature parameterizes the ConfigMap name based on appName, enabling framework reusability. The clear documentation on line 174 explains the naming convention.


88-105: LGTM!

The GetConfig method correctly uses constants.ConfigFilename for both data lookup (line 93) and error reporting (line 98), ensuring consistency throughout the codebase.


43-85: LGTM!

The GetConfigMap method correctly uses the new Selector constant (lines 53, 64) for label-based queries, centralizing the selector logic and improving maintainability.


23-24: The annotations.Config constant is correctly configured.

The Selector constant resolves to "helmet.redhat-appstudio.github.com/config=true", which matches the expected label key. No compatibility issues were found with existing ConfigMaps, and the file contains no hardcoded API keys.

pkg/k8s/delete_resources.go (1)

13-13: LGTM!

The label selector correctly uses annotations.PostDeploy to maintain consistency with the Helm template update in installer/charts/_common/_helpers.tpl (line 49). This ensures post-deployment cleanup targets the right resources.

installer/charts/_common/_helpers.tpl (1)

49-49: Helm label is consistent with Go constant annotation.

The helmet.redhat-appstudio.github.com/post-deploy label correctly matches the annotations.PostDeploy constant defined as RepoURI + "/post-deploy" where RepoURI = "helmet.redhat-appstudio.github.com". Post-deployment resource cleanup will function as intended.

installer/charts/tssc-iam/Chart.yaml (1)

8-8: Dependency resolver correctly handles the updated annotation.

The annotation namespace update is properly configured. The DependsOn constant in pkg/annotations/annotations.go is already defined as helmet.redhat-appstudio.github.com/depends-on, and pkg/resolver/dependency.go uses this constant to read the annotation value, avoiding hardcoded keys. All charts are consistently updated with the new namespace.

installer/charts/tssc-pipelines/Chart.yaml (1)

9-11: LGTM! Annotation namespace updated consistently.

The annotation keys have been correctly updated from tssc.redhat-appstudio.github.com/* to helmet.redhat-appstudio.github.com/* as part of the framework refactor. The annotation values remain unchanged, ensuring continuity of the chart's metadata.

pkg/hooks/hooks_test.go (3)

5-5: LGTM! Import additions support the refactored test.

The os and api imports are correctly added to support the new os.DirFS usage and api.NewAppContext instantiation.

Also applies to: 8-8


20-20: LGTM! ChartFS updated to use standard fs.FS interface.

The refactor to chartfs.New(os.DirFS("../../test")) correctly adopts the standard fs.FS interface, making the ChartFS abstraction more generic and reusable.


25-27: LGTM! Test updated to use AppContext pattern.

The test now correctly instantiates an AppContext and uses its Namespace property instead of a global constant. This aligns with the framework refactor's goal of making the codebase more modular and testable.

docs/topology.md (2)

18-80: LGTM! Documentation updated consistently with code changes.

All annotation key references have been correctly updated from tssc.redhat-appstudio.github.com/* to helmet.redhat-appstudio.github.com/*, maintaining consistency with the Chart.yaml changes across the codebase.


94-95: LGTM! Namespace determination logic documentation updated.

The documentation correctly reflects the updated annotation key prefix while maintaining the clarity of the namespace determination logic.

installer/charts/tssc-tas/Chart.yaml (1)

9-11: LGTM! Annotation namespace updated consistently.

The annotation keys have been correctly updated from tssc.redhat-appstudio.github.com/* to helmet.redhat-appstudio.github.com/*, consistent with the framework-wide refactor.

pkg/subcmd/config_helper.go (4)

8-8: LGTM! Import added to support AppContext parameter.

The api import is correctly added to support the new *api.AppContext parameter.


19-19: LGTM! ConfigMapManager initialization uses dynamic application name.

The change from a hardcoded constant to appCtx.Name enables the config manager to work with different application contexts, supporting the framework refactor's goals.


22-29: LGTM! Error messages now use dynamic application name.

The error messages have been correctly updated to use appCtx.Name, making them contextually appropriate for different application instances while maintaining clarity for users.


14-18: Function signature supports dependency injection pattern.

The addition of the appCtx *api.AppContext parameter enables the function to work with different application contexts, and all callers have been properly updated to pass this parameter. The function uses appCtx.Name to configure the ConfigMap manager, making this dependency necessary.

installer/charts/tssc-infrastructure/Chart.yaml (1)

8-8: Annotation namespace migration looks correct.

The annotation key update from tssc.redhat-appstudio.github.com/depends-on to helmet.redhat-appstudio.github.com/depends-on aligns with the centralized annotations.DependsOn constant defined in pkg/annotations/annotations.go.

installer/charts/tssc-acs/Chart.yaml (1)

9-11: Annotation namespace migration is consistent.

All three annotation keys (product-name, depends-on, integrations-provided) correctly use the new helmet.redhat-appstudio.github.com prefix, matching the corresponding constants in pkg/annotations/annotations.go.

pkg/api/appcontext.go (1)

56-72: Well-structured factory with functional options pattern.

The NewAppContext factory provides sensible defaults and follows idiomatic Go functional options pattern. The defaults for Version ("v0.0.0-SNAPSHOT") and CommitID ("unknown") are appropriate for development builds.

pkg/subcmd/template.go (3)

7-7: Correctly integrates AppContext into Template subcommand.

The changes properly:

  • Import the api package
  • Add appCtx field to the Template struct
  • Update interface assertion to api.SubCommand

This follows the coding guidelines for dependency injection via constructors and implementing a common interface.

Also applies to: 23-23, 38-38


89-92: bootstrapConfig correctly receives appCtx.

The Complete method properly passes t.appCtx to bootstrapConfig, enabling app-context-aware configuration bootstrapping.


150-172: Constructor follows dependency injection pattern.

NewTemplate correctly accepts appCtx *api.AppContext as the first parameter and injects it into the Template struct. This aligns with the coding guidelines for injecting dependencies via constructors in command structs.

pkg/subcmd/config.go (5)

7-7: Correctly integrates AppContext into Config subcommand.

The changes properly:

  • Import the api package
  • Add appCtx field to the Config struct
  • Update interface assertion to api.SubCommand

This follows the coding guidelines for defining commands as structs that implement a common interface.

Also applies to: 26-26, 38-38


85-86: Dynamic namespace default is appropriate.

Using c.appCtx.Namespace instead of a static constant allows the namespace to be configured per-application, supporting the framework's goal of reusable installer applications.


178-181: Collection creation updated for app context.

The resolver.NewCollection(c.appCtx, charts) call correctly passes the application context, enabling the collection to derive app-specific metadata.


192-194: DRY-RUN output uses dynamic manager name.

Using c.manager.Name() and config.Selector instead of hardcoded values ensures consistent naming derived from the application context.


284-304: Constructor properly injects dependencies.

NewConfig correctly:

  • Accepts appCtx *api.AppContext as the first parameter
  • Returns api.SubCommand interface type
  • Initializes ConfigMapManager with appCtx.Name for dynamic naming

This aligns with the coding guidelines for injecting dependencies like k8s.Kube and chartfs.ChartFS via constructors in command structs. Based on learnings.

pkg/annotations/annotations.go (1)

1-17: Annotation constants are well-organized and migration is complete.

This package cleanly consolidates all Helm chart annotation keys under a single RepoURI prefix, eliminating scattered string literals across the codebase. The naming convention is consistent with Kubernetes annotation best practices (reverse domain notation).

Migration from the old tssc.redhat-appstudio.github.com prefix is complete—no legacy references remain in the codebase. The new helmet.redhat-appstudio.github.com prefix is consistently used across all Chart.yaml files in installer/charts/.

Note: The annotations package constants are currently defined but not yet imported in any Go code. Consider integrating package imports in Go consumers once they exist to avoid hardcoding annotation keys.

Copy link
Member

@Roming22 Roming22 left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm label Jan 9, 2026
@openshift-ci
Copy link

openshift-ci bot commented Jan 9, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: otaviof, Roming22

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit 594757b into redhat-appstudio:main Jan 9, 2026
9 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 23, 2026
Roming22 pushed a commit to Roming22/tssc-cli that referenced this pull request Jan 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants