Skip to content

Commit d68c7ec

Browse files
committed
feat: gen public action
1 parent f0d1298 commit d68c7ec

4 files changed

Lines changed: 216 additions & 1 deletion

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Generate Action List
2+
3+
on:
4+
push:
5+
branches:
6+
- chore/pure_doc_skill
7+
paths:
8+
- 'config/.claude/skills/cloudbase-api-direct/references/**'
9+
- 'scripts/generate-actionlist.ts'
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
generate:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
with:
23+
token: ${{ secrets.GITHUB_TOKEN }}
24+
25+
- name: Setup Node.js
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: '20'
29+
30+
- name: Generate actionlist.ts
31+
run: npx tsx scripts/generate-actionlist.ts
32+
33+
- name: Check for changes
34+
id: changes
35+
run: |
36+
# 检查文件是否有变更(包括新文件和修改)
37+
if git status --porcelain config/.claude/skills/cloudbase-api-direct/scripts/lib/src/action-list.ts | grep -q .; then
38+
echo "changed=true" >> $GITHUB_OUTPUT
39+
fi
40+
41+
- name: Commit and push
42+
if: steps.changes.outputs.changed == 'true'
43+
run: |
44+
git config user.name "github-actions[bot]"
45+
git config user.email "github-actions[bot]@users.noreply.github.com"
46+
git add config/.claude/skills/cloudbase-api-direct/scripts/lib/src/action-list.ts
47+
git commit -m "chore: 🔄 update action-list.ts [skip ci]"
48+
git pull --rebase
49+
git push
50+
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* 自动生成的 TCB 对外 API Action 列表
3+
* 从 references/ 目录下的文档中提取
4+
*
5+
* ⚠️ 请勿手动编辑此文件,由 scripts/generate-actionlist.ts 自动生成
6+
*
7+
* Action 数量: 51
8+
*/
9+
10+
const TCB_ALLOWED_ACTIONS: string[] = [
11+
'BindCloudBaseAccessDomain',
12+
'BindCloudBaseGWDomain',
13+
'CheckTcbService',
14+
'CreateAuthDomain',
15+
'CreateBillDeal',
16+
'CreateCloudBaseGWAPI',
17+
'CreateEnv',
18+
'CreateHostingDomain',
19+
'CreateMySQL',
20+
'CreateStaticStore',
21+
'CreateTable',
22+
'CreateUser',
23+
'DeleteCloudBaseGWAPI',
24+
'DeleteCloudBaseGWDomain',
25+
'DeleteTable',
26+
'DeleteUsers',
27+
'DescribeAuthDomains',
28+
'DescribeBaasPackageList',
29+
'DescribeCloudBaseBuildService',
30+
'DescribeCloudBaseGWAPI',
31+
'DescribeCloudBaseGWService',
32+
'DescribeCreateMySQLResult',
33+
'DescribeDatabaseACL',
34+
'DescribeEnvAccountCircle',
35+
'DescribeEnvLimit',
36+
'DescribeEnvs',
37+
'DescribeHostingDomainTask',
38+
'DescribeMySQLClusterDetail',
39+
'DescribeMySQLTaskStatus',
40+
'DescribeQuotaData',
41+
'DescribeSafeRule',
42+
'DescribeStaticStore',
43+
'DescribeTable',
44+
'DescribeTables',
45+
'DescribeUserList',
46+
'DestroyEnv',
47+
'DestroyMySQL',
48+
'DestroyStaticStore',
49+
'EditAuthConfig',
50+
'ListTables',
51+
'ModifyCloudBaseGWAPI',
52+
'ModifyClsTopic',
53+
'ModifyDatabaseACL',
54+
'ModifyEnv',
55+
'ModifyEnvPlan',
56+
'ModifyUser',
57+
'ReinstateEnv',
58+
'RenewEnv',
59+
'RunSql',
60+
'SearchClsLog',
61+
'UpdateTable',
62+
];
63+
64+
export default TCB_ALLOWED_ACTIONS;

config/.claude/skills/cloudbase-api-direct/scripts/lib/src/tcb-api.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
import CloudBase from './index'
19+
import TCB_ALLOWED_ACTIONS from './action-list'
1920

2021
interface CliArgs {
2122
action: string
@@ -162,8 +163,14 @@ async function main() {
162163

163164
try {
164165
if (service === 'tcb') {
166+
// 1. 检查是否在允许列表中(从文档提取的对外 API)
167+
if (!TCB_ALLOWED_ACTIONS.includes(action)) {
168+
console.error(`❌ ${action} 不在允许的 TCB API 列表中,可能是未公开的 API`)
169+
process.exit(1)
170+
}
171+
// 2. 检查是否在禁止列表中(即使在文档里,但我们不允许使用)
165172
if (tcbCapiForbidList.includes(action)) {
166-
console.error(`❌ ${service}/${action} 云API未对外或不存在,请使用其他API`)
173+
console.error(`❌ ${action} 云API未对外或已禁止使用,请使用其他API`)
167174
process.exit(1)
168175
}
169176
}

scripts/generate-actionlist.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env npx tsx
2+
/**
3+
* 从 references/ 目录提取所有 TCB API Action 列表
4+
* 生成 action-list.ts 文件
5+
*/
6+
7+
import * as fs from 'fs';
8+
import * as path from 'path';
9+
10+
const REFERENCES_DIR = path.join(__dirname, '../config/.claude/skills/cloudbase-api-direct/references');
11+
const OUTPUT_FILE = path.join(__dirname, '../config/.claude/skills/cloudbase-api-direct/scripts/lib/src/action-list.ts');
12+
13+
async function extractActions(): Promise<string[]> {
14+
// 多种匹配模式
15+
const patterns = [
16+
/X-TC-Action:\s*(\w+)/g, // X-TC-Action: ActionName
17+
/(\w+)/g, // 本接口取值:ActionName。
18+
/Action=(\w+)/g, // Action=ActionName (URL 参数)
19+
];
20+
21+
// 需要跳过的文件(非具体 API 文档)
22+
const skipFiles = ['README.md', 'API-概览', '公共参数'];
23+
24+
// 读取并过滤文件
25+
const files = fs.readdirSync(REFERENCES_DIR)
26+
.filter(f => f.endsWith('.md'))
27+
.filter(f => !skipFiles.some(skip => f.includes(skip)));
28+
29+
// 并行读取文件并提取 action
30+
const results = await Promise.all(
31+
files.map(async (file) => {
32+
const content = await fs.promises.readFile(path.join(REFERENCES_DIR, file), 'utf-8');
33+
const actions: string[] = [];
34+
35+
for (const pattern of patterns) {
36+
const regex = new RegExp(pattern.source, pattern.flags);
37+
let match;
38+
while ((match = regex.exec(content)) !== null) {
39+
actions.push(match[1]);
40+
}
41+
}
42+
43+
return actions;
44+
})
45+
);
46+
47+
// 合并去重排序
48+
return [...new Set(results.flat())].sort();
49+
}
50+
51+
function generateFile(actions: string[]): string {
52+
const content = `/**
53+
* 自动生成的 TCB 对外 API Action 列表
54+
* 从 references/ 目录下的文档中提取
55+
*
56+
* ⚠️ 请勿手动编辑此文件,由 scripts/generate-actionlist.ts 自动生成
57+
*
58+
* Action 数量: ${actions.length}
59+
*/
60+
61+
const TCB_ALLOWED_ACTIONS: string[] = [
62+
${actions.map(a => ` '${a}',`).join('\n')}
63+
];
64+
65+
export default TCB_ALLOWED_ACTIONS;
66+
`;
67+
68+
return content;
69+
}
70+
71+
async function main() {
72+
console.log('📖 扫描 references 目录...');
73+
const actions = await extractActions();
74+
console.log(`✅ 提取到 ${actions.length} 个 Action`);
75+
76+
console.log('📝 生成 action-list.ts...');
77+
const content = generateFile(actions);
78+
79+
// 确保输出目录存在
80+
const outputDir = path.dirname(OUTPUT_FILE);
81+
if (!fs.existsSync(outputDir)) {
82+
fs.mkdirSync(outputDir, { recursive: true });
83+
}
84+
85+
fs.writeFileSync(OUTPUT_FILE, content, 'utf-8');
86+
console.log(`✅ 已生成: ${OUTPUT_FILE}`);
87+
88+
// 打印 action 列表
89+
console.log('\n📋 Action 列表:');
90+
actions.forEach(a => console.log(` - ${a}`));
91+
}
92+
93+
main();
94+

0 commit comments

Comments
 (0)