This commit is contained in:
dataeaseShu
2025-09-03 14:35:30 +08:00
6 changed files with 183 additions and 70 deletions
+104
View File
@@ -0,0 +1,104 @@
name: build-base-and-push
run-name: 构建镜像并推送仓库 ${{ github.event.inputs.dockerImageTag }} (${{ github.event.inputs.registry }}) (${{ github.event.inputs.architecture }})
on:
workflow_dispatch:
inputs:
dockerImageTag:
description: 'Image Tag'
default: 'v0.9.0'
required: true
dockerImageTagWithLatest:
description: '是否发布latest tag(正式发版时选择,测试版本切勿选择)'
default: false
required: true
type: boolean
architecture:
description: 'Architecture'
required: true
default: 'linux/amd64'
type: choice
options:
- linux/amd64
- linux/arm64
- linux/amd64,linux/arm64
registry:
description: 'Push To Registry'
required: true
default: 'aliyun-registry'
type: choice
options:
- aliyun-registry
- dockerhub
- dockerhub, aliyun-registry
jobs:
build-and-push-to-aliyun-registry:
if: ${{ contains(github.event.inputs.registry, 'aliyun') }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Prepare
id: prepare
run: |
DOCKER_IMAGE=${{ secrets.ALIYUN_REGISTRY_HOST }}/dataease/sqlbot-python-pg
DOCKER_PLATFORMS=${{ github.event.inputs.architecture }}
TAG_NAME=${{ github.event.inputs.dockerImageTag }}
TAG_NAME_WITH_LATEST=${{ github.event.inputs.dockerImageTagWithLatest }}
if [[ ${TAG_NAME_WITH_LATEST} == 'true' ]]; then
DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:${TAG_NAME%%.*} --tag ${DOCKER_IMAGE}:latest"
else
DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME}"
fi
echo ::set-output name=buildx_args::--platform ${DOCKER_PLATFORMS} --memory-swap -1 \
--build-arg DOCKER_IMAGE_TAG=${{ github.event.inputs.dockerImageTag }} --build-arg BUILD_AT=$(TZ=Asia/Shanghai date +'%Y-%m-%dT%H:%M') --build-arg GITHUB_COMMIT=`git rev-parse --short HEAD` --no-cache \
${DOCKER_IMAGE_TAGS} .
- name: Set up Docker Buildx
uses: crazy-max/ghaction-docker-buildx@v3
- name: Login to Aliyun Registry
uses: docker/login-action@v2
with:
registry: ${{ secrets.ALIYUN_REGISTRY_HOST }}
username: ${{ secrets.ALIYUN_REGISTRY_USERNAME }}
password: ${{ secrets.ALIYUN_REGISTRY_PASSWORD }}
- name: Docker Buildx (build-and-push)
run: |
docker buildx build -f Dockerfile-base --output "type=image,push=true" ${{ steps.prepare.outputs.buildx_args }}
build-and-push-to-dockerhub:
if: ${{ contains(github.event.inputs.registry, 'dockerhub') }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Prepare
id: prepare
run: |
DOCKER_IMAGE=dataease/sqlbot-python-pg
DOCKER_PLATFORMS=${{ github.event.inputs.architecture }}
TAG_NAME=${{ github.event.inputs.dockerImageTag }}
TAG_NAME_WITH_LATEST=${{ github.event.inputs.dockerImageTagWithLatest }}
if [[ ${TAG_NAME_WITH_LATEST} == 'true' ]]; then
DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:${TAG_NAME%%.*} --tag ${DOCKER_IMAGE}:latest"
else
DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME}"
fi
echo ::set-output name=buildx_args::--platform ${DOCKER_PLATFORMS} --memory-swap -1 \
--build-arg DOCKER_IMAGE_TAG=${{ github.event.inputs.dockerImageTag }} --build-arg BUILD_AT=$(TZ=Asia/Shanghai date +'%Y-%m-%dT%H:%M') --build-arg GITHUB_COMMIT=`git rev-parse --short HEAD` --no-cache \
${DOCKER_IMAGE_TAGS} .
- name: Set up Docker Buildx
uses: crazy-max/ghaction-docker-buildx@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker Buildx (build-and-push)
run: |
docker buildx build -f Dockerfile-base --output "type=image,push=true" ${{ steps.prepare.outputs.buildx_args }}
+3 -39
View File
@@ -1,6 +1,6 @@
# Build sqlbot
FROM ghcr.io/1panel-dev/maxkb-vector-model:v1.0.1 AS vector-model
FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-base:latest AS sqlbot-builder
FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-python-pg:latest AS sqlbot-builder
# Set build environment variables
ENV PYTHONUNBUFFERED=1
@@ -36,7 +36,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --extra cpu
# Build g2-ssr
FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-base:latest AS ssr-builder
FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-python-pg:latest AS ssr-builder
WORKDIR /app
@@ -45,44 +45,8 @@ COPY g2-ssr/charts/* /app/charts/
RUN npm install
FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-base:latest AS python-builder
# Runtime stage
# FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-base:latest
FROM registry.cn-qingdao.aliyuncs.com/dataease/postgres:17.6
# python environment
COPY --from=python-builder /usr/local /usr/local
RUN python --version && pip --version
# Install uv tool
COPY --from=ghcr.io/astral-sh/uv:0.7.8 /uv /uvx /bin/
ARG DEPENDENCIES=" \
wait-for-it \
build-essential \
curl \
gnupg \
gcc \
g++ \
libcairo2-dev \
libpango1.0-dev \
libjpeg-dev \
libgif-dev \
librsvg2-dev"
RUN apt-get update && apt-get install -y --no-install-recommends $DEPENDENCIES \
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/* \
&& chmod g-xr /usr/local/bin/* /usr/bin/* /bin/* /usr/sbin/* /sbin/* /usr/lib/postgresql/17/bin/* \
&& chmod g+xr /usr/bin/ld.so \
&& chmod g+x /usr/local/bin/python*
# ENV PGDATA=/var/lib/postgresql/data \
# POSTGRES_USER=root \
# POSTGRES_PASSWORD=Password123@pg \
# POSTGRES_DB=sqlbot
FROM registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-python-pg:latest
# Set runtime environment variables
ENV PYTHONUNBUFFERED=1
+29
View File
@@ -0,0 +1,29 @@
FROM python:3.11-slim-bookworm AS python-builder
FROM registry.cn-qingdao.aliyuncs.com/dataease/postgres:17.6
# python environment
COPY --from=python-builder /usr/local /usr/local
RUN python --version && pip --version
# Install uv tool
COPY --from=ghcr.io/astral-sh/uv:0.7.8 /uv /uvx /bin/
RUN apt-get update && apt-get install -y --no-install-recommends \
wait-for-it \
build-essential \
curl \
gnupg \
gcc \
g++ \
libcairo2-dev \
libpango1.0-dev \
libjpeg-dev \
libgif-dev \
librsvg2-dev \
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs \
&& curl -L --connect-timeout 60 -m 1800 https://fit2cloud-support.oss-cn-beijing.aliyuncs.com/xpack-license/get-validator-linux | sh \
&& rm -rf /var/lib/apt/lists/* \
&& chmod g+xr /usr/bin/ld.so \
&& chmod g+x /usr/local/bin/python*
@@ -63,6 +63,8 @@ const dataObject = computed<{
const assistantStore = useAssistantStore()
const isCompletePage = computed(() => !assistantStore.getAssistant || assistantStore.getEmbedded)
const isAssistant = computed(() => assistantStore.getAssistant)
const chartId = computed(() => props.message?.record?.id + (props.enlarge ? '-fullscreen' : ''))
const data = computed(() => {
@@ -395,7 +397,7 @@ watch(
</div>
</el-popover>
</div>
<div v-if="message?.record?.chart && isCompletePage">
<div v-if="message?.record?.chart && !isAssistant">
<el-tooltip effect="dark" :content="t('chat.add_to_dashboard')" placement="top">
<el-button class="tool-btn" text @click="addToDashboard">
<el-icon size="16">
@@ -864,7 +864,7 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
html2canvas(clonedSlot).then((canvas) => {
img.src = canvas.toDataURL()
infoBox.value.cloneItem.appendChild(img)
infoBox.value.cloneItem?.appendChild(img)
})
if (containerRef.value) {
@@ -994,6 +994,12 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
if (infoBox.value.resizeItem) {
delete infoBox.value.resizeItem.isPlayer
props.resizeEnd(e, infoBox.value.resizeItem, infoBox.value.resizeItem._dragId)
if (infoBox.value.resizeItem.component === 'SQTab') {
const refTabInstance =
currentInstance.refs['shape_component_' + infoBox.value.resizeItem.id][0]
refTabInstance.outResizeEnd()
}
}
if (infoBox.value.moveItem) {
props.dragEnd(e, infoBox.value.moveItem, infoBox.value.moveItem._dragId)
@@ -119,7 +119,12 @@ const beforeHandleCommand = (item: any, param: any) => {
}
}
const isEditMode = computed(() => props.showPosition === 'canvas')
const outResizeEnd = () => {
state.tabShow = false
nextTick(() => {
state.tabShow = true
})
}
const addTabItem = (item: CanvasItem) => {
// do addTabItem
const index = configItem.value.propValue.findIndex(
@@ -168,6 +173,7 @@ onMounted(() => {
defineExpose({
addTabItem,
outResizeEnd,
})
</script>
@@ -224,35 +230,37 @@ defineExpose({
</template>
</el-tab-pane>
</template>
<div
v-for="(tabItem, index) in configItem.propValue"
:key="tabItem.name + '-content'"
class="tab-content-custom"
:class="{ 'switch-hidden': configItem.activeTabName !== tabItem.name }"
>
<SQPreview
v-if="showPosition === 'preview'"
:ref="'tabPreviewRef_' + index"
class="tab-dashboard-preview"
:component-data="tabItem.componentData"
:canvas-view-info="canvasViewInfo"
:base-matrix-count="tabBaseMatrixCount"
:canvas-id="tabItem.name"
></SQPreview>
<DashboardEditor
v-else
:ref="'tabEditorRef_' + index"
class="tab-dashboard-editor-main"
:canvas-component-data="tabItem.componentData"
:canvas-view-info="canvasViewInfo"
:move-in-active="configItem.moveInActive"
:base-matrix-count="tabBaseMatrixCount"
:canvas-id="tabItem.name"
:parent-config-item="configItem"
@parent-add-item-box="(item) => emits('parentAddItemBox', item)"
<template v-if="state.tabShow">
<div
v-for="(tabItem, index) in configItem.propValue"
:key="tabItem.name + '-content'"
class="tab-content-custom"
:class="{ 'switch-hidden': configItem.activeTabName !== tabItem.name }"
>
</DashboardEditor>
</div>
<SQPreview
v-if="showPosition === 'preview'"
:ref="'tabPreviewRef_' + index"
class="tab-dashboard-preview"
:component-data="tabItem.componentData"
:canvas-view-info="canvasViewInfo"
:base-matrix-count="tabBaseMatrixCount"
:canvas-id="tabItem.name"
></SQPreview>
<DashboardEditor
v-else
:ref="'tabEditorRef_' + index"
class="tab-dashboard-editor-main"
:canvas-component-data="tabItem.componentData"
:canvas-view-info="canvasViewInfo"
:move-in-active="configItem.moveInActive"
:base-matrix-count="tabBaseMatrixCount"
:canvas-id="tabItem.name"
:parent-config-item="configItem"
@parent-add-item-box="(item) => emits('parentAddItemBox', item)"
>
</DashboardEditor>
</div>
</template>
</custom-tab>
<el-dialog
v-model="state.dialogVisible"