Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 12 additions & 0 deletions .github/actions/i18n-lint/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Run i18n Lint
description: Run i18n Lint

runs:
using: 'composite'
steps:
- name: Setup env
uses: ./.github/actions/setup

- name: Run i18n linters
shell: bash
run: yarn lint-l10n
12 changes: 12 additions & 0 deletions .github/actions/lint/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Run Lint
description: Run Lint

runs:
using: 'composite'
steps:
- name: Setup env
uses: ./.github/actions/setup

- name: Run linters
shell: bash
run: yarn lint
14 changes: 14 additions & 0 deletions .github/actions/setup/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Setup UI Env
description: Setup node environment and install packages

runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'

- name: Install packages
shell: bash
run: yarn install --frozen-lockfile
38 changes: 38 additions & 0 deletions .github/scripts/deploy-ai-agent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

# Helper script to install the AI Agent Helm chart into a Kubernetes cluster

KUBECONFIG_PATH=$1

if [ -z "$KUBECONFIG_PATH" ]; then
echo "ERROR: kubeconfig path required (arg or KUBECONFIG env)"
usage
fi

if [ ! -f "$KUBECONFIG_PATH" ]; then
echo "ERROR: kubeconfig not found at $KUBECONFIG_PATH"
exit 2
fi

export KUBECONFIG="$KUBECONFIG_PATH"

echo ""
echo "Cloning rancher-ai-agent chart repository..."

git clone https://github.com/rancher-sandbox/rancher-ai-agent.git

echo ""
echo "Installing ai-agent"

helm upgrade --install ai-agent ./rancher-ai-agent/chart/agent \
--namespace cattle-ai-agent-system \
--create-namespace \
--set "imagePullSecrets[0].name=gh-secret" \
--set llmModel=gemini-2.0-flash \
--set googleApiKey=your_token \
--set insecureSkipTls=true \
--set activeLlm=gemini \
--wait --timeout 1m

kubectl -n cattle-ai-agent-system rollout status deployment/rancher-ai-agent --timeout=1m
kubectl -n cattle-ai-agent-system wait --for=condition=available --timeout=1m deployment/rancher-ai-agent
77 changes: 77 additions & 0 deletions .github/scripts/install-rancher.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/bin/bash

# Helper script to run Rancher in a Docker container

VERSION="head"
CATTLE_SERVER_URL="https://localhost"
CATTLE_BOOTSTRAP_PASSWORD="asd"

if [ -n "$1" ]; then
VERSION=$1
fi

if [ -n "$2" ]; then
CATTLE_SERVER_URL="$2"
fi

if [ -n "$3" ]; then
CATTLE_BOOTSTRAP_PASSWORD="$3"
fi

IMAGE="rancher/rancher:${VERSION}"

echo ""
echo "Starting '${IMAGE}' container ..."

echo ""
ID=$(docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged -e CATTLE_SERVER_URL=${CATTLE_SERVER_URL} -e CATTLE_BOOTSTRAP_PASSWORD=${CATTLE_BOOTSTRAP_PASSWORD} -e CATTLE_PASSWORD_MIN_LENGTH=3 ${IMAGE})

if [ $? -ne 0 ]; then
echo "An error occurred running the Docker container"
exit 1
fi

echo ""
echo "Container Id: ${ID}"

echo ""
echo "Waiting for backend to become ready"

TIME=0
while [[ "$(curl --insecure -s -m 5 -o /dev/null -w ''%{http_code}'' ${CATTLE_SERVER_URL})" != "200" ]]; do
sleep 5;
TIME=$((TIME + 5))
echo "${TIME}s ..."
done

echo ""
echo "Login to Rancher"

RANCHER_TOKEN=$(curl -vkL \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"'"$CATTLE_BOOTSTRAP_PASSWORD"'" ,"responseType":"cookie"}' \
-X POST \
${CATTLE_SERVER_URL}/v3-public/localProviders/local?action=login 2>&1 | \
awk -F'[=;]' '/Set-Cookie/{gsub(" ","",$2);print $2;exit}')

echo ""
echo "Get kubeconfig from local cluster"

HEADER="Cookie: R_SESS=$RANCHER_TOKEN"
curl -kL \
-H 'Content-Type: application/json' \
-X POST \
-H "$HEADER" \
${CATTLE_SERVER_URL}/v3/clusters/local?action=generateKubeconfig | \
yq '.config' > kubeconfig.yaml

sleep 2;

echo ""
kubectl --kubeconfig=kubeconfig.yaml cluster-info
if [ $? -ne 0 ]; then
echo "Unable to get Rancher resources"
exit 1
fi

echo "Done"
5 changes: 5 additions & 0 deletions .github/workflows/build-extension-catalog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ defaults:
working-directory: ./

jobs:
validation:
name: Build Test
uses: ./.github/workflows/build-test.yaml
build-extension-catalog:
uses: rancher/dashboard/.github/workflows/build-extension-catalog.yml@master
permissions:
Expand All @@ -23,3 +26,5 @@ jobs:
tagged_release: ${{ github.ref_name }}
secrets:
registry_token: ${{ secrets.GITHUB_TOKEN }}
needs:
- validation
5 changes: 5 additions & 0 deletions .github/workflows/build-extension-charts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ defaults:
working-directory: ./

jobs:
validation:
name: Build Test
uses: ./.github/workflows/build-test.yaml
build-extension-charts:
uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@master
permissions:
Expand All @@ -21,3 +24,5 @@ jobs:
with:
target_branch: gh-pages
tagged_release: ${{ github.ref_name }}
needs:
- validation
28 changes: 28 additions & 0 deletions .github/workflows/build-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Validation steps required before a build occurs.
name: Build Test

on:
workflow_call:

jobs:
# TODO add unit tests job

i18n:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 1

- name: Run i18n lint
uses: ./.github/actions/i18n-lint

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 1

- name: Run lint
uses: ./.github/actions/lint
104 changes: 104 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Tests
on:
push:
branches:
- main
- 'release-*'
pull_request:
branches:
- main
- 'release-*'

env:
RANCHER_VERSION: head
CATTLE_SERVER_URL: https://127.0.0.1
CATTLE_BOOTSTRAP_PASSWORD: password
KUBECONFIG_PATH: ${{ github.workspace }}/kubeconfig.yaml
DEV_UI_URL: https://localhost:8005

jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 1

- name: Setup Node env
uses: ./.github/actions/setup

- name: Start Rancher
run: .github/scripts/install-rancher.sh ${{ env.RANCHER_VERSION }} ${{ env.CATTLE_SERVER_URL }} ${{ env.CATTLE_BOOTSTRAP_PASSWORD }}

- name: Deploy AI Agent chart
run: .github/scripts/deploy-ai-agent.sh ${{ env.KUBECONFIG_PATH }}

- name: Start Mock Agent
working-directory: ./mock-agent
run: |
yarn install --frozen-lockfile
nohup yarn mock:agent:start > mock-agent.log 2>&1 & echo $! > mock-agent.pid

- name: Start dev UI
env:
API: ${{ env.CATTLE_SERVER_URL }}
VUE_APP_AGENT_MESSAGES_WS_PATH: ws://localhost:8000/ws/agent
run: |
nohup yarn dev > dev.log 2>&1 & echo $! > dev.pid

- name: Wait for dev UI to be ready
run: |
npx wait-on ${{ env.DEV_UI_URL }}

- name: Run Cypress tests
id: cypress
continue-on-error: true
env:
TEST_USERNAME: admin
TEST_PASSWORD: ${{ env.CATTLE_BOOTSTRAP_PASSWORD }}
CATTLE_BOOTSTRAP_PASSWORD: ${{ env.CATTLE_BOOTSTRAP_PASSWORD }}
TEST_BASE_URL: ${{ env.DEV_UI_URL }}
TEST_SKIP: setup
API: ${{ env.CATTLE_SERVER_URL }}
run: |
yarn e2e --browser chrome

- name: Upload videos on failure
if: steps.cypress.outcome != 'success'
uses: actions/upload-artifact@v4
with:
name: cypress-videos
path: cypress/videos
retention-days: 7

- name: Tear down background processes
if: always()
run: |
if [ -f dev.pid ]; then kill $(cat dev.pid) || true; fi
if [ -f mock-agent.pid ]; then kill $(cat mock-agent.pid) || true; fi

- name: Check failed tests
if: steps.cypress.outcome != 'success'
run: |
echo "Cypress tests failed"
exit 1

i18n:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 1

- name: Run i18n lint
uses: ./.github/actions/i18n-lint

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 1

- name: Run tests
uses: ./.github/actions/lint
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,6 @@ shell/rancher-components
scripts/standalone/ui
scripts/standalone/cert
scripts/standalone/node

# Cypress
browser-logs
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ Bump the app version on `package.json` file, then run:
yarn serve-pkgs
```

## E2E tests
Running locally:
```bash
# Build and Run the mock Agent
cd mock-agent
yarn install
yarn mock:agent:start

# Launch Cypress dashboard
API=https://your-rancher VUE_APP_AGENT_MESSAGES_WS_PATH=ws://localhost:8000/ws/agent yarn dev
```
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we're missing a step. This doesn't launch the cypress dashboard, it starts the dev server. I think we need a line for ➤ TEST_PASSWORD=${ rancher-password } yarn e2e.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed, thanks.


License
=======
Check Rancher AI UI Apache License details [here](LICENSE)
Loading