Skip to content

feat: reference variables can path into related resource's variables#1005

Merged
adityachoudhari26 merged 3 commits intomainfrom
ref-vars-use-resource-variable
Apr 16, 2026
Merged

feat: reference variables can path into related resource's variables#1005
adityachoudhari26 merged 3 commits intomainfrom
ref-vars-use-resource-variable

Conversation

@adityachoudhari26
Copy link
Copy Markdown
Member

@adityachoudhari26 adityachoudhari26 commented Apr 16, 2026

fixes #890

Summary by CodeRabbit

  • New Features

    • Resources now support storing and managing variables.
    • Added support for accessing resource variables, including traversal of nested objects.
    • Deployment variables can reference variables from related resources.
  • Tests

    • Added comprehensive test coverage for resource variable resolution and nested variable references.

Copilot AI review requested due to automatic review settings April 16, 2026 22:12
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 16, 2026

Warning

Rate limit exceeded

@adityachoudhari26 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 44 minutes and 20 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 44 minutes and 20 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a8131152-b654-4916-afe9-3f1f38bdec3c

📥 Commits

Reviewing files that changed from the base of the PR and between e0f56dc and 8d01cdf.

📒 Files selected for processing (5)
  • apps/workspace-engine/pkg/db/queries/resource_variables.sql
  • apps/workspace-engine/pkg/db/resource_variables.sql.go
  • apps/workspace-engine/pkg/workspace/relationships/property.go
  • apps/workspace-engine/pkg/workspace/relationships/property_test.go
  • apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/getters_postgres_test.go
📝 Walkthrough

Walkthrough

The changes add support for resource-scoped variables throughout the workspace engine. A new variables field is introduced to the Resource schema, generated into Go code, loaded from the database per resource, mapped into resource objects during variable resolution, and made accessible via property getters for reference-variable traversal.

Changes

Cohort / File(s) Summary
Schema and Code Generation
apps/workspace-engine/oapi/openapi.json, apps/workspace-engine/oapi/spec/schemas/entities.jsonnet, apps/workspace-engine/pkg/oapi/oapi.gen.go
Added variables field to the Resource schema as an object with additionalProperties typed by the Value schema, enabling resource instances to hold arbitrary key/value pairs. Generated into Go struct with optional *map[string]Value field.
Property Access
apps/workspace-engine/pkg/workspace/relationships/property.go
Introduced getResourceVariableProperty helper to route "variables" path prefix lookups, enforcing non-nil resource.Variables, performing variable key lookups, validating literal conversion, and supporting nested object traversal with targeted error messages.
Data Loading
apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/getters_postgres.go
Enhanced PostgresGetter to preload resource variables from the database for both individual and batch operations via loadResourceVariables and loadResourceVariablesByWorkspace, injecting them into resource entity maps returned to the variable resolver.
Variable Mapping
apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go
Extended mapToResource to populate oapi.Resource.Variables from entity raw data when variables are present, enabling loaded variable data to flow into the final resource representation.
Test Infrastructure and Coverage
apps/workspace-engine/test/controllers/harness/pipeline_opts.go, apps/workspace-engine/test/controllers/variable_test.go
Updated test harness to conditionally include resource variables in entity data, and added two new test cases validating reference-variable resolution through related resource variables (both literal and nested object types).

Sequence Diagram(s)

sequenceDiagram
    participant VarResolver as Variable Resolver
    participant PGGetter as PostgresGetter
    participant DB as Database
    participant ResMapper as Resource Mapper
    participant PropGetter as Property Getter

    VarResolver->>PGGetter: LoadCandidates(resource)
    PGGetter->>DB: ListResourceVariablesByWorkspaceID
    DB-->>PGGetter: resource variables rows
    PGGetter->>PGGetter: Convert to oapi.Value map
    PGGetter-->>VarResolver: EntityData with variables in Raw
    
    VarResolver->>ResMapper: mapToResource(entityData)
    ResMapper->>ResMapper: Extract variables from Raw
    ResMapper-->>VarResolver: oapi.Resource with Variables populated
    
    VarResolver->>PropGetter: getResourceProperty(resource, "variables.db_url")
    PropGetter->>PropGetter: getResourceVariableProperty
    PropGetter->>PropGetter: Lookup variable, validate, convert
    PropGetter-->>VarResolver: Resolved variable value
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • PR #902: Modifies the same variableresolver code paths (getters_postgres.go and resolve.go) to add global variable sets as an additional variable source alongside resource variables.
  • PR #661: Introduces engine-level ResourceVariable types and in-memory repository infrastructure that complements the schema and database integration added in this PR.

Poem

🐰 A whisper of variables now flows,
Through resources where data grows,
No longer bound to configs alone,
Resource secrets are finally known!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: enabling reference variables to access variables on related resources.
Linked Issues check ✅ Passed The pull request implements the objective from issue #890 by adding support for reference variables to reference variables on related resources across multiple layers.
Out of Scope Changes check ✅ Passed All changes are scoped to enabling the feature: schema updates, Go struct generation, property retrieval logic, variable loading in database queries, entity mapping, and corresponding tests.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ref-vars-use-resource-variable

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

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/workspace-engine/test/controllers/variable_test.go (1)

523-553: Nit: missing section-header comment for consistency.

Every other test in this file (including the sibling test added right below at line 559) is preceded by a // ----style section-header comment describing the case. Please add one here too so the file style stays uniform.

✏️ Proposed addition
+// ---------------------------------------------------------------------------
+// Reference variable resolves from a variable on a related resource
+// ---------------------------------------------------------------------------
+
 func TestVariable_ReferenceVariable_ResolvesFromRelatedResourceVariables(t *testing.T) {

As per coding guidelines: *"Follow the existing test structure used in _test.go files".

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

In `@apps/workspace-engine/test/controllers/variable_test.go` around lines 523 -
553, Add the missing section-header comment above the test function
TestVariable_ReferenceVariable_ResolvesFromRelatedResourceVariables to match the
file's style (a `// ---`-style header describing the case), using the same short
descriptive phrasing pattern as the sibling test below (e.g., a one-line `// ---
Resolve reference variable from related resource variables` comment) so the test
file remains consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/workspace-engine/test/controllers/variable_test.go`:
- Around line 523-553: Add the missing section-header comment above the test
function TestVariable_ReferenceVariable_ResolvesFromRelatedResourceVariables to
match the file's style (a `// ---`-style header describing the case), using the
same short descriptive phrasing pattern as the sibling test below (e.g., a
one-line `// --- Resolve reference variable from related resource variables`
comment) so the test file remains consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a0ba2bd8-1d51-48bc-a940-ab9bd74ed8e9

📥 Commits

Reviewing files that changed from the base of the PR and between 7204759 and e0f56dc.

📒 Files selected for processing (8)
  • apps/workspace-engine/oapi/openapi.json
  • apps/workspace-engine/oapi/spec/schemas/entities.jsonnet
  • apps/workspace-engine/pkg/oapi/oapi.gen.go
  • apps/workspace-engine/pkg/workspace/relationships/property.go
  • apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/getters_postgres.go
  • apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go
  • apps/workspace-engine/test/controllers/harness/pipeline_opts.go
  • apps/workspace-engine/test/controllers/variable_test.go

Copy link
Copy Markdown
Contributor

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

Adds support for reference variables to traverse into a related resource’s variables (not just config/metadata), addressing issue #890 in the workspace-engine variable resolution flow.

Changes:

  • Extend relationship property traversal to support resource.variables.<key>[.<nested>...].
  • Ensure related resource candidates (test harness + Postgres getter) include resource variables in their raw entity maps for reference resolution.
  • Update the workspace-engine OpenAPI Resource schema/type to include an optional variables map.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
apps/workspace-engine/test/controllers/variable_test.go Adds controller-level tests covering reference resolution from related resource variables (including nested object traversal).
apps/workspace-engine/test/controllers/harness/pipeline_opts.go Includes related resource variables in scenario candidate Raw maps to enable reference traversal in tests.
apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go Maps variables from EntityData.Raw into oapi.Resource so relationship property lookup can access them.
apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/getters_postgres.go Loads resource variables from Postgres and attaches them to resource candidate Raw maps and GetEntityByID results.
apps/workspace-engine/pkg/workspace/relationships/property.go Adds variables handling for resource property traversal, including nested object lookups.
apps/workspace-engine/pkg/oapi/oapi.gen.go Updates generated oapi.Resource type to include optional Variables.
apps/workspace-engine/oapi/spec/schemas/entities.jsonnet Adds variables to the Resource schema in the OAPI spec source.
apps/workspace-engine/oapi/openapi.json Updates the generated OpenAPI artifact to include the Resource variables field.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 213 to 228
rows, err := q.ListActiveResourcesByWorkspace(ctx, workspaceID)
if err != nil {
return nil, fmt.Errorf("list resources for workspace %s: %w", workspaceID, err)
}
varsByResource, err := loadResourceVariablesByWorkspace(ctx, q, workspaceID)
if err != nil {
return nil, err
}
candidates := make([]eval.EntityData, 0, len(rows))
for _, r := range rows {
candidates = append(candidates, eval.EntityData{
ID: r.ID,
WorkspaceID: r.WorkspaceID,
EntityType: "resource",
Raw: resourceRowToMap(r),
Raw: resourceRowToMap(r, varsByResource[r.ID]),
})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

LoadCandidates now fetches all resource variables for the workspace in a separate query. The underlying ListResourceVariablesByWorkspaceID SQL only filters by workspace_id (no deleted_at IS NULL), so this will also pull variables for soft-deleted resources and any other inactive rows, increasing work/memory for large workspaces. Consider tightening the query to active resources (e.g., join with resource.deleted_at IS NULL) or otherwise scoping the variable load to the active resource IDs returned by ListActiveResourcesByWorkspace.

Copilot uses AI. Check for mistakes.
Comment on lines +217 to 228
varsByResource, err := loadResourceVariablesByWorkspace(ctx, q, workspaceID)
if err != nil {
return nil, err
}
candidates := make([]eval.EntityData, 0, len(rows))
for _, r := range rows {
candidates = append(candidates, eval.EntityData{
ID: r.ID,
WorkspaceID: r.WorkspaceID,
EntityType: "resource",
Raw: resourceRowToMap(r),
Raw: resourceRowToMap(r, varsByResource[r.ID]),
})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

The new behavior of loading and attaching variables into resource candidates (via loadResourceVariablesByWorkspace/resourceRowToMap) isn’t covered by the existing PostgresGetter tests. Adding a test that inserts rows into resource_variable and asserts LoadCandidates includes a variables entry in EntityData.Raw would help prevent regressions and ensure DB-backed reference-path resolution works.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to 89
case "variables":
return getResourceVariableProperty(resource, propertyPath)
default:
return getPropertyReflection(resource, propertyPath)
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

New variables path handling for resources (getResourceVariableProperty) isn’t covered by the existing property extraction unit tests. Adding tests for variables/<key> and nested object traversal (plus key-missing / non-literal cases) would help prevent regressions.

Copilot uses AI. Check for mistakes.

obj, err := lv.AsObjectValue()
if err != nil {
return nil, fmt.Errorf("cannot traverse into non-object variable %s", propertyPath[1])
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

When AsObjectValue() fails, the returned error drops the underlying reason (err). Wrapping the original error (e.g., with %w) would make it much easier to debug why traversal failed (wrong type vs malformed literal, etc.).

Suggested change
return nil, fmt.Errorf("cannot traverse into non-object variable %s", propertyPath[1])
return nil, fmt.Errorf("cannot traverse into non-object variable %s: %w", propertyPath[1], err)

Copilot uses AI. Check for mistakes.
@adityachoudhari26 adityachoudhari26 merged commit 7c209a8 into main Apr 16, 2026
10 checks passed
@adityachoudhari26 adityachoudhari26 deleted the ref-vars-use-resource-variable branch April 16, 2026 22:36
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.

bug: reference variables do not support referencing of other resource varibales (just configs)

2 participants