修改使install.sh脚本兼容DoD,修复一些错误,增加了一些关键位置的截图和超时判断

This commit is contained in:
jiaojm
2025-11-30 09:52:48 +08:00
repo.diff.parent dd60ca2100
repo.diff.commit decbb3336e
repo.diff.stats_desc%!(EXTRA int=6, int=57, int=51)

repo.diff.view_file

@@ -11,22 +11,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Clean
run: |
public/assets/install.sh clean
docker volume rm devstar_data_vol || true
uses: actions/checkout@v4
- name: start DevStar Container
run: |
# 替换数据卷路径
sed -i 's|~/devstar_data|devstar_data_vol|g' public/assets/install.sh
# 启动容器
public/assets/install.sh start --image=devstar-studio:latest
LOGS=$(public/assets/install.sh start \
--port=8082 \
--ssh-port=2224 \
--data-dir=/tmp/devstar_ci \
--image=devstar-studio:latest 2>&1)
echo "$LOGS"
TARGET_URL=$(echo "$LOGS" | grep -o 'http://[^ ]*' | tail -1 | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g")
echo "TARGET_URL=$TARGET_URL" >> $GITHUB_ENV
- name: Run E2E Tests
run: |
make e2e-test TARGET_URL="http://localhost:80"
make e2e-test TARGET_URL="$TARGET_URL"
env:
GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT: "true"
- name: 4. Upload E2E Test Report

repo.diff.view_file

@@ -15,7 +15,7 @@ const config: PlaywrightTestConfig = {
forbidOnly: Boolean(env.CI),
retries: env.CI ? 2 : 0,
reporter: env.CI ? 'list' : [['list'], ['html', {
reporter: [['html', {
outputFolder: 'playwright-report/html',
open: 'never'
}]],

repo.diff.view_file

@@ -2,14 +2,13 @@
# Copyright 2024 Mengning Software All rights reserved.
# 默认值
NAME=DevStar-Studio
NAME="DevStar-Studio-$(date +%Y%m%d-%H-%M-%S)"
IMAGE_REGISTRY_USER=mengning997
IMAGE_NAME=devstar-studio
VERSION=latest # DevStar Studio的默认版本为最新版本
PORT=80 # 设置端口默认值为 80
SSH_PORT=2222 # 设置ssh默认端口号2222
DATA_DIR=${HOME}/devstar_data
APP_INI=${DATA_DIR}/app.ini
# 错误处理函数
error_handler() {
@@ -111,25 +110,30 @@ function start {
mkdir -p $DATA_DIR
sudo chown 1000:1000 $DATA_DIR
sudo chmod 666 /var/run/docker.sock
if [ ! -f "$APP_INI" ]; then
DOMAIN_NAME=$(hostname -I | awk '{print $1}')
if [[ -n "$CI" ]]; then
echo "检测到 CI 环境,正在获取网关 IP..."
DOMAIN_NAME=$(ip route show | grep default | awk '{print $3}')
else
#本地环境不做变化
DOMAIN_NAME=$(hostname -I | awk '{print $1}')
fi
if [ ! -f "${DATA_DIR}/app.ini" ]; then
echo "DOMAIN_NAME=$DOMAIN_NAME"
else
# 读取 DOMAIN 值
DOMAIN_NAME=$(grep -E '^\s*DOMAIN\s*=' "$APP_INI" | cut -d'=' -f2 | xargs)
DOMAIN_NAME_APP_INI=$(grep -E '^\s*DOMAIN\s*=' "${DATA_DIR}/app.ini" | cut -d'=' -f2 | xargs)
# 检查是否成功读取到值
if [[ -z "$DOMAIN_NAME" ]]; then
DOMAIN_NAME="localhost"
if [[ -n "$DOMAIN_NAME_APP_INI" ]]; then
DOMAIN_NAME=$DOMAIN_NAME_APP_INI
fi
echo "DOMAIN_NAME=$DOMAIN_NAME"
fi
# 启动devstar-studio容器
stop
if [[ -z "$IMAGE_STR" ]]; then
IMAGE_STR="$IMAGE_REGISTRY_USER/$IMAGE_NAME:$VERSION"
fi
echo "image=$IMAGE_STR"
sudo docker run --restart=always --name $NAME -d -p $PORT:3000 -p $SSH_PORT:$SSH_PORT -v /var/run/docker.sock:/var/run/docker.sock -v ~/devstar_data:/var/lib/gitea -v ~/devstar_data:/etc/gitea $IMAGE_STR
sudo docker run --restart=always --name $NAME -d -p $PORT:3000 -p $SSH_PORT:$SSH_PORT -v /var/run/docker.sock:/var/run/docker.sock -v ${DATA_DIR}:/var/lib/gitea -v ${DATA_DIR}:/etc/gitea $IMAGE_STR
# 打开 `http://localhost:8080` 完成安装。
success "-------------------------------------------------------"
success "DevStar started in http://$DOMAIN_NAME:$PORT successfully!"
@@ -139,30 +143,37 @@ function start {
# Function to stop
function stop {
if [ $(docker ps -a --filter "name=^/${NAME}$" -q | wc -l) -gt 0 ]; then
sudo docker stop $NAME && sudo docker rm -f $NAME
fi
if [ $(docker ps -a --filter "name=^/devstar-studio$" -q | wc -l) -gt 0 ]; then
sudo docker stop devstar-studio && sudo docker rm -f devstar-studio
if [ $(docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" -q | wc -l) -gt 0 ]; then
sudo docker stop $(docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" -q) && \
sudo docker rm -f $(docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" -q)
fi
if [ $(docker ps -a --filter "name=^/webterminal-" -q | wc -l) -gt 0 ]; then
sudo docker stop $(docker ps -a --filter "name=^/webterminal-" -q) && sudo docker rm -f $(docker ps -a --filter "name=^/webterminal-" -q)
fi
if [ $(docker ps -a --filter "name=^/runner-" -q | wc -l) -gt 0 ]; then
sudo docker stop $(docker ps -a --filter "name=^/runner-" -q) && sudo docker rm -f $(docker ps -a --filter "name=^/runner-" -q)
fi
fi
}
# Function to logs
function logs {
# 查看devstar-studio容器的运行日志
sudo docker logs $NAME
sudo docker ps -a --filter "name=^/DevStar-Studio.*|devstar-studio.*" --format "table {{.ID}}\t{{.Names}}" | tail -n +2 | while read container_id container_name; do
echo "=== 容器日志: $container_name (ID: $container_id) ==="
sudo docker logs "$container_id"
done
}
# Function to clean
function clean {
stop
rm -rf $DATA_DIR
read -p "警告:即将永久删除目录 $DATA_DIR,此操作不可恢复!请输入 'YES' 确认: " confirm
if [[ "$confirm" == "YES" ]]; then
rm -rf "$DATA_DIR"
echo "目录已删除"
else
echo "操作已取消"
fi
}
# Function to usage help
@@ -173,6 +184,7 @@ function usage {
success " start Start DevStar Studio"
success " --port=<arg> Specify the port number (default port is 80)"
success " --ssh-port=<arg> Specify the ssh-port number (default ssh-port is 2222)"
success " --data-dir=<arg> Specify the data directory (default data directory is ~/devstar_data)"
success " --version=<arg> Specify the DevStar Studio Image Version (default verson is latest)"
success " --image=<arg> Specify the DevStar Studio Image example: devstar-studio:latest "
success " stop Stop the running DevStar Studio"
@@ -188,7 +200,7 @@ case "$1" in
usage
;;
start)
ARGS=$(getopt --long port::,ssh-port::,version::,image:: -- "$@")
ARGS=$(getopt --long port::,ssh-port::,data-dir::,version::,image:: -- "$@")
if [ $? -ne 0 ]; then
failure "ARGS ERROR!"
exit 1
@@ -205,6 +217,10 @@ case "$1" in
SSH_PORT="$2"
echo "The SSH_Port is: $SSH_PORT"
shift 2 ;;
--data-dir)
DATA_DIR="$2"
echo "The SSH_Port is: $DATA_DIR"
shift 2 ;;
--version)
VERSION="$2"
echo "The DevStar Studio Image Version is: $VERSION"
@@ -246,5 +262,4 @@ case "$1" in
devstar help
fi
;;
esac
esac

repo.diff.view_file

@@ -31,7 +31,7 @@ async function globalSetup(config: FullConfig) {
await page.getByRole('textbox', { name: '邮箱地址' }).fill('ilovcatlyn750314@gmail.com');
await page.getByRole('textbox', { name: '管理员密码', exact: true }).fill('12345678');
await page.getByRole('textbox', { name: '确认密码' }).fill('12345678');
await page.getByRole('button', { name: '立即安装'}).click();
await page.getByRole('button', { name: '立即安装'}).click({ timeout: 50000 });
console.log("安装中,请耐心等待");
await page.waitForTimeout(90000);
} catch (error) {

repo.diff.view_file

@@ -3,27 +3,18 @@
# 它会处理所有清理、权限、拉取和执行工作
# 任何命令失败立即退出
set -e
# 获取脚本所在目录和项目根目录test/e2e和devstar项目根目录
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
PROJECT_ROOT=$( cd -- "$SCRIPT_DIR/../.." &> /dev/null && pwd )
# 导出当前用户 ID防止 Docker 生成 root 权限文件
export CURRENT_UID=$(id -u)
export CURRENT_GID=$(id -g)
# 切换到项目根目录
cd "$PROJECT_ROOT"
echo "===== [1/3] 清理旧的测试环境... ====="
#删除旧的e2e-runner
if [ "$(docker ps -aq -f name=e2e-test-runner-container)" ]; then
docker rm -f e2e-test-runner-container
fi
#清理旧的构建缓存
docker image prune -f
#清理并重建报告和数据目录
rm -rf ./tests/e2e/reports ./tests/e2e/test-data
mkdir -p ./tests/e2e/reports/html ./tests/e2e/test-data/devstar_data
#赋予目录权限,防止挂载后容器无权写入
chmod -R 777 ./tests/e2e/reports
#这里添加的代码是因为需要执行npm install,我们以当前用户启动测试容器避免root权限冲突所以先预构建文件夹也作为缓存缓存npm install.
echo "处理 node_modules 权限..."
@@ -39,8 +30,6 @@ echo "清理完成。"
echo ""
echo "===== [2/3] 准备环境变量... ====="
# 检查从 Makefile 传来的 TARGET_URL 变量是否为空
echo " 检查devstar位置:TARGET_URL"
export DEVSTAR_URL=$TARGET_URL
export E2E_MODE="url"
if [ -n "$CI" ] || [ "$CI" = "true" ]; then
@@ -68,7 +57,6 @@ set +e
docker run -d --rm --init --ipc=host \
--name e2e-test-runner-container \
--network host \
-u "root" \
-e DEVSTAR_URL="$DEVSTAR_URL" \
-e E2E_SKIP_INSTALL="$E2E_SKIP_INSTALL" \
@@ -80,7 +68,6 @@ docker run -d --rm --init --ipc=host \
-e HOME=/tmp \
-w /app \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$(pwd)/tests/e2e/reports:/app/playwright-report" \
mcr.microsoft.com/playwright:v1.53.2-jammy \
tail -f /dev/null
echo "容器已启动,正在使用 docker cp 注入代码..."
@@ -96,11 +83,11 @@ docker exec e2e-test-runner-container bash -c "
npm install --no-package-lock
echo '依赖安装完成,开始测试...'
PLAYWRIGHT_HTML_REPORT=/app/playwright-report npx playwright test
npx playwright test
"
# 捕获 test-runner 的退出码
EXIT_CODE=$?
set -e
docker cp e2e-test-runner-container:/app/playwright-report/. tests/e2e/reports/html-report/
docker rm -f e2e-test-runner-container
echo "========================================"
if [ $EXIT_CODE -eq 0 ]; then
@@ -109,14 +96,13 @@ else
echo "测试执行失败!"
fi
echo "========================================"
REPORT_DIR="./tests/e2e/reports"
if [ -f "$REPORT_DIR/html/index.html" ]; then
echo "HTML 报告已生成: $REPORT_DIR//html/index.html"
REPORT_DIR="./tests/e2e/reports/"
if [ -f "$REPORT_DIR" ]; then
echo "HTML 报告已生成: $REPORT_DIR"
else
echo "未检测到HTML报告 "
echo "可能是测试运行中途崩溃,或者未生成报告。"
echo "请检查日志或目录: $REPORT_DIR"
fi
echo ""
# 以 test-runner 的退出码退出
exit $EXIT_CODE

repo.diff.view_file

@@ -78,6 +78,7 @@ test('DevContainer 功能和配置', async ({ page,context }) => {
//第二次刷新,容器应该正常启动了
await page.reload({ waitUntil: 'domcontentloaded' });
await expect(stopButton).toBeVisible({ timeout: 30000 });
await page.screenshot({ path: 'full-page.png', fullPage: true });
}
console.log("Dev container 创建成功!");
await page.getByRole('button',{ name: '停止开发容器'}).click();
@@ -94,6 +95,10 @@ test('DevContainer 功能和配置', async ({ page,context }) => {
await page.getByRole('link',{name: 'open with WebTerminal'}).click();
const newPage = await pagePromise;
await newPage.waitForLoadState(); // 等待新页面加载完成
await page.reload({ waitUntil: 'domcontentloaded' });
await page.waitForTimeout(30000);
await page.reload({ waitUntil: 'domcontentloaded' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
console.log("Web Terminal: 新标签页已打开!");
//await expect(newPage.getByText('Successfully connected to the container')).toBeVisible(); //这里ttyd里的信息PlayWright看不见容器的交互没办法自动化测试
await page.getByRole('link', { name: '删除开发容器' }).click();