Skip to content

feat: added parsing and interpolation for component.* variables#1839

Open
N1lzh wants to merge 7 commits into
firecow:masterfrom
N1lzh:master
Open

feat: added parsing and interpolation for component.* variables#1839
N1lzh wants to merge 7 commits into
firecow:masterfrom
N1lzh:master

Conversation

@N1lzh

@N1lzh N1lzh commented Apr 22, 2026

Copy link
Copy Markdown

I ran into the problem that while input interpolations like $[[ input.variable ]] were replaced successfully in the yml files, component interpolations were not.

Gitlab component interpolations allows four different variables, name, reference, version and sha, with the following characteristics:

  • name: The component name as specified in the component path.
  • reference: The original reference specified after @ in the component path.
  • version: The resolved semantic version from the catalog resource, null if the component is not a catalog resource or a released version.
  • sha: The commit SHA of the component.

As the current ParsedComponent type differed a bit from these characteristics, I made the following changes to it:

  • renamed name to componentPath as this property is the full path to the component starting from the project path.
  • renamed ref to effectiveRef as this is the already resolved reference, meaning either the reference specified or the concrete semantic version if existing.
  • added name, reference, version and sha that mimic the characteristics of the gitlab properties.
    These properties get populated in the parseIncludeComponent function in parser-includes.ts.

In the parser.ts I added the replacement for the component variables in the same way as it was done for input variables. However, the logic is a bit easier, since there are only four different variables that all have the same type.


Summary by cubic

Adds parsing and interpolation for GitLab component variables so $[[ component.name|reference|version|sha ]] resolves in included templates. Also improves version/ref/sha resolution and uses the resolved ref to locate and expand includes.

  • New Features

    • Parse components with componentPath, effectiveRef, name, reference, version (nullable), and sha.
    • Resolve semantic versions (~latest, x, x.y) and compute SHAs (remote via git ls-remote, local via git rev-parse).
    • Interpolate $[[ component.* ]] during YAML load using a component context; use componentPath/effectiveRef for downloading and locating includes and expanding inner local includes.
  • Bug Fixes

    • Preserve null component.version values per GitLab spec.
    • Handle commit SHA refs and return the correct SHA for annotated tags.

Written for commit d9852a3. Summary will update on new commits.

@N1lzh

N1lzh commented Apr 22, 2026

Copy link
Copy Markdown
Author

I just noticed that while I worked and procrastinated this, another PR was opened for a similar topic. This implementation here, however, allows component.* interpolation in the whole file and not only the includes.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

4 issues found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/parser.ts">

<violation number="1" location="src/parser.ts:397">
P1: Rejects valid `component.version` values when they are null by asserting on the resolved value’s truthiness.</violation>

<violation number="2" location="src/parser.ts:398">
P2: Component interpolation injects unescaped raw string values into JSON text before `JSON.parse`, which can break parsing or alter values when component fields contain JSON-significant characters (e.g., `"`).</violation>
</file>

<file name="src/parser-includes.ts">

<violation number="1" location="src/parser-includes.ts:263">
P2: Unconditionally resolving the component SHA forces a remote `git ls-remote` during parsing, which breaks offline/cached runs and adds avoidable latency.</violation>

<violation number="2" location="src/parser-includes.ts:503">
P1: `getComponentSha` cannot resolve commit-SHA component refs and returns the wrong SHA for annotated tags.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/parser.ts Outdated
Comment thread src/parser-includes.ts
Comment thread src/parser.ts
Comment thread src/parser-includes.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/parser.ts">

<violation number="1" location="src/parser.ts:397">
P2: Unsupported `component.*` keys are no longer validated and can serialize as `undefined`, breaking config parsing or producing malformed output.</violation>

<violation number="2" location="src/parser.ts:397">
P1: Component interpolation stringifies an already-serialized JSON string, which can produce invalid JSON with doubled quotes.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/parser.ts Outdated
Comment thread src/parser.ts Outdated
@jrd

jrd commented Apr 24, 2026

Copy link
Copy Markdown

Well this other MR #1836 is also for the whole file, included the spec document where the component could also be reference. (I amend it)

But there should also be other ways to do it, maybe better. I’m not attached to my code in #1836 and any merge version is ok with me. I had simply preferred contributing directly rather than opening another issue…

But it seems we concur to same code resolution :-)

@N1lzh

N1lzh commented Apr 27, 2026

Copy link
Copy Markdown
Author

Well this other MR #1836 is also for the whole file, included the spec document where the component could also be reference. (I amend it)

But there should also be other ways to do it, maybe better. I’m not attached to my code in #1836 and any merge version is ok with me. I had simply preferred contributing directly rather than opening another issue…

But it seems we concur to same code resolution :-)

@jrd Not attached to my code either, I just need this to work ;) What I noticed on your code is, though, that you do not handle component.name, only reference, version and sha. Also you reuse the current ref for the reference, sha and version, which doesn't fit the logic in the original gitlab parser. See my original comment or this for more info on this.

@jrd

jrd commented Apr 29, 2026

Copy link
Copy Markdown

Yes my implementation is a bit crude about version, sha or reference. That was because the ParsedComponent object only has ref initially and I didn’t want to alter it further as for my case, it’s good enough to test my components locally. And I didn’t use name either.

So yes having a more complete ParsedComponent object like you did is better. But also think it’s better to use part of what I did on parser.ts because you can also use $[[ component ]] references in spec area. I do not for my component but it’s possible to use this in rules of some inputs for instance.

Can you amend your commit that way? Then I delete my PR.

Comment thread src/parser.ts
// is specified in the specs via component: [{interpolationKey}, ...]
const configurationWithInterpolatedInputsAndComponent = configurationWithInterpolatedInputs
.replaceAll(
/(?<firstChar>.)?(?<secondChar>.)?\$\[\[\s*component.(?<interpolationKey>[\w-]+)\s*\]\](?<lastChar>[^$])?/g,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

firstChar, secondChar and lastChar are useless for component interpolation as this is just a raw replace and there is no array or object type. This makes it more complicated that it should.

Comment thread src/parser.ts
@@ -328,7 +328,7 @@ export class Parser {
const inputsSpecification: any = fileData[0];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This should be also be parsed for component.XXX interpolation.

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.

3 participants