github-actions[bot]
Update from GitHub Actions
15ff6c7
raw
history blame
7.7 kB
//https://docs.github.com/en/rest/repos/contents
export const onRequest = async (context: RouteContext): Promise<Response> => {
const request = context.request;
const env = context.env as Env;
// 从 Authorization header 中获取 token
const authHeader = request.headers.get('Authorization');
if (!authHeader || (!authHeader.startsWith('Bearer ') && !authHeader.startsWith('token '))) {
return new Response(JSON.stringify({ error: '未提供有效的授权令牌' }), {
status: 401,
headers: { 'Content-Type': 'application/json' }
});
}
const githubToken = authHeader.startsWith('Bearer ')
? authHeader.replace('Bearer ', '')
: authHeader.replace('token ', '');
console.log('Request URL:', request.url);
try {
const url = new URL(request.url);
// 提取仓库所有者和仓库名称
const pathParts = url.pathname.split('/').filter(Boolean);
const owner = pathParts[2] || url.searchParams.get('owner'); // 仓库所有者
const repo = pathParts[3] || url.searchParams.get('repo'); // 仓库名称
const path = pathParts[4] || url.searchParams.get('path') || ""; // 文件路径
if (!owner || !repo) {
return new Response(JSON.stringify({ error: '缺少仓库所有者或仓库名称' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
// GitHub API 基础 URL
const githubApiBase = 'https://api.github.com';
if (request.method === 'GET') {
const ref = url.searchParams.get('ref'); // 分支或标签
// 获取文件内容或列出目录
const githubUrl = `${githubApiBase}/repos/${owner}/${repo}/contents/${path}${ref ? '?ref=' + ref : ''}`;
console.log(githubUrl);
const response = await fetch(githubUrl, {
headers: {
'Authorization': `token ${githubToken}`,
'Accept': 'application/vnd.github.v3+json',
'User-Agent': 'Cloudflare-Worker'
}
});
const data = await response.json();
return new Response(JSON.stringify(data), {
status: response.status,
headers: { 'Content-Type': 'application/json' }
});
}
if (request.method === 'POST') {
// 创建新文件
const body = await request.json() as any;
const { content, message, branch } = body;
if (!path || content === undefined) {
return new Response(JSON.stringify({ error: '缺少必要参数: path, content' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
// Base64 编码内容
let encodedContent;
try {
// 检查内容是否已经是 Base64 编码
atob(content);
encodedContent = content;
} catch (e) {
// 如果不是,则编码它
encodedContent = btoa(unescape(encodeURIComponent(content)));
}
const githubUrl = `${githubApiBase}/repos/${owner}/${repo}/contents/${path}`;
const response = await fetch(githubUrl, {
method: 'PUT',
headers: {
'Authorization': `token ${githubToken}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
'User-Agent': 'Cloudflare-Worker'
},
body: JSON.stringify({
message: message || `Create file ${path}`,
content: encodedContent,
branch: branch
})
});
const data = await response.json();
return new Response(JSON.stringify(data), {
status: response.status,
headers: { 'Content-Type': 'application/json' }
});
}
if (request.method === 'PUT') {
// 更新现有文件
const body = await request.json() as any;
const { content, message, sha, branch } = body;
if (!path || content === undefined || !sha) {
return new Response(JSON.stringify({ error: '缺少必要参数: path, content, sha' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
// Base64 编码内容
let encodedContent;
try {
atob(content);
encodedContent = content;
} catch (e) {
encodedContent = btoa(unescape(encodeURIComponent(content)));
}
const githubUrl = `${githubApiBase}/repos/${owner}/${repo}/contents/${path}`;
const response = await fetch(githubUrl, {
method: 'PUT',
headers: {
'Authorization': `token ${githubToken}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
'User-Agent': 'Cloudflare-Worker'
},
body: JSON.stringify({
message: message || `Update file ${path}`,
content: encodedContent,
sha: sha,
branch: branch
})
});
const data = await response.json();
return new Response(JSON.stringify(data), {
status: response.status,
headers: { 'Content-Type': 'application/json' }
});
}
if (request.method === 'DELETE') {
const body = await request.json() as any;
// 单个文件删除
const { message, sha, branch } = body;
if (!path || !sha) {
return new Response(JSON.stringify({ error: '缺少必要参数: path, sha' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
const githubUrl = `${githubApiBase}/repos/${owner}/${repo}/contents/${path}`;
const response = await fetch(githubUrl, {
method: 'DELETE',
headers: {
'Authorization': `token ${githubToken}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
'User-Agent': 'Cloudflare-Worker'
},
body: JSON.stringify({
message: message || `Delete file ${path}`,
sha: sha,
branch: branch
})
});
const data = await response.json();
return new Response(JSON.stringify(data), {
status: response.status,
headers: { 'Content-Type': 'application/json' }
});
}
// 不支持的请求方法
return new Response(JSON.stringify({ error: '不支持的请求方法' }), {
status: 405,
headers: { 'Content-Type': 'application/json' }
});
} catch (error: any) {
return new Response(JSON.stringify({ error: '服务器内部错误', details: error.message }), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}
};