未验证 提交 5dd70f3c 编写于 作者: Mr.奇淼('s avatar Mr.奇淼( 提交者: GitHub

Bug fix test (#1061)


* fix 腾讯云COS上传配置无效

* Create docker-cicd.yaml

* 修复InitDataFailed 打印bug
Co-authored-by: Ntesun <36953434+tesun@users.noreply.github.com>
Co-authored-by: Ntask <ms.yangdan@gmail.com>
Co-authored-by: Ntask <121913992@qq.com>
Co-authored-by: Ntscuite <tscuite@qq.com>
Co-authored-by: Ntscuite <64051240+tscuite@users.noreply.github.com>
Co-authored-by: Nwyh <yinhua_wu@arcplus.com.cn>
上级 565ddf2e
name: Docker-CICD
on:
push:
branches: [main]
workflow_dispatch:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Login to Aliyun Registry
uses: docker/login-action@v1
with:
registry: ${{ secrets.ALIYUN_REGISTRY }}
username: ${{ secrets.ALIYUN_DOCKERHUB_USER }}
password: ${{ secrets.ALIYUN_DOCKERHUB_PASSWORD }}
- name: Sed Config
shell: bash
run: |
sed -i 's#./entrypoint.sh"#./entrypoint.sh","actions"#g' Dockerfile
sed -i "s#COPY build/ /usr/share/nginx/html/#COPY . /opt/gva#g" Dockerfile
sed -i 16c"\ && cd /opt/gva/server/ && go mod tidy && cd /opt/gva/web/ && yarn" Dockerfile
sed -i "s#open: true#open: false#g" web/vite.config.js
make images TAGS_OPT="latest"
docker push registry.cn-hangzhou.aliyuncs.com/gva/web:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/server:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/all:latest
FROM centos:7
WORKDIR /opt
ENV LANG=en_US.utf8
COPY entrypoint.sh .
COPY build/ /usr/share/nginx/html/
COPY server/config.yaml /usr/share/nginx/html/config.yaml
COPY web/.docker-compose/nginx/conf.d/nginx.conf /etc/nginx/conf.d/nginx.conf
RUN set -ex \
&& echo "LANG=en_US.utf8" > /etc/locale.conf \
&& echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf \
&& echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf \
&& yum -y install yum -y install *epel* \
&& yum -y localinstall http://mirrors.ustc.edu.cn/mysql-repo/mysql57-community-release-el7.rpm \
&& yum -y install mysql-community-server git redis nginx go npm --nogpgcheck && chmod +x ./entrypoint.sh \
&& npm install -g yarn && go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct \
&& echo "start" > /dev/null
EXPOSE 80
ENTRYPOINT ["./entrypoint.sh"]
\ No newline at end of file
SHELL = /bin/bash
CONFIG_FILE = config.yaml
PROJECT_NAME = github.com/flipped-aurora/gin-vue-admin/server
#SCRIPT_DIR = $(shell pwd)/etc/script
BUILD_IMAGE_SERVER = golang:1.16
BUILD_IMAGE_WEB = node:16
IMAGE_NAME = gva
REPOSITORY = registry.cn-hangzhou.aliyuncs.com/${IMAGE_NAME}
ifeq ($(TAGS_OPT),)
TAGS_OPT = 2.5.0b
else
endif
#容器环境前后端共同打包
build: build-web build-server
docker run --name build-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_SERVER} make build-local
#容器环境打包前端
build-web:
docker run --name build-web-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_WEB} make build-web-local
#容器环境打包后端
build-server:
docker run --name build-server-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_SERVER} make build-server-local
#构建web镜像
build-image-web:
@cd web/ && docker build -t ${REPOSITORY}/web:${TAGS_OPT} .
#构建server镜像
build-image-server:
@cd server/ && docker build -t ${REPOSITORY}/server:${TAGS_OPT} .
#本地环境打包前后端
build-local:
if [ -d "build" ];then rm -rf build; else echo "OK!"; fi \
&& if [ -f "/.dockerenv" ];then echo "OK!"; else make build-web-local && make build-server-local; fi \
&& mkdir build && cp -r web/dist build/ && cp server/server build/ && cp -r server/resource build/resource
#本地环境打包前端
build-web-local:
@cd web/ && if [ -d "dist" ];then rm -rf dist; else echo "OK!"; fi \
&& yarn config set registry http://mirrors.cloud.tencent.com/npm/ \
&& yarn install && yarn build
#本地环境打包后端
build-server-local:
@cd server/ && if [ -f "server" ];then rm -rf server; else echo "OK!"; fi \
&& go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct \
&& go env -w CGO_ENABLED=0 && go env && go mod tidy \
&& go build -ldflags "-B 0x$(shell head -c20 /dev/urandom|od -An -tx1|tr -d ' \n') -X main.Version=${TAGS_OPT}" -v
#打包前后端二合一镜像
image: build
docker build -t ${REPOSITORY}/all-one:${TAGS_OPT} .
#尝鲜版
images: build build-image-web build-image-server
docker build -t ${REPOSITORY}/all:${TAGS_OPT} .
\ No newline at end of file
#!/bin/bash
if [ ! -d "/var/lib/mysql/gva" ]; then
mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql
mysqld --daemonize --user=mysql
sleep 5s
mysql -uroot -e "create database gva default charset 'utf8' collate 'utf8_bin'; grant all on gva.* to 'root'@'127.0.0.1' identified by '123456'; flush privileges;"
else
mysqld --daemonize --user=mysql
fi
redis-server &
if [ "$1" = "actions" ]; then
cd /opt/gva/server && go run main.go &
cd /opt/gva/web/ && yarn serve &
else
/usr/sbin/nginx &
cd /usr/share/nginx/html/ && ./server &
fi
echo "gva ALL start!!!"
tail -f /dev/null
\ No newline at end of file
......@@ -81,7 +81,7 @@ func (h MysqlInitHandler) InitData(ctx context.Context, inits initSlice) error {
continue
}
if n, err := init.InitializeData(next); err != nil {
color.Info.Printf(InitDataFailed, Mysql, err)
color.Info.Printf(InitDataFailed, Mysql, init.InitializerName(), err)
return err
} else {
next = n
......
......@@ -80,7 +80,7 @@ func (h PgsqlInitHandler) InitData(ctx context.Context, inits initSlice) error {
continue
}
if n, err := inits[i].InitializeData(next); err != nil {
color.Info.Printf(InitDataFailed, Pgsql, err)
color.Info.Printf(InitDataFailed, Pgsql, inits[i].InitializerName(), err)
return err
} else {
next = n
......
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html/dist;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
try_files $uri $uri/ /index.html;
}
location /api {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^/api/(.*)$ /$1 break; #重写
proxy_pass http://127.0.0.1:8888; # 设置代理服务器的协议和地址
}
location /form-generator {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8888;
}
location /api/swagger/index.html {
proxy_pass http://127.0.0.1:8888/swagger/index.html;
}
}
\ No newline at end of file
<template>
<el-drawer v-model="drawer" title="媒体库" size="650px">
<warning-bar
title="点击“文件名/备注”可以编辑文件名或者备注内容。"
/>
<div class="gva-btn-list">
<upload-common
v-model:imageCommon="imageCommon"
......@@ -61,6 +64,7 @@ import { getFileList, editFileName } from '@/api/fileUploadAndDownload'
import UploadImage from '@/components/upload/image.vue'
import UploadCommon from '@/components/upload/common.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import warningBar from '@/components/warningBar/warningBar.vue'
const imageUrl = ref('')
const imageCommon = ref('')
......@@ -69,7 +73,6 @@ const search = ref({})
const page = ref(1)
const total = ref(0)
const pageSize = ref(20)
const keyword = ref('')
// 分页
const handleSizeChange = (val) => {
......@@ -128,7 +131,7 @@ const editFileNameFunc = async(row) => {
cancelButtonText: '取消',
inputPattern: /\S/,
inputErrorMessage: '不能为空',
inputValue: row.name
inputValue: row.name
}).then(async({ value }) => {
row.name = value
// console.log(row)
......
<template>
<div v-loading.fullscreen.lock="fullscreenLoading">
<div class="gva-table-box">
<warning-bar
title="点击“文件名/备注”可以编辑文件名或者备注内容。"
/>
<div class="gva-btn-list">
<upload-common
v-model:imageCommon="imageCommon"
class="upload-btn"
@on-success="getTableData"
v-model:imageCommon="imageCommon"
class="upload-btn"
@on-success="getTableData"
/>
<upload-image
v-model:imageUrl="imageUrl"
:file-size="512"
:max-w-h="1080"
class="upload-btn"
@on-success="getTableData"
v-model:imageUrl="imageUrl"
:file-size="512"
:max-w-h="1080"
class="upload-btn"
@on-success="getTableData"
/>
<el-form ref="searchForm" :inline="true" :model="search">
<el-form-item label="">
<el-input v-model="search.keyword" class="keyword" placeholder="请输入文件名或备注"/>
<el-input v-model="search.keyword" class="keyword" placeholder="请输入文件名或备注" />
</el-form-item>
<el-form-item>
......@@ -31,7 +33,7 @@
<el-table :data="tableData">
<el-table-column align="left" label="预览" width="100">
<template #default="scope">
<CustomPic pic-type="file" :pic-src="scope.row.url"/>
<CustomPic pic-type="file" :pic-src="scope.row.url" />
</template>
</el-table-column>
<el-table-column align="left" label="日期" prop="UpdatedAt" width="180">
......@@ -41,15 +43,15 @@
</el-table-column>
<el-table-column align="left" label="文件名/备注" prop="name" width="180">
<template #default="scope">
<div class="name" @click="editFileNameFunc(scope.row)">{{scope.row.name}}</div>
<div class="name" @click="editFileNameFunc(scope.row)">{{ scope.row.name }}</div>
</template>
</el-table-column>
<el-table-column align="left" label="链接" prop="url" min-width="300"/>
<el-table-column align="left" label="链接" prop="url" min-width="300" />
<el-table-column align="left" label="标签" prop="tag" width="100">
<template #default="scope">
<el-tag
:type="scope.row.tag === 'jpg' ? 'primary' : 'success'"
disable-transitions
:type="scope.row.tag === 'jpg' ? 'primary' : 'success'"
disable-transitions
>{{ scope.row.tag }}
</el-tag>
</template>
......@@ -63,14 +65,14 @@
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:style="{ float: 'right', padding: '20px' }"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:style="{ float: 'right', padding: '20px' }"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</div>
......@@ -85,6 +87,7 @@ import CustomPic from '@/components/customPic/index.vue'
import UploadImage from '@/components/upload/image.vue'
import UploadCommon from '@/components/upload/common.vue'
import { formatDate } from '@/utils/format'
import warningBar from '@/components/warningBar/warningBar.vue'
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
......@@ -130,25 +133,25 @@ const deleteFileFunc = async(row) => {
cancelButtonText: '取消',
type: 'warning',
})
.then(async() => {
const res = await deleteFile(row)
if (res.code === 0) {
ElMessage({
type: 'success',
message: '删除成功!',
})
if (tableData.value.length === 1 && page.value > 1) {
page.value--
}
getTableData()
}
})
.catch(() => {
.then(async() => {
const res = await deleteFile(row)
if (res.code === 0) {
ElMessage({
type: 'info',
message: '已取消删除',
type: 'success',
message: '删除成功!',
})
if (tableData.value.length === 1 && page.value > 1) {
page.value--
}
getTableData()
}
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消删除',
})
})
}
const downloadFile = (row) => {
......@@ -170,10 +173,10 @@ const editFileNameFunc = async(row) => {
cancelButtonText: '取消',
inputPattern: /\S/,
inputErrorMessage: '不能为空',
inputValue: row.name
inputValue: row.name
}).then(async({ value }) => {
row.name = value;
//console.log(row)
row.name = value
// console.log(row)
const res = await editFileName(row)
if (res.code === 0) {
ElMessage({
......@@ -186,8 +189,8 @@ const editFileNameFunc = async(row) => {
ElMessage({
type: 'info',
message: '取消修改'
});
});
})
})
}
</script>
......@@ -198,9 +201,10 @@ export default {
}
</script>
<style scoped>
.name{
.name {
cursor: pointer;
}
.upload-btn + .upload-btn {
margin-left: 12px;
}
......
......@@ -5,7 +5,11 @@
<el-collapse v-model="activeNames">
<el-collapse-item title="系统配置" name="1">
<el-form-item label="环境值">
<el-input v-model="config.system.env" />
<!-- <el-input v-model="config.system.env" />-->
<el-select v-model="config.system.env" style="width:100%">
<el-option value="public" />
<el-option value="develop" />
</el-select>
</el-form-item>
<el-form-item label="端口值">
<el-input v-model.number="config.system.addr" />
......@@ -79,13 +83,13 @@
</el-form-item>
</el-collapse-item>
<el-collapse-item title="Redis admin数据库配置" name="4">
<el-form-item label="db">
<el-form-item label="">
<el-input v-model="config.redis.db" />
</el-form-item>
<el-form-item label="addr">
<el-form-item label="地址">
<el-input v-model="config.redis.addr" />
</el-form-item>
<el-form-item label="password">
<el-form-item label="密码">
<el-input v-model="config.redis.password" />
</el-form-item>
</el-collapse-item>
......@@ -120,28 +124,28 @@
</el-collapse-item>
<el-collapse-item title="验证码配置" name="7">
<el-form-item label="keyLong">
<el-form-item label="字符长度">
<el-input v-model.number="config.captcha['key-long']" />
</el-form-item>
<el-form-item label="imgWidth">
<el-form-item label="平台宽度">
<el-input v-model.number="config.captcha['img-width']" />
</el-form-item>
<el-form-item label="imgHeight">
<el-form-item label="图片高度">
<el-input v-model.number="config.captcha['img-height']" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="数据库配置" name="9">
<template v-if="config.system['db-type'] === 'mysql'">
<el-form-item label="username">
<el-form-item label="用户名">
<el-input v-model="config.mysql.username" />
</el-form-item>
<el-form-item label="password">
<el-form-item label="密码">
<el-input v-model="config.mysql.password" />
</el-form-item>
<el-form-item label="path">
<el-form-item label="地址">
<el-input v-model="config.mysql.path" />
</el-form-item>
<el-form-item label="dbname">
<el-form-item label="数据库">
<el-input v-model="config.mysql['db-name']" />
</el-form-item>
<el-form-item label="maxIdleConns">
......@@ -150,21 +154,21 @@
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.mysql['max-open-conns']" />
</el-form-item>
<el-form-item label="logMode">
<el-form-item label="日志模式">
<el-checkbox v-model="config.mysql['log-mode']" />
</el-form-item>
</template>
<template v-if="config.system.dbType === 'pgsql'">
<el-form-item label="username">
<el-form-item label="用户名">
<el-input v-model="config.pgsql.username" />
</el-form-item>
<el-form-item label="password">
<el-form-item label="密码">
<el-input v-model="config.pgsql.password" />
</el-form-item>
<el-form-item label="path">
<el-form-item label="地址">
<el-input v-model="config.pgsql.path" />
</el-form-item>
<el-form-item label="dbname">
<el-form-item label="数据库">
<el-input v-model="config.pgsql.dbname" />
</el-form-item>
<el-form-item label="maxIdleConns">
......@@ -173,7 +177,7 @@
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.pgsql['max-open-conns']" />
</el-form-item>
<el-form-item label="logMode">
<el-form-item label="日志模式">
<el-checkbox v-model="config.pgsql['log-mode']" />
</el-form-item>
</template>
......@@ -212,28 +216,28 @@
</template>
<template v-if="config.system['oss-type'] === 'tencent-cos'">
<h2>腾讯云COS上传配置</h2>
<el-form-item label="bucket">
<el-form-item label="存储桶名称">
<el-input v-model="config['tencent-cos']['bucket']" />
</el-form-item>
<el-form-item label="region">
<el-form-item label="所属地域">
<el-input v-model="config['tencent-cos'].region" />
</el-form-item>
<el-form-item label="secretID">
<el-input v-model="config['tencent-cos'].secretID" />
<el-input v-model="config['tencent-cos']['secret-id']" />
</el-form-item>
<el-form-item label="secretKey">
<el-input v-model="config['tencent-cos'].secretKey" />
<el-input v-model="config['tencent-cos']['secret-key']" />
</el-form-item>
<el-form-item label="pathPrefix">
<el-input v-model="config['tencent-cos'].pathPrefix" />
<el-form-item label="路径前缀">
<el-input v-model="config['tencent-cos']['path-prefix']" />
</el-form-item>
<el-form-item label="baseURL">
<el-input v-model="config['tencent-cos'].baseURL" />
<el-form-item label="访问域名">
<el-input v-model="config['tencent-cos']['base-url']" />
</el-form-item>
</template>
<template v-if="config.system['oss-type'] === 'aliyun-oss'">
<h2>阿里云OSS上传配置</h2>
<el-form-item label="endpoint">
<el-form-item label="区域">
<el-input v-model="config['aliyun-oss'].endpoint" />
</el-form-item>
<el-form-item label="accessKeyId">
......@@ -242,22 +246,22 @@
<el-form-item label="accessKeySecret">
<el-input v-model="config['aliyun-oss']['access-key-secret']" />
</el-form-item>
<el-form-item label="bucketName">
<el-form-item label="存储桶名称">
<el-input v-model="config['aliyun-oss']['bucket-name']" />
</el-form-item>
<el-form-item label="bucketUrl">
<el-form-item label="访问域名">
<el-input v-model="config['aliyun-oss']['bucket-url']" />
</el-form-item>
</template>
<template v-if="config.system['oss-type'] === 'huawei-obs'">
<h2>华为云Obs上传配置</h2>
<el-form-item label="path">
<el-form-item label="路径">
<el-input v-model="config['hua-wei-obs'].path" />
</el-form-item>
<el-form-item label="bucket">
<el-form-item label="存储桶名称">
<el-input v-model="config['hua-wei-obs'].bucket" />
</el-form-item>
<el-form-item label="endpoint">
<el-form-item label="区域">
<el-input v-model="config['hua-wei-obs'].endpoint" />
</el-form-item>
<el-form-item label="accessKey">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册