feat: 添加空白提交功能以确保仓库在列表中顺序活跃,并更新相关逻辑

This commit is contained in:
2026-02-20 15:00:18 +08:00
parent fe3a3cfdc3
commit d85a1cf84b
3 changed files with 60 additions and 6 deletions

View File

@@ -13,7 +13,7 @@ import {
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
} from '@/components/ui/popover' } from '@/components/ui/popover'
import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy } from 'lucide-react' import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info } from 'lucide-react'
import { useRepoStore } from '../store' import { useRepoStore } from '../store'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { myOrgs } from '../store/build' import { myOrgs } from '../store/build'
@@ -32,7 +32,7 @@ interface RepoCardProps {
export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) { export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) {
const [deletePopoverOpen, setDeletePopoverOpen] = useState(false) const [deletePopoverOpen, setDeletePopoverOpen] = useState(false)
const { workspaceList, getWorkspaceDetail, getList } = useRepoStore(); const { workspaceList, getWorkspaceDetail, getList, buildUpdate } = useRepoStore();
const workspace = useMemo(() => { const workspace = useMemo(() => {
return workspaceList.find(ws => ws.slug === repo.path) return workspaceList.find(ws => ws.slug === repo.path)
}, [workspaceList, repo.path]) }, [workspaceList, repo.path])
@@ -56,6 +56,9 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
toast.error('复制失败') toast.error('复制失败')
}) })
} }
const onUpdate = async () => {
await buildUpdate({ path: repo.path });
}
return ( return (
<> <>
<Card className="relative p-0 overflow-hidden border border-neutral-200 bg-white hover:shadow-xl hover:border-neutral-300 transition-all duration-300 group pb-14"> <Card className="relative p-0 overflow-hidden border border-neutral-200 bg-white hover:shadow-xl hover:border-neutral-300 transition-all duration-300 group pb-14">
@@ -136,6 +139,21 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
<BookOpen className="w-4 h-4 mr-2" /> <BookOpen className="w-4 h-4 mr-2" />
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem onClick={() => {
onUpdate()
}} className="cursor-pointer">
<TooltipProvider>
<Tooltip>
<TooltipTrigger className={'flex gap-1 items-center'}>
<Clock className="w-4 h-4 mr-2" />
</TooltipTrigger>
<TooltipContent side="right" className="max-w-xs">
<p> commit </p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</DropdownMenuItem>
<DropdownMenuItem onClick={onClone} className="cursor-pointer"> <DropdownMenuItem onClick={onClone} className="cursor-pointer">
<Copy className="w-4 h-4 mr-2" /> <Copy className="w-4 h-4 mr-2" />
Clone URL Clone URL
@@ -220,7 +238,7 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
)} )}
{repo.description && ( {repo.description && (
<p className="text-sm text-neutral-600 line-clamp-2 min-h-[2.5rem]"> <p className="text-sm text-neutral-600 line-clamp-2 min-h-10">
{repo.description} {repo.description}
</p> </p>
)} )}

View File

@@ -1,5 +1,5 @@
export const myOrgs = ['kevisual', 'kevision', 'skillpod', 'zxj.im', 'abearxiong'] export const myOrgs = ['kevisual', 'kevision', 'skillpod', 'zxj.im', 'abearxiong']
import dayjs from 'dayjs'
export const createBuildConfig = (params: { repo: string }) => { export const createBuildConfig = (params: { repo: string }) => {
const toRepo = params.repo!; const toRepo = params.repo!;
return ` return `
@@ -30,4 +30,23 @@ main:
api_trigger_sync_from_gitea: api_trigger_sync_from_gitea:
- <<: *common_sync_from_gitea - <<: *common_sync_from_gitea
` `
}; };
export const createCommitBlankConfig = (params: { repo?: string, event: 'api_trigger_event' }) => {
const now = dayjs().format('YYYY-MM-DD HH:mm')
const event = params?.event || 'api_trigger_event'
return `main:
${event}:
-
services:
- docker
stages:
- name: 显示 git remote
script: git remote -v
- name: commit_blank
script: |
echo "这是一个空白提交 时间: ${now}"
git commit --allow-empty -m "up: ${now}"
git push
`
}

View File

@@ -3,7 +3,7 @@ import { query } from '@/modules/query';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { cnb } from '@/agents/app' import { cnb } from '@/agents/app'
import { WorkspaceInfo } from '@kevisual/cnb' import { WorkspaceInfo } from '@kevisual/cnb'
import { createBuildConfig } from './build'; import { createBuildConfig, createCommitBlankConfig } from './build';
interface DisplayModule { interface DisplayModule {
activity: boolean; activity: boolean;
contributors: boolean; contributors: boolean;
@@ -82,6 +82,7 @@ type State = {
selectedSyncRepo: Data | null; selectedSyncRepo: Data | null;
setSelectedSyncRepo: (repo: Data | null) => void; setSelectedSyncRepo: (repo: Data | null) => void;
buildSync: (data: Partial<Data>, params: { toRepo?: string, fromRepo?: string }) => Promise<any>; buildSync: (data: Partial<Data>, params: { toRepo?: string, fromRepo?: string }) => Promise<any>;
buildUpdate: (data: Partial<Data>, params?: any) => Promise<any>;
} }
export const useRepoStore = create<State>((set, get) => { export const useRepoStore = create<State>((set, get) => {
@@ -347,6 +348,22 @@ export const useRepoStore = create<State>((set, get) => {
} else { } else {
toast.error(res.message || '同步提交失败') toast.error(res.message || '同步提交失败')
} }
},
buildUpdate: async (data) => {
const res = await cnb.build.startBuild(data.path!, {
branch: 'main',
env: {},
event: 'api_trigger_event',
config: createCommitBlankConfig({ repo: data.path!, event: 'api_trigger_event' }),
})
if (res.code === 200) {
toast.success('更新成功')
setTimeout(() => {
get().refresh({ showTips: false })
}, 5000)
} else {
toast.error(res.message || '更新失败')
}
} }
} }
}) })