Skip to content

New Multi-option React Scaffolder template #83

Open
hoangphuc841 wants to merge 6 commits into
mainfrom
users/nhphuc/multi-option-react-template
Open

New Multi-option React Scaffolder template #83
hoangphuc841 wants to merge 6 commits into
mainfrom
users/nhphuc/multi-option-react-template

Conversation

@hoangphuc841
Copy link
Copy Markdown
Collaborator

@hoangphuc841 hoangphuc841 commented Jun 1, 2026

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

  1. Scaffolder Template (template.yaml):
    • Defined parameters for customizable stack options:
      • Build Tool: Vite or Webpack
      • Styling: Tailwind CSS or Vanilla CSS
      • State Management: Zustand, Redux Toolkit, or None
      • Data Fetching: React Query (TanStack Query) or standard fetch (None)
    • Evaluated dynamic list generation in a single step using Nunjucks array concatenation and inline conditionals to ensure the Backstage UI pipeline remains clean without showing multiple "Skipped" steps.
    • Fixed an array evaluation issue (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.
    • Fixed catalog parsing errors by wrapping the template expressions inside single quotes.
  2. Boilerplate Sources & Config Cleanup:
    • Programmed dynamic package.json dependency injection and configurations.
    • Programmed conditional entry points (index.vite.html vs. index.webpack.html, vite.config.js vs. webpack.config.js).
    • Integrated dynamic fs:rename and fs:delete cleanup actions that automatically wipe out all unused configuration files, styling dependencies, and state-management stores based on the user's selected combination.
  3. Deployment Integration:
    • Generated Kubernetes secrets (kubernetes:create-git-credentials-secret) and applied HeliosApp CRD manifests (kubernetes:apply) via ArgoCD, Gitea webhooks, and Tekton.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added evidence that prove my fix is effective or that my feature works
  • I have added unit tests for new feature
  • Existing unit tests pass locally with my changes
  • Prettier and linting checks pass (Backstage)
  • Issues linked to this Pull Request (Development section on the right)

Evidence of Successful Run

image image

Summary by CodeRabbit

Tính Năng Mới

  • Thêm mẫu Scaffolder React cho phép tạo dự án React với tùy chọn: công cụ build (Vite/Webpack), styling (Tailwind/vanilla), quản lý state (Zustand/Redux) và data fetching (React Query).
  • Cập nhật cấu hình hệ thống để khám phá mẫu mới.
  • Tích hợp quy trình CI/CD tự động với Tekton Triggers và Argo CD.

…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.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Warning

Rate limit exceeded

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

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 @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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8e752d93-d566-46a2-bec0-7d3b5047adff

📥 Commits

Reviewing files that changed from the base of the PR and between d96bdd1 and fe0212b.

📒 Files selected for processing (4)
  • apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml
  • apps/portal/examples/multi-option-react-template/content/source/package.json
  • apps/portal/examples/multi-option-react-template/template.yaml
📝 Walkthrough

Walkthrough

Pull 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.

Changes

Multi-Option React Scaffolder Template với GitOps Integration

Layer / File(s) Tóm tắt
Đăng ký template vào Backstage catalog
apps/portal/app-config.yaml
Cập nhật cấu hình database connection từ dạng string sang object, đồng thời thêm location mới để đăng ký "Multi-Option React Scaffolder Template" cho phép Backstage khám phá template mới.
GitOps manifests cho CI/CD automation
apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml, helios-app.yaml, pipeline.yaml, triggers.yaml
Tạo bộ manifests Kubernetes hoàn chỉnh: Argo CD Application (khai báo sync policy automated), HeliosApp CRD (cấu hình component web-service), Tekton PipelineRun (build & push image), và Tekton Triggers (webhook binding, template tạo PipelineRun, event listener, RBAC) để tự động hóa quy trình từ push code tới deployment.
React build tooling configuration
apps/portal/examples/multi-option-react-template/content/source/.eslintrc.json, .eslintignore, .gitignore, babel.config.json, tailwind.config.cjs, postcss.config.cjs, vite.config.js, webpack.config.ejs, package.json
Cấu hình tools build có điều kiện: ESLint với React plugin, Babel presets, Tailwind CSS và PostCSS (khi chọn), Vite hoặc Webpack theo lựa chọn, package.json động với dependencies thay đổi theo tech stack (Redux Toolkit, Zustand, React Query).
React application source code
apps/portal/examples/multi-option-react-template/content/source/src/App.jsx, src/main.jsx, src/store/reduxStore.js, src/store/zustandStore.js, src/index.tailwind.css, src/index.vanilla.css, index.vite.html, index.webpack.html, Dockerfile, catalog-info.yaml
Triển khai ứng dụng React hoàn chỉnh: App component có counter demo và GitHub data fetch, stores Redux/Zustand (tuỳ chọn), entry point React với provider nesting (QueryClient, Redux), HTML templates cho Vite/Webpack, Dockerfile multi-stage (build & production), Backstage catalog metadata.
Backstage scaffolder template definition
apps/portal/examples/multi-option-react-template/template.yaml
Định nghĩa template Backstage 230 dòng: khai báo 10 tham số input (name, port, dockerOrg, buildTool, styling, stateManagement, dataFetching), quy trình 10 bước (fetch/configure/cleanup source, publish, webhook, fetch/publish GitOps, create secret, apply manifest, register catalog), và 3 output links (source repo, GitOps repo, catalog link).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • helios-platform-team/helios-platform#78: Cả hai PR cập nhật apps/portal/app-config.yaml bằng cách thêm entries mới vào catalog.locations để đăng ký Backstage Templates khác nhau.

Suggested reviewers

  • NgocAnhDo26

Poem

🐰 Một template React tuyệt vời được sinh ra,
Đa tuỳ chọn, GitOps tự động hóa,
Vite hay Webpack, Redux hay Zustand,
Từ code tới cluster, kỳ diệu thay thay,
Scaffolder magic, Tekton vận hành! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 Tiêu đề rõ ràng và cụ thể mô tả thay đổi chính: thêm mới một template Backstage Scaffolder cho React với các tùy chọn cấu hình động.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 users/nhphuc/multi-option-react-template

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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

📥 Commits

Reviewing files that changed from the base of the PR and between d2fec19 and d8ea155.

📒 Files selected for processing (25)
  • apps/operator/config/crd/bases/app.helios.io_heliosapps.yaml
  • apps/portal/app-config.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/helios-app.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml
  • apps/portal/examples/multi-option-react-template/content/source/.eslintignore
  • apps/portal/examples/multi-option-react-template/content/source/.eslintrc.json
  • apps/portal/examples/multi-option-react-template/content/source/.gitignore
  • apps/portal/examples/multi-option-react-template/content/source/Dockerfile
  • apps/portal/examples/multi-option-react-template/content/source/babel.config.json
  • apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml
  • apps/portal/examples/multi-option-react-template/content/source/index.vite.html
  • apps/portal/examples/multi-option-react-template/content/source/index.webpack.html
  • apps/portal/examples/multi-option-react-template/content/source/package.json
  • apps/portal/examples/multi-option-react-template/content/source/postcss.config.cjs
  • apps/portal/examples/multi-option-react-template/content/source/src/App.jsx
  • apps/portal/examples/multi-option-react-template/content/source/src/index.css
  • apps/portal/examples/multi-option-react-template/content/source/src/main.jsx
  • apps/portal/examples/multi-option-react-template/content/source/src/store/reduxStore.js
  • apps/portal/examples/multi-option-react-template/content/source/src/store/zustandStore.js
  • apps/portal/examples/multi-option-react-template/content/source/tailwind.config.cjs
  • apps/portal/examples/multi-option-react-template/content/source/vite.config.js
  • apps/portal/examples/multi-option-react-template/content/source/webpack.config.js
  • apps/portal/examples/multi-option-react-template/template.yaml

Comment thread apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml Outdated
Comment on lines +23 to +31
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Suggested change
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.

Comment thread apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml Outdated
Comment thread apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml Outdated
Comment thread apps/portal/examples/multi-option-react-template/content/source/Dockerfile Outdated
Comment thread apps/portal/examples/multi-option-react-template/content/source/src/App.jsx Outdated
Comment on lines +1 to +5
{% if values.styling == 'tailwind' -%}
@tailwind base;
@tailwind components;
@tailwind utilities;
{%- else -%}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Comment thread apps/portal/examples/multi-option-react-template/content/source/webpack.config.js Outdated
Comment thread apps/portal/examples/multi-option-react-template/template.yaml
Comment thread apps/portal/examples/multi-option-react-template/template.yaml Outdated
@hoangphuc841
Copy link
Copy Markdown
Collaborator Author

hoangphuc841 commented Jun 2, 2026

Addressed RabbitMQ suggested actions in commit 1a04d4d and merge new changes from main

@NgocAnhDo26
Copy link
Copy Markdown
Contributor

Can you also include screenshots for:

  • The CI/CD pipeline: what are the CI steps? Run successfully?
  • Deployment: Did ArgoCD deploys it? Can you access and use the app normally?

- 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.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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 win

Bổ sung đủ params và workspace cho PipelineRun sinh từ webhook.

TriggerTemplate đang gọi cùng pipeline from-code-to-cluster như content/gitops/pipeline.yaml, nhưng lại thiếu test-command, argocd-namespace, argocd-app-name và 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 win

Trường Name vẫn chưa được propagate vào artifact render.

values.name vẫn map từ parameters.repoName, nên input bắt buộc name gần như không đi vào source template mà chỉ còn ảnh hưởng ở mô tả repo. Nếu repoName là slug kỹ thuật, nên truyền riêng repoName cho resource name và map values.name từ parameters.name; còn nếu không, nên bỏ hẳn field name để 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 win

Biểu thức template ở Line 28 vẫn làm webpack.config.js khô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 .js nà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 trong webpack.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

📥 Commits

Reviewing files that changed from the base of the PR and between d8ea155 and 47ac855.

📒 Files selected for processing (12)
  • apps/portal/app-config.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/helios-app.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml
  • apps/portal/examples/multi-option-react-template/content/source/Dockerfile
  • apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml
  • apps/portal/examples/multi-option-react-template/content/source/src/App.jsx
  • apps/portal/examples/multi-option-react-template/content/source/src/index.tailwind.css
  • apps/portal/examples/multi-option-react-template/content/source/src/index.vanilla.css
  • apps/portal/examples/multi-option-react-template/content/source/webpack.config.js
  • apps/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 }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

@hoangphuc841
Copy link
Copy Markdown
Collaborator Author

template.yaml name value was incorrect making all the sequencing steps CI pipeline, kubernetes status and argocd applications break so I have changed it to the correct value. The template was also missing the backstage annotation causing it not displaying those status on the Portal. I have added them and it's displaying correctly.

App available and runs correctly

image

CI pipeline runs successfully

image

ArgoCD applications deploy and sync healthy in the console. App is also ported to 9000.

image

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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 | 🔵 Trivial

PipelineRun tên cố định nằm trong repo GitOps được Argo CD sync (prune: true, selfHeal: true).

PipelineRun này có metadata.name cố định (${{ values.repoName }}-pipeline-run) và được publish vào repo GitOps mà Argo CD đồng bộ với path: ./. Vì PipelineRun là immutable và sẽ chuyển sang trạng thái Completed sau khi chạy, Argo CD nhiều khả năng báo OutOfSync liê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 win

Thiếu spec.params trong TriggerTemplate khiến $(tt.params.*) không được thay thế đúng
Trong apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml (TriggerTemplate spec lines 21-38), resourcetemplates dùng $(tt.params.git-repo-url)$(tt.params.git-revision) nhưng TriggerTemplate.spec không khai báo params, nên TriggerTemplate sẽ fail validation/không inject giá trị cho PipelineRun.

🐛 Đề 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-url vẫn có nguy cơ trỏ sai owner của repo.

Line 7 vẫn ghép URL từ values.owner thay 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

📥 Commits

Reviewing files that changed from the base of the PR and between 47ac855 and d96bdd1.

📒 Files selected for processing (9)
  • apps/portal/app-config.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/argocd-app.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/helios-app.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml
  • apps/portal/examples/multi-option-react-template/content/gitops/triggers.yaml
  • apps/portal/examples/multi-option-react-template/content/source/catalog-info.yaml
  • apps/portal/examples/multi-option-react-template/content/source/package.json
  • apps/portal/examples/multi-option-react-template/content/source/webpack.config.ejs
  • apps/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

Comment thread apps/portal/examples/multi-option-react-template/content/gitops/pipeline.yaml Outdated
Comment thread apps/portal/examples/multi-option-react-template/content/source/package.json Outdated
Comment thread apps/portal/examples/multi-option-react-template/template.yaml
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.

2 participants