Compare commits

..
Author SHA1 Message Date
mergify[bot]andAndy Lee b8b4ee4c41 replace tag format v1.5.0 to harvester-1.5.0 (#190) (#313)
(cherry picked from commit 374b904191)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-05-26 14:21:47 +08:00
Andy Lee 021d6f673f bump version to 1.0.6
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-26 13:48:57 +08:00
Andy Lee a849671034 bump to v1.0.6-rc4
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-23 11:19:39 +08:00
mergify[bot]andYiya Chen b98f878c5d fix: range condition (#299) (#300)
(cherry picked from commit cbfcf4dbae)

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
Co-authored-by: Yiya Chen <yiya.chen@suse.com>
2025-05-15 16:26:48 +08:00
mergify[bot]andJack Yu 78482285b3 chore: use default imag repo name (#212) (#291)
(cherry picked from commit de4edbbf3b)

Signed-off-by: Jack Yu <jack.yu@suse.com>
Co-authored-by: Jack Yu <jack.yu@suse.com>
2025-05-13 12:10:05 +08:00
mergify[bot]andJack Yu 4656976b91 chore: add building catalog GA (#181) (#290)
* chore: add building catalog GA



* feat: should include prerelease



---------


(cherry picked from commit 1880043a80)

Signed-off-by: Jack Yu <jack.yu@suse.com>
Co-authored-by: Jack Yu <jack.yu@suse.com>
2025-05-13 12:08:06 +08:00
renovate[bot] aeb3588b83 chore(deps): update dependency follow-redirects to v1.15.6 [security] (#287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-13 04:07:25 +00:00
renovate[bot] d14b0cb95c chore(deps): update dependency ejs to v3.1.10 [security] (#286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-13 03:10:36 +00:00
Andy Lee 2f0884d7bd bump to v1.0.6-rc3
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-13 11:07:05 +08:00
mergify[bot]andAndy Lee 037ce6132b VM Access Credentials SSH Keys Not Rendering (backport #279) (#281)
* Remove unneeded condition (#279)

Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 8410f75859)

# Conflicts:
#	pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineSSHKey.vue

* solve conflict

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-05-12 10:56:49 +08:00
Andy Lee 47b54b4f06 bump version to 1.0.6-rc2
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-08 17:35:08 +08:00
Andy Lee 9dd8ae479a fix #cloud-config disappear when add/remove ssh key (#273)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-08 17:32:35 +08:00
Andy Lee 5682bf4c3a Fix create ssh key modal not pop up in rancher integration mode (#269)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-07 15:50:29 +08:00
Andy Lee 960df31667 Bump version to 1.0.6-rc1
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-06 11:57:48 +08:00
Yi-Ya Chen 63451e7d2b ci: rename file
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-05-06 11:56:30 +08:00
Yi-Ya Chen 55aaa8440d ci: revert change
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-05-06 11:56:29 +08:00
Yi-Ya Chen da4121da69 ci: rename the workflow 2025-05-06 11:56:29 +08:00
Yi-Ya Chen 30e49a6f2c ci: add ci pipeline
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-05-06 11:56:28 +08:00
Andy Lee 2255bd4f69 Add 1.4.3 feature flag
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-05-06 11:26:53 +08:00
Andy Lee 7e5ee04637 fix template page should be groupable (#262)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-04-17 15:45:40 +08:00
mergify[bot]andAndy Lee 8863de8874 fix the doneOverride path for harvesterhci.io.virtualmachinetemplate (#211) (#261)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 22a032e56c)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-17 15:40:34 +08:00
mergify[bot]andAndy Lee 73952a6b4e update RadioGroup update value action (#255) (#259)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 74300f24b3)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-17 15:29:29 +08:00
mergify[bot]andAndy Lee 0496fae623 fix percent typo (#258)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 487f9abc10)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-17 15:25:00 +08:00
mergify[bot]andandy.lee d5cd97aafd Fix upgrade cluster model styles (backport #162) (#257)
* fix upgrade model style

Signed-off-by: andy.lee <andy.lee@suse.com>
(cherry picked from commit ff439e66a9)

* change overallMessage color to red

Signed-off-by: andy.lee <andy.lee@suse.com>
(cherry picked from commit 50901a2eaf)

---------

Co-authored-by: andy.lee <andy.lee@suse.com>
2025-04-17 15:23:32 +08:00
mergify[bot]andYi-Ya Chen 31c6a794be fix: register upgrade component in header (#256)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
(cherry picked from commit b499f62c56)

Co-authored-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-04-17 15:19:08 +08:00
mergify[bot]andandy.lee 9d9383ba90 fix: vGPU number not correct (#254)
Signed-off-by: andy.lee <andy.lee@suse.com>
(cherry picked from commit 26afffc2f1)
(cherry picked from commit 40dc31226b)

Co-authored-by: andy.lee <andy.lee@suse.com>
2025-04-17 14:56:05 +08:00
mergify[bot]andandy.lee 1e02dbffe3 fix: isEncrypted breaks all the volume page (#253)
Signed-off-by: andy.lee <andy.lee@suse.com>
(cherry picked from commit 2232e56ba1)
(cherry picked from commit c188f3367d)

Co-authored-by: andy.lee <andy.lee@suse.com>
2025-04-17 14:50:31 +08:00
mergify[bot]andandy.lee b0609020cc fix sshkey is not added to cloud init user data immediately (#252)
Signed-off-by: andy.lee <andy.lee@suse.com>
(cherry picked from commit e2daa1ea0c)

Co-authored-by: andy.lee <andy.lee@suse.com>
2025-04-17 14:50:10 +08:00
mergify[bot]andAndy Lee feca476e36 Fix error banner position in all dialogs (backport #226) (#250)
* Fix error banner position in all dialogs (#226)

* fix error banner position in all dialogs

Signed-off-by: Andy Lee <andy.lee@suse.com>

* update HarvesterImageDownloader.vue

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 25439aee65)

# Conflicts:
#	pkg/harvester/dialog/ConfirmExecutionDialog.vue
#	pkg/harvester/dialog/HarvesterImageDownloader.vue

* remove unneeded dialog components

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-17 14:46:30 +08:00
mergify[bot]andAndy Lee e6e36e94f1 fix image.repo to image.repository (#214) (#251)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit a24d01717a)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-17 14:46:11 +08:00
Andy Lee 54d48ce396 bump version to 1.0.6
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-04-17 13:47:13 +08:00
Andy Lee 404395c7d9 bump version to 1.0.5
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-04-08 15:26:18 +08:00
Andy Lee dc2437db99 bring status object in PUT dismiss API
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-04-08 15:12:13 +08:00
Andy Lee e8c8a54b9f add cleanForSave in harvester model
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-04-08 15:12:07 +08:00
andy.lee f3e4a8afe8 add pcideviceclaim and usbdeviceclaim models
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-04-08 15:11:55 +08:00
andy.lee e73c62739f fix unable to add/delete new hard disk
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-04-08 15:03:14 +08:00
Andy Lee 696af4e04f update yarn.lock
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-03-12 12:05:24 +08:00
Yi-Ya Chen 009f384a73 feat: fix $ctx redefine issue
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-03-12 12:04:24 +08:00
andy.lee 37766454bd move harvester schema.js into harvester folder
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-03-12 12:02:36 +08:00
Andy Lee 7943913ef7 replace tag format v1.5.0 to harvester-1.5.0 (#190)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-03-12 12:02:11 +08:00
Andy Lee 56a0fefd40 bump release version to v1.0.4
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-03-11 12:11:37 +08:00
Andy Lee ff1d5925a8 remove require dot for non-longhorn v1
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-03-11 12:09:18 +08:00
Andy Lee 63b5b980b7 Fix infobox style
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-03-11 12:09:10 +08:00
Yi-Ya Chen 1f7fd1246f refactor: default should selectable
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-03-11 12:07:52 +08:00
Yi-Ya Chen 34a25e9fc8 feat: gray out class name selector
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-03-11 12:07:32 +08:00
Andy Lee fb8d81d953 bump version to v1.0.4-rc2 2025-03-11 12:06:29 +08:00
andy.lee ba810a52b2 add refreshIntervalInSecond in 1.4.2 feature flag
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-03-11 12:06:29 +08:00
andy.lee 3f4f30ba0b Add refreshIntervalInSeconds in backup targe edit page
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-03-11 12:06:29 +08:00
andy.lee b428aaecf8 bump version to v1.0.4-rc1
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-02-13 14:34:14 +08:00
andy.lee 6b07a03451 add v1.4.2 feature flag
Signed-off-by: andy.lee <andy.lee@suse.com>
2025-02-13 14:19:37 +08:00
Volker Theile 2c756582e3 The hints on the branding page is using the wrong product name
The hints on the `Branding` page at `Advanced > Settings > UI > branding` are using the product name `Rancher` instead of `Harvester`.

Related to: https://github.com/harvester/harvester/issues/6341

Signed-off-by: Volker Theile <vtheile@suse.com>
(cherry picked from commit 849dcb6f26d52c955db669207f008de4480fe048)
2025-02-13 14:11:24 +08:00
380 changed files with 8323 additions and 34365 deletions
-1
View File
@@ -14,4 +14,3 @@ dist-pkg
pkg/harvester/index.ts pkg/harvester/index.ts
pkg/harvester/store/* pkg/harvester/store/*
scripts/pkgfile.js scripts/pkgfile.js
tmp
+1 -2
View File
@@ -4,8 +4,7 @@ description: Setup node and install dependencies
runs: runs:
using: 'composite' using: 'composite'
steps: steps:
- name: Setup Nodejs with yarn caching - uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
+17 -12
View File
@@ -1,14 +1,19 @@
pull_request_rules: pull_request_rules:
- name: Ask to resolve conflict - name: Automatically open backport PR to release-harvester-v1.5
conditions: conditions:
- conflict - base=main
actions: actions:
comment: backport:
message: This pull request is now in conflict. Could you fix it @{{author}}? 🙏 branches:
- "release-harvester-v1.5"
assignees:
- "{{ author }}"
labels:
- "v1.5 backport PR"
commands_restrictions: - name: Ask to resolve conflict
backport: conditions:
conditions: - conflict
- or: actions:
- sender-permission>=write comment:
- sender=github-actions[bot] message: This pull request is now in conflict. Could you fix it @{{author}}? 🙏
+12 -16
View File
@@ -1,23 +1,19 @@
<!-- This template is for Devs to give QA details before moving the issue To-Test -->
### Summary ### Summary
<!-- Give the fix root cause or feature requirement, at least list what this PR changes -->
### PR Checklists
- Do we need to backport this PR change to the [Harvester Dashboard](https://github.com/harvester/dashboard)?
- [ ] Yes, the relevant PR is at:
- Are backend engineers aware of UI changes?
- [ ] Yes, the backend owner is:
### PR Checklist ### Related Issue #
<!-- Check Yes if there is backend PR related to this UI PR, tag the backend owner's Github account --> <!-- Define findings related to the feature or bug issue. -->
- Are backend engineers aware of UI changes ?
- [ ] Yes, the backend owner is @
- [ ] No, frontend-only.
### Related Issue ### Test screenshot/video
<!-- Link the issue as harvester/harvester#<issue_number> --> <!-- Attach screenshot or video of the changes and eventual comparison if you find it necessary -->
harvester/harvester#<issue_number>
### Extra technical notes summary
### Test Steps <!-- Outline technical changes which may pass unobserved or may help to understand the process of solving the issue -->
<!-- Provide the test steps for reviewer to verify the issue -->
1. Go to ... page
### Test screenshot or video
<!-- Attach screenshot or video of the changes and eventual comparison -->
-40
View File
@@ -1,40 +0,0 @@
# .github/release.yml
changelog:
categories:
- title: Features
labels:
- feat
- title: Bug Fixes
labels:
- fix
- title: Dependencies
labels:
- deps
- title: Performance
labels:
- perf
- title: Documentation
labels:
- docs
- title: Style
labels:
- style
- title: Build & Continuous Integration
labels:
- build
- ci
- title: Security
labels:
- security
- title: Tests
labels:
- test
- title: Refactoring
labels:
- refactor
- title: Chores
labels:
- chore
- title: Others
labels:
- other
-57
View File
@@ -1,57 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":semanticCommitTypeAll(deps)",
":semanticCommitScopeDisabled"
],
"baseBranches": [
"main",
"release-harvester-v1.7",
"release-harvester-v1.8"
],
"automergeMajor": false,
"semanticCommits": "enabled",
"semanticCommitType": "deps",
"prHourlyLimit": 12,
"digest": {
"enabled": false
},
"timezone": "Asia/Taipei",
"schedule": ["after 10am on sunday"],
"postUpdateOptions": ["yarnDedupeFewer"],
"packageRules": [
{
"matchUpdateTypes": ["digest"],
"enabled": false
},
{
"matchUpdateTypes": ["major"],
"enabled": false
},
{
"matchPackagePatterns": ["vue", "vue-router", "vuex"],
"matchUpdateTypes": ["major"],
"enabled": false
},
{
"matchPackageNames": ["@rancher/shell"],
"enabled": false
},
{
"matchUpdateTypes": ["minor"],
"groupName": "minor dependencies",
"minimumReleaseAge": "7 days",
"labels": ["minor-update"],
"reviewers": ["a110605", "houhoucoop"]
},
{
"matchUpdateTypes": ["patch"],
"automerge": false,
"minimumReleaseAge": "7 days",
"groupName": "patch dependencies",
"labels": ["patch-update"],
"reviewers": ["a110605", "houhoucoop"]
}
]
}
-39
View File
@@ -1,39 +0,0 @@
name: "PR Management Add PR Label Collect Data"
on:
pull_request:
types: [opened, reopened, edited]
branches:
- main
- 'release-harvester-v*'
jobs:
collect:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.base_ref }}
- name: Setup Nodejs and yarn install
uses: ./.github/actions/setup
- name: Extract PR label
run: |
PR_LABEL=$(node ./scripts/extract-release-label.mjs "${{ github.event.pull_request.title }}")
echo "PR_LABEL=$PR_LABEL"
{
echo "PR_NUMBER=${{ github.event.pull_request.number }}"
echo "PR_LABEL=$PR_LABEL"
} > pr-add-label-data.env
- name: Upload PR data artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: pr-add-label-data
path: pr-add-label-data.env
-33
View File
@@ -1,33 +0,0 @@
name: "PR Management Add PR Label"
on:
workflow_run:
workflows:
- "PR Management Add PR Label Collect Data"
types: [completed]
jobs:
auto-assign-pr-label:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
actions: read
pull-requests: write
steps:
- name: Download PR data artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: pr-add-label-data
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Load PR data
run: |
cat pr-add-label-data.env >> $GITHUB_ENV
- name: Set PR label
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "PR_LABEL = $PR_LABEL"
gh pr edit "$PR_NUMBER" --repo "${{ github.repository }}" --add-label "$PR_LABEL"
-28
View File
@@ -1,28 +0,0 @@
name: "PR Management Auto Assign Collect Data"
on:
pull_request:
types: [opened, ready_for_review]
branches:
- main
- 'release-harvester-v*'
jobs:
collect:
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- name: Save PR data to artifact
run: |
{
echo "PR_NUMBER=${{ github.event.pull_request.number }}"
echo "PR_AUTHOR=${{ github.event.pull_request.user.login }}"
} > pr-auto-assign-data.env
- name: Upload PR data artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: pr-auto-assign-data
path: pr-auto-assign-data.env
-35
View File
@@ -1,35 +0,0 @@
name: "PR Management Auto Assign"
on:
workflow_run:
workflows:
- "PR Management Auto Assign Collect Data"
types: [completed]
jobs:
auto-assign:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
env:
REVIEWERS: "a110605,houhoucoop"
permissions:
actions: read
pull-requests: write
steps:
- name: Download PR data artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: pr-auto-assign-data
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Load PR data
run: |
cat pr-auto-assign-data.env >> $GITHUB_ENV
- name: Auto assign PR author
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "Assigning PR author: $PR_AUTHOR"
gh pr edit "$PR_NUMBER" --repo "${{ github.repository }}" --add-assignee "$PR_AUTHOR" --add-reviewer "$REVIEWERS"
@@ -1,30 +0,0 @@
name: "PR Management Add Labels Collect Data"
on:
pull_request:
types: [opened, reopened]
branches:
- main
- 'release-harvester-v*'
jobs:
collect:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- name: Save PR data to artifact
run: |
{
echo "PR_NUMBER=${{ github.event.pull_request.number }}"
echo "PR_BASE_REF=${{ github.event.pull_request.base.ref }}"
echo "PR_USER_LOGIN=${{ github.event.pull_request.user.login }}"
} > pr-backport-label-data.env
- name: Upload PR data artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: pr-backport-label-data
path: pr-backport-label-data.env
-83
View File
@@ -1,83 +0,0 @@
name: "PR Management Add Backport Labels"
on:
workflow_run:
workflows:
- "PR Management Add Labels Collect Data"
types: [completed]
jobs:
add-require-backport-label:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
actions: read
pull-requests: write
steps:
- name: Download PR data artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: pr-backport-label-data
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Load PR data
run: |
cat pr-backport-label-data.env >> $GITHUB_ENV
- name: Add require-backport label (main branch PRs)
if: env.PR_BASE_REF == 'main'
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
repo="${{ github.repository }}"
pr_number="$PR_NUMBER"
release_branches=$(gh api "repos/${repo}/branches" --paginate --jq '.[].name' | grep -E '^release-harvester-v[0-9]+\.[0-9]+$' || true)
if [[ -z "$release_branches" ]]; then
echo "No release branches found, skipping."
exit 0
fi
latest_branch=$(echo "$release_branches" | sort -Vr | head -n1)
version="${latest_branch#release-harvester-v}"
release_tag="v${version}.0"
tags=$(gh api "repos/${repo}/releases" --paginate --jq '.[].tag_name')
if echo "$tags" | grep -Fxq "$release_tag"; then
echo "Release $release_tag already published, skipping."
exit 0
fi
label="require backport/v${version}"
pr_labels=$(gh pr view "$pr_number" --repo "$repo" --json labels --jq '.labels[].name' || echo "")
if echo "$pr_labels" | grep -Fxq "$label"; then
echo "Label '$label' already present, skipping."
exit 0
fi
echo "Adding label: $label"
gh pr edit "$pr_number" --repo "$repo" --add-label "$label"
- name: Add backport label (release branch PRs opened by Mergify)
if: startsWith(env.PR_BASE_REF, 'release-harvester-v')
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
IS_MERGIFY=$(echo "$PR_USER_LOGIN" | grep -iq 'mergify' && echo true || echo false)
if [[ "$IS_MERGIFY" != "true" ]]; then
echo "PR author is not Mergify, skipping."
exit 0
fi
version="${PR_BASE_REF#release-harvester-v}"
label="backport/v${version}"
echo "Adding label: $label"
gh pr edit "$PR_NUMBER" --repo "${{ github.repository }}" --add-label "$label"
@@ -1,28 +0,0 @@
name: "PR Management Request Backport via Mergify Collect Data"
on:
pull_request:
types: [closed]
branches: [main]
jobs:
collect:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- name: Save PR data to artifact
run: |
labels_json='${{ toJson(github.event.pull_request.labels.*.name) }}'
{
echo "PR_NUMBER=${{ github.event.pull_request.number }}"
echo "PR_LABELS=$(echo "$labels_json" | jq -r '[.[]] | join(",")')"
} > pr-backport-request-data.env
- name: Upload PR data artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: pr-backport-request-data
path: pr-backport-request-data.env
-55
View File
@@ -1,55 +0,0 @@
name: "PR Management Request Backport via Mergify"
on:
workflow_run:
workflows:
- "PR Management Request Backport via Mergify Collect Data"
types: [completed]
jobs:
comment-backport:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
actions: read
pull-requests: write
steps:
- name: Download PR data artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: pr-backport-request-data
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Load PR data
run: |
cat pr-backport-request-data.env >> $GITHUB_ENV
- name: Post Mergify backport command
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
pr_number="$PR_NUMBER"
repo="${{ github.repository }}"
labels=$(echo "$PR_LABELS" | tr ',' '\n')
echo "Labels on PR: $labels"
matches=$(echo "$labels" | grep -oE '^require backport/v[0-9]+\.[0-9]+$' || true)
if [[ -z "$matches" ]]; then
echo "No back-port labels found — skipping."
exit 0
fi
branches=$(echo "$matches" \
| sed -E 's/^require backport\/v/release-harvester-v/' \
| sort -u | tr '\n' ' ')
branches=${branches%% }
cmd="@Mergifyio backport $branches"
echo "Posting Mergify command: $cmd"
gh pr comment "$pr_number" --repo "$repo" --body "$cmd"
@@ -11,19 +11,18 @@ defaults:
working-directory: ./ working-directory: ./
jobs: jobs:
check-version: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with:
fetch-depth: 1
- name: Check package version - name: Run tests
env: uses: ./.github/actions/lint
TAG_VERSION: ${{ github.event.release.tag_name }}
run: ./scripts/check-version.sh $TAG_VERSION
build-and-push-extension-catalog: build-and-push-extension-catalog:
needs: check-version needs: lint
uses: ./.github/workflows/build-extension-catalog.yml uses: ./.github/workflows/build-extension-catalog.yml
permissions: permissions:
actions: write actions: write
@@ -25,12 +25,12 @@ jobs:
name: Build & Upload Hosted name: Build & Upload Hosted
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 1 fetch-depth: 1
# Note - Cannot use the setup action here as it uses a different yarn install arg # Note - Cannot use the setup action here as it uses a different yarn install arg
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 - uses: actions/setup-node@v4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
@@ -45,20 +45,19 @@ jobs:
run: ./scripts/build-upload-gate run: ./scripts/build-upload-gate
- name: Get gcs auth - name: Get gcs auth
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3 uses: rancher-eio/read-vault-secrets@main
with: with:
secrets: | secrets: |
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ; secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
- name: Apply gcs auth - name: Apply gcs auth
# https://github.com/google-github-actions/auth # https://github.com/google-github-actions/auth
uses: google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed # v2 uses: 'google-github-actions/auth@v2'
with: with:
credentials_json: "${{ env.GOOGLE_AUTH }}" credentials_json: "${{ env.GOOGLE_AUTH }}"
- name: Upload build - name: Upload build
uses: google-github-actions/upload-cloud-storage@c0f6160ff80057923ff50e5e567695cea181ec23 # v2 uses: 'google-github-actions/upload-cloud-storage@v2'
# https://github.com/google-github-actions/upload-cloud-storage # https://github.com/google-github-actions/upload-cloud-storage
with: with:
path: ${{steps.build-hosted.outputs.BUILD_HOSTED_DIR}} path: ${{steps.build-hosted.outputs.BUILD_HOSTED_DIR}}
@@ -72,12 +71,12 @@ jobs:
name: Build & Upload Embedded name: Build & Upload Embedded
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 1 fetch-depth: 1
# Note - Cannot use the setup action here as it uses a different yarn install arg # Note - Cannot use the setup action here as it uses a different yarn install arg
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 - uses: actions/setup-node@v4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
@@ -90,19 +89,19 @@ jobs:
DISABLED_EMBED_PKG: https://releases.rancher.com/harvester-ui/plugin/harvester-1.0.3.tar.gz DISABLED_EMBED_PKG: https://releases.rancher.com/harvester-ui/plugin/harvester-1.0.3.tar.gz
- name: Get gcs auth - name: Get gcs auth
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3 uses: rancher-eio/read-vault-secrets@main
with: with:
secrets: | secrets: |
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ; secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
- name: Apply gcs auth - name: Apply gcs auth
# https://github.com/google-github-actions/auth # https://github.com/google-github-actions/auth
uses: google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed # v2 uses: 'google-github-actions/auth@v2'
with: with:
credentials_json: "${{ env.GOOGLE_AUTH }}" credentials_json: "${{ env.GOOGLE_AUTH }}"
- name: Upload tar - name: Upload tar
uses: google-github-actions/upload-cloud-storage@c0f6160ff80057923ff50e5e567695cea181ec23 # v2 uses: 'google-github-actions/upload-cloud-storage@v2'
with: with:
path: ${{steps.build-embedded.outputs.BUILD_EMBEDED_TGZ}} path: ${{steps.build-embedded.outputs.BUILD_EMBEDED_TGZ}}
destination: releases.rancher.com/harvester-ui/dashboard destination: releases.rancher.com/harvester-ui/dashboard
@@ -115,12 +114,12 @@ jobs:
name: Build & Upload Plugin name: Build & Upload Plugin
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 1 fetch-depth: 1
# Note - Cannot use the setup action here as it uses a different yarn install arg # Note - Cannot use the setup action here as it uses a different yarn install arg
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 - uses: actions/setup-node@v4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
@@ -134,19 +133,19 @@ jobs:
run: ./scripts/build-upload-gate run: ./scripts/build-upload-gate
- name: Get gcs auth - name: Get gcs auth
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3 uses: rancher-eio/read-vault-secrets@main
with: with:
secrets: | secrets: |
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ; secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
- name: Apply gcs auth - name: Apply gcs auth
# https://github.com/google-github-actions/auth # https://github.com/google-github-actions/auth
uses: google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed # v2 uses: 'google-github-actions/auth@v2'
with: with:
credentials_json: "${{ env.GOOGLE_AUTH }}" credentials_json: "${{ env.GOOGLE_AUTH }}"
- name: Upload plugin tar - name: Upload plugin tar
uses: google-github-actions/upload-cloud-storage@c0f6160ff80057923ff50e5e567695cea181ec23 # v2 uses: 'google-github-actions/upload-cloud-storage@v2'
with: with:
path: dist-pkg/${{steps.ci-build-pkg.outputs.PKG_TARBALL}} path: dist-pkg/${{steps.ci-build-pkg.outputs.PKG_TARBALL}}
destination: releases.rancher.com/harvester-ui/plugin destination: releases.rancher.com/harvester-ui/plugin
@@ -156,7 +155,7 @@ jobs:
process_gcloudignore: false process_gcloudignore: false
- name: Upload plugin directory - name: Upload plugin directory
uses: google-github-actions/upload-cloud-storage@c0f6160ff80057923ff50e5e567695cea181ec23 # v2 uses: 'google-github-actions/upload-cloud-storage@v2'
with: with:
path: dist-pkg/${{steps.ci-build-pkg.outputs.PKG_NAME}} path: dist-pkg/${{steps.ci-build-pkg.outputs.PKG_NAME}}
destination: releases.rancher.com/harvester-ui/plugin/${{steps.ci-build-pkg.outputs.PKG_NAME}} destination: releases.rancher.com/harvester-ui/plugin/${{steps.ci-build-pkg.outputs.PKG_NAME}}
+13 -7
View File
@@ -27,14 +27,14 @@ jobs:
build-status: ${{ job.status }} build-status: ${{ job.status }}
steps: steps:
- name: Read Secrets - name: Read Secrets
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3 uses: rancher-eio/read-vault-secrets@main
with: with:
secrets: | secrets: |
secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ;
secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD ; secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD ;
- name: Checkout repository (normal flow) - name: Checkout repository (normal flow)
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
- name: Enable Corepack - name: Enable Corepack
run: corepack enable run: corepack enable
@@ -45,20 +45,26 @@ jobs:
git config user.email 'github-actions[bot]@users.noreply.github.com' git config user.email 'github-actions[bot]@users.noreply.github.com'
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 uses: docker/login-action@v3
with: with:
username: ${{ env.DOCKER_USERNAME }} username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }} password: ${{ env.DOCKER_PASSWORD }}
- name: Setup Helm - name: Setup Helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3 uses: azure/setup-helm@v3
with: with:
version: v3.8.0 version: v3.8.0
- name: Setup Nodejs with yarn install - name: Setup Nodejs with yarn caching
uses: ./.github/actions/setup uses: actions/setup-node@v4
with:
node-version: '20'
cache: yarn
- name: Install dependencies
run: yarn
- name: Build and push UI image - name: Build and push UI image
run: | run: |
publish="yarn publish-pkgs -cp -r ${{ inputs.registry_target }} -o ${{ inputs.registry_user }}" publish="yarn publish-pkgs -cp -r ${{ inputs.registry_target }} -o ${{ inputs.registry_user }}"
$publish $publish
+12 -22
View File
@@ -4,7 +4,6 @@ on:
push: push:
branches: branches:
- 'release-harvester-v*' - 'release-harvester-v*'
- 'main'
jobs: jobs:
setup-target-branch: setup-target-branch:
@@ -13,22 +12,19 @@ jobs:
target_branch: ${{ steps.get-version.outputs.target_branch }} target_branch: ${{ steps.get-version.outputs.target_branch }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
- name: Determine target branch - name: Determine target branch
id: get-version id: get-version
run: | run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then if [[ "${{ github.ref_name }}" =~ ^release-harvester-v([0-9]+\.[0-9]+)$ ]]; then
TARGET_BRANCH="main-head"
elif [[ "${{ github.ref_name }}" =~ ^release-harvester-v([0-9]+\.[0-9]+)$ ]]; then
TARGET_BRANCH="v${BASH_REMATCH[1]}-head" TARGET_BRANCH="v${BASH_REMATCH[1]}-head"
echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_ENV
echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_OUTPUT
else else
echo "Error: invalid branch format." && exit 1 echo "Error: invalid branch format." && exit 1
fi fi
echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_ENV
echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_OUTPUT
- name: Ensure target branch exists - name: Ensure target branch exists
run: | run: |
git fetch --all git fetch --all
@@ -44,7 +40,7 @@ jobs:
version: ${{ steps.get_version.outputs.version }} version: ${{ steps.get_version.outputs.version }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
- name: Extract version from package.json - name: Extract version from package.json
id: get_version id: get_version
@@ -62,13 +58,7 @@ jobs:
contents: write contents: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
- name: Setup Node from .nvmrc
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Setup environment - name: Setup environment
run: | run: |
@@ -76,7 +66,7 @@ jobs:
yarn install --frozen-lockfile yarn install --frozen-lockfile
- name: Setup Helm - name: Setup Helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3 uses: azure/setup-helm@v3
with: with:
version: v3.8.0 version: v3.8.0
@@ -85,7 +75,7 @@ jobs:
yarn publish-pkgs -s ${{ github.repository }} -b ${{ needs.setup-target-branch.outputs.target_branch }} -t harvester-${{ needs.extract-version.outputs.version }} yarn publish-pkgs -s ${{ github.repository }} -b ${{ needs.setup-target-branch.outputs.target_branch }} -t harvester-${{ needs.extract-version.outputs.version }}
- name: Upload charts artifact - name: Upload charts artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 uses: actions/upload-artifact@v4
with: with:
name: charts name: charts
path: tmp path: tmp
@@ -100,7 +90,7 @@ jobs:
contents: write contents: write
steps: steps:
- name: Checkout release branch - name: Checkout release branch
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
with: with:
ref: '${{ github.ref_name }}' ref: '${{ github.ref_name }}'
@@ -111,7 +101,7 @@ jobs:
echo "LAST_COMMIT=${LAST_COMMIT}" >> $GITHUB_ENV echo "LAST_COMMIT=${LAST_COMMIT}" >> $GITHUB_ENV
- name: Checkout target branch - name: Checkout target branch
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
with: with:
ref: '${{ needs.setup-target-branch.outputs.target_branch }}' ref: '${{ needs.setup-target-branch.outputs.target_branch }}'
@@ -127,7 +117,7 @@ jobs:
git config user.email 'github-actions[bot]@users.noreply.github.com' git config user.email 'github-actions[bot]@users.noreply.github.com'
- name: Download build artifacts - name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 uses: actions/download-artifact@v4
with: with:
name: charts name: charts
@@ -138,7 +128,7 @@ jobs:
git push origin ${{ needs.setup-target-branch.outputs.target_branch }} git push origin ${{ needs.setup-target-branch.outputs.target_branch }}
- name: Run Helm chart releaser - name: Run Helm chart releaser
uses: helm/chart-releaser-action@cae68fefc6b5f367a0275617c9f83181ba54714f # v1.7.0 uses: helm/chart-releaser-action@v1.4.1
with: with:
charts_dir: ./charts charts_dir: ./charts
env: env:
@@ -17,36 +17,37 @@ jobs:
release_tag: ${{ steps.determine_tag.outputs.release_tag }} release_tag: ${{ steps.determine_tag.outputs.release_tag }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 uses: actions/checkout@v4
- name: Determine release tag - name: Determine release tag
id: determine_tag id: determine_tag
run: | run: |
if [[ "${{ github.event.release.tag_name }}" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then if [[ "${{ github.ref_name }}" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then
RELEASE_TAG="harvester-${BASH_REMATCH[1]}" RELEASE_TAG="harvester-${BASH_REMATCH[1]}"
echo "${RELEASE_TAG}" echo "${RELEASE_TAG}"
echo "release_tag=${RELEASE_TAG}" >> $GITHUB_OUTPUT echo "release_tag=${RELEASE_TAG}" >> $GITHUB_OUTPUT
else else
echo "Error: invalid tag format." && exit 1 echo "Error: invalid tag format." && exit 1
fi fi
check-version: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with:
- name: Check package version fetch-depth: 1
env:
TAG_VERSION: ${{ github.event.release.tag_name }}
run: ./scripts/check-version.sh $TAG_VERSION
- name: Run tests
uses: ./.github/actions/lint
build-extension-charts: build-extension-charts:
needs: needs:
- setup-release-tag - setup-release-tag
- check-version - lint
uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@9bf23dff6650116673346447bcf0b088e0edb27f # creators-pkg-v3.0.12 uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@master
permissions: permissions:
actions: write
contents: write contents: write
pull-requests: write deployments: write
pages: write
with: with:
target_branch: gh-pages target_branch: gh-pages
tagged_release: '${{ needs.setup-release-tag.outputs.release_tag }}' tagged_release: '${{ needs.setup-release-tag.outputs.release_tag }}'
@@ -1,7 +1,6 @@
name: Build Standalone on PR Merge name: Build Standalone on PR Merge
on: on:
workflow_dispatch: # manually trigger on Github Actions only support PR branch pushed to harvester/harvester-ui-extension
push: push:
branches: branches:
- main - main
@@ -30,35 +29,3 @@ jobs:
id-token: write id-token: write
with: with:
CI_BRANCH: ${{github.ref_name}} CI_BRANCH: ${{github.ref_name}}
comment-on-pr:
name: Comment build result on PR
# Only for manual runs so the existing push / pull_request flows are untouched.
if: github.event_name == 'workflow_dispatch'
needs:
- build
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Add build artifact comment to the PR opened from this branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: ${{ github.ref_name }}
run: |
set -euo pipefail
# Match scripts/version: sanitize the branch and map main -> latest.
if [ "$BRANCH" = "main" ]; then
DIR="latest"
else
DIR=$(printf '%s' "$BRANCH" | sed -E 's/[^a-zA-Z0-9.-]+/-/g')
fi
URL="https://releases.rancher.com/harvester-ui/dashboard/${DIR}/index.html"
PR=$(gh pr list --repo "$GITHUB_REPOSITORY" --state open --base main --head "$BRANCH" --json number --jq '.[0].number // empty')
if [ -z "$PR" ]; then
echo "No open PR found for branch $BRANCH, skipping comment."
exit 0
fi
BODY=$(printf '🚀 **UI Artifact Build Status:** `SUCCESS` ✅\n> ui-index: %s\n> ui-source: external' "$URL")
gh pr comment "$PR" --repo "$GITHUB_REPOSITORY" --body "$BODY"
@@ -5,20 +5,14 @@ on:
- v[1-9].* - v[1-9].*
jobs: jobs:
check-version: build-validation:
runs-on: ubuntu-latest name: Build Test
steps: uses: ./.github/workflows/run-lint.yaml
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Check package version
env:
TAG_VERSION: ${{github.ref_name}}
run: ./scripts/check-version.sh $TAG_VERSION
build: build:
name: Build and Upload Package name: Build and Upload Package
uses: ./.github/workflows/build-and-publish-standalone.yaml uses: ./.github/workflows/build-and-publish-standalone.yaml
needs: check-version needs:
- build-validation
permissions: permissions:
contents: read contents: read
packages: write packages: write
-34
View File
@@ -1,34 +0,0 @@
name: FOSSA Scanning
on:
push:
branches: ["main", "release-harvester-v*"]
workflow_dispatch:
permissions:
contents: read
id-token: write
jobs:
fossa-scanning:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
# The FOSSA token is shared between all repos in Harvester's GH org. It can
# be used directly and there is no need to request specific access to EIO.
- name: Read FOSSA token
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3
with:
secrets: |
secret/data/github/org/harvester/fossa/credentials token | FOSSA_API_KEY_PUSH_ONLY
- name: FOSSA scan
uses: fossas/fossa-action@ff70fe9fe17cbd2040648f1c45e8ec4e4884dcf3 # v1.9.0
with:
api-key: ${{ env.FOSSA_API_KEY_PUSH_ONLY }}
# Only runs the scan and do not provide/returns any results back to the
# pipeline.
run-tests: false
+3 -53
View File
@@ -1,13 +1,12 @@
name: Tests name: Tests
on: on:
workflow_call: # This tells GH that the workflow is reusable workflow_call: # This tells GH that the workflow is reusable
push: push:
branches: branches:
- main - main
- 'release-*' - 'release-*'
pull_request: pull_request:
types: [opened, reopened, edited, synchronize]
branches: branches:
- main - main
- 'release-*' - 'release-*'
@@ -16,58 +15,9 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 # Need full history for commit-lint fetch-depth: 1
- name: Run tests - name: Run tests
uses: ./.github/actions/lint uses: ./.github/actions/lint
- name: Validate PR title lint
if: github.event_name == 'pull_request'
shell: bash
run: echo "${{ github.event.pull_request.title }}" | npx commitlint
- name: Validate commit messages
shell: bash
run: |
echo "GITHUB_EVENT_NAME=$GITHUB_EVENT_NAME"
echo "GITHUB_BASE_SHA=$GITHUB_BASE_SHA"
echo "GITHUB_HEAD_SHA=$GITHUB_HEAD_SHA"
echo "GITHUB_BEFORE=$GITHUB_BEFORE"
echo "GITHUB_AFTER=$GITHUB_AFTER"
if [ "$GITHUB_EVENT_NAME" = "pull_request" ] && [ -n "$GITHUB_BASE_SHA" ] && [ -n "$GITHUB_HEAD_SHA" ]; then
FROM="$GITHUB_BASE_SHA"
TO="$GITHUB_HEAD_SHA"
elif [ -n "$GITHUB_BEFORE" ] && [ -n "$GITHUB_AFTER" ]; then
if [ "$GITHUB_BEFORE" = "0000000000000000000000000000000000000000" ]; then
# first push to HEAD
FROM=""
TO="$GITHUB_AFTER"
else
FROM="$GITHUB_BEFORE"
TO="$GITHUB_AFTER"
fi
else
echo "No valid commit range found, skipping commitlint."
exit 0
fi
echo "FROM=$FROM"
echo "TO=$TO"
if [ -z "$FROM" ]; then
echo "Linting last commit $TO"
npx commitlint --last --verbose
else
echo "Linting commits from $FROM to $TO"
npx commitlint --from "$FROM" --to "$TO" --verbose
fi
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_BASE_SHA: ${{ github.event.pull_request.base.sha }}
GITHUB_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
GITHUB_BEFORE: ${{ github.event.before }}
GITHUB_AFTER: ${{ github.event.after }}
-1
View File
@@ -1 +0,0 @@
npx --no -- commitlint --edit $1
-1
View File
@@ -1 +0,0 @@
yarn lint
+1 -1
View File
@@ -1 +1 @@
24 20
-261
View File
@@ -1,261 +0,0 @@
> This `./AGENTS.md` file is generated by running `yarn agents:generate`. `CLAUDE.md` and `GEMINI.md` are symlinks to this file so Claude Code, GitHub Copilot and Gemini all read the same content.
# Project Overview
The Harvester UI Extension is a Rancher extension that provides the user interface for Harvester within the Rancher Dashboard.
```
Note: This extension is available starting from Rancher 2.10.0. Ensure your Rancher version is 2.10.0 or later to access Harvester integration.
```
# Personas
## Software Developer
You are an expert Senior Software Engineer specializing in Vue.js and TypeScript. You have deep knowledge of Kubernetes and the Rancher ecosystem.
- **Focus**: Writing clean, maintainable, and performant code.
- **Priorities**: Adhering to the project's code style, ensuring type safety, and following best practices for component design.
# Agents
## Boundaries
- ✅ **Always:**
- Write to `.github`, `docs/`, `pkg/harvester`, `scripts/`.
- Make commits in a new branch (for a PR).
- Run `yarn lint:fix` before commits.
- Use conventional commit format:
```
<type>: <description>
```
- Follow existing naming conventions (PascalCase for components, camelCase for functions).
- After changing a Vue, JS, or TS file, make sure it's automatically formatted with ESLint.
- After updating files in `docs/agents.md/`, run `yarn agents:generate` to update root `AGENTS.md`.
- ⚠️ **Ask first:**
- Adding dependencies
- Upgrading dependencies
- 🚫 **Never:**
- Commit or log secrets, `.env`, `kubeconfig` or any API keys.
- Edit `node_modules/`.
- Commit directly to `main` (use PRs).
- Skip git hooks with `--no-verify` flag.
## Tools
### Prerequisites
- **Node.js**: `>= 24.0.0` (see `.nvmrc` for the pinned version: `24`)
- **Package manager**: `yarn` (v1 classic)
### Common Commands
| Command | Description |
|---------|-------------|
| `yarn install --frozen-lockfile` | Install dependencies (CI-safe, no lockfile changes) |
| `RANCHER_ENV=harvester API=https://<harvester-ip> yarn dev` | Start development server at `https://127.0.0.1:8005` |
| `yarn build-pkg harvester` | Build the Harvester extension package |
| `yarn serve-pkgs` | Serve the locally built extension for testing |
| `yarn lint` | Run ESLint (zero warnings allowed) |
| `yarn lint:fix` | Run ESLint with auto-fix |
| `yarn clean` | Clean build artifacts |
| `yarn agents:generate` | Regenerate `AGENTS.md` from `docs/agents.md/` sources |
### Development
- **Start dev server**:
```bash
RANCHER_ENV=harvester API=https://your-harvester-ip yarn dev
```
- `API` should point to a running Harvester cluster (e.g., `https://x.x.x.x`).
- The dashboard will be available at `https://127.0.0.1:8005`.
### Building
- **Build extension package**:
```bash
yarn build-pkg harvester
```
- **Serve locally built extension** (for integration testing with a Rancher instance):
```bash
yarn serve-pkgs
```
### Linting
- **Check** (must pass with zero warnings):
```bash
yarn lint
```
- **Auto-fix**:
```bash
yarn lint:fix
```
- ESLint covers `.js`, `.ts`, and `.vue` files.
- Always run `yarn lint:fix` before committing.
### Commit Conventions
- Commits are validated by [commitlint](https://commitlint.js.org/) via a Husky `commit-msg` hook.
- Follow [Conventional Commits](https://www.conventionalcommits.org/) format (configured in `commitlint.config.js`).
### Agent Documentation
- Source files live in `docs/agents.md/` (agents, contributors, personas subdirectories).
- After editing any source file, regenerate the root `AGENTS.md`:
```bash
yarn agents:generate
```
# Contributors Guide
## Getting Started
Please see the [Harvester UI Extension README](https://github.com/harvester/harvester-ui-extension).
To get started, follow the `Development Setup` section.
## Project Information
- **Tech Stack:**
- `Vue.js`: Framework
- `Linting`: ESLint
- `CSS`: SCSS should be used
- `TypeScript`: Primary language for logic.
- **Code Style and Standards:**
- `Language`: TypeScript is preferred for new code.
- `Vue.js`:
- Composition API components are preferred over Options API.
- Large pages with lots of code and styles should be avoided by breaking the page up into smaller Vue components.
- Order the Single File Component blocks as `<script>`, then `<template>`, then `<style>`.
- The `<style>` tag should include `lang="scss" scoped`.
- `Linting`: Follow the ESLint configuration in the root.
- **File Structure:**
- `.github/`: CI/CD workflows and Renovate config.
- `docs/`: Documentation source for `AGENTS.md` generation.
- `scripts/`: Bash scripts for build, CI and doc generation.
- `pkg/harvester/`: Main extension source. Files are named after K8s resource types (e.g., `kubevirt.io.virtualmachine`, `harvesterhci.io.volume`).
- `index.ts`: Plugin entry point — registers the product and auto-imports models/detail/edit views.
- `types.ts`: `HCI` constant mapping 60+ K8s resource types to string identifiers.
- `components/`: Reusable Vue components (VNC/serial console, settings panels, upgrade banners, filters).
- `config/`: Constants — settings keys, table column definitions, feature flags, type mappings, doc links.
- `detail/`: Read-only detail views per resource type. Complex resources use subdirectories with tabs.
- `dialog/`: Modal dialogs for operations (VM clone/migrate/restart, backup/restore, device passthrough, etc.).
- `edit/`: Create/edit forms. Complex resources (e.g., VM) split into subcomponents (CpuMemory, Network, Volume, CloudConfig, etc.).
- `formatters/`: Table cell formatters — state badges, usage bars, resource references.
- `l10n/`: Localization (`en-us.yaml`).
- `list/`: List (table) views per resource type, mirroring `detail/` and `edit/` naming.
- `mixins/`: Shared Vue mixins — VM helpers (`harvester-vm/`) and disk helpers (`harvester-disk.js`).
- `models/`: Model classes extending `SteveModel` with computed properties and actions. Base class: `harvester.js`.
- `pages/`: Route-level pages — dashboard, support, console, members, brand, alertmanager.
- `promptRemove/`: Custom delete-confirmation dialogs (VM, backup).
- `routing/`: Vue Router config — all product routes (CRUD, console, support, upgrade, etc.).
- `store/`: Vuex modules — `harvester-common.js` for shared state; `harvester-store/` for VM/resource creation actions with Steve integration.
- `styles/`: Global SCSS files.
- `utils/`: Helpers — VM volume templates, CPU/memory calc, cron parsing, regex validators, feature flags.
- `validators/`: Form validation functions per resource type, pushing i18n error messages.
## Harvester UI Extension Development Guide
### Backward Compatibility
The Harvester UI Extension supports earlier cluster versions (e.g., UI Ext v1.8.0 works with clusters v1.7.0 and v1.6.0). It uses Feature Flags defined in `pkg/harvester/config/` to ensure the UI matches the cluster's specific version.
### Implementation Steps for New Features
To add a feature in a new release, follow these steps:
1. **Register**: Add a unique `[Feature Name]` to the corresponding release array in the configuration.
2. **Check**: Use the following getter to verify if the feature is enabled for the current version:
```js
computed: {
newFeatureEnabled() {
return this.$store.getters['harvester-common/getFeatureEnabled']('[Feature Name]');
},
},
```
3. **Render**: Use the result of the check to conditionally render the UI components.
## E2E Tests (Cypress)
See https://github.com/harvester/harvester-ui-tests
## Node Dependencies
Dependencies are managed via `package.json` and `yarn`
- To install dependencies use `yarn install`. This will fail if dependencies and versions listed in `package.json` are out of step with the `yarn.lock` file
- To add a dependency use `yarn run add:no-lock ...` instead of `yarn add`
- To upgrade a dependency use `yarn run upgrade:no-lock ...` instead of `yarn upgrade`
Renovate automatically updates dependencies and opens upgrade PRs after 10:00 AM on Sundays (`Asia/Taipei`).
For the Renovate config, see `.github/renovate.json`.
## Milestone guidance
- All issues must first be resolved in the `main` branch
- If backports are needed they can be made via the backport bot
- pull requests
- comment `@Mergifyio backport <target branch>` e.g. `@Mergifyio backport release-harvester-v1.8`
- All backported pull requests must link to a backported issue
## Creating a branch
### To resolve an issue
- Checkout the branch matching the milestone of the issue `git checkout ${targetMilestoneBranch}`. Replace `${targetMilestoneBranch}` with the target milestone of the issue. For example
- `main` for the latest unreleased minor version
- `release-harvester-v.X` for release minor versions
- `release-harvester-v1.6`
- `release-harvester-v1.7`
- `release-harvester-v1.8`
- Ensure you have the latest of that branch `git pull --rebase`
- Checkout the branch to commit the changes to `git checkout issue-${issueNumber}`. Replace `${issueNumber}` with the issue number.
## Creating a commit
- This project uses commit-lint with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to ensure consistent and meaningful commit messages.
### Commit Message Format
All commit messages must follow the conventional commit format:
```
<type>: <description>
[optional body]
[optional footer(s)]
```
### Supported Types
- feat: New features
- fix: Bug fixes
- docs: Documentation changes
- style: Code style changes (formatting, missing semicolons, etc.)
- refactor: Code refactoring
- perf: Performance improvements
- test: Adding or updating tests
- build: Build system or external dependencies
- ci: CI/CD changes
- chore: Other changes that don't modify src or test files
- revert: Reverts a previous commit
- wip: Work in progress
- deps: Dependency updates
- security: Security fixes
## Creating a Pull Request
- Pull requests must come from forks
- Description should always have commit supported type prefix. E.g `fix: XXX`, `feat: OOO`
- A Pull Request will only be merged once
- ALL CI gates have passed
- At least one harvester/harvester-ui-extension code owners reviews and approves the PR
-1
View File
@@ -1 +0,0 @@
./AGENTS.md
-2
View File
@@ -1,2 +0,0 @@
@a110605
@houhoucoop
-1
View File
@@ -1 +0,0 @@
./AGENTS.md
+40 -153
View File
@@ -1,189 +1,76 @@
# harvester-ui-extension # harvester-ui-extension
The Harvester UI Extension is a Rancher extension that provides the user interface for [Harvester](https://harvesterhci.io) within the [Rancher Dashboard](https://github.com/rancher/dashboard). Rancher Extension used in [rancher/dashboard](https://github.com/rancher/dashboard) for [Harvester](https://harvesterhci.io) Dashboard UI.
> **Note:**
> This extension is available starting from **Rancher 2.10.0**. Ensure your Rancher version is **2.10.0 or later** to access Harvester integration.
## Table of Contents
- [Installation](#installation)
- [Development Setup](#development-setup)
- [Commit Message Guidelines](#commit-message-guidelines)
- [Branch Structure](#branch-structure)
- [Testing Guidelines](#testing-guidelines)
- [Release](#release)
- [Contributing](#contributing)
- [License](#license)
`
From Rancher 2.10.0, Harvester integration is provided by this new Harvester UI Extension.
`
## Installation ## Installation
For Harvester UI extension installation instructions, please refer to the page **Rancher Integration** -> **Harvester UI Extension** in [official Harvester documentation](https://docs.harvesterhci.io). To install the Harvester UI Extension in Rancher 2.10.0 and newer:
- Go to 'Extensions' in the Rancher UI (click on the jigsaw icon in the side bar)
- From the three-dots menu in the upper right of the page, open the menu and select 'Manage Repositories'
- From the Repositories page, click 'Create'
- For name, enter 'harvester-ui-extension'
- For Target, choose 'Git repository'
- For Git Repo URL, enter `https://github.com/harvester/harvester-ui-extension`
- For Git Branch, enter `gh-pages`
- Click 'Create`
- From the Repositories list, wait until the new Repository added updates to the 'Active' state
- Go back to 'Extensions'
- Click on the 'Available' tab if not already selected
- Click on 'Install' for the Harvester UI Extension
## Development Setup ## Running for Development
This is what you probably want to get started.
### Prerequisite
Nodejs version >= 20
Ensure **Node.js v24 or later** is installed for development and debugging.
### Standalone Mode ### Standalone Mode
Run the extension standalone with hot reload at `https://localhost:8005`. For development, serve with hot reload at https://localhost:8005
```bash ```bash
# Install dependencies # Install dependencies
yarn install yarn install
# Start the development server # Use RANCHER_ENV to specify the endpoint for your Harvester API
RANCHER_ENV=harvester API=https://your-harvester-ip yarn dev RANCHER_ENV=harvester API=https://your-harvester-ip yarn dev
# Example with specific server version # Use VUE_APP_SERVER_VERSION to specify the Harvester server version
RANCHER_ENV=harvester VUE_APP_SERVER_VERSION=v1.5.0 API=https://192.168.1.123 yarn dev # in case your are running a dev build of Harvester
``` RANCHER_ENV=harvester VUE_APP_SERVER_VERSION=your-harvester-server-version API=https://your-harvester-ip yarn dev
You may also define environment variables in a `.env` file: # or put your env variables into a .env file
```env # Example
RANCHER_ENV=harvester RANCHER_ENV=harvester VUE_APP_SERVER_VERSION=v1.4.0 API=https://192.168.1.123 yarn dev
VUE_APP_SERVER_VERSION=v1.5.0
API=https://192.168.1.123
``` ```
### Rancher Integration Mode ### Rancher Integration Mode
To run as a Rancher extension, follow the [Rancher UI Extension Guide](https://extensions.rancher.io/extensions/next/extensions-getting-started#running-the-app). In this mode, you need to have Rancher and run Harvester UI Extension as Rancher extension, see more detail in [Rancher UI extension](https://extensions.rancher.io/extensions/next/extensions-getting-started#running-the-app).
```bash ```bash
API=https://your-rancher-ip yarn dev API=https://your-rancher-ip yarn dev
# Example
API=https://192.168.1.123 yarn dev
``` ```
## Commit Message Guidelines
This project uses [commit-lint](https://commitlint.js.org/) with [Conventional Commits](https://www.conventionalcommits.org/) to ensure consistent and meaningful commit messages.
### Commit Message Format
All commit messages must follow the conventional commit format:
```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
### Supported Types
- **feat**: New features
- **fix**: Bug fixes
- **docs**: Documentation changes
- **style**: Code style changes (formatting, missing semicolons, etc.)
- **refactor**: Code refactoring
- **perf**: Performance improvements
- **test**: Adding or updating tests
- **build**: Build system or external dependencies
- **ci**: CI/CD changes
- **chore**: Other changes that don't modify src or test files
- **revert**: Reverts a previous commit
- **wip**: Work in progress
- **deps**: Dependency updates
- **security**: Security fixes
### Examples
```bash
# Feature
git commit -m "feat: add new virtual machine creation wizard"
# Bug fix
git commit -m "fix: resolve memory leak in VM console"
# Documentation
git commit -m "docs: update installation instructions"
# Breaking change
git commit -m "feat!: change API endpoint structure
BREAKING CHANGE: The /api/v1/vms endpoint has been replaced with /api/v2/vms"
```
### Git Hooks
The project uses [Husky](https://typicode.github.io/husky/) to automatically validate commit messages and run linting before commits:
- **pre-commit**: Runs ESLint to ensure code quality
- **commit-msg**: Validates commit message format using commit-lint
These hooks are automatically installed when you run `yarn install`.
### Manual Validation
You can manually validate commit messages:
```bash
# Validate the last commit
yarn commitlint
# Validate a specific commit
npx commitlint --from <commit-hash>
# Validate a range of commits
npx commitlint --from <start-hash> --to <end-hash>
```
## Branch Structure
- **`main`** – Main development branch
- **`release-harvester-vX.Y`** – Stable release branches per version series
- **`vX.Y-head`** – Testing branches for ongoing changes to extension builds in each release series
> **Note:**
> The `vX.Y-head` branches are auto-generated and kept in sync with release branches. Use these for testing the latest changes in each version series.
## Testing Guidelines
### UI Extension Testing
To validate changes in a release series, switch to the appropriate `vX.Y-head` branch. For main branch testing, use `main-head`.
- Examples:
- Test `1.0.x` series → `v1.0-head`
- Test `1.5.x` series → `v1.5-head`
**Steps:**
1. Navigate to **Rancher UI** → **Local** → **App** → **Repositories**
2. Refresh the Harvester repository using the target `vX.Y-head` branch
3. Go to the **Extensions** page and install the desired version
### Standalone Mode Testing
To test the standalone UI, configure Harvester to load the UI from an external source.
- Examples of `ui-index`:
- Main branch → `https://releases.rancher.com/harvester-ui/dashboard/latest/index.html`
- Release series `1.5.x` → `https://releases.rancher.com/harvester-ui/dashboard/release-harvester-v1.5/index.html`
**Steps:**
1. Go to **Harvester UI** → **Advanced** → **Settings** → **UI**
2. Set **ui-source** to `External`
3. Set **ui-index** to the desired URL
## Release
The Harvester UI Extension follows the [Harvester](https://github.com/harvester/harvester) release cycle. After RC1 is cut for a new Harvester version, we usually create and work from the corresponding release branch (for example, `release-harvester-v1.8`). The remaining RC builds and the final official release are published from that branch.
After Harvester releases a new version, update the Harvester entry in rancher/ui-plugin-charts [manifest.json](https://github.com/rancher/ui-plugin-charts/blob/aafd215debbc6cb3100e7ba4b0a542c932397acd/manifest.json#L133-L151). This ensures air-gapped users can pull the new Harvester UI Extension image.
## Contributing ## Contributing
If you want to contribute, start by reading this document, then visit our [Getting Started guide](https://extensions.rancher.io/extensions/next/extensions-getting-started) to learn how to develop and submit changes. For developers, after reading through the introduction on this page, head over to our [Getting Started](https://extensions.rancher.io/extensions/next/extensions-getting-started) guide to learn more.
## License License
=======
Copyright (c) 2014-2026 [SUSE, LLC.](https://www.suse.com/) Copyright (c) 2014-2023 [Rancher Labs, Inc.](http://rancher.com)
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
Binary file not shown.
-26
View File
@@ -1,26 +0,0 @@
apiVersion: v1
entries:
harvester:
- annotations:
catalog.cattle.io/certified: rancher
catalog.cattle.io/display-name: Harvester
catalog.cattle.io/kube-version: '>= 1.16.0-0'
catalog.cattle.io/namespace: cattle-ui-plugin-system
catalog.cattle.io/os: linux
catalog.cattle.io/permits-os: linux, windows
catalog.cattle.io/rancher-version: '>= 2.15.0-0'
catalog.cattle.io/scope: management
catalog.cattle.io/ui-component: plugins
catalog.cattle.io/ui-extensions-version: '>= 3.0.0 < 4.0.0'
apiVersion: v2
appVersion: 1.10.0-dev
created: "2026-08-17T09:53:47.7476+08:00"
description: Rancher UI Extension for Harvester
digest: 8800a65761d4b9dbdadb9f9050b9053738021c43d02cf7249e6922e230fdd95b
icon: https://raw.githubusercontent.com/harvester/harvester-ui-extension/main/pkg/harvester/icon.svg
name: harvester
type: application
urls:
- assets/harvester/harvester-1.10.0-dev.tgz
version: 1.10.0-dev
generated: "2026-08-17T09:53:47.74717+08:00"
-19
View File
@@ -1,19 +0,0 @@
annotations:
catalog.cattle.io/certified: rancher
catalog.cattle.io/namespace: cattle-ui-plugin-system
catalog.cattle.io/os: linux
catalog.cattle.io/permits-os: linux, windows
catalog.cattle.io/scope: management
catalog.cattle.io/ui-component: plugins
catalog.cattle.io/display-name: Harvester
catalog.cattle.io/kube-version: '>= 1.16.0-0'
catalog.cattle.io/rancher-version: '>= 2.15.0-0'
catalog.cattle.io/ui-extensions-version: '>= 3.0.0 < 4.0.0'
apiVersion: v2
appVersion: 1.10.0-dev
description: Rancher UI Extension for Harvester
name: harvester
type: application
version: 1.10.0-dev
icon: >-
https://raw.githubusercontent.com/harvester/harvester-ui-extension/main/pkg/harvester/icon.svg
-177
View File
@@ -1,177 +0,0 @@
# harvester-ui-extension
The Harvester UI Extension is a Rancher extension that provides the user interface for [Harvester](https://harvesterhci.io) within the [Rancher Dashboard](https://github.com/rancher/dashboard).
> **Note:**
> This extension is available starting from **Rancher 2.10.0**. Ensure your Rancher version is **2.10.0 or later** to access Harvester integration.
## Installation
For Harvester UI extension installation instructions, please refer to the page **Rancher Integration** -> **Harvester UI Extension** in [official Harvester documentation](https://docs.harvesterhci.io).
## Development Setup
Ensure **Node.js v20 or later** is installed for development and debugging.
### Standalone Mode
Run the extension standalone with hot reload at `https://localhost:8005`.
```bash
# Install dependencies
yarn install
# Start the development server
RANCHER_ENV=harvester API=https://your-harvester-ip yarn dev
# Example with specific server version
RANCHER_ENV=harvester VUE_APP_SERVER_VERSION=v1.5.0 API=https://192.168.1.123 yarn dev
```
You may also define environment variables in a `.env` file:
```env
RANCHER_ENV=harvester
VUE_APP_SERVER_VERSION=v1.5.0
API=https://192.168.1.123
```
### Rancher Integration Mode
To run as a Rancher extension, follow the [Rancher UI Extension Guide](https://extensions.rancher.io/extensions/next/extensions-getting-started#running-the-app).
```bash
API=https://your-rancher-ip yarn dev
```
## Commit Message Guidelines
This project uses [commit-lint](https://commitlint.js.org/) with [Conventional Commits](https://www.conventionalcommits.org/) to ensure consistent and meaningful commit messages.
### Commit Message Format
All commit messages must follow the conventional commit format:
```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
### Supported Types
- **feat**: New features
- **fix**: Bug fixes
- **docs**: Documentation changes
- **style**: Code style changes (formatting, missing semicolons, etc.)
- **refactor**: Code refactoring
- **perf**: Performance improvements
- **test**: Adding or updating tests
- **build**: Build system or external dependencies
- **ci**: CI/CD changes
- **chore**: Other changes that don't modify src or test files
- **revert**: Reverts a previous commit
- **wip**: Work in progress
- **deps**: Dependency updates
- **security**: Security fixes
### Examples
```bash
# Feature
git commit -m "feat: add new virtual machine creation wizard"
# Bug fix
git commit -m "fix: resolve memory leak in VM console"
# Documentation
git commit -m "docs: update installation instructions"
# Breaking change
git commit -m "feat!: change API endpoint structure
BREAKING CHANGE: The /api/v1/vms endpoint has been replaced with /api/v2/vms"
```
### Git Hooks
The project uses [Husky](https://typicode.github.io/husky/) to automatically validate commit messages and run linting before commits:
- **pre-commit**: Runs ESLint to ensure code quality
- **commit-msg**: Validates commit message format using commit-lint
These hooks are automatically installed when you run `yarn install`.
### Manual Validation
You can manually validate commit messages:
```bash
# Validate the last commit
yarn commitlint
# Validate a specific commit
npx commitlint --from <commit-hash>
# Validate a range of commits
npx commitlint --from <start-hash> --to <end-hash>
```
## Branch Structure
- **`main`** – Main development branch
- **`release-harvester-vX.Y`** – Stable release branches per version series
- **`vX.Y-head`** – Testing branches for ongoing changes to extension builds in each release series
> **Note:**
> The `vX.Y-head` branches are auto-generated and kept in sync with release branches. Use these for testing the latest changes in each version series.
## Testing Guidelines
### UI Extension Testing
To validate changes in a release series, switch to the appropriate `vX.Y-head` branch. For main branch testing, use `main-head`.
- Examples:
- Test `1.0.x` series → `v1.0-head`
- Test `1.5.x` series → `v1.5-head`
**Steps:**
1. Navigate to **Rancher UI** → **Local** → **App** → **Repositories**
2. Refresh the Harvester repository using the target `vX.Y-head` branch
3. Go to the **Extensions** page and install the desired version
### Standalone Mode Testing
To test the standalone UI, configure Harvester to load the UI from an external source.
- Examples of `ui-index`:
- Main branch → `https://releases.rancher.com/harvester-ui/dashboard/latest/index.html`
- Release series `1.5.x` → `https://releases.rancher.com/harvester-ui/dashboard/release-harvester-v1.5/index.html`
**Steps:**
1. Go to **Harvester UI** → **Advanced** → **Settings** → **UI**
2. Set **ui-source** to `External`
3. Set **ui-index** to the desired URL
## Contributing
If you want to contribute, start by reading this document, then visit our [Getting Started guide](https://extensions.rancher.io/extensions/next/extensions-getting-started) to learn how to develop and submit changes.
## License
Copyright (c) 2014-2026 [SUSE, LLC.](https://www.suse.com/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -1,63 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "extension-server.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "extension-server.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "extension-server.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "extension-server.labels" -}}
helm.sh/chart: {{ include "extension-server.chart" . }}
{{ include "extension-server.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | replace "+" "_" | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "extension-server.selectorLabels" -}}
app.kubernetes.io/name: {{ include "extension-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Pkg annotations
*/}}
{{- define "extension-server.pluginMetadata" -}}
{{- with .Values.plugin.metadata }}
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end }}
@@ -1,15 +0,0 @@
apiVersion: catalog.cattle.io/v1
kind: UIPlugin
metadata:
name: {{ include "extension-server.fullname" . }}
namespace: {{ .Release.Namespace }}
labels: {{ include "extension-server.labels" . | nindent 4 }}
spec:
plugin:
name: {{ include "extension-server.fullname" . }}
version: {{ (semver (default .Chart.AppVersion .Values.plugin.versionOverride)).Original }}
endpoint: {{ .Values.plugin.endpoint | quote }}
compressedEndpoint: {{ .Values.plugin.compressedEndpoint | quote }}
noCache: {{ .Values.plugin.noCache }}
noAuth: {{ .Values.plugin.noAuth }}
metadata: {{ include "extension-server.pluginMetadata" . | indent 6 }}
-16
View File
@@ -1,16 +0,0 @@
nameOverride: ""
fullnameOverride: ""
plugin:
enabled: true
versionOverride: ""
endpoint: >-
https://raw.githubusercontent.com/a110605/harvester-ui-extension/fix_forklift_ns_test/extensions/harvester/1.10.0-dev
compressedEndpoint: >-
https://raw.githubusercontent.com/a110605/harvester-ui-extension/fix_forklift_ns_test/extensions/harvester/1.10.0-dev.tgz
noCache: false
noAuth: false
metadata:
catalog.cattle.io/display-name: Harvester
catalog.cattle.io/kube-version: ">= 1.16.0-0"
catalog.cattle.io/rancher-version: ">= 2.15.0-0"
catalog.cattle.io/ui-extensions-version: ">= 3.0.0 < 4.0.0"
-48
View File
@@ -1,48 +0,0 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// Enforce conventional commit format
'type-enum': [
2,
'always',
[
'feat', // New features
'fix', // Bug fixes
'docs', // Documentation changes
'style', // Code style changes (formatting, missing semicolons, etc.)
'refactor', // Code refactoring
'perf', // Performance improvements
'test', // Adding or updating tests
'build', // Build system or external dependencies
'ci', // CI/CD changes
'chore', // Other changes that don't modify src or test files
'revert', // Reverts a previous commit
'wip', // Work in progress
'deps', // Dependency updates
'security', // Security fixes
]
],
// Allows the scope to be empty. [0] means the rule is disabled.
'scope-empty': [0, 'always'],
// Allows any string for the scope.
'scope-case': [2, 'always', 'kebab-case'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'subject-case': [0, 'never'],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'subject-max-length': [0, 'never'],
'header-max-length': [0, 'always', 100],
'body-leading-blank': [2, 'always'],
'body-max-line-length': [0, 'always', 100],
'footer-leading-blank': [2, 'always'],
'footer-max-line-length': [0, 'always', 100],
},
// Ignore merge commits and revert commits
ignores: [
(commit) => commit.includes('Merge'),
(commit) => commit.includes('Revert'),
(commit) => commit.includes('merge'),
(commit) => commit.includes('revert'),
],
};
-63
View File
@@ -1,63 +0,0 @@
# Agents.md
This folder contains files used to construct a single root `AGENTS.md`
We do this because
- The single commonality between almost all AI tools is that they look for a root `AGENTS.md`
- Having the information in a single place for all AI tools is better than duplicating and maintaining the information in multiple files for each AI tool
## Process
1. Add files to or update files in `./docs/agents.md/agents`, `./docs/agents.md/personas`, `./docs/agents.md/contributors`.
2. Each file must
- Start markdown headers at the `##` level
- End in a new line
- Order contents in AGENTS.md by giving an optional number prefix
3. Run `yarn agents:generate`.
- Take the contents of `./docs/agents.md/template_agents.md`
- Insert the contents of the agents, personas and contributors files
- Output to `./AGENTS.md`
4. Commit all changes, including root `./AGENTS.md` and any files that link to it
## Guidance
### Examples
When referencing code or configuration it's good to include an example
## Future Tasks
- Add real world examples when referencing code
- Create a GH workflow to monitor `agents.md` folder files in a PR, if changed run generate script and add new AGENTS.md to PR
- Discuss
- Three multi AI tool related questions
- Questions
- how AI specific patterns, like co-pilot instructions, can be expressed in a way to be adopted by or reduce duplication with the root agents.md
- how AI tool specific metadata code can be included
- multiple agents vs personas approach works
- Proposal
- Generic information applicable to all AI tools is added to the root `agents.md`
- Agent, instruction or other AI specific files or patterns can be used in files specific to that AI tool. They must not contain duplicate information to the root `agents.md`
- The root `agents.md` continues to be AI tool agnostic
- How can folder specific agents be used
- Proposal
- `agents.md` are added to folders as long as most LLMs can make use of them and they do not duplicate information in the root `agents.md`
## Test Prompts
To validate LLMs are picking up information consider running the following prompts.
### Information
Can they provide correct information?
- `what's this project about?`
- `can you tell me the process for fixing a github issue in this repo?`
- `what makes a good software developer?`
- `what should never be done in this project?`
- `what are the folders in this project for?`
- `what are the env vars i could use when running e2e tests?`
### Actions
Can they use the information in their actions?
Pending
-21
View File
@@ -1,21 +0,0 @@
## Boundaries
- ✅ **Always:**
- Write to `.github`, `docs/`, `pkg/harvester`, `scripts/`.
- Make commits in a new branch (for a PR).
- Run `yarn lint:fix` before commits.
- Use conventional commit format:
```
<type>: <description>
```
- Follow existing naming conventions (PascalCase for components, camelCase for functions).
- After changing a Vue, JS, or TS file, make sure it's automatically formatted with ESLint.
- After updating files in `docs/agents.md/`, run `yarn agents:generate` to update root `AGENTS.md`.
- ⚠️ **Ask first:**
- Adding dependencies
- Upgrading dependencies
- 🚫 **Never:**
- Commit or log secrets, `.env`, `kubeconfig` or any API keys.
- Edit `node_modules/`.
- Commit directly to `main` (use PRs).
- Skip git hooks with `--no-verify` flag.
-65
View File
@@ -1,65 +0,0 @@
## Tools
### Prerequisites
- **Node.js**: `>= 24.0.0` (see `.nvmrc` for the pinned version: `24`)
- **Package manager**: `yarn` (v1 classic)
### Common Commands
| Command | Description |
|---------|-------------|
| `yarn install --frozen-lockfile` | Install dependencies (CI-safe, no lockfile changes) |
| `RANCHER_ENV=harvester API=https://<harvester-ip> yarn dev` | Start development server at `https://127.0.0.1:8005` |
| `yarn build-pkg harvester` | Build the Harvester extension package |
| `yarn serve-pkgs` | Serve the locally built extension for testing |
| `yarn lint` | Run ESLint (zero warnings allowed) |
| `yarn lint:fix` | Run ESLint with auto-fix |
| `yarn clean` | Clean build artifacts |
| `yarn agents:generate` | Regenerate `AGENTS.md` from `docs/agents.md/` sources |
### Development
- **Start dev server**:
```bash
RANCHER_ENV=harvester API=https://your-harvester-ip yarn dev
```
- `API` should point to a running Harvester cluster (e.g., `https://x.x.x.x`).
- The dashboard will be available at `https://127.0.0.1:8005`.
### Building
- **Build extension package**:
```bash
yarn build-pkg harvester
```
- **Serve locally built extension** (for integration testing with a Rancher instance):
```bash
yarn serve-pkgs
```
### Linting
- **Check** (must pass with zero warnings):
```bash
yarn lint
```
- **Auto-fix**:
```bash
yarn lint:fix
```
- ESLint covers `.js`, `.ts`, and `.vue` files.
- Always run `yarn lint:fix` before committing.
### Commit Conventions
- Commits are validated by [commitlint](https://commitlint.js.org/) via a Husky `commit-msg` hook.
- Follow [Conventional Commits](https://www.conventionalcommits.org/) format (configured in `commitlint.config.js`).
### Agent Documentation
- Source files live in `docs/agents.md/` (agents, contributors, personas subdirectories).
- After editing any source file, regenerate the root `AGENTS.md`:
```bash
yarn agents:generate
```
@@ -1,72 +0,0 @@
## Getting Started
Please see the [Harvester UI Extension README](https://github.com/harvester/harvester-ui-extension).
To get started, follow the `Development Setup` section.
## Project Information
- **Tech Stack:**
- `Vue.js`: Framework
- `Linting`: ESLint
- `CSS`: SCSS should be used
- `TypeScript`: Primary language for logic.
- **Code Style and Standards:**
- `Language`: TypeScript is preferred for new code.
- `Vue.js`:
- Composition API components are preferred over Options API.
- Large pages with lots of code and styles should be avoided by breaking the page up into smaller Vue components.
- Order the Single File Component blocks as `<script>`, then `<template>`, then `<style>`.
- The `<style>` tag should include `lang="scss" scoped`.
- `Linting`: Follow the ESLint configuration in the root.
- **File Structure:**
- `.github/`: CI/CD workflows and Renovate config.
- `docs/`: Documentation source for `AGENTS.md` generation.
- `scripts/`: Bash scripts for build, CI and doc generation.
- `pkg/harvester/`: Main extension source. Files are named after K8s resource types (e.g., `kubevirt.io.virtualmachine`, `harvesterhci.io.volume`).
- `index.ts`: Plugin entry point — registers the product and auto-imports models/detail/edit views.
- `types.ts`: `HCI` constant mapping 60+ K8s resource types to string identifiers.
- `components/`: Reusable Vue components (VNC/serial console, settings panels, upgrade banners, filters).
- `config/`: Constants — settings keys, table column definitions, feature flags, type mappings, doc links.
- `detail/`: Read-only detail views per resource type. Complex resources use subdirectories with tabs.
- `dialog/`: Modal dialogs for operations (VM clone/migrate/restart, backup/restore, device passthrough, etc.).
- `edit/`: Create/edit forms. Complex resources (e.g., VM) split into subcomponents (CpuMemory, Network, Volume, CloudConfig, etc.).
- `formatters/`: Table cell formatters — state badges, usage bars, resource references.
- `l10n/`: Localization (`en-us.yaml`).
- `list/`: List (table) views per resource type, mirroring `detail/` and `edit/` naming.
- `mixins/`: Shared Vue mixins — VM helpers (`harvester-vm/`) and disk helpers (`harvester-disk.js`).
- `models/`: Model classes extending `SteveModel` with computed properties and actions. Base class: `harvester.js`.
- `pages/`: Route-level pages — dashboard, support, console, members, brand, alertmanager.
- `promptRemove/`: Custom delete-confirmation dialogs (VM, backup).
- `routing/`: Vue Router config — all product routes (CRUD, console, support, upgrade, etc.).
- `store/`: Vuex modules — `harvester-common.js` for shared state; `harvester-store/` for VM/resource creation actions with Steve integration.
- `styles/`: Global SCSS files.
- `utils/`: Helpers — VM volume templates, CPU/memory calc, cron parsing, regex validators, feature flags.
- `validators/`: Form validation functions per resource type, pushing i18n error messages.
## Harvester UI Extension Development Guide
### Backward Compatibility
The Harvester UI Extension supports earlier cluster versions (e.g., UI Ext v1.8.0 works with clusters v1.7.0 and v1.6.0). It uses Feature Flags defined in `pkg/harvester/config/` to ensure the UI matches the cluster's specific version.
### Implementation Steps for New Features
To add a feature in a new release, follow these steps:
1. **Register**: Add a unique `[Feature Name]` to the corresponding release array in the configuration.
2. **Check**: Use the following getter to verify if the feature is enabled for the current version:
```js
computed: {
newFeatureEnabled() {
return this.$store.getters['harvester-common/getFeatureEnabled']('[Feature Name]');
},
},
```
3. **Render**: Use the result of the check to conditionally render the UI components.
@@ -1,3 +0,0 @@
## E2E Tests (Cypress)
See https://github.com/harvester/harvester-ui-tests
@@ -1,12 +0,0 @@
## Node Dependencies
Dependencies are managed via `package.json` and `yarn`
- To install dependencies use `yarn install`. This will fail if dependencies and versions listed in `package.json` are out of step with the `yarn.lock` file
- To add a dependency use `yarn run add:no-lock ...` instead of `yarn add`
- To upgrade a dependency use `yarn run upgrade:no-lock ...` instead of `yarn upgrade`
Renovate automatically updates dependencies and opens upgrade PRs after 10:00 AM on Sundays (`Asia/Taipei`).
For the Renovate config, see `.github/renovate.json`.
@@ -1,58 +0,0 @@
## Milestone guidance
- All issues must first be resolved in the `main` branch
- If backports are needed they can be made via the backport bot
- pull requests
- comment `@Mergifyio backport <target branch>` e.g. `@Mergifyio backport release-harvester-v1.8`
- All backported pull requests must link to a backported issue
## Creating a branch
### To resolve an issue
- Checkout the branch matching the milestone of the issue `git checkout ${targetMilestoneBranch}`. Replace `${targetMilestoneBranch}` with the target milestone of the issue. For example
- `main` for the latest unreleased minor version
- `release-harvester-v.X` for release minor versions
- `release-harvester-v1.6`
- `release-harvester-v1.7`
- `release-harvester-v1.8`
- Ensure you have the latest of that branch `git pull --rebase`
- Checkout the branch to commit the changes to `git checkout issue-${issueNumber}`. Replace `${issueNumber}` with the issue number.
## Creating a commit
- This project uses commit-lint with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to ensure consistent and meaningful commit messages.
### Commit Message Format
All commit messages must follow the conventional commit format:
```
<type>: <description>
[optional body]
[optional footer(s)]
```
### Supported Types
- feat: New features
- fix: Bug fixes
- docs: Documentation changes
- style: Code style changes (formatting, missing semicolons, etc.)
- refactor: Code refactoring
- perf: Performance improvements
- test: Adding or updating tests
- build: Build system or external dependencies
- ci: CI/CD changes
- chore: Other changes that don't modify src or test files
- revert: Reverts a previous commit
- wip: Work in progress
- deps: Dependency updates
- security: Security fixes
## Creating a Pull Request
- Pull requests must come from forks
- Description should always have commit supported type prefix. E.g `fix: XXX`, `feat: OOO`
- A Pull Request will only be merged once
- ALL CI gates have passed
- At least one harvester/harvester-ui-extension code owners reviews and approves the PR
@@ -1,5 +0,0 @@
## Software Developer
You are an expert Senior Software Engineer specializing in Vue.js and TypeScript. You have deep knowledge of Kubernetes and the Rancher ecosystem.
- **Focus**: Writing clean, maintainable, and performant code.
- **Priorities**: Adhering to the project's code style, ensuring type safety, and following best practices for component design.
-22
View File
@@ -1,22 +0,0 @@
> This `./AGENTS.md` file is generated by running `yarn agents:generate`. `CLAUDE.md` and `GEMINI.md` are symlinks to this file so Claude Code, GitHub Copilot and Gemini all read the same content.
# Project Overview
The Harvester UI Extension is a Rancher extension that provides the user interface for Harvester within the Rancher Dashboard.
```
Note: This extension is available starting from Rancher 2.10.0. Ensure your Rancher version is 2.10.0 or later to access Harvester integration.
```
# Personas
`<personas>`
# Agents
`<agents>`
# Contributors Guide
`<contributors>`
Binary file not shown.
-76
View File
@@ -1,76 +0,0 @@
plugin/harvester-1.10.0-dev.umd.min.106.js
plugin/harvester-1.10.0-dev.umd.min.106.js.map
plugin/harvester-1.10.0-dev.umd.min.238.js
plugin/harvester-1.10.0-dev.umd.min.238.js.map
plugin/harvester-1.10.0-dev.umd.min.277.js
plugin/harvester-1.10.0-dev.umd.min.277.js.map
plugin/harvester-1.10.0-dev.umd.min.303.js
plugin/harvester-1.10.0-dev.umd.min.303.js.map
plugin/harvester-1.10.0-dev.umd.min.37.js
plugin/harvester-1.10.0-dev.umd.min.37.js.map
plugin/harvester-1.10.0-dev.umd.min.375.js
plugin/harvester-1.10.0-dev.umd.min.375.js.map
plugin/harvester-1.10.0-dev.umd.min.431.js
plugin/harvester-1.10.0-dev.umd.min.431.js.map
plugin/harvester-1.10.0-dev.umd.min.446.js
plugin/harvester-1.10.0-dev.umd.min.446.js.map
plugin/harvester-1.10.0-dev.umd.min.460.js
plugin/harvester-1.10.0-dev.umd.min.460.js.map
plugin/harvester-1.10.0-dev.umd.min.489.js
plugin/harvester-1.10.0-dev.umd.min.489.js.map
plugin/harvester-1.10.0-dev.umd.min.573.js
plugin/harvester-1.10.0-dev.umd.min.573.js.map
plugin/harvester-1.10.0-dev.umd.min.60.js
plugin/harvester-1.10.0-dev.umd.min.60.js.map
plugin/harvester-1.10.0-dev.umd.min.619.js
plugin/harvester-1.10.0-dev.umd.min.619.js.map
plugin/harvester-1.10.0-dev.umd.min.682.js
plugin/harvester-1.10.0-dev.umd.min.682.js.map
plugin/harvester-1.10.0-dev.umd.min.730.js
plugin/harvester-1.10.0-dev.umd.min.730.js.map
plugin/harvester-1.10.0-dev.umd.min.740.js
plugin/harvester-1.10.0-dev.umd.min.740.js.map
plugin/harvester-1.10.0-dev.umd.min.763.js
plugin/harvester-1.10.0-dev.umd.min.763.js.map
plugin/harvester-1.10.0-dev.umd.min.813.js
plugin/harvester-1.10.0-dev.umd.min.813.js.map
plugin/harvester-1.10.0-dev.umd.min.856.js
plugin/harvester-1.10.0-dev.umd.min.856.js.map
plugin/harvester-1.10.0-dev.umd.min.880.js
plugin/harvester-1.10.0-dev.umd.min.880.js.map
plugin/harvester-1.10.0-dev.umd.min.895.js
plugin/harvester-1.10.0-dev.umd.min.895.js.map
plugin/harvester-1.10.0-dev.umd.min.97.js
plugin/harvester-1.10.0-dev.umd.min.97.js.map
plugin/harvester-1.10.0-dev.umd.min.csv.js
plugin/harvester-1.10.0-dev.umd.min.csv.js.map
plugin/harvester-1.10.0-dev.umd.min.detail.js
plugin/harvester-1.10.0-dev.umd.min.detail.js.map
plugin/harvester-1.10.0-dev.umd.min.dialog.js
plugin/harvester-1.10.0-dev.umd.min.dialog.js.map
plugin/harvester-1.10.0-dev.umd.min.edit.js
plugin/harvester-1.10.0-dev.umd.min.edit.js.map
plugin/harvester-1.10.0-dev.umd.min.formatters.js
plugin/harvester-1.10.0-dev.umd.min.formatters.js.map
plugin/harvester-1.10.0-dev.umd.min.js
plugin/harvester-1.10.0-dev.umd.min.js.map
plugin/harvester-1.10.0-dev.umd.min.list.js
plugin/harvester-1.10.0-dev.umd.min.list.js.map
plugin/harvester-1.10.0-dev.umd.min.promptRemove.js
plugin/harvester-1.10.0-dev.umd.min.promptRemove.js.map
plugin/harvester-1.10.0-dev.umd.min.xccdf.js
plugin/harvester-1.10.0-dev.umd.min.xccdf.js.map
plugin/harvester-1.10.0-dev.umd.min.xterm.js
plugin/harvester-1.10.0-dev.umd.min.xterm.js.map
plugin/img/custom.6f45244d.svg
plugin/img/email.b67ceff2.svg
plugin/img/generic-catalog.1842a50e.svg
plugin/img/generic-plugin.f1ebdd74.svg
plugin/img/grafana.2db31bb8.svg
plugin/img/harvester.0168283e.svg
plugin/img/icon.42954c0f.svg
plugin/img/pagerduty.9871fbd3.svg
plugin/img/prometheus.be8ac54d.svg
plugin/img/slack.34dfd73f.svg
plugin/img/webhook.f86c012b.svg
plugin/package.json
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
"use strict";(("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]=("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]||[]).push([[277],{28277:function(e,n,t){t.r(n),t.d(n,{default:function(){return f}});var r=t(9274);function s(e,n,t,s,o,c){const u=(0,r.resolveComponent)("ResourceDetail");return(0,r.openBlock)(),(0,r.createBlock)(u)}var o=t(97867),c={name:"ClusterResourceNamespaceId",components:{ResourceDetail:o.A}},u=t(47433);const a=(0,u.A)(c,[["render",s]]);var f=a}}]);
//# sourceMappingURL=harvester-1.10.0-dev.umd.min.277.js.map
@@ -1 +0,0 @@
{"version":3,"file":"harvester-1.10.0-dev.umd.min.277.js","mappings":"uWAUEA,EAAAA,EAAAA,aAAkBC,E,gBAPpB,GACEC,KAAY,6BACZC,WAAY,CAAEC,eAAcA,EAAAA,I,WCA9B,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE,O","sources":["webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/_namespace/_id.vue","webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/_namespace/_id.vue?9724"],"sourcesContent":["<script>\nimport ResourceDetail from '@shell/components/ResourceDetail';\n\nexport default {\n name: 'ClusterResourceNamespaceId',\n components: { ResourceDetail },\n};\n</script>\n\n<template>\n <ResourceDetail />\n</template>\n","import { render } from \"./_id.vue?vue&type=template&id=36f5b1f9\"\nimport script from \"./_id.vue?vue&type=script&lang=js\"\nexport * from \"./_id.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../../../../../../../vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_ResourceDetail","name","components","ResourceDetail","__exports__","render"],"sourceRoot":""}
@@ -1,2 +0,0 @@
"use strict";(("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]=("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]||[]).push([[303],{66303:function(e,n,t){t.r(n),t.d(n,{default:function(){return f}});var r=t(9274);function s(e,n,t,s,o,u){const c=(0,r.resolveComponent)("ResourceDetail");return(0,r.openBlock)(),(0,r.createBlock)(c)}var o=t(97867),u={name:"ClusterResourcedId",components:{ResourceDetail:o.A}},c=t(47433);const a=(0,c.A)(u,[["render",s]]);var f=a}}]);
//# sourceMappingURL=harvester-1.10.0-dev.umd.min.303.js.map
@@ -1 +0,0 @@
{"version":3,"file":"harvester-1.10.0-dev.umd.min.303.js","mappings":"uWAUEA,EAAAA,EAAAA,aAAkBC,E,gBAPpB,GACEC,KAAY,qBACZC,WAAY,CAAEC,eAAcA,EAAAA,I,WCA9B,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE,O","sources":["webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/_id.vue","webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/_id.vue?96bb"],"sourcesContent":["<script>\nimport ResourceDetail from '@shell/components/ResourceDetail';\n\nexport default {\n name: 'ClusterResourcedId',\n components: { ResourceDetail },\n};\n</script>\n\n<template>\n <ResourceDetail />\n</template>\n","import { render } from \"./_id.vue?vue&type=template&id=7d01dbfe\"\nimport script from \"./_id.vue?vue&type=script&lang=js\"\nexport * from \"./_id.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../../../../../../vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_ResourceDetail","name","components","ResourceDetail","__exports__","render"],"sourceRoot":""}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
"use strict";(("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]=("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]||[]).push([[446],{36446:function(e,n,t){t.r(n),t.d(n,{default:function(){return i}});var s=t(9274);function r(e,n,t,r,o,u){const c=(0,s.resolveComponent)("ResourceList");return(0,s.openBlock)(),(0,s.createBlock)(c)}var o=t(62348),u={name:"ClusterResourcedList",components:{ResourceList:o.A}},c=t(47433);const f=(0,c.A)(u,[["render",r]]);var i=f}}]);
//# sourceMappingURL=harvester-1.10.0-dev.umd.min.446.js.map
@@ -1 +0,0 @@
{"version":3,"file":"harvester-1.10.0-dev.umd.min.446.js","mappings":"qWAUEA,EAAAA,EAAAA,aAAgBC,E,gBAPlB,GACEC,KAAY,uBACZC,WAAY,CAAEC,aAAYA,EAAAA,I,WCA5B,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE,O","sources":["webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/index.vue","webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/index.vue?1ef3"],"sourcesContent":["<script>\nimport ResourceList from '@shell/components/ResourceList';\n\nexport default {\n name: 'ClusterResourcedList',\n components: { ResourceList },\n};\n</script>\n\n<template>\n <ResourceList />\n</template>\n","import { render } from \"./index.vue?vue&type=template&id=00d07840\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../../../../../../vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_ResourceList","name","components","ResourceList","__exports__","render"],"sourceRoot":""}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
(("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]=("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]||[]).push([[60],{45060:function(e,t,n){var o,a,i,r=n(4364);(function(n,r){a=[],o=r,i="function"===typeof o?o.apply(t,a):o,void 0===i||(e.exports=i)})(0,function(){"use strict";function t(e,t){return"undefined"==typeof t?t={autoBom:!1}:"object"!=typeof t&&(r.warn("Deprecated: Expected third argument to be a object"),t={autoBom:!t}),t.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob(["\ufeff",e],{type:e.type}):e}function o(e,t,n){var o=new XMLHttpRequest;o.open("GET",e),o.responseType="blob",o.onload=function(){f(o.response,t,n)},o.onerror=function(){r.error("could not download file")},o.send()}function a(e){var t=new XMLHttpRequest;t.open("HEAD",e,!1);try{t.send()}catch(e){}return 200<=t.status&&299>=t.status}function i(e){try{e.dispatchEvent(new MouseEvent("click"))}catch(o){var t=document.createEvent("MouseEvents");t.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),e.dispatchEvent(t)}}var s="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof n.g&&n.g.global===n.g?n.g:void 0,c=s.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),f=s.saveAs||("object"!=typeof window||window!==s?function(){}:"download"in HTMLAnchorElement.prototype&&!c?function(e,t,n){var r=s.URL||s.webkitURL,c=document.createElement("a");t=t||e.name||"download",c.download=t,c.rel="noopener","string"==typeof e?(c.href=e,c.origin===location.origin?i(c):a(c.href)?o(e,t,n):i(c,c.target="_blank")):(c.href=r.createObjectURL(e),setTimeout(function(){r.revokeObjectURL(c.href)},4e4),setTimeout(function(){i(c)},0))}:"msSaveOrOpenBlob"in navigator?function(e,n,r){if(n=n||e.name||"download","string"!=typeof e)navigator.msSaveOrOpenBlob(t(e,r),n);else if(a(e))o(e,n,r);else{var s=document.createElement("a");s.href=e,s.target="_blank",setTimeout(function(){i(s)})}}:function(e,t,n,a){if(a=a||open("","_blank"),a&&(a.document.title=a.document.body.innerText="downloading..."),"string"==typeof e)return o(e,t,n);var i="application/octet-stream"===e.type,r=/constructor/i.test(s.HTMLElement)||s.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent);if((f||i&&r||c)&&"undefined"!=typeof FileReader){var u=new FileReader;u.onloadend=function(){var e=u.result;e=f?e:e.replace(/^data:[^;]*;/,"data:attachment/file;"),a?a.location.href=e:location=e,a=null},u.readAsDataURL(e)}else{var l=s.URL||s.webkitURL,d=l.createObjectURL(e);a?a.location=d:location.href=d,a=null,setTimeout(function(){l.revokeObjectURL(d)},4e4)}});s.saveAs=f.saveAs=f,e.exports=f})}}]);
//# sourceMappingURL=harvester-1.10.0-dev.umd.min.60.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
"use strict";(("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]=("undefined"!==typeof self?self:this)["webpackChunkharvester_1_10_0_dev"]||[]).push([[856],{13856:function(e,t,n){n.r(t),n.d(t,{default:function(){return f}});var r=n(9274);function s(e,t,n,s,o,c){const u=(0,r.resolveComponent)("ResourceDetail");return(0,r.openBlock)(),(0,r.createBlock)(u,{"component-testid":"cluster-manager-create"})}var o=n(97867),c={name:"ClusterResourceCreate",components:{ResourceDetail:o.A}},u=n(47433);const a=(0,u.A)(c,[["render",s]]);var f=a}}]);
//# sourceMappingURL=harvester-1.10.0-dev.umd.min.856.js.map
@@ -1 +0,0 @@
{"version":3,"file":"harvester-1.10.0-dev.umd.min.856.js","mappings":"uWAUEA,EAAAA,EAAAA,aAA4DC,EAAA,CAA5C,mBAAiB,0B,gBAPnC,GACEC,KAAY,wBACZC,WAAY,CAAEC,eAAcA,EAAAA,I,WCA9B,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE,O","sources":["webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/create.vue","webpack://harvester-1.10.0-dev/../../node_modules/@rancher/shell/pages/c/_cluster/_product/_resource/create.vue?41a9"],"sourcesContent":["<script>\nimport ResourceDetail from '@shell/components/ResourceDetail';\n\nexport default {\n name: 'ClusterResourceCreate',\n components: { ResourceDetail },\n};\n</script>\n\n<template>\n <ResourceDetail component-testid=\"cluster-manager-create\" />\n</template>\n","import { render } from \"./create.vue?vue&type=template&id=60b40cbd\"\nimport script from \"./create.vue?vue&type=script&lang=js\"\nexport * from \"./create.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../../../../../../vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_ResourceDetail","name","components","ResourceDetail","__exports__","render"],"sourceRoot":""}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More