New Multi-option React Scaffolder template #83
Conversation
…evaluation - Create the 'multi-option-react-template' under apps/portal/examples. - Implement parameter schemas allowing the choice of Vite/Webpack, Tailwind/Vanilla CSS, Zustand/Redux/None, and React Query/None. - Add dynamic file configure and cleanup steps using single-line Nunjucks expressions returning array values, resolving 'instance.files is not of a type(s) array' schema validation errors. - Wrap template expressions in single quotes to resolve YAML syntax parsing errors in the Backstage catalog loader. - Set targetPath to './source' and './gitops' to structure output directories correctly for file rename, delete, and publish steps. - Add corresponding boilerplate template files for react sources and GitOps manifests.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughPull request này thêm "Multi-Option React Scaffolder Template" — một template Backstage hoàn chỉnh cho phép người dùng tạo React app với tuỳ chọn build tool, styling, state management, và data fetching, kèm theo GitOps automation tự động publish, setup CI/CD, và deploy lên Kubernetes. ChangesMulti-Option React Scaffolder Template với GitOps Integration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml`:
- Line 4: Argo CD Application name in the manifest is mismatched with the
pipeline variable: update the "name" field in
apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml
from `${{ values.name }}-service` to match the pipeline's `argocd-app-name`
pattern (e.g., `${{ values.name }}-argocd`) so the sync/wait step that uses the
pipeline variable `argocd-app-name` can find the correct Application; ensure any
other references to the app name (pipeline params or scripts) are updated to the
same `${{ values.name }}-argocd` convention.
In
`@apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml`:
- Around line 23-31: Pipeline params reference the wrong GitOps resources: the
param with value "./deployment.yaml" does not exist in the GitOps template and
the argocd-app-name param uses "${{ values.name }}-argocd" while the Argo CD
manifest uses "${{ values.name }}-service". Update the pipeline param entries in
pipeline.yaml so the file param points to the actual manifest path used by the
GitOps repo (replace "./deployment.yaml" with the real manifest path/name used
in the repo) and change the argocd-app-name param value to "${{ values.name
}}-service" (or whatever the ArgoCD application name is in the manifests) so the
PipelineRun targets the correct Argo CD app; verify the test-command and
docker-secret names still match existing resources.
In
`@apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml`:
- Around line 41-46: TriggerTemplate is incorrectly deriving the GitOps repo and
manifest path: stop concatenating "-gitops" onto tt.params.git-repo-url and
instead reference an explicit GitOps repo param (e.g.,
tt.params.gitops-repo-url) for GITOPS_REPO_URL, keep GITOPS_REPO_BRANCH as
needed, and update MANIFEST_PATH to the actual manifest produced by the scaffold
(replace "deployment.yaml" with the real manifest path or file name used in the
repo, e.g., kustomization.yaml or the manifests directory). Ensure the
TriggerTemplate variable names GITOPS_REPO_URL and MANIFEST_PATH are updated
accordingly so they match the real scaffolded repo and files.
In
`@apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml`:
- Around line 5-7: The multi-line Jinja conditional block `{%- if
values.description %}` / `{%- endif %}` makes catalog-info.yaml invalid for
YAMLlint; replace that block with a single-line inline expression for the
description key so the template always produces valid YAML (i.e., keep the
existing `description: ${{ values.description | dump }}` but convert it into an
inline conditional/filtered expression that only emits a value when
`values.description` exists, removing the surrounding `{%- if ... %}` block).
In `@apps/portal/examples/multi-option-react-template/content/source/Dockerfile`:
- Around line 12-13: The EXPOSE line uses a template expression which is not a
valid Dockerfile token and will cause linters/parsers to fail; update the
Dockerfile so that EXPOSE does not contain the template expression (replace
EXPOSE ${{ values.port }} with a literal port or remove the EXPOSE line here)
and, if you need a dynamic exposed port, generate/render a separate Dockerfile
(or write a build step) that writes a Dockerfile with a concrete port value;
locate the EXPOSE entry and the related RUN sed 's/listen...' line in this
Dockerfile to apply the change and ensure nginx config substitution still uses
the template.
In `@apps/portal/examples/multi-option-react-template/content/source/src/App.jsx`:
- Around line 26-31: Trong useQuery's queryFn (the
fetch('https://api.github.com/repos/facebook/react') call) add a res.ok check
and throw when non-2xx so errors surface to React Query just like the manual
fetch branch; specifically, after receiving res in the queryFn, if (!res.ok)
throw new Error(`Request failed ${res.status} ${res.statusText}`) (or include
await res.text() for body) otherwise return await res.json(); update the queryFn
in useQuery to perform this check.
In
`@apps/portal/examples/multi-option-react-template/content/source/src/index.css`:
- Around line 1-5: The CSS file contains template tags ("{% if values.styling ==
'tailwind' -%}" / "{%- else -%}") which break CSS parsers (Biome/Stylelint);
move the templating logic out of index.css into a template file (e.g.,
index.njk) that renders plain CSS (or output separate files) so index.css only
contains final CSS, or alternatively configure the linter to ignore the
templates directory; update the template that currently generates index.css to
emit either the Tailwind directives (`@tailwind` base; `@tailwind` components;
`@tailwind` utilities;) or the fallback CSS, and ensure no `{% ... %}` tags remain
in any .css asset so Stylelint/Biome parsing no longer fails.
In
`@apps/portal/examples/multi-option-react-template/content/source/webpack.config.js`:
- Around line 31-33: The Nunjucks conditional tags are being injected directly
inside the JavaScript "use" array in webpack.config.js which breaks parsing;
refactor the template so the conditional returns a complete array expression (or
a variable) and interpolate that instead of inline block tags—for example,
define a Nunjucks variable like {% set postcss = values.styling == 'tailwind' ?
['postcss-loader'] : [] %} and then insert it into the "use" array via {{
postcss | dump | safe }} or similar so the generated JS is always valid, or
alternatively convert the file to a template extension and exclude it from JS
linting; update the code around the "use" array and the existing {% if
values.styling %}...{% endif %} occurrences accordingly.
In `@apps/portal/examples/multi-option-react-template/template.yaml`:
- Around line 115-117: The template's values.name is currently set from
parameters.repoName so the user-provided "Name" input isn't applied to rendered
artifacts; update the mapping in template.yaml so values.name uses the actual
input parameter (e.g., parameters.name) or remove the values.name field entirely
if repoName/slug is the intended source; look for the values.name entry and
change its source from parameters.repoName to parameters.name (or delete
values.name) so the required Name input is correctly propagated to artifacts.
- Around line 155-157: Hiện đang dùng parameters.repoName làm webhookSecret
(webhookSecret: ${{ parameters.repoName }}), điều này không an toàn vì repoName
dễ đoán; thay vào đó tạo một secret ngẫu nhiên riêng cho từng app và sử dụng giá
trị đó cả khi gọi tạo webhook và khi tạo Kubernetes Secret. Cụ thể: add/accept a
distinct parameter hoặc variable (ví dụ parameters.webhookSecret hoặc
generatedWebhookSecret) that is populated with a cryptographically-random value
at deployment time (or generated by the pipeline), replace webhookSecret: ${{
parameters.repoName }} with that parameter, and ensure the same parameter is
reused for the Kubernetes Secret creation step and the webhook creation call
(the entries referencing webhookUrl/webhookSecret and the k8s secret resource).
Also update the other occurrence where repoName was used as the secret so both
places consume the new random secret.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6b58ba4e-967f-4815-9b7b-008033bd0409
📒 Files selected for processing (25)
apps/operator/config/crd/bases/app.helios.io_heliosapps.yamlapps/portal/app-config.yamlapps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yamlapps/portal/examples/multi-option-react-template/content/gitops/helios-app.yamlapps/portal/examples/multi-option-react-template/content/gitops/pipeline.yamlapps/portal/examples/multi-option-react-template/content/gitops/triggers.yamlapps/portal/examples/multi-option-react-template/content/source/.eslintignoreapps/portal/examples/multi-option-react-template/content/source/.eslintrc.jsonapps/portal/examples/multi-option-react-template/content/source/.gitignoreapps/portal/examples/multi-option-react-template/content/source/Dockerfileapps/portal/examples/multi-option-react-template/content/source/babel.config.jsonapps/portal/examples/multi-option-react-template/content/source/catalog-info.yamlapps/portal/examples/multi-option-react-template/content/source/index.vite.htmlapps/portal/examples/multi-option-react-template/content/source/index.webpack.htmlapps/portal/examples/multi-option-react-template/content/source/package.jsonapps/portal/examples/multi-option-react-template/content/source/postcss.config.cjsapps/portal/examples/multi-option-react-template/content/source/src/App.jsxapps/portal/examples/multi-option-react-template/content/source/src/index.cssapps/portal/examples/multi-option-react-template/content/source/src/main.jsxapps/portal/examples/multi-option-react-template/content/source/src/store/reduxStore.jsapps/portal/examples/multi-option-react-template/content/source/src/store/zustandStore.jsapps/portal/examples/multi-option-react-template/content/source/tailwind.config.cjsapps/portal/examples/multi-option-react-template/content/source/vite.config.jsapps/portal/examples/multi-option-react-template/content/source/webpack.config.jsapps/portal/examples/multi-option-react-template/template.yaml
| value: ./deployment.yaml | ||
| - name: docker-secret | ||
| value: docker-credentials | ||
| - name: test-command | ||
| value: ${{ values.testCommand }} | ||
| - name: argocd-namespace | ||
| value: argocd | ||
| - name: argocd-app-name | ||
| value: ${{ values.name }}-argocd |
There was a problem hiding this comment.
Tham số pipeline đang không khớp tài nguyên GitOps thực tế.
Line 23 trỏ ./deployment.yaml nhưng trong template GitOps hiện không có file này. Đồng thời Line 31 dùng ${{ values.name }}-argocd nhưng manifest Argo CD đang đặt tên khác (${{ values.name }}-service). Hai lệch này có thể làm PipelineRun fail ở bước cập nhật/sync deployment.
Đề xuất chỉnh sửa
- name: MANIFEST_PATH
- value: ./deployment.yaml
+ value: ./helios-app.yaml
...
- name: argocd-app-name
- value: ${{ values.name }}-argocd
+ value: ${{ values.name }}-service📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| value: ./deployment.yaml | |
| - name: docker-secret | |
| value: docker-credentials | |
| - name: test-command | |
| value: ${{ values.testCommand }} | |
| - name: argocd-namespace | |
| value: argocd | |
| - name: argocd-app-name | |
| value: ${{ values.name }}-argocd | |
| value: ./helios-app.yaml | |
| - name: docker-secret | |
| value: docker-credentials | |
| - name: test-command | |
| value: ${{ values.testCommand }} | |
| - name: argocd-namespace | |
| value: argocd | |
| - name: argocd-app-name | |
| value: ${{ values.name }}-service |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml`
around lines 23 - 31, Pipeline params reference the wrong GitOps resources: the
param with value "./deployment.yaml" does not exist in the GitOps template and
the argocd-app-name param uses "${{ values.name }}-argocd" while the Argo CD
manifest uses "${{ values.name }}-service". Update the pipeline param entries in
pipeline.yaml so the file param points to the actual manifest path used by the
GitOps repo (replace "./deployment.yaml" with the real manifest path/name used
in the repo) and change the argocd-app-name param value to "${{ values.name
}}-service" (or whatever the ArgoCD application name is in the manifests) so the
PipelineRun targets the correct Argo CD app; verify the test-command and
docker-secret names still match existing resources.
| {% if values.styling == 'tailwind' -%} | ||
| @tailwind base; | ||
| @tailwind components; | ||
| @tailwind utilities; | ||
| {%- else -%} |
There was a problem hiding this comment.
Template tags trong .css đang làm hỏng parser của CSS tools.
{% ... %} đặt trực tiếp trong file .css làm Biome/Stylelint parse fail. Nên đổi sang file template riêng (ví dụ .njk) rồi render ra CSS thuần, hoặc exclude thư mục template khỏi lint để tránh chặn CI.
Also applies to: 142-142
🧰 Tools
🪛 Biome (2.4.16)
[error] 1-1: Expected a qualified rule, or an at rule but instead found '{%'.
(parse)
[error] 1-1: Expected a compound selector but instead found '='.
(parse)
[error] 1-1: expected , but instead found }
(parse)
[error] 5-5: Expected a qualified rule, or an at rule but instead found '{%-'.
(parse)
[error] 5-5: Expected a compound selector but instead found '-'.
(parse)
[error] 5-5: expected , but instead found }
(parse)
🪛 Stylelint (17.12.0)
[error] 1-1: Unknown word % (CssSyntaxError)
(CssSyntaxError)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@apps/portal/examples/multi-option-react-template/content/source/src/index.css`
around lines 1 - 5, The CSS file contains template tags ("{% if values.styling
== 'tailwind' -%}" / "{%- else -%}") which break CSS parsers (Biome/Stylelint);
move the templating logic out of index.css into a template file (e.g.,
index.njk) that renders plain CSS (or output separate files) so index.css only
contains final CSS, or alternatively configure the linter to ignore the
templates directory; update the template that currently generates index.css to
emit either the Tailwind directives (`@tailwind` base; `@tailwind` components;
`@tailwind` utilities;) or the fallback CSS, and ensure no `{% ... %}` tags remain
in any .css asset so Stylelint/Biome parsing no longer fails.
|
Addressed RabbitMQ suggested actions in commit 1a04d4d and merge new changes from main |
|
Can you also include screenshots for:
|
- Use repoName in template variables to align resource and secret names. - Change webhookSecret parameter to use secure ui:field: Secret. - Template testCommand in helios-app.yaml instead of using a hardcoded value. - Add missing Backstage annotations for Tekton, ArgoCD, and Kubernetes status.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml (1)
30-49:⚠️ Potential issue | 🟠 Major | ⚡ Quick winBổ sung đủ params và workspace cho PipelineRun sinh từ webhook.
TriggerTemplateđang gọi cùng pipelinefrom-code-to-clusternhưcontent/gitops/pipeline.yaml, nhưng lại thiếutest-command,argocd-namespace,argocd-app-namevà cảsource-workspace. Với contract hiện tại, các PipelineRun tạo từ webhook sẽ khác hẳn bản bootstrap và rất dễ fail validation hoặc bỏ qua bước test/deploy.Đề xuất chỉnh sửa
spec: serviceAccountName: pipeline pipelineRef: name: from-code-to-cluster params: - name: app-repo-url value: $(tt.params.git-repo-url) - name: app-repo-revision value: $(tt.params.git-revision) - name: image-repo value: "${{ values.image }}" - name: GITOPS_REPO_URL value: "${{ values.gitopsRepo }}" - name: GITOPS_REPO_BRANCH value: "main" - name: MANIFEST_PATH value: "helios-app.yaml" - name: docker-secret value: "docker-credentials" + - name: test-command + value: "${{ values.testCommand }}" + - name: argocd-namespace + value: "argocd" + - name: argocd-app-name + value: "${{ values.name }}-argocd" + workspaces: + - name: source-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml` around lines 30 - 49, TriggerTemplate invoking the pipeline from-code-to-cluster is missing required params and a workspace, causing PipelineRuns from the webhook to fail validation or skip test/deploy; add params test-command, argocd-namespace, argocd-app-name with appropriate values (e.g., from values or tt params) and add the source-workspace binding named source-workspace to the TriggerTemplate so generated PipelineRuns match the contract used by the pipeline from-code-to-cluster and the bootstrap runs.
♻️ Duplicate comments (2)
apps/portal/examples/multi-option-react-template/template.yaml (1)
121-123:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTrường
Namevẫn chưa được propagate vào artifact render.
values.namevẫn map từparameters.repoName, nên input bắt buộcnamegần như không đi vào source template mà chỉ còn ảnh hưởng ở mô tả repo. NếurepoNamelà slug kỹ thuật, nên truyền riêngrepoNamecho resource name và mapvalues.nametừparameters.name; còn nếu không, nên bỏ hẳn fieldnameđể tránh thu một giá trị bắt buộc nhưng không dùng.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/portal/examples/multi-option-react-template/template.yaml` around lines 121 - 123, The template currently maps values.name to parameters.repoName so the user-facing Name input isn't propagated into the rendered artifact; update the mapping so values.name = ${{ parameters.name }} (and keep resource naming using ${{ parameters.repoName }} for a technical slug), or if you don't need a separate human-facing name remove the values.name field entirely to avoid requiring an unused parameter; adjust any resource name references that currently use values.name to instead use parameters.repoName if they need the slug.apps/portal/examples/multi-option-react-template/content/source/webpack.config.js (1)
27-28:⚠️ Potential issue | 🟠 Major | ⚡ Quick winBiểu thức template ở Line 28 vẫn làm
webpack.config.jskhông parse được.Việc rút gọn về một dòng chưa giải quyết gốc vấn đề: file
.jsnày vẫn chứa cú pháp template thô, nên Biome/JS parser sẽ fail trước khi Backstage render. Nếu muốn giữ templating trongwebpack.config.js, cần loại path template này khỏi JS lint/parser hoặc chuyển nó sang dạng template không bị tooling đọc như JavaScript thuần.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/portal/examples/multi-option-react-template/content/source/webpack.config.js` around lines 27 - 28, Dòng chứa biểu thức template thô trong webpack.config.js (the "use" array line with {% if values.styling == 'tailwind' %}…) khiến file JS không parse được; thay vào đó loại bỏ cú pháp template khỏi JS thuần: hoặc chuyển toàn bộ file thành template riêng (ví dụ webpack.config.ejs) so Backstage chỉ thao tác trên template và xuất ra webpack.config.js hợp lệ, hoặc giữ webpack.config.js thuần và thay expression bằng một placeholder (ví dụ "__STYLING_USE_TAILWIND__") trong dòng "use" rồi thay placeholder này ở bước scaffolding/generation; đảm bảo cuối cùng commit là một file JS hợp lệ (không còn {% ... %}) và cập nhật logic generation to replace the placeholder or point to the .ejs template.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml`:
- Line 7: The gitea.org/repo-url annotation is built from
values.owner/values.name but values.owner is derived from
user.entity.metadata.name; change it to use the owner parsed from
parameters.repoUrl so the SCM link matches the published repo. Update the
template rendering so values.owner is populated from (parameters.repoUrl |
parseRepoUrl).owner (or directly use (parameters.repoUrl | parseRepoUrl).owner
in the catalog-info.yaml expression) and keep values.name as-is, ensuring the
gitea.org/repo-url uses that parsed owner and values.name instead of the current
values.owner source.
---
Outside diff comments:
In
`@apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml`:
- Around line 30-49: TriggerTemplate invoking the pipeline from-code-to-cluster
is missing required params and a workspace, causing PipelineRuns from the
webhook to fail validation or skip test/deploy; add params test-command,
argocd-namespace, argocd-app-name with appropriate values (e.g., from values or
tt params) and add the source-workspace binding named source-workspace to the
TriggerTemplate so generated PipelineRuns match the contract used by the
pipeline from-code-to-cluster and the bootstrap runs.
---
Duplicate comments:
In
`@apps/portal/examples/multi-option-react-template/content/source/webpack.config.js`:
- Around line 27-28: Dòng chứa biểu thức template thô trong webpack.config.js
(the "use" array line with {% if values.styling == 'tailwind' %}…) khiến file JS
không parse được; thay vào đó loại bỏ cú pháp template khỏi JS thuần: hoặc
chuyển toàn bộ file thành template riêng (ví dụ webpack.config.ejs) so Backstage
chỉ thao tác trên template và xuất ra webpack.config.js hợp lệ, hoặc giữ
webpack.config.js thuần và thay expression bằng một placeholder (ví dụ
"__STYLING_USE_TAILWIND__") trong dòng "use" rồi thay placeholder này ở bước
scaffolding/generation; đảm bảo cuối cùng commit là một file JS hợp lệ (không
còn {% ... %}) và cập nhật logic generation to replace the placeholder or point
to the .ejs template.
In `@apps/portal/examples/multi-option-react-template/template.yaml`:
- Around line 121-123: The template currently maps values.name to
parameters.repoName so the user-facing Name input isn't propagated into the
rendered artifact; update the mapping so values.name = ${{ parameters.name }}
(and keep resource naming using ${{ parameters.repoName }} for a technical
slug), or if you don't need a separate human-facing name remove the values.name
field entirely to avoid requiring an unused parameter; adjust any resource name
references that currently use values.name to instead use parameters.repoName if
they need the slug.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ebd2bb96-2e97-4db9-986d-ebfd0e675a24
📒 Files selected for processing (12)
apps/portal/app-config.yamlapps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yamlapps/portal/examples/multi-option-react-template/content/gitops/helios-app.yamlapps/portal/examples/multi-option-react-template/content/gitops/pipeline.yamlapps/portal/examples/multi-option-react-template/content/gitops/triggers.yamlapps/portal/examples/multi-option-react-template/content/source/Dockerfileapps/portal/examples/multi-option-react-template/content/source/catalog-info.yamlapps/portal/examples/multi-option-react-template/content/source/src/App.jsxapps/portal/examples/multi-option-react-template/content/source/src/index.tailwind.cssapps/portal/examples/multi-option-react-template/content/source/src/index.vanilla.cssapps/portal/examples/multi-option-react-template/content/source/webpack.config.jsapps/portal/examples/multi-option-react-template/template.yaml
💤 Files with no reviewable changes (1)
- apps/portal/examples/multi-option-react-template/content/source/src/index.vanilla.css
| name: ${{ values.name | dump }} | ||
| description: ${{ (values.description or "") | dump }} | ||
| annotations: | ||
| gitea.org/repo-url: http://localhost:3030/${{ values.owner }}/${{ values.name }} |
There was a problem hiding this comment.
gitea.org/repo-url có thể trỏ sai repo thực tế.
Source repo được publish theo parameters.repoUrl, nhưng annotation ở Line 7 lại ghép từ values.owner/values.name. Hiện values.owner lấy từ user.entity.metadata.name trong template.yaml, nên nếu user scaffold vào org/user khác thì link SCM trong catalog sẽ lệch repo đã tạo. Nên truyền owner từ (parameters.repoUrl | parseRepoUrl).owner rồi dùng giá trị đó ở đây.
💡 Hướng sửa
# template.yaml
values:
name: ${{ parameters.repoName }}
description: ${{ parameters.description }}
+ repoOwner: ${{ (parameters.repoUrl | parseRepoUrl).owner }}
buildTool: ${{ parameters.buildTool }}
styling: ${{ parameters.styling }}
stateManagement: ${{ parameters.stateManagement }}
dataFetching: ${{ parameters.dataFetching }}
port: ${{ parameters.port }}
owner: ${{ user.entity.metadata.name or 'guest' }}
# catalog-info.yaml
- gitea.org/repo-url: http://localhost:3030/${{ values.owner }}/${{ values.name }}
+ gitea.org/repo-url: http://localhost:3030/${{ values.repoOwner }}/${{ values.name }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml`
at line 7, The gitea.org/repo-url annotation is built from
values.owner/values.name but values.owner is derived from
user.entity.metadata.name; change it to use the owner parsed from
parameters.repoUrl so the SCM link matches the published repo. Update the
template rendering so values.owner is populated from (parameters.repoUrl |
parseRepoUrl).owner (or directly use (parameters.repoUrl | parseRepoUrl).owner
in the catalog-info.yaml expression) and keep values.name as-is, ensuring the
gitea.org/repo-url uses that parsed owner and values.name instead of the current
values.owner source.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml (1)
1-40: 🧹 Nitpick | 🔵 TrivialPipelineRun tên cố định nằm trong repo GitOps được Argo CD sync (
prune: true,selfHeal: true).
PipelineRunnày cómetadata.namecố định (${{ values.repoName }}-pipeline-run) và được publish vào repo GitOps mà Argo CD đồng bộ vớipath: ./. VìPipelineRunlà immutable và sẽ chuyển sang trạng thái Completed sau khi chạy, Argo CD nhiều khả năng báoOutOfSyncliên tục hoặc tái tạo run khi self-heal. Cân nhắc tách build run khỏi tài nguyên được Argo CD quản lý (chỉ dùng cơ chế Tekton Triggers ởtriggers.yaml), hoặc loại trừ tài nguyên này khỏi sync.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml` around lines 1 - 40, The PipelineRun resource (kind: PipelineRun with metadata.name set to ${{ values.repoName }}-pipeline-run) is a fixed, completed Tekton object that will be stored in the GitOps repo Argo CD syncs, causing perpetual OutOfSync/self-heal churn; remove this PipelineRun from the GitOps-managed manifests and instead trigger runs dynamically (e.g., via Tekton Triggers in triggers.yaml) or change the lifetime/placement so Argo CD does not manage it (alternatively exclude this path/resource from Argo CD sync or make the run non-committed by using a generated name/ephemeral creation mechanism), updating references to image-repo/app-repo-url/app-repo-revision and argocd-app-name as needed.apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml (1)
21-38:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winThiếu
spec.paramstrongTriggerTemplatekhiến$(tt.params.*)không được thay thế đúng
Trongapps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml(TriggerTemplatespeclines 21-38),resourcetemplatesdùng$(tt.params.git-repo-url)và$(tt.params.git-revision)nhưngTriggerTemplate.speckhông khai báoparams, nên TriggerTemplate sẽ fail validation/không inject giá trị choPipelineRun.🐛 Đề xuất thêm khai báo params
spec: + params: + - name: git-repo-url + - name: git-revision + - name: git-repo-name + - name: git-owner resourcetemplates:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml` around lines 21 - 38, The TriggerTemplate is missing a spec.params declaration so the placeholders used in resourcetemplates (e.g., $(tt.params.git-repo-url) and $(tt.params.git-revision)) won't be substituted; update the TriggerTemplate (look for the resource named TriggerTemplate with resourcetemplates containing the PipelineRun) to add a spec.params array defining at least git-repo-url and git-revision (matching the names used in the PipelineRun params) so the TriggerTemplate will validate and inject values into the PipelineRun.
♻️ Duplicate comments (1)
apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml (1)
7-7:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
gitea.org/repo-urlvẫn có nguy cơ trỏ sai owner của repo.Line 7 vẫn ghép URL từ
values.ownerthay vì owner parse từrepoUrl, nên có thể lệch với repo thực tế đã publish khi user scaffold vào org/user khác.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml` at line 7, The gitea.org/repo-url is built from values.owner which can diverge from the actual owner parsed from values.repoUrl; change the template so gitea.org/repo-url uses the owner derived from repoUrl (the parsed owner variable) instead of values.owner — locate the gitea.org/repo-url entry in catalog-info.yaml and replace the interpolation to reference the parsed owner from repoUrl (or ensure repoUrl is parsed once into an owner variable and reuse that) so the generated URL always matches the actual published repository owner.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml`:
- Line 1: Cập nhật tất cả chỗ khai báo PipelineRun từ apiVersion:
tekton.dev/v1beta1 thành apiVersion: tekton.dev/v1; cụ thể sửa file
content/gitops/pipeline.yaml (đổi apiVersion của tài nguyên PipelineRun) và file
content/gitops/triggers.yaml nơi TriggerTemplate nhúng một PipelineRun (cập nhật
apiVersion trong template). Sau khi đổi apiVersion, rà soát các trường trong đối
tượng PipelineRun/TriggerTemplate để đảm bảo không có thuộc tính deprecated và
điều chỉnh schema nếu cần.
In
`@apps/portal/examples/multi-option-react-template/content/source/package.json`:
- Line 2: The package name is set directly from values.repoName in package.json
which allows invalid npm names; update the template to ensure valid names by
either (1) adding a validation pattern to template.yaml for the repoName input
that enforces npm package name rules (lowercase, no leading dot/underscore,
allowed characters, optional scoped format) or (2) change the package.json
template to derive the name from values.repoName via a sanitization/slugify step
(lowercase, replace invalid chars with hyphens, trim leading/trailing
dots/underscores, and enforce max length) so the value used in "name": "${{
values.repoName }}" is guaranteed valid; reference values.repoName,
package.json, and template.yaml when applying the fix.
In `@apps/portal/examples/multi-option-react-template/template.yaml`:
- Line 138: The long single-line Nunjucks expression in the files field (the
concatenated expression using parameters.buildTool, parameters.styling and
parameters.stateManagement) is hard to read; add a clear YAML comment
immediately above this step in template.yaml that documents each branch: explain
how index.* and styling files are selected via parameters.buildTool and
parameters.styling, how the stateManagement conditional chooses reduxStore.js vs
zustandStore.js and maps them to ./source/src/store/store.js, and note the
webpack.config.ejs inclusion only when parameters.buildTool == "webpack"; keep
the expression unchanged but ensure the comment names the exact parameters
(parameters.buildTool, parameters.styling, parameters.stateManagement) and the
intended mappings so future maintainers can understand the logic.
---
Outside diff comments:
In
`@apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml`:
- Around line 1-40: The PipelineRun resource (kind: PipelineRun with
metadata.name set to ${{ values.repoName }}-pipeline-run) is a fixed, completed
Tekton object that will be stored in the GitOps repo Argo CD syncs, causing
perpetual OutOfSync/self-heal churn; remove this PipelineRun from the
GitOps-managed manifests and instead trigger runs dynamically (e.g., via Tekton
Triggers in triggers.yaml) or change the lifetime/placement so Argo CD does not
manage it (alternatively exclude this path/resource from Argo CD sync or make
the run non-committed by using a generated name/ephemeral creation mechanism),
updating references to image-repo/app-repo-url/app-repo-revision and
argocd-app-name as needed.
In
`@apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml`:
- Around line 21-38: The TriggerTemplate is missing a spec.params declaration so
the placeholders used in resourcetemplates (e.g., $(tt.params.git-repo-url) and
$(tt.params.git-revision)) won't be substituted; update the TriggerTemplate
(look for the resource named TriggerTemplate with resourcetemplates containing
the PipelineRun) to add a spec.params array defining at least git-repo-url and
git-revision (matching the names used in the PipelineRun params) so the
TriggerTemplate will validate and inject values into the PipelineRun.
---
Duplicate comments:
In
`@apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml`:
- Line 7: The gitea.org/repo-url is built from values.owner which can diverge
from the actual owner parsed from values.repoUrl; change the template so
gitea.org/repo-url uses the owner derived from repoUrl (the parsed owner
variable) instead of values.owner — locate the gitea.org/repo-url entry in
catalog-info.yaml and replace the interpolation to reference the parsed owner
from repoUrl (or ensure repoUrl is parsed once into an owner variable and reuse
that) so the generated URL always matches the actual published repository owner.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: c456b96c-ad5c-4c49-9693-d53bf2ced5ef
📒 Files selected for processing (9)
apps/portal/app-config.yamlapps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yamlapps/portal/examples/multi-option-react-template/content/gitops/helios-app.yamlapps/portal/examples/multi-option-react-template/content/gitops/pipeline.yamlapps/portal/examples/multi-option-react-template/content/gitops/triggers.yamlapps/portal/examples/multi-option-react-template/content/source/catalog-info.yamlapps/portal/examples/multi-option-react-template/content/source/package.jsonapps/portal/examples/multi-option-react-template/content/source/webpack.config.ejsapps/portal/examples/multi-option-react-template/template.yaml
💤 Files with no reviewable changes (1)
- apps/portal/examples/multi-option-react-template/content/source/webpack.config.ejs
…ers. Comments added for Nunjucks logic.



Description
This PR introduces the Multi-Option React Scaffolder Template to the Backstage Software Templates catalogue. It provides a highly configurable React project template that dynamically customizes its build system, styling configuration, state management library, and data fetching approach based on user inputs.
Key Changes
template.yaml):instance.files is not of a type(s) array) by writing template expressions that compile into valid JSON strings representing arrays, which Backstage parses back into native JavaScript arrays.package.jsondependency injection and configurations.index.vite.htmlvs.index.webpack.html,vite.config.jsvs.webpack.config.js).fs:renameandfs:deletecleanup actions that automatically wipe out all unused configuration files, styling dependencies, and state-management stores based on the user's selected combination.kubernetes:create-git-credentials-secret) and appliedHeliosAppCRD manifests (kubernetes:apply) via ArgoCD, Gitea webhooks, and Tekton.Type of change
Checklist
Evidence of Successful Run
Summary by CodeRabbit
Tính Năng Mới