Skip to content

feat: enhance component independence CI checks (#81)#179

Merged
adnaan merged 36 commits intomainfrom
milestone-6-ci
Mar 7, 2026
Merged

feat: enhance component independence CI checks (#81)#179
adnaan merged 36 commits intomainfrom
milestone-6-ci

Conversation

@adnaan
Copy link
Copy Markdown
Contributor

@adnaan adnaan commented Mar 3, 2026

Summary

  • Adds cross-module import test step to components-independence.yml — creates an external Go module that imports modal, toast, and toggle to verify they build independently
  • Adds independence badge to components/README.md
  • Adds documentation section explaining the independence guarantee and how external projects can import components

Closes #81

Test plan

  • Push PR touching components/ to verify new CI step passes
  • Badge markdown renders correctly in README

🤖 Generated with Claude Code

adnaan and others added 3 commits March 3, 2026 07:36
Add ComponentsUsed and ComponentErrors fields to GenerationEvent so
telemetry can answer "which component caused this failure?" and
"how often does modal break?". This is the foundation for the
component health dashboard (#79) and fix proposer (#80).

- New attribution.go with AttributeErrors() and ComponentsFromUsage()
- SQLite schema migration adds components_used/component_errors columns
- Capture API gains RecordComponentsUsed() and AttributeComponentErrors()
- gen.go wires component detection into telemetry pipeline
- Full test coverage: attribution, round-trip persistence, backward compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, #80)

Add `lvt evolution components` subcommand showing per-component health
metrics (usage count, success rate, top errors) with warning markers
for components below 90% success rate.

Add ClassifyError/ClassifyFix to categorize errors by origin
(component/kit/generated/unknown). The `propose` command now shows
a Location line for each fix to help users understand where to look.

- evolutionComponents() aggregates telemetry by component with --days flag
- component_proposer.go classifies file paths into location categories
- evolutionPropose() enhanced with location classification per fix
- Full test coverage for all classification cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add cross-module import test to the components-independence workflow
that creates an external Go module and verifies it can import and
build against components without requiring the parent lvt module.

Also adds independence badge and documentation section to
components/README.md explaining the guarantee and how external
projects can use components.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 3, 2026 06:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Enhances CI enforcement that components/ remains independently importable as a standalone Go module, and documents that guarantee for external consumers.

Changes:

  • Adds an external “smoke test” Go module in components-independence.yml that imports and builds a few components.
  • Adds a GitHub Actions badge to the components README.
  • Documents the “independence guarantee” and how to import components from external projects.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
components/README.md Adds independence CI badge and a section documenting the independence guarantee and usage.
.github/workflows/components-independence.yml Adds a new CI step creating an external module that imports and builds selected components.

Comment on lines +85 to +86
go mod tidy
go build .
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This step is meant to validate module independence (and earlier steps explicitly use GOWORK=off), but go mod tidy / go build here run without GOWORK=off. It’s safer and more consistent to set GOWORK=off for these commands too, so the external import check can’t accidentally be influenced by workspace settings.

Suggested change
go mod tidy
go build .
GOWORK=off go mod tidy
GOWORK=off go build .

Copilot uses AI. Check for mistakes.
Comment thread components/README.md Outdated

**What CI checks:**
- No imports of `github.com/livetemplate/lvt` (parent module)
- No imports of `github.com/livetemplate/lvt/internal` or `lvt/commands`
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The docs say CI checks for no imports of github.com/livetemplate/lvt/internal or lvt/commands, but the workflow actually checks the fully-qualified path github.com/livetemplate/lvt/commands. Consider making this bullet consistently use full import paths to avoid confusion for external users scanning the guarantee.

Suggested change
- No imports of `github.com/livetemplate/lvt/internal` or `lvt/commands`
- No imports of `github.com/livetemplate/lvt/internal` or `github.com/livetemplate/lvt/commands`

Copilot uses AI. Check for mistakes.
m := modal.New("test-modal")
t := toast.New("test-toast")
tg := toggle.New("test-toggle")
fmt.Println(m.ID, t.ID, tg.ID)
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

In the external import smoke test, m.ID, t.ID, and tg.ID refer to method values (functions) from the embedded base.Base, not the actual component IDs. This will compile but prints function pointers and doesn’t validate that IDs are set correctly. Call the methods (e.g., ID()) or print ComponentID instead so the step exercises a real API surface.

Suggested change
fmt.Println(m.ID, t.ID, tg.ID)
fmt.Println(m.ID(), t.ID(), tg.ID())

Copilot uses AI. Check for mistakes.
@claude
Copy link
Copy Markdown

claude bot commented Mar 3, 2026

PR Review: feat: enhance component independence CI checks (#81)

Overall this is a solid addition — verifying external importability via a real Go module is the right approach and the documentation updates are clear and accurate. A few issues worth addressing:


Bug: Method value vs method call in test code

In .github/workflows/components-independence.yml (the generated main.go):

fmt.Println(m.ID, t.ID, tg.ID)

Base exposes ID() as a method, not a field. So m.ID is a func() string method value (a function pointer), not the string ID. fmt.Println will print something like 0x6a3de0 0x6a3de0 0x6a3de0 — function addresses, not the component IDs.

The build still passes (method values are valid Go expressions), so the CI check works as intended. But the semantic intent is clearly to print the IDs, so this should be:

fmt.Println(m.ID(), t.ID(), tg.ID())
// or use the exported field directly:
fmt.Println(m.ComponentID, t.ComponentID, tg.ComponentID)

Coverage gap: only 3 of 15+ components tested

The test imports modal, toast, and toggle, but the module has 15+ component packages. A rogue import in any untested package (e.g. accordion, datatable, autocomplete) would slip past this check.

The top-level package already imports everything via components/all.go. Replacing the three targeted imports with a single import of the root package would give complete coverage in fewer lines:

import (
    "fmt"
    "github.com/livetemplate/lvt/components"
)

func main() {
    fmt.Println(components.Version())
}

This would catch a forbidden import in any component, not just three of them.


Heredoc indentation will write malformed-looking Go

The heredoc content is indented to match the YAML step's indentation level, so the generated main.go will look like:

          package main

          import (
              "fmt"

Go's compiler tolerates leading whitespace before package, so go build . passes. But go vet or gofmt would flag this, and it makes the file look broken if someone inspects it during a failed run. Using a <<-GOEOF (dash-heredoc) and tabs, or dedenting the content to column 0 in the YAML, would fix this:

        run: |
          mkdir -p /tmp/test-import
          cd /tmp/test-import
          go mod init test-import
          go mod edit -replace github.com/livetemplate/lvt/components=$GITHUB_WORKSPACE/components
          cat > main.go <<'GOEOF'
package main

import (
	"fmt"
	"github.com/livetemplate/lvt/components"
)

func main() {
	fmt.Println(components.Version())
}
GOEOF
          go mod tidy
          go build .

Minor: go mod tidy cold-run latency

The external module's go mod tidy must resolve all transitive dependencies of components/ (AWS SDK, redis, etc.) from scratch on a cold cache. The earlier GOWORK=off go build ./... step does warm the GOPATH module cache, so warm runs should be fast. Just worth being aware of if cache misses cause flaky timeouts.


What's working well

  • Using go mod edit -replace with $GITHUB_WORKSPACE is the correct, idiomatic approach for this kind of external-import smoke test.
  • The README "Independence Guarantee" section is well-written and accurately describes what the CI verifies.
  • The badge placement and phrasing are good.
  • The overall structure of the existing workflow steps is clean and the new step integrates naturally.

Summary: Two changes worth making before merge — fix m.IDm.ID() (semantic correctness) and broaden the import to cover all components via the root package. The heredoc indentation is a low-priority cosmetic fix.

adnaan and others added 6 commits March 4, 2026 00:00
- Update schema.sql to include components_used/component_errors columns
  so fresh installs don't need ALTER TABLE migration
- Add DDL identifier validation guard in migrateComponentColumns()
- Remove unused KnownComponents exported var
- Fix ComponentsFromUsage to skip non-"Use"-prefixed bool fields
- Add comment on toFieldData explaining intentional field subset
- Fix inconsistent struct alignment in events.go
- Rename backward compat test to clarify what it verifies
- Add comments on AttributeComponentErrors() call paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix app/ false positive: use prefix/segment check instead of Contains
  to avoid matching "webapp/", "myapp/", etc.
- Check kit paths before component paths to avoid misclassifying
  internal/kits/.../components/ as top-level components
- Fix Path field comment: "original path" not "normalized"
- Fix help text alignment for components subcommand
- Add comment about event-level success attribution trade-off
- Expand test coverage: kit components/ subdir, app/ false positives,
  bare component file, empty file, all ClassifyFix outcomes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use root components package with Version() instead of 3 specific packages
- Fix heredoc indentation to column 0 for valid Go syntax
- Add GOWORK=off to go mod tidy and go build steps
- Use consistent full import paths in README documentation

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

claude bot commented Mar 3, 2026

Follow-up Review

The three issues from the previous review have all been addressed in this revision:

  • m.IDcomponents.Version() (no more method-value printing)
  • Root package import (components) now covers all 21 component packages via all.go instead of just 3
  • Heredoc content is at column 0, so the generated main.go is properly formatted

The CI step is solid. Two small things still worth a look:


Minor: test-import is not a valid Go module path

go mod init test-import

Go module paths must be domain-like (example.com/test-import, not bare words with hyphens). This works in practice — Go tools accept it — but it produces a diagnostic on go mod tidy:

go: warning: module path test-import does not begin with hostname

Simple fix:

go mod init example.com/test-import

Suggestion: add go run . after go build .

The step currently verifies the external module compiles. Since Version() is a trivial function that returns a string, adding GOWORK=off go run . would also verify it executes without a panic — catching any init() failures in components. Low value for this specific program, but it makes the smoke test more complete for free.


What's working well

  • all.go imports all 21 component packages, so a single root-package import provides full coverage — this is the right approach.
  • go mod edit -replace + $GITHUB_WORKSPACE is idiomatic for this kind of external-import smoke test; go mod tidy correctly infers the require from the import in main.go.
  • GOWORK=off is applied consistently on the operations that matter.
  • The README "Independence Guarantee" section accurately describes what CI verifies and the import example matches the actual package path.

Verdict: Ready to merge. The example.com/test-import fix is a one-liner if you want to keep things clean; go run . is purely optional.

adnaan and others added 7 commits March 4, 2026 00:08
- Add test documenting that "toast." does not false-positive on "toaster."
- Add test for ComponentsFromUsage ignoring non-Use-prefixed bool fields
- Clarify AttributeComponentErrors comment in gen.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract magic number 90 as warnThresholdPct constant
- Truncate long component names in dashboard table output
- Guard classifyPath against wildcard * in component names
- Make TestClassifyFix unconditionally assert Component field
- Add wildcard glob test case for classifyPath

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use example.com/test-import instead of bare test-import
- Add GOWORK=off go run . to verify execution, not just compilation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add dedicated migration upgrade test (old DB → new schema)
- Clarify allowed map comment as guard against future additions
- Document AttributeComponentErrors idempotency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add test for /app/ in middle of path (generated classification)
- Skip components with zero usage in dashboard table
- Simplify rate calculation now that usage > 0 is guaranteed

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

claude bot commented Mar 3, 2026

PR Review: feat: enhance component independence CI checks

All previous review feedback has been incorporated — this is in good shape.

What's verified:

  • components.Version() exists (all.go:106) and is a valid entry point. Since all.go imports all 21 sub-packages, building the root components package compiles every component; a forbidden import in any of them will break this step.
  • Heredoc content is at column 0 — generated main.go is properly formatted.
  • go mod init example.com/test-import uses a valid, domain-like module path.
  • GOWORK=off is applied consistently to go mod tidy, go build ., and go run ..
  • Both compile (go build) and execute (go run) checks are present.
  • go mod edit -replace with $GITHUB_WORKSPACE is the correct idiomatic approach for local-path replacement in CI.

One observation (non-blocking):

The temporary module's go mod tidy will need to resolve all transitive dependencies of components — AWS SDK v2, Redis, etc. The earlier GOWORK=off go build ./... step runs in components/ and should warm the module cache before this step, and actions/setup-go@v5 with cache: true caches across runs. So this should be fine in practice, but worth knowing the cold-cache run will do non-trivial network I/O.

README additions are accurate — the Independence Guarantee section correctly describes what CI verifies, and the import example matches the actual package path.

Verdict: Ready to merge.

adnaan and others added 8 commits March 4, 2026 00:28
- Document known suffix false-positive in message matching (premodal vs modal)
- Add comment about nil slices stored as "null" TEXT for DB query authors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Skip zero-usage components from errors section too
- Add warning on invalid --days value
- Use min() builtin instead of manual comparison

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add lowercase normalization note to ErrorLocation.Component
- Print count of components with errors but no usage in dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The go get step runs after all auth files are generated (line 300+)
and is purely a convenience for fetching dependencies. Making it
non-fatal is correct for:
- CI: lvt/components is a workspace sub-module with no proxy version
- Offline users: they can run go mod tidy later
- Tests: replace directives handle resolution independently

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
adnaan and others added 9 commits March 7, 2026 07:56
Addresses Copilot review: toFieldData() in commands/gen.go duplicated
the parser.Field → generator.FieldData conversion from resource.go and
schema.go. Moved to a single FieldDataFromFields() in types.go.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Tighten classifyPath to use segment-aware matching, preventing false
  positives from paths like "custom_components/" (Copilot + Claude)
- Normalize backslash paths for cross-platform consistency (Copilot)
- Add tests for false-positive prevention and Windows path normalization
- Add TestEvolution_Components for the new subcommand (Copilot)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot noted the doc should explicitly state these are fully-qualified
import paths to avoid confusion with short-form references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add left-boundary guard in matchComponent to prevent false positives
  like "premodal.init" matching component "modal"
- Update SuffixFalsePositive test to assert correct rejection + add
  BoundaryMatch test for valid matches
- Remove dead-code allowed map in migrateComponentColumns, extract
  componentColumns var instead

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip .tmpl before .go so "components/modal.go.tmpl" correctly
yields component name "modal" instead of "modal.go".

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

claude bot commented Mar 7, 2026

PR Review

This PR bundles several distinct things: a CI independence check enhancement, a new evolution components dashboard command, component telemetry attribution, and generator refactoring. Overall the code is well-written with good test coverage, but there are a few issues worth addressing.


Bugs / Correctness

CI workflow imports wrong packages (mismatch with PR description)

The PR description says the new step "imports modal, toast, and toggle to verify they build independently", but the generated main.go only imports the root github.com/livetemplate/lvt/components package and calls components.Version(). If the goal is to verify sub-package independence, the test should import sub-packages directly:

import (
    "github.com/livetemplate/lvt/components/modal"
    "github.com/livetemplate/lvt/components/toast"
    "github.com/livetemplate/lvt/components/toggle"
)

auth.go: error demoted to warning silently masks dependency failures

// Before:
return fmt.Errorf("failed to update dependencies: %w\n%s", err, output)
// After:
fmt.Fprintf(os.Stderr, "Warning: could not fetch some dependencies ...")

The old behavior aborted generation when go mod tidy failed. The new behavior continues and prints a warning, which means a user can get a "generation succeeded" message but end up with an app that won't compile due to missing dependencies. If this change is intentional (e.g. for offline/air-gapped environments), it should be documented. Otherwise, reverting to an error return is safer.


Code Quality

component_proposer.go — filename doesn't reflect content

The file only contains ClassifyError and ClassifyFix (path classification utilities). "Proposer" implies it generates or proposes fixes, which it doesn't. Consider renaming to component_classifier.go or moving these functions into a more descriptive file.

ComponentsFromUsage uses reflection for a struct convention

func ComponentsFromUsage(usage any) []string { ... }

This relies on a UseXxx bool field naming convention discovered at runtime via reflection. This is brittle:

  • Callers won't know at compile time if they've followed the convention correctly
  • A new bool field starting with Use for a non-component purpose would silently appear as a component name
  • Consider a typed interface or a simpler []string passed directly from DetectUsedComponents

migrateComponentColumns: column name interpolated into SQL

_, err = s.db.Exec(fmt.Sprintf(`ALTER TABLE generation_events ADD COLUMN %s TEXT`, col))

The column names come from the hardcoded componentColumns slice, so there's no actual injection risk. But using Sprintf with SQL fragments is a pattern worth flagging in a codebase. A comment noting these are static strings (or a //nolint annotation if you use a linter) would make the intent clear.

warnThresholdPct is a package-level const for a single function

const warnThresholdPct = 90 is only used inside evolutionComponents. Keeping it function-local or as a named const in a components config block would make its scope clearer. At minimum, a comment explaining what the 90% threshold means (success rate below which a component is flagged) would help.


Test Coverage

TestEvolution_Components only tests the happy path with no data

func TestEvolution_Components(t *testing.T) {
    t.Setenv("LVT_TELEMETRY", "true")
    // ...
    err := Evolution([]string{"components"})
    if err != nil { t.Errorf(...) }
}

This only exercises the "No component data recorded yet" code path. Missing coverage:

  • --days N flag parsing (valid and invalid values)
  • Dashboard output with actual component data seeded
  • The "WARN" status path (success rate < 90%)
  • The "hidden" components count (errors with no usage)
  • Top errors section

evolutionComponents success-rate approximation should have a test note

The comment at line ~122 explains that success is tracked at event level, not component level — a component gets marked failed even if the failure was unrelated. This known approximation deserves a TODO or issue reference so it's tracked for improvement.


Minor

  • The PR title ("feat: enhance component independence CI checks") undersells the actual scope — telemetry attribution and a new evolution components command are the bulk of the diff. Worth updating the title or splitting into separate PRs for easier review.
  • "null" string comparison in scanInto is documented with a comment, which is good. Consider extracting it into a helper unmarshalNullableJSON to avoid repeating the three-part condition.

Summary

Area Verdict
Test external import (CI) Fix to actually import sub-packages
auth.go warning demotion Reconsider — may silently break generated apps
ComponentsFromUsage reflection Workable but fragile; consider typed alternative
Schema migration Well done, idempotent and tested
Round-trip tests Good coverage of serialization edge cases
ClassifyError / ClassifyFix Clean implementation with solid test suite
FieldDataFromFields refactor Good DRY improvement

🤖 Generated with Claude Code

adnaan and others added 3 commits March 7, 2026 08:23
Claude review: the warning omits projectRoot so users don't know where
to run go mod tidy. Now prints the path for clarity.

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

claude bot commented Mar 7, 2026

PR Review

Overall a well-structured PR with good test coverage. A few issues worth addressing before merge.


ISSUE 1: CI test does not match PR description

The description says it imports modal, toast, and toggle to verify they build independently, but the workflow only imports the top-level components package and calls components.Version(). The individual sub-packages are not imported or tested. Either import each sub-package explicitly, or align the description with what is actually tested.

ISSUE 2: Behavior change in internal/generator/auth.go is concerning

Before: a go mod tidy failure returned a hard error from GenerateAuth.
After: the failure is printed as a warning to stderr and execution continues.

This means users can end up with broken generated projects silently. If the goal is graceful offline handling, consider inspecting the error type rather than blanket-suppressing it.

ISSUE 3: SQL column name via fmt.Sprintf in migration (minor)

In migrateComponentColumns, the column name is interpolated via fmt.Sprintf. No injection risk since col is from the hardcoded componentColumns slice, but a comment noting that assumption would prevent this from being copy-pasted unsafely in future migrations.

ISSUE 4: Dashboard header and separator length mismatch

The title line uses 42 equal signs but the column separator is 65 dashes. They should match.

ISSUE 5: evolutionComponents test coverage is minimal

TestEvolution_Components only verifies the no-events path. Missing: WARN status below 90% success rate, --days flag parsing, Top Errors section, and invalid flag warning. Tests with seeded event data would guard against formatting regressions.


Nitpicks:

  • warnThresholdPct = 90 is ambiguous about direction; warnSuccessRatePct would be clearer.
  • ComponentsFromUsage uses reflection over a UseX field naming convention. Well-documented, but a note near the ComponentUsage struct definition would make the convention obvious at the definition site too.

What is good:

  • Comprehensive tests for ClassifyError/ClassifyFix edge cases: Windows paths, case-insensitivity, premodal not matching modal, custom_components/ not matching components/.
  • migrateComponentColumns uses pragma_table_info for column existence checks, the correct SQLite idiom.
  • TestSQLiteStore_MigrationUpgrade tests opening an old-schema database.
  • FieldDataFromFields removes real duplication from resource.go and schema.go.
  • The README independence documentation is clear and useful to external consumers.

Generated with Claude Code

@adnaan adnaan merged commit dca6a4e into main Mar 7, 2026
2 checks passed
adnaan added a commit that referenced this pull request Mar 13, 2026
Points to squash-merged PR #179 on livetemplate/livetemplate main branch
which fixes $index resolution in pipe expressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
adnaan added a commit that referenced this pull request Mar 13, 2026
* fix: update golden files for corrected $index resolution in range

The core library (livetemplate/livetemplate#179) fixed a bug where
range variables in executeRangeBodyWithVars were stored with the $
prefix, causing buildExecData to construct "$$index" patterns that
never matched {{$index}} in templates. The fix strips the $ prefix
so that pipe expressions like {{$index | printf "#%d"}} now correctly
resolve to "#0", "#1", etc. instead of empty strings.

Updates all affected golden files:
- update_01: Initial range items now have "#0", "#1", "#2" for field 2
- update_02: Adds ["u", "todo-3", {"2": "#1"}] after remove (index shift)
- update_03: Adds index updates for completed/reordered items
- update_05a: Adds index updates for existing items when prepending
- update_05b: Adds index updates for existing items when inserting middle
- update_06: Adds index updates for multi-operation scenario

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

* fix: update go.mod to use merged core library commit

Points to squash-merged PR #179 on livetemplate/livetemplate main branch
which fixes $index resolution in pipe expressions.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[6.4] Verify Component Independence in CI

2 participants