Skip to content

Commit 18d41cd

Browse files
committed
Add CI steps: lint, lint-i18n, node setup, cypress e2e
Signed-off-by: Francesco Torchia <[email protected]>
1 parent 41185a5 commit 18d41cd

File tree

12 files changed

+372
-6
lines changed

12 files changed

+372
-6
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Run i18n Lint
2+
description: Run i18n Lint
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- name: Setup env
8+
uses: ./.github/actions/setup
9+
10+
- name: Run i18n linters
11+
shell: bash
12+
run: yarn lint-l10n

.github/actions/lint/action.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Run Lint
2+
description: Run Lint
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- name: Setup env
8+
uses: ./.github/actions/setup
9+
10+
- name: Run linters
11+
shell: bash
12+
run: yarn lint

.github/actions/setup/action.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Setup UI Env
2+
description: Setup node environment and install packages
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- uses: actions/setup-node@v4
8+
with:
9+
node-version-file: '.nvmrc'
10+
cache: 'yarn'
11+
12+
- name: Install packages
13+
shell: bash
14+
run: yarn install --frozen-lockfile

.github/scripts/deploy-ai-agent.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
# Helper script to install the AI Agent Helm chart into a Kubernetes cluster
4+
5+
KUBECONFIG_PATH=$1
6+
7+
if [ -z "$KUBECONFIG_PATH" ]; then
8+
echo "ERROR: kubeconfig path required (arg or KUBECONFIG env)"
9+
usage
10+
fi
11+
12+
if [ ! -f "$KUBECONFIG_PATH" ]; then
13+
echo "ERROR: kubeconfig not found at $KUBECONFIG_PATH"
14+
exit 2
15+
fi
16+
17+
export KUBECONFIG="$KUBECONFIG_PATH"
18+
19+
echo ""
20+
echo "Cloning rancher-ai-agent chart repository..."
21+
22+
git clone https://github.com/rancher-sandbox/rancher-ai-agent.git
23+
24+
echo ""
25+
echo "Installing ai-agent"
26+
27+
helm upgrade --install ai-agent ./rancher-ai-agent/chart/agent \
28+
--namespace cattle-ai-agent-system \
29+
--create-namespace \
30+
--set "imagePullSecrets[0].name=gh-secret" \
31+
--set llmModel=gemini-2.0-flash \
32+
--set googleApiKey=your_token \
33+
--set insecureSkipTls=true \
34+
--set activeLlm=gemini \
35+
--wait --timeout 1m
36+
37+
kubectl -n cattle-ai-agent-system rollout status deployment/rancher-ai-agent --timeout=1m
38+
kubectl -n cattle-ai-agent-system wait --for=condition=available --timeout=1m deployment/rancher-ai-agent

.github/scripts/install-rancher.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/bash
2+
3+
# Helper script to run Rancher in a Docker container
4+
5+
VERSION="head"
6+
CATTLE_SERVER_URL="https://localhost"
7+
CATTLE_BOOTSTRAP_PASSWORD="asd"
8+
9+
if [ -n "$1" ]; then
10+
VERSION=$1
11+
fi
12+
13+
if [ -n "$2" ]; then
14+
CATTLE_SERVER_URL="$2"
15+
fi
16+
17+
if [ -n "$3" ]; then
18+
CATTLE_BOOTSTRAP_PASSWORD="$3"
19+
fi
20+
21+
IMAGE="rancher/rancher:${VERSION}"
22+
23+
echo ""
24+
echo "Starting '${IMAGE}' container ..."
25+
26+
echo ""
27+
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})
28+
29+
if [ $? -ne 0 ]; then
30+
echo "An error occurred running the Docker container"
31+
exit 1
32+
fi
33+
34+
echo ""
35+
echo "Container Id: ${ID}"
36+
37+
echo ""
38+
echo "Waiting for backend to become ready"
39+
40+
TIME=0
41+
while [[ "$(curl --insecure -s -m 5 -o /dev/null -w ''%{http_code}'' ${CATTLE_SERVER_URL})" != "200" ]]; do
42+
sleep 5;
43+
TIME=$((TIME + 5))
44+
echo "${TIME}s ..."
45+
done
46+
47+
echo ""
48+
echo "Login to Rancher"
49+
50+
RANCHER_TOKEN=$(curl -vkL \
51+
-H 'Content-Type: application/json' \
52+
-d '{"username":"admin","password":"'"$CATTLE_BOOTSTRAP_PASSWORD"'" ,"responseType":"cookie"}' \
53+
-X POST \
54+
${CATTLE_SERVER_URL}/v3-public/localProviders/local?action=login 2>&1 | \
55+
awk -F'[=;]' '/Set-Cookie/{gsub(" ","",$2);print $2;exit}')
56+
57+
echo ""
58+
echo "Get kubeconfig from local cluster"
59+
60+
HEADER="Cookie: R_SESS=$RANCHER_TOKEN"
61+
curl -kL \
62+
-H 'Content-Type: application/json' \
63+
-X POST \
64+
-H "$HEADER" \
65+
${CATTLE_SERVER_URL}/v3/clusters/local?action=generateKubeconfig | \
66+
yq '.config' > kubeconfig.yaml
67+
68+
sleep 2;
69+
70+
echo ""
71+
kubectl --kubeconfig=kubeconfig.yaml cluster-info
72+
if [ $? -ne 0 ]; then
73+
echo "Unable to get Rancher resources"
74+
exit 1
75+
fi
76+
77+
echo "Done"

.github/workflows/build-extension-catalog.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ defaults:
1111
working-directory: ./
1212

1313
jobs:
14+
validation:
15+
name: Build Test
16+
uses: ./.github/workflows/build-test.yaml
1417
build-extension-catalog:
1518
uses: rancher/dashboard/.github/workflows/build-extension-catalog.yml@master
1619
permissions:
@@ -23,3 +26,5 @@ jobs:
2326
tagged_release: ${{ github.ref_name }}
2427
secrets:
2528
registry_token: ${{ secrets.GITHUB_TOKEN }}
29+
needs:
30+
- validation

.github/workflows/build-extension-charts.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ defaults:
1111
working-directory: ./
1212

1313
jobs:
14+
validation:
15+
name: Build Test
16+
uses: ./.github/workflows/build-test.yaml
1417
build-extension-charts:
1518
uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@master
1619
permissions:
@@ -21,3 +24,5 @@ jobs:
2124
with:
2225
target_branch: gh-pages
2326
tagged_release: ${{ github.ref_name }}
27+
needs:
28+
- validation

.github/workflows/build-test.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Validation steps required before a build occurs.
2+
name: Build Test
3+
4+
on:
5+
workflow_call:
6+
7+
jobs:
8+
# TODO add unit tests job
9+
10+
i18n:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v5
14+
with:
15+
fetch-depth: 1
16+
17+
- name: Run i18n lint
18+
uses: ./.github/actions/i18n-lint
19+
20+
lint:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v5
24+
with:
25+
fetch-depth: 1
26+
27+
- name: Run lint
28+
uses: ./.github/actions/lint

.github/workflows/test.yaml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Tests
2+
on:
3+
push:
4+
branches:
5+
- main
6+
- 'release-*'
7+
pull_request:
8+
branches:
9+
- main
10+
- 'release-*'
11+
12+
env:
13+
RANCHER_VERSION: head
14+
CATTLE_SERVER_URL: https://127.0.0.1
15+
CATTLE_BOOTSTRAP_PASSWORD: password
16+
API: https://127.0.0.1
17+
KUBECONFIG_PATH: ${{ github.workspace }}/kubeconfig.yaml
18+
19+
jobs:
20+
e2e:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v5
24+
with:
25+
fetch-depth: 1
26+
27+
- name: Setup Node env
28+
uses: ./.github/actions/setup
29+
30+
- name: Start Rancher
31+
run: .github/scripts/install-rancher.sh ${{ env.RANCHER_VERSION }} ${{ env.CATTLE_SERVER_URL }} ${{ env.CATTLE_BOOTSTRAP_PASSWORD }}
32+
33+
- name: Deploy AI Agent chart
34+
run: .github/scripts/deploy-ai-agent.sh ${{ env.KUBECONFIG_PATH }}
35+
36+
- name: Start Mock Agent
37+
working-directory: ./mock-agent
38+
run: |
39+
yarn install --frozen-lockfile
40+
nohup yarn mock:agent:start > mock-agent.log 2>&1 & echo $! > mock-agent.pid
41+
42+
- name: Start dev server
43+
env:
44+
API: ${{ env.API }}
45+
VUE_APP_AGENT_MESSAGES_WS_PATH: ws://localhost:8000/ws/agent
46+
run: |
47+
nohup yarn dev > dev.log 2>&1 & echo $! > dev.pid
48+
49+
- name: Wait for dev UI to be ready
50+
run: |
51+
npx wait-on https://localhost:8005
52+
53+
- name: Run Cypress tests
54+
id: cypress
55+
continue-on-error: true
56+
env:
57+
TEST_USERNAME: admin
58+
TEST_PASSWORD: ${{ env.CATTLE_BOOTSTRAP_PASSWORD }}
59+
CATTLE_BOOTSTRAP_PASSWORD: ${{ env.CATTLE_BOOTSTRAP_PASSWORD }}
60+
TEST_BASE_URL: https://localhost:8005
61+
TEST_SKIP: setup
62+
API: ${{ env.API }}
63+
run: |
64+
yarn e2e --browser chrome
65+
66+
- name: Upload videos on failure
67+
if: steps.cypress.outcome != 'success'
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: cypress-videos
71+
path: cypress/videos
72+
retention-days: 7
73+
74+
- name: Tear down background processes
75+
if: always()
76+
run: |
77+
if [ -f dev.pid ]; then kill $(cat dev.pid) || true; fi
78+
if [ -f mock-agent.pid ]; then kill $(cat mock-agent.pid) || true; fi
79+
80+
- name: Cypress failed
81+
if: steps.cypress.outcome != 'success'
82+
run: |
83+
echo "Cypress tests failed"
84+
exit 1
85+
86+
i18n:
87+
runs-on: ubuntu-latest
88+
steps:
89+
- uses: actions/checkout@v5
90+
with:
91+
fetch-depth: 1
92+
93+
- name: Run i18n lint
94+
uses: ./.github/actions/i18n-lint
95+
96+
lint:
97+
runs-on: ubuntu-latest
98+
steps:
99+
- uses: actions/checkout@v5
100+
with:
101+
fetch-depth: 1
102+
103+
- name: Run tests
104+
uses: ./.github/actions/lint
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { RancherSetupLoginPagePo } from '@/cypress/e2e/po/pages/rancher-setup-login.po';
2+
import { RancherSetupConfigurePage } from '@/cypress/e2e/po/pages/rancher-setup-configure.po';
3+
import HomePagePo from '@/cypress/e2e/po/pages/home.po';
4+
5+
describe('Rancher setup', () => {
6+
const rancherSetupLoginPage = new RancherSetupLoginPagePo();
7+
const rancherSetupConfigurePage = new RancherSetupConfigurePage();
8+
const homePage = new HomePagePo();
9+
10+
it('First login & Configure', () => {
11+
cy.intercept('POST', '/v3-public/localProviders/local?action=login').as('bootstrapReq');
12+
13+
rancherSetupLoginPage.goTo();
14+
rancherSetupLoginPage.waitForPage();
15+
rancherSetupLoginPage.bootstrapLogin();
16+
17+
cy.wait('@bootstrapReq').then((login) => {
18+
expect(login.response?.statusCode).to.equal(200);
19+
rancherSetupConfigurePage.waitForPage();
20+
});
21+
22+
cy.intercept('PUT', '/v1/userpreferences/*').as('firstLoginReq');
23+
24+
rancherSetupConfigurePage.waitForPage();
25+
rancherSetupConfigurePage.canSubmit().should('eq', false);
26+
27+
rancherSetupConfigurePage.termsAgreement().set();
28+
rancherSetupConfigurePage.canSubmit().should('eq', true);
29+
rancherSetupConfigurePage.submit();
30+
31+
cy.location('pathname', { timeout: 15000 }).should('include', '/home');
32+
33+
cy.wait('@firstLoginReq').then((login) => {
34+
expect(login.response?.statusCode).to.equal(200);
35+
homePage.waitForPage();
36+
});
37+
});
38+
});

0 commit comments

Comments
 (0)