Commit 935aef74 by Archer Committed by GitHub

perf: action (#7231)

* fix: upgrade shell

* doc

* perf: action
parent c24f2667
...@@ -152,30 +152,13 @@ jobs: ...@@ -152,30 +152,13 @@ jobs:
- name: Create manifest list and push - name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests working-directory: ${{ runner.temp }}/digests
timeout-minutes: 30 timeout-minutes: 120
env:
GODEBUG: http2client=0
run: | run: |
retry_imagetools_create() { SOURCES="$(printf 'ghcr.io/${{ github.repository_owner }}/fastgpt-code-sandbox@sha256:%s ' *)"
local tag="$1"
local sources
sources="$(printf 'ghcr.io/${{ github.repository_owner }}/fastgpt-code-sandbox@sha256:%s ' *)"
for attempt in 1 2 3 4 5 6; do
if docker buildx imagetools create -t "$tag" $sources; then
return 0
fi
if [ "$attempt" -eq 6 ]; then
echo "::error::Failed to push manifest ${tag} after 5 retries."
return 1
fi
echo "::warning::Failed to push manifest ${tag}; retrying in $((attempt * 60)) seconds (${attempt}/5)."
sleep $((attempt * 60))
done
}
TAGS="$(echo -e "${Git_Tag}\n${Git_Latest}\n${Ali_Tag}\n${Ali_Latest}")" TAGS="$(echo -e "${Git_Tag}\n${Git_Latest}\n${Ali_Tag}\n${Ali_Latest}")"
for TAG in $TAGS; do for TAG in $TAGS; do
retry_imagetools_create "$TAG" docker buildx imagetools create -t "$TAG" $SOURCES
sleep 5 sleep 5
done done
---
title: 'V4.14.27'
description: 'FastGPT V4.14.27 release notes'
---
## Upgrade Guide
### 1. Update image tags
- Update the fastgpt-app image tag (FastGPT main service): v4.14.27
- Update the fastgpt-pro image tag (FastGPT commercial edition): v4.14.27
## Changes
1. Fixed an issue where the V4.13.2 upgrade script could skip S3 lifecycle cleanup. The script no longer depends on `instanceof MinioStorageAdapter` to detect MinIO clients, avoiding false negatives when workspace packages are loaded as separate module instances in Next.js dev or bundled runtimes.
2. Fixed the image migration log resource type in the V4.14.3 upgrade script by changing `data_image` to `dataset_image`, so completed image migrations can be recognized correctly.
3. Fixed the completed-image migration filter in the V4.14.4 upgrade script to also use `dataset_image`, preventing already migrated images from being migrated again when the script is rerun.
---
title: 'V4.14.27'
description: 'FastGPT V4.14.27 更新说明'
---
## 升级指南
### 1. 更新镜像 tag
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.27
- 更新 fastgpt-pro(fastgpt 商业版) 镜像 tag: v4.14.27
## 变更说明
该版本修复一些历史升级脚本问题,由于近期变更导致旧的升级脚本无法正常使用。
1. 修复 V4.13.2 升级脚本中 S3 lifecycle 清理可能被跳过的问题。该脚本不再依赖 `instanceof MinioStorageAdapter` 判断 MinIO 客户端,避免 Next.js dev 或 bundle 场景下 workspace package 被加载为不同模块实例导致误判。
2. 修复 V4.14.3 升级脚本中图片迁移日志的资源类型,将 `data_image` 修正为 `dataset_image`,避免已完成的图片迁移记录无法被正确识别。
3. 修复 V4.14.4 升级脚本中图片迁移已完成记录的过滤条件,同样使用 `dataset_image`,避免重复执行脚本时再次迁移已完成的图片。
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
"title": "4.14.x", "title": "4.14.x",
"description": "", "description": "",
"pages": [ "pages": [
"41427",
"41426", "41426",
"41425", "41425",
"41424", "41424",
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
"title": "4.14.x", "title": "4.14.x",
"description": "", "description": "",
"pages": [ "pages": [
"41427",
"41426", "41426",
"41425", "41425",
"41424", "41424",
......
...@@ -141,6 +141,7 @@ description: FastGPT Toc ...@@ -141,6 +141,7 @@ description: FastGPT Toc
- [/en/self-host/upgrading/4-14/41424](/en/self-host/upgrading/4-14/41424) - [/en/self-host/upgrading/4-14/41424](/en/self-host/upgrading/4-14/41424)
- [/en/self-host/upgrading/4-14/41425](/en/self-host/upgrading/4-14/41425) - [/en/self-host/upgrading/4-14/41425](/en/self-host/upgrading/4-14/41425)
- [/en/self-host/upgrading/4-14/41426](/en/self-host/upgrading/4-14/41426) - [/en/self-host/upgrading/4-14/41426](/en/self-host/upgrading/4-14/41426)
- [/en/self-host/upgrading/4-14/41427](/en/self-host/upgrading/4-14/41427)
- [/en/self-host/upgrading/4-14/4143](/en/self-host/upgrading/4-14/4143) - [/en/self-host/upgrading/4-14/4143](/en/self-host/upgrading/4-14/4143)
- [/en/self-host/upgrading/4-14/4144](/en/self-host/upgrading/4-14/4144) - [/en/self-host/upgrading/4-14/4144](/en/self-host/upgrading/4-14/4144)
- [/en/self-host/upgrading/4-14/4145](/en/self-host/upgrading/4-14/4145) - [/en/self-host/upgrading/4-14/4145](/en/self-host/upgrading/4-14/4145)
......
...@@ -143,6 +143,7 @@ description: FastGPT 文档目录 ...@@ -143,6 +143,7 @@ description: FastGPT 文档目录
- [/self-host/upgrading/4-14/41424](/self-host/upgrading/4-14/41424) - [/self-host/upgrading/4-14/41424](/self-host/upgrading/4-14/41424)
- [/self-host/upgrading/4-14/41425](/self-host/upgrading/4-14/41425) - [/self-host/upgrading/4-14/41425](/self-host/upgrading/4-14/41425)
- [/self-host/upgrading/4-14/41426](/self-host/upgrading/4-14/41426) - [/self-host/upgrading/4-14/41426](/self-host/upgrading/4-14/41426)
- [/self-host/upgrading/4-14/41427](/self-host/upgrading/4-14/41427)
- [/self-host/upgrading/4-14/4143](/self-host/upgrading/4-14/4143) - [/self-host/upgrading/4-14/4143](/self-host/upgrading/4-14/4143)
- [/self-host/upgrading/4-14/4144](/self-host/upgrading/4-14/4144) - [/self-host/upgrading/4-14/4144](/self-host/upgrading/4-14/4144)
- [/self-host/upgrading/4-14/4145](/self-host/upgrading/4-14/4145) - [/self-host/upgrading/4-14/4145](/self-host/upgrading/4-14/4145)
......
...@@ -181,8 +181,8 @@ ...@@ -181,8 +181,8 @@
"content/self-host/config/remote-debug-suite.mdx": "2026-06-27T22:05:51+08:00", "content/self-host/config/remote-debug-suite.mdx": "2026-06-27T22:05:51+08:00",
"content/self-host/config/sandbox/common.en.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/config/sandbox/common.en.mdx": "2026-06-30T22:10:03+08:00",
"content/self-host/config/sandbox/common.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/config/sandbox/common.mdx": "2026-06-30T22:10:03+08:00",
"content/self-host/config/sandbox/opensandbox.en.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/config/sandbox/opensandbox.en.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/config/sandbox/opensandbox.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/config/sandbox/opensandbox.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/config/sandbox/sealosdevbox.en.mdx": "2026-06-30T14:56:33+08:00", "content/self-host/config/sandbox/sealosdevbox.en.mdx": "2026-06-30T14:56:33+08:00",
"content/self-host/config/sandbox/sealosdevbox.mdx": "2026-06-30T14:56:33+08:00", "content/self-host/config/sandbox/sealosdevbox.mdx": "2026-06-30T14:56:33+08:00",
"content/self-host/config/signoz.en.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/config/signoz.en.mdx": "2026-04-26T21:08:47+08:00",
...@@ -296,10 +296,10 @@ ...@@ -296,10 +296,10 @@
"content/self-host/upgrading/4-14/41481.en.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/4-14/41481.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/4-14/41481.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/4-14/41481.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/4-14/4149.en.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/4-14/4149.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/4-14/4149.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/4-14/4149.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/upgrading/4-15/41500.en.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/upgrading/4-15/41500.en.mdx": "2026-06-30T22:10:03+08:00",
"content/self-host/upgrading/4-15/41500.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/upgrading/4-15/41500.mdx": "2026-06-30T22:10:03+08:00",
"content/self-host/upgrading/4-15/41501.mdx": "2026-06-23T21:09:39+08:00", "content/self-host/upgrading/4-15/41501.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/upgrading/4-15/41502.en.mdx": "2026-05-25T11:21:30+08:00", "content/self-host/upgrading/4-15/41502.en.mdx": "2026-05-25T11:21:30+08:00",
"content/self-host/upgrading/4-15/41502.mdx": "2026-06-23T13:54:06+08:00", "content/self-host/upgrading/4-15/41502.mdx": "2026-06-23T13:54:06+08:00",
"content/self-host/upgrading/4-15/41503.en.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/upgrading/4-15/41503.en.mdx": "2026-06-30T22:10:03+08:00",
...@@ -307,11 +307,13 @@ ...@@ -307,11 +307,13 @@
"content/self-host/upgrading/4-15/41504.en.mdx": "2026-06-10T19:02:59+08:00", "content/self-host/upgrading/4-15/41504.en.mdx": "2026-06-10T19:02:59+08:00",
"content/self-host/upgrading/4-15/41504.mdx": "2026-06-15T23:34:43+08:00", "content/self-host/upgrading/4-15/41504.mdx": "2026-06-15T23:34:43+08:00",
"content/self-host/upgrading/4-15/41505.en.mdx": "2026-06-29T10:49:24+08:00", "content/self-host/upgrading/4-15/41505.en.mdx": "2026-06-29T10:49:24+08:00",
"content/self-host/upgrading/4-15/41505.mdx": "2026-06-29T10:45:58+08:00", "content/self-host/upgrading/4-15/41505.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/upgrading/4-15/41506.en.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/upgrading/4-15/41506.en.mdx": "2026-06-30T22:10:03+08:00",
"content/self-host/upgrading/4-15/41506.mdx": "2026-06-30T22:10:03+08:00", "content/self-host/upgrading/4-15/41506.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/upgrading/4-15/41507.en.mdx": "2026-06-30T17:31:43+08:00", "content/self-host/upgrading/4-15/41507.en.mdx": "2026-06-30T17:31:43+08:00",
"content/self-host/upgrading/4-15/41507.mdx": "2026-06-30T17:31:43+08:00", "content/self-host/upgrading/4-15/41507.mdx": "2026-06-30T17:31:43+08:00",
"content/self-host/upgrading/4-15/4151.en.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/upgrading/4-15/4151.mdx": "2026-07-01T12:13:58+08:00",
"content/self-host/upgrading/outdated/40.en.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/outdated/40.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/outdated/40.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/outdated/40.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/outdated/41.en.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/outdated/41.en.mdx": "2026-04-26T21:08:47+08:00",
...@@ -452,6 +454,6 @@ ...@@ -452,6 +454,6 @@
"content/self-host/upgrading/outdated/499.mdx": "2026-05-07T15:06:40+08:00", "content/self-host/upgrading/outdated/499.mdx": "2026-05-07T15:06:40+08:00",
"content/self-host/upgrading/upgrade-intruction.en.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/upgrade-intruction.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/upgrade-intruction.mdx": "2026-04-26T21:08:47+08:00", "content/self-host/upgrading/upgrade-intruction.mdx": "2026-04-26T21:08:47+08:00",
"content/toc.en.mdx": "2026-06-30T22:10:03+08:00", "content/toc.en.mdx": "2026-07-01T12:13:58+08:00",
"content/toc.mdx": "2026-06-30T22:10:03+08:00" "content/toc.mdx": "2026-07-01T12:13:58+08:00"
} }
\ No newline at end of file
...@@ -2,7 +2,14 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -2,7 +2,14 @@ import { NextAPI } from '@/service/middleware/entry';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { type NextApiRequest, type NextApiResponse } from 'next'; import { type NextApiRequest, type NextApiResponse } from 'next';
import { S3Buckets } from '@fastgpt/service/common/s3/config/constants'; import { S3Buckets } from '@fastgpt/service/common/s3/config/constants';
import { MinioStorageAdapter } from '@fastgpt-sdk/storage';
type BucketLifecycleRemovableClient = {
removeBucketLifecycle: () => Promise<void>;
};
const hasRemoveBucketLifecycle = (client: unknown): client is BucketLifecycleRemovableClient =>
typeof (client as Partial<BucketLifecycleRemovableClient> | undefined)?.removeBucketLifecycle ===
'function';
// 将 S3 原先的 circleLife 策略全部去掉 // 将 S3 原先的 circleLife 策略全部去掉
async function handler(req: NextApiRequest, _res: NextApiResponse) { async function handler(req: NextApiRequest, _res: NextApiResponse) {
...@@ -15,14 +22,15 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { ...@@ -15,14 +22,15 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) {
const publicClient = global.s3BucketMap[S3Buckets.public].client; const publicClient = global.s3BucketMap[S3Buckets.public].client;
const privateClient = global.s3BucketMap[S3Buckets.private].client; const privateClient = global.s3BucketMap[S3Buckets.private].client;
if (publicClient instanceof MinioStorageAdapter) { // Next dev / bundle 场景下 workspace package 可能被加载为不同模块实例,instanceof 会误判。
if (hasRemoveBucketLifecycle(publicClient)) {
await publicClient.removeBucketLifecycle(); await publicClient.removeBucketLifecycle();
} }
if (privateClient instanceof MinioStorageAdapter) { if (hasRemoveBucketLifecycle(privateClient)) {
await privateClient.removeBucketLifecycle(); await privateClient.removeBucketLifecycle();
} }
return {}; return;
} }
export default NextAPI(handler); export default NextAPI(handler);
...@@ -550,7 +550,7 @@ async function processImageBatch({ ...@@ -550,7 +550,7 @@ async function processImageBatch({
// 3. 过滤已完成的 // 3. 过滤已完成的
const completedMigrations = await MongoDatasetMigrationLog.find( const completedMigrations = await MongoDatasetMigrationLog.find(
{ {
resourceType: 'data_image', resourceType: 'dataset_image',
resourceId: { $in: dataList.map((d) => d._id) }, resourceId: { $in: dataList.map((d) => d._id) },
status: 'completed' status: 'completed'
}, },
...@@ -603,7 +603,7 @@ async function processImageBatch({ ...@@ -603,7 +603,7 @@ async function processImageBatch({
const imageMigrationLogs = imageDataPairs.map(({ data, imageFile }) => ({ const imageMigrationLogs = imageDataPairs.map(({ data, imageFile }) => ({
batchId, batchId,
migrationVersion, migrationVersion,
resourceType: 'data_image' as const, resourceType: 'dataset_image' as const,
resourceId: data._id, resourceId: data._id,
teamId: data.teamId, teamId: data.teamId,
datasetId: data.datasetId, datasetId: data.datasetId,
...@@ -931,7 +931,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { ...@@ -931,7 +931,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) {
const totalCollectionFiles = await getGFSCollection('dataset').countDocuments({}); const totalCollectionFiles = await getGFSCollection('dataset').countDocuments({});
logger.info(`[Migration ${batchId}] Total collection files in GridFS: ${totalCollectionFiles}`); logger.info(`[Migration ${batchId}] Total collection files in GridFS: ${totalCollectionFiles}`);
let collectionStats = { const collectionStats = {
processed: 0, processed: 0,
succeeded: 0, succeeded: 0,
failed: 0, failed: 0,
...@@ -979,7 +979,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { ...@@ -979,7 +979,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) {
const totalImageFiles = await getDatasetImageGFSCollection().countDocuments({}); const totalImageFiles = await getDatasetImageGFSCollection().countDocuments({});
logger.info(`[Migration ${batchId}] Total image files in GridFS: ${totalImageFiles}`); logger.info(`[Migration ${batchId}] Total image files in GridFS: ${totalImageFiles}`);
let imageStats = { const imageStats = {
processed: 0, processed: 0,
succeeded: 0, succeeded: 0,
failed: 0, failed: 0,
......
...@@ -498,7 +498,7 @@ async function processImageBatch({ ...@@ -498,7 +498,7 @@ async function processImageBatch({
// 3. 过滤已完成的 // 3. 过滤已完成的
const completedMigrations = await MongoDatasetMigrationLog.find( const completedMigrations = await MongoDatasetMigrationLog.find(
{ {
resourceType: 'data_image', resourceType: 'dataset_image',
resourceId: { $in: dataList.map((d) => d._id) }, resourceId: { $in: dataList.map((d) => d._id) },
status: 'completed' status: 'completed'
}, },
...@@ -881,7 +881,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { ...@@ -881,7 +881,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) {
}); });
logger.info(`[Migration ${batchId}] Total collection files in GridFS: ${totalCollectionFiles}`); logger.info(`[Migration ${batchId}] Total collection files in GridFS: ${totalCollectionFiles}`);
let collectionStats = { const collectionStats = {
processed: 0, processed: 0,
succeeded: 0, succeeded: 0,
failed: 0, failed: 0,
...@@ -929,7 +929,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { ...@@ -929,7 +929,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) {
const totalImageFiles = await getDatasetImageGFSCollection().countDocuments({}); const totalImageFiles = await getDatasetImageGFSCollection().countDocuments({});
logger.info(`[Migration ${batchId}] Total image files in GridFS: ${totalImageFiles}`); logger.info(`[Migration ${batchId}] Total image files in GridFS: ${totalImageFiles}`);
let imageStats = { const imageStats = {
processed: 0, processed: 0,
succeeded: 0, succeeded: 0,
failed: 0, failed: 0,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment