semantic-release-minecraft 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.github/workflows/release.yml +43 -0
  2. package/.prettierrc +18 -0
  3. package/.releaserc.json +51 -0
  4. package/CHANGELOG.md +10 -0
  5. package/dist/curseforge.d.ts +4 -0
  6. package/dist/curseforge.d.ts.map +1 -0
  7. package/dist/curseforge.js +131 -0
  8. package/dist/curseforge.js.map +1 -0
  9. package/dist/definitions/curseforge.d.ts +40 -0
  10. package/dist/definitions/curseforge.d.ts.map +1 -0
  11. package/dist/definitions/curseforge.js +6 -0
  12. package/dist/definitions/curseforge.js.map +1 -0
  13. package/dist/definitions/plugin_config.d.ts +49 -0
  14. package/dist/definitions/plugin_config.d.ts.map +1 -0
  15. package/dist/definitions/plugin_config.js +2 -0
  16. package/dist/definitions/plugin_config.js.map +1 -0
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +60 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/modrinth.d.ts +7 -0
  22. package/dist/modrinth.d.ts.map +1 -0
  23. package/dist/modrinth.js +238 -0
  24. package/dist/modrinth.js.map +1 -0
  25. package/dist/prepare.d.ts +11 -0
  26. package/dist/prepare.d.ts.map +1 -0
  27. package/dist/prepare.js +88 -0
  28. package/dist/prepare.js.map +1 -0
  29. package/dist/utils/utils.d.ts +29 -0
  30. package/dist/utils/utils.d.ts.map +1 -0
  31. package/dist/utils/utils.js +92 -0
  32. package/dist/utils/utils.js.map +1 -0
  33. package/eslint.config.js +22 -0
  34. package/package.json +49 -0
  35. package/src/curseforge.ts +192 -0
  36. package/src/definitions/curseforge.ts +51 -0
  37. package/src/definitions/plugin_config.ts +68 -0
  38. package/src/index.ts +98 -0
  39. package/src/modrinth.ts +316 -0
  40. package/src/prepare.ts +199 -0
  41. package/src/utils/utils.ts +120 -0
  42. package/tsconfig.json +25 -0
@@ -0,0 +1,43 @@
1
+ name: Release
2
+ on:
3
+ push:
4
+ branches:
5
+ - master # or main
6
+
7
+ permissions:
8
+ contents: read # for checkout
9
+
10
+ jobs:
11
+ release:
12
+ name: Release
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: write # to be able to publish a GitHub release
16
+ issues: write # to be able to comment on released issues
17
+ pull-requests: write # to be able to comment on released pull requests
18
+ id-token: write # to enable use of OIDC for npm provenance
19
+ steps:
20
+ - name: Checkout
21
+ uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 0
24
+
25
+ - name: Setup Node.js
26
+ uses: actions/setup-node@v4
27
+ with:
28
+ node-version: "lts/*"
29
+
30
+ - name: Install dependencies
31
+ run: npm install
32
+
33
+ - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
34
+ run: npm audit signatures
35
+
36
+ - name: Build
37
+ run: npm run build
38
+
39
+ - name: Release
40
+ env:
41
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
43
+ run: npx semantic-release
package/.prettierrc ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "trailingComma": "es5",
3
+ "tabWidth": 4,
4
+ "singleQuote": true,
5
+ "importOrder": [
6
+ "^(?:@[^/].*|[A-Za-z].*)$",
7
+ "^@/.*$",
8
+ "^[./].*$"
9
+ ],
10
+ "importOrderSortSpecifiers": true,
11
+ "importOrderParserPlugins": [
12
+ "typescript",
13
+ "decorators"
14
+ ],
15
+ "plugins": [
16
+ "@trivago/prettier-plugin-sort-imports"
17
+ ],
18
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "branches": [
3
+ "master"
4
+ ],
5
+ "plugins": [
6
+ "@semantic-release/commit-analyzer",
7
+ [
8
+ "@semantic-release/release-notes-generator",
9
+ {
10
+ "preset": "conventionalcommits",
11
+ "presetConfig": {
12
+ "types": [
13
+ { "type": "feat", "section": "✨ 功能更新" },
14
+ { "type": "fix", "section": "🐛 Bug修复" },
15
+ { "type": "docs", "section": "📚 文档更新" },
16
+ { "type": "style", "section": "💄 样式优化" },
17
+ { "type": "refactor", "section": "♻️ 代码重构" },
18
+ { "type": "perf", "section": "⚡ 性能优化" },
19
+ { "type": "test", "section": "✅ 测试" },
20
+ { "type": "build", "section": "📦 构建" },
21
+ { "type": "ci", "section": "👷 CI/CD" },
22
+ { "type": "chore", "section": "🔧 其他更改" }
23
+ ]
24
+ }
25
+ }
26
+ ],
27
+ "@semantic-release/changelog",
28
+ "@semantic-release/npm",
29
+ [
30
+ "@semantic-release/git",
31
+ {
32
+ "assets": [
33
+ "CHANGELOG.md",
34
+ "package.json"
35
+ ],
36
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
37
+ }
38
+ ]
39
+ ],
40
+ "preset": "angular",
41
+ "releaseRules": [
42
+ {
43
+ "type": "refactor",
44
+ "release": "patch"
45
+ },
46
+ {
47
+ "type": "style",
48
+ "release": "patch"
49
+ }
50
+ ]
51
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ ## 1.0.0 (2025-10-18)
2
+
3
+ ### ✨ 功能更新
4
+
5
+ * basic implementation ([87acefd](https://github.com/pynickle/semantic-release-minecraft/commit/87acefd71ef6e3b3ad7b5d5654894615c49a7980))
6
+
7
+ ### 🔧 其他更改
8
+
9
+ * **package:** add missing dependency for semantic release ([046846b](https://github.com/pynickle/semantic-release-minecraft/commit/046846b6c4380d75c2f2cfeea74c0960a6758315))
10
+ * **workflow:** add github action ([7b0f475](https://github.com/pynickle/semantic-release-minecraft/commit/7b0f475e8aba46deeb366034259a363910ff652e))
@@ -0,0 +1,4 @@
1
+ import { PublishContext } from 'semantic-release';
2
+ import { Plugin_config } from './definitions/plugin_config';
3
+ export declare function publishToCurseforge(pluginConfig: Plugin_config, context: PublishContext, curseforgeGameVersionIds?: number[]): Promise<string>;
4
+ //# sourceMappingURL=curseforge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curseforge.d.ts","sourceRoot":"","sources":["../src/curseforge.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAuD5D,wBAAsB,mBAAmB,CACrC,YAAY,EAAE,aAAa,EAC3B,OAAO,EAAE,cAAc,EACvB,wBAAwB,CAAC,EAAE,MAAM,EAAE,GACpC,OAAO,CAAC,MAAM,CAAC,CA+HjB"}
@@ -0,0 +1,131 @@
1
+ import axios from 'axios';
2
+ import FormData from 'form-data';
3
+ import { readFile } from 'fs/promises';
4
+ import { findFiles, getCurseForgeModLoaders, resolveTemplate, } from './utils/utils';
5
+ /**
6
+ * 为 CurseForge 查找单个文件
7
+ */
8
+ async function findFileCurseforge(pluginConfig, context) {
9
+ const { logger } = context;
10
+ const version = context.nextRelease.version;
11
+ // 获取 CurseForge 的 glob 配置,如果没有则使用全局配置
12
+ const curseforgeGlob = pluginConfig.curseforge?.glob || pluginConfig.glob || [];
13
+ // 查找文件
14
+ const files = await findFiles(curseforgeGlob, context);
15
+ // 如果只找到一个文件,直接返回
16
+ if (files.length === 1) {
17
+ logger.log(`Using the only found file for CurseForge: ${files[0]}`);
18
+ return files[0];
19
+ }
20
+ logger.log(`Found ${files.length} files for CurseForge, trying to filter by version`);
21
+ // 如果有版本号,尝试筛选包含版本号的文件
22
+ if (version) {
23
+ const versionedFiles = files.filter((file) => file.includes(version));
24
+ if (versionedFiles.length === 1) {
25
+ logger.log(`Using versioned file for CurseForge: ${versionedFiles[0]}`);
26
+ return versionedFiles[0];
27
+ }
28
+ else if (versionedFiles.length > 1) {
29
+ throw new Error(`Multiple files found containing version ${version} for CurseForge. Please specify a more specific glob pattern. Found: ${versionedFiles.join(', ')}`);
30
+ }
31
+ }
32
+ // 如果无法筛选出单个文件,报错
33
+ throw new Error(`Multiple files found for CurseForge but could not determine which to use. Found: ${files.join(', ')}`);
34
+ }
35
+ export async function publishToCurseforge(pluginConfig, context, curseforgeGameVersionIds) {
36
+ const { env, logger } = context;
37
+ const { curseforge } = pluginConfig;
38
+ const apiKey = env.CURSEFORGE_TOKEN;
39
+ const projectId = curseforge.project_id;
40
+ const nextRelease = context.nextRelease;
41
+ // 查找单个文件
42
+ const filePath = await findFileCurseforge(pluginConfig, context);
43
+ logger.log(`Publishing file ${filePath} to CurseForge project ${projectId}...`);
44
+ const form = new FormData();
45
+ const file = await readFile(filePath);
46
+ form.append('file', file, {
47
+ filename: filePath.split('\\').pop() || 'mod.jar',
48
+ });
49
+ // 准备 metadata
50
+ // display_name 按照优先级:平台特定配置 > 全局配置 > 平台特定环境变量 > 全局环境变量
51
+ const displayName = resolveTemplate([
52
+ curseforge?.display_name,
53
+ pluginConfig.display_name,
54
+ env.CURSEFORGE_DISPLAY_NAME,
55
+ env.DISPLAY_NAME,
56
+ ], nextRelease);
57
+ // 准备基础 metadata
58
+ const metadata = {
59
+ gameVersions: curseforgeGameVersionIds,
60
+ releaseType: pluginConfig.release_type || 'release',
61
+ changelog: curseforge?.changelog || context.nextRelease.notes,
62
+ changelogType: curseforge?.changelog_type || 'markdown',
63
+ };
64
+ // 只有找到值时才添加 displayName
65
+ if (displayName) {
66
+ metadata.displayName = displayName;
67
+ }
68
+ else {
69
+ // 如果没有找到任何配置,使用默认值
70
+ metadata.displayName = context.nextRelease.name;
71
+ }
72
+ // 添加 metadataModLoaders(如果有值)
73
+ const metadataModLoaders = getCurseForgeModLoaders(pluginConfig, env, nextRelease);
74
+ if (metadataModLoaders) {
75
+ metadata.modLoaders = metadataModLoaders;
76
+ }
77
+ // 只有当提供值时才添加这三个特定字段
78
+ if (curseforge?.parent_file_id !== undefined) {
79
+ metadata.parentFileID = curseforge.parent_file_id;
80
+ }
81
+ if (curseforge?.is_marked_for_manual_release !== undefined) {
82
+ metadata.isMarkedForManualRelease =
83
+ curseforge.is_marked_for_manual_release;
84
+ }
85
+ if (curseforge?.relations && Object.keys(curseforge.relations).length > 0) {
86
+ metadata.relations = curseforge.relations;
87
+ }
88
+ form.append('metadata', JSON.stringify(metadata));
89
+ try {
90
+ const response = await axios.post(`https://upload.curseforge.com/api/projects/${projectId}/upload-file`, form, {
91
+ headers: {
92
+ ...form.getHeaders(),
93
+ 'X-API-Key': apiKey,
94
+ },
95
+ });
96
+ // 验证返回的数据是否包含 id 字段
97
+ if (response.data && typeof response.data.id === 'number') {
98
+ logger.log(`Successfully published to CurseForge: ${response.data.displayName || `File ID: ${response.data.id}`}`);
99
+ return response.data.id.toString();
100
+ }
101
+ else {
102
+ throw new Error(`CurseForge API returned unexpected response: ${JSON.stringify(response.data)}`);
103
+ }
104
+ }
105
+ catch (error) {
106
+ if (error.response) {
107
+ // 服务器返回了错误响应
108
+ const status = error.response.status;
109
+ const data = error.response.data;
110
+ if (data && data.error && data.description) {
111
+ logger.error(`CurseForge API Error (${status}): ${data.error} - ${data.description}`);
112
+ throw new Error(`CurseForge 发布失败:${data.error} - ${data.description}`);
113
+ }
114
+ else {
115
+ logger.error(`CurseForge API Error (${status}): ${JSON.stringify(data)}`);
116
+ throw new Error(`CurseForge 发布失败 (状态码:${status}): ${JSON.stringify(data)}`);
117
+ }
118
+ }
119
+ else if (error.request) {
120
+ // 请求已发送但未收到响应
121
+ logger.error('CurseForge API 请求失败,未收到响应');
122
+ throw new Error('CurseForge 发布失败:未收到服务器响应');
123
+ }
124
+ else {
125
+ // 请求配置出错
126
+ logger.error('CurseForge API 请求配置错误:', error.message);
127
+ throw new Error(`CurseForge 发布失败:${error.message}`);
128
+ }
129
+ }
130
+ }
131
+ //# sourceMappingURL=curseforge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curseforge.js","sourceRoot":"","sources":["../src/curseforge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export interface CurseForgeGameVersion {
2
+ id: number;
3
+ gameVersionTypeID: number;
4
+ name: string;
5
+ slug: string;
6
+ url: string;
7
+ }
8
+ export interface CurseForgeGameVersionType {
9
+ id: number;
10
+ name: string;
11
+ slug: string;
12
+ }
13
+ export interface CurseForgeGameVersionMap {
14
+ /**
15
+ * Minecraft 游戏版本的数组。
16
+ */
17
+ game_versions: CurseForgeGameVersion[];
18
+ /**
19
+ * 主要用于 Bukkit 插件的游戏版本数组。
20
+ */
21
+ game_versions_for_plugins: CurseForgeGameVersion[];
22
+ /**
23
+ * 附加组件的游戏版本数组。
24
+ */
25
+ game_versions_for_addons: CurseForgeGameVersion[];
26
+ /**
27
+ * Java 版本的数组。
28
+ */
29
+ java_versions: CurseForgeGameVersion[];
30
+ /**
31
+ * 模组加载器的游戏版本数组。
32
+ */
33
+ loaders: CurseForgeGameVersion[];
34
+ /**
35
+ * 不同环境的游戏版本数组。
36
+ */
37
+ environments: CurseForgeGameVersion[];
38
+ }
39
+ export declare const BUKKIT_GAME_VERSION_TYPE: CurseForgeGameVersionType;
40
+ //# sourceMappingURL=curseforge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curseforge.d.ts","sourceRoot":"","sources":["../../src/definitions/curseforge.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACrC;;OAEG;IACH,aAAa,EAAE,qBAAqB,EAAE,CAAC;IAEvC;;OAEG;IACH,yBAAyB,EAAE,qBAAqB,EAAE,CAAC;IAEnD;;OAEG;IACH,wBAAwB,EAAE,qBAAqB,EAAE,CAAC;IAElD;;OAEG;IACH,aAAa,EAAE,qBAAqB,EAAE,CAAC;IAEvC;;OAEG;IACH,OAAO,EAAE,qBAAqB,EAAE,CAAC;IAEjC;;OAEG;IACH,YAAY,EAAE,qBAAqB,EAAE,CAAC;CACzC;AAED,eAAO,MAAM,wBAAwB,EAAE,yBAItC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const BUKKIT_GAME_VERSION_TYPE = {
2
+ id: 1,
3
+ name: 'Bukkit',
4
+ slug: 'bukkit',
5
+ };
6
+ //# sourceMappingURL=curseforge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curseforge.js","sourceRoot":"","sources":["../../src/definitions/curseforge.ts"],"names":[],"mappings":"AA8CA,MAAM,CAAC,MAAM,wBAAwB,GAA8B;IAC/D,EAAE,EAAE,CAAC;IACL,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;CACjB,CAAC"}
@@ -0,0 +1,49 @@
1
+ export type Plugin_config = {
2
+ release_type?: 'alpha' | 'beta' | 'release';
3
+ game_versions?: string | string[];
4
+ mod_loaders?: string | string[];
5
+ display_name?: string;
6
+ glob?: string | string[];
7
+ curseforge?: {
8
+ project_id: string;
9
+ game_versions?: string | string[];
10
+ java_versions?: string | string[];
11
+ environments?: string | string[];
12
+ game_versions_for_plugins?: string | string[];
13
+ game_versions_for_addon?: string | string[];
14
+ mod_loaders?: string | string[];
15
+ changelog?: string;
16
+ changelog_type?: 'text' | 'html' | 'markdown';
17
+ display_name?: string;
18
+ parent_file_id?: number;
19
+ is_marked_for_manual_release?: boolean;
20
+ relations?: {
21
+ projects?: Array<{
22
+ slug: string;
23
+ project_id?: string;
24
+ type: 'embedded_library' | 'incompatible' | 'optional_dependency' | 'required_dependency' | 'tool';
25
+ }>;
26
+ };
27
+ glob?: string | string[];
28
+ };
29
+ modrinth?: {
30
+ project_id: string;
31
+ version_number?: string;
32
+ display_name?: string;
33
+ game_versions?: string[];
34
+ mod_loaders?: string[];
35
+ changelog?: string;
36
+ dependencies?: Array<{
37
+ version_id?: string;
38
+ project_id?: string;
39
+ file_name?: string;
40
+ dependency_type: 'required' | 'optional' | 'incompatible' | 'embedded';
41
+ }>;
42
+ featured?: boolean;
43
+ status?: 'listed' | 'archived' | 'draft' | 'unlisted' | 'scheduled' | 'unknown';
44
+ requested_status?: 'listed' | 'archived' | 'draft' | 'unlisted';
45
+ glob?: string | string[];
46
+ primary_file_glob?: string | string[];
47
+ };
48
+ };
49
+ //# sourceMappingURL=plugin_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin_config.d.ts","sourceRoot":"","sources":["../../src/definitions/plugin_config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAExB,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAGzB,UAAU,CAAC,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAClC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAClC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACjC,yBAAyB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC9C,uBAAuB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC5C,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAChC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;QAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,4BAA4B,CAAC,EAAE,OAAO,CAAC;QACvC,SAAS,CAAC,EAAE;YACR,QAAQ,CAAC,EAAE,KAAK,CAAC;gBACb,IAAI,EAAE,MAAM,CAAC;gBACb,UAAU,CAAC,EAAE,MAAM,CAAC;gBACpB,IAAI,EACE,kBAAkB,GAClB,cAAc,GACd,qBAAqB,GACrB,qBAAqB,GACrB,MAAM,CAAC;aAChB,CAAC,CAAC;SACN,CAAC;QACF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,QAAQ,CAAC,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,KAAK,CAAC;YACjB,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,eAAe,EACT,UAAU,GACV,UAAU,GACV,cAAc,GACd,UAAU,CAAC;SACpB,CAAC,CAAC;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EACD,QAAQ,GACR,UAAU,GACV,OAAO,GACP,UAAU,GACV,WAAW,GACX,SAAS,CAAC;QAChB,gBAAgB,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;QAChE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KACzC,CAAC;CACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin_config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin_config.js","sourceRoot":"","sources":["../../src/definitions/plugin_config.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { PrepareContext, PublishContext, VerifyConditionsContext } from 'semantic-release';
2
+ import { Plugin_config } from './definitions/plugin_config';
3
+ export declare function verifyConditions(pluginConfig: Plugin_config, context: VerifyConditionsContext): Promise<void>;
4
+ export declare function prepare(pluginConfig: Plugin_config, context: PrepareContext): Promise<void>;
5
+ export declare function publish(pluginConfig: Plugin_config, context: PublishContext): Promise<{
6
+ url: string;
7
+ }[]>;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,cAAc,EACd,uBAAuB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAO5D,wBAAsB,gBAAgB,CAClC,YAAY,EAAE,aAAa,EAC3B,OAAO,EAAE,uBAAuB,iBAUnC;AAED,wBAAsB,OAAO,CACzB,YAAY,EAAE,aAAa,EAC3B,OAAO,EAAE,cAAc,iBA0B1B;AAED,wBAAsB,OAAO,CACzB,YAAY,EAAE,aAAa,EAC3B,OAAO,EAAE,cAAc,GACxB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAqC5B"}
package/dist/index.js ADDED
@@ -0,0 +1,60 @@
1
+ import { publishToCurseforge } from './curseforge';
2
+ import { publishToModrinth } from './modrinth';
3
+ import { getCurseForgeGameVersionIds } from './prepare';
4
+ // 模块级变量存储 CurseForge 版本映射
5
+ let curseforgeGameVersionsIds;
6
+ export async function verifyConditions(pluginConfig, context) {
7
+ // 验证配置:只检查 project_id,token 通过环境变量验证
8
+ if (pluginConfig.curseforge && !pluginConfig.curseforge.project_id) {
9
+ throw new Error('CurseForge project ID is required');
10
+ }
11
+ if (pluginConfig.modrinth && !pluginConfig.modrinth.project_id) {
12
+ throw new Error('Modrinth project ID is required');
13
+ }
14
+ }
15
+ export async function prepare(pluginConfig, context) {
16
+ const { env, logger } = context;
17
+ if (env.CURSEFORGE_TOKEN) {
18
+ const apiKey = env.CURSEFORGE_TOKEN;
19
+ try {
20
+ logger.log('Fetching CurseForge game versions and types...');
21
+ // 创建版本映射并存储在模块级变量中供后续使用
22
+ curseforgeGameVersionsIds = await getCurseForgeGameVersionIds(apiKey, pluginConfig.curseforge, env, context.nextRelease);
23
+ logger.log(`Successfully transform ${Object.keys(curseforgeGameVersionsIds).length} CurseForge game versions`);
24
+ }
25
+ catch (error) {
26
+ logger.warn(`Failed to fetch CurseForge game versions: ${error instanceof Error ? error.message : 'Unknown error'}`);
27
+ }
28
+ }
29
+ }
30
+ export async function publish(pluginConfig, context) {
31
+ const { env, logger } = context;
32
+ const results = [];
33
+ try {
34
+ if (env.CURSEFORGE_TOKEN) {
35
+ const curseforgeId = await publishToCurseforge(pluginConfig, context, curseforgeGameVersionsIds);
36
+ results.push({
37
+ url: `https://www.curseforge.com/minecraft/mc-mods/${pluginConfig.curseforge.project_id}/files/${curseforgeId}`,
38
+ });
39
+ }
40
+ else {
41
+ logger.log('CurseForge publishing is skipped: CURSEFORGE_TOKEN environment variable not found.');
42
+ }
43
+ // 发布到 Modrinth(如果配置了 Modrinth 且存在环境变量)
44
+ if (env.MODRINTH_TOKEN) {
45
+ const modrinthId = await publishToModrinth(pluginConfig, context);
46
+ results.push({
47
+ url: `https://modrinth.com/mod/${pluginConfig.modrinth.project_id}/version/${modrinthId}`,
48
+ });
49
+ }
50
+ else {
51
+ logger.log('Modrinth publishing is skipped: MODRINTH_TOKEN environment variable not found.');
52
+ }
53
+ return results;
54
+ }
55
+ catch (error) {
56
+ logger.error('Failed to publish:', error);
57
+ throw error;
58
+ }
59
+ }
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { PublishContext } from 'semantic-release';
2
+ import { Plugin_config } from './definitions/plugin_config';
3
+ /**
4
+ * 发布到 Modrinth
5
+ */
6
+ export declare function publishToModrinth(pluginConfig: Plugin_config, context: PublishContext): Promise<string>;
7
+ //# sourceMappingURL=modrinth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modrinth.d.ts","sourceRoot":"","sources":["../src/modrinth.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAQ5D;;GAEG;AACH,wBAAsB,iBAAiB,CACnC,YAAY,EAAE,aAAa,EAC3B,OAAO,EAAE,cAAc,GACxB,OAAO,CAAC,MAAM,CAAC,CA+NjB"}