@voxelio/deploy 1.0.1 → 1.0.3
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.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/workflow-D_9q4YIy.js +2 -0
- package/dist/workflow-D_9q4YIy.js.map +1 -0
- package/examples/deploy.yml +456 -456
- package/examples/happy-pandas-dance.md +10 -10
- package/package.json +2 -2
- package/dist/workflow-JsUijDQh.js +0 -2
- package/dist/workflow-JsUijDQh.js.map +0 -1
package/examples/deploy.yml
CHANGED
|
@@ -1,456 +1,456 @@
|
|
|
1
|
-
name: Deploy
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
paths:
|
|
6
|
-
- '.changeset/*.md'
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
deploy:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
permissions:
|
|
12
|
-
contents: write
|
|
13
|
-
|
|
14
|
-
steps:
|
|
15
|
-
- name: Checkout
|
|
16
|
-
uses: actions/checkout@v4
|
|
17
|
-
with:
|
|
18
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
19
|
-
fetch-depth: 0
|
|
20
|
-
|
|
21
|
-
- name: Setup Node.js
|
|
22
|
-
uses: actions/setup-node@v4
|
|
23
|
-
with:
|
|
24
|
-
node-version: '20'
|
|
25
|
-
|
|
26
|
-
- name: Setup Python
|
|
27
|
-
uses: actions/setup-python@v5
|
|
28
|
-
with:
|
|
29
|
-
python-version: '3.11'
|
|
30
|
-
|
|
31
|
-
- name: Install dependencies
|
|
32
|
-
run: pip install pyyaml
|
|
33
|
-
|
|
34
|
-
- name: Detect changeset
|
|
35
|
-
id: changeset
|
|
36
|
-
run: |
|
|
37
|
-
CHANGESET_FILE=$(find .changeset -name "*.md" -type f | head -n 1)
|
|
38
|
-
if [ -z "$CHANGESET_FILE" ]; then
|
|
39
|
-
echo "found=false" >> $GITHUB_OUTPUT
|
|
40
|
-
exit 0
|
|
41
|
-
fi
|
|
42
|
-
echo "found=true" >> $GITHUB_OUTPUT
|
|
43
|
-
echo "file=$CHANGESET_FILE" >> $GITHUB_OUTPUT
|
|
44
|
-
|
|
45
|
-
- name: Parse changeset
|
|
46
|
-
id: parse
|
|
47
|
-
if: steps.changeset.outputs.found == 'true'
|
|
48
|
-
run: |
|
|
49
|
-
python - <<'EOF'
|
|
50
|
-
import re, json, os, yaml
|
|
51
|
-
|
|
52
|
-
with open("${{ steps.changeset.outputs.file }}", 'r') as f:
|
|
53
|
-
content = f.read()
|
|
54
|
-
|
|
55
|
-
match = re.match(r'^---\n(.*?)\n---\n(.*)$', content, re.DOTALL)
|
|
56
|
-
if not match:
|
|
57
|
-
exit(1)
|
|
58
|
-
|
|
59
|
-
frontmatter = yaml.safe_load(match.group(1))
|
|
60
|
-
changelog = match.group(2).strip()
|
|
61
|
-
|
|
62
|
-
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
63
|
-
f.write(f"game_versions={json.dumps(frontmatter.get('game_versions', []))}\n")
|
|
64
|
-
f.write(f"loaders={json.dumps(frontmatter.get('loaders', None)) if frontmatter.get('loaders') else 'null'}\n")
|
|
65
|
-
f.write(f"version_type={frontmatter.get('version_type', 'release')}\n")
|
|
66
|
-
f.write(f"version_bump={frontmatter.get('version_bump', 'patch')}\n")
|
|
67
|
-
f.write(f"changelog<<EOF\n{changelog}\nEOF\n")
|
|
68
|
-
EOF
|
|
69
|
-
|
|
70
|
-
- name: Read config
|
|
71
|
-
id: config
|
|
72
|
-
if: steps.changeset.outputs.found == 'true'
|
|
73
|
-
run: |
|
|
74
|
-
python - <<'EOF'
|
|
75
|
-
import yaml, json, os
|
|
76
|
-
|
|
77
|
-
with open('deploy.yaml', 'r') as f:
|
|
78
|
-
config = yaml.safe_load(f)
|
|
79
|
-
|
|
80
|
-
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
81
|
-
f.write(f"current_version={config['project']['version']}\n")
|
|
82
|
-
f.write(f"project_name={config['project']['name']}\n")
|
|
83
|
-
f.write(f"project_filename={config['project']['filename']}\n")
|
|
84
|
-
f.write(f"modrinth_enabled={str(config['modrinth']['enabled']).lower()}\n")
|
|
85
|
-
f.write(f"modrinth_project_id={config['modrinth']['project_id']}\n")
|
|
86
|
-
f.write(f"modrinth_featured={str(config['modrinth'].get('featured', False)).lower()}\n")
|
|
87
|
-
f.write(f"curseforge_datapack_enabled={str(config['curseforge']['datapack']['enabled']).lower()}\n")
|
|
88
|
-
f.write(f"curseforge_datapack_id={config['curseforge']['datapack'].get('project_id', '')}\n")
|
|
89
|
-
f.write(f"curseforge_mod_enabled={str(config['curseforge']['mod']['enabled']).lower()}\n")
|
|
90
|
-
f.write(f"curseforge_mod_id={config['curseforge']['mod'].get('project_id', '')}\n")
|
|
91
|
-
f.write(f"curseforge_java_versions={json.dumps(config['curseforge']['mod'].get('java_versions', []))}\n")
|
|
92
|
-
f.write(f"curseforge_environments={json.dumps(config['curseforge']['mod'].get('environments', []))}\n")
|
|
93
|
-
f.write(f"package_as_mod_enabled={str(config['package_as_mod']['enabled']).lower()}\n")
|
|
94
|
-
f.write(f"package_as_mod_loaders={json.dumps(config['package_as_mod']['loaders'])}\n")
|
|
95
|
-
f.write(f"package_as_mod_id={config['package_as_mod']['id']}\n")
|
|
96
|
-
f.write(f"package_as_mod_filename={config['package_as_mod'].get('filename', config['package_as_mod']['id'])}\n")
|
|
97
|
-
f.write(f"package_as_mod_authors={json.dumps(config['package_as_mod']['authors'])}\n")
|
|
98
|
-
f.write(f"exclude_patterns={json.dumps(config.get('build', {}).get('exclude', []))}\n")
|
|
99
|
-
EOF
|
|
100
|
-
|
|
101
|
-
- name: Increment version
|
|
102
|
-
id: version
|
|
103
|
-
if: steps.changeset.outputs.found == 'true'
|
|
104
|
-
run: |
|
|
105
|
-
python - <<'EOF'
|
|
106
|
-
import os
|
|
107
|
-
|
|
108
|
-
bump = "${{ steps.parse.outputs.version_bump }}"
|
|
109
|
-
current = "${{ steps.config.outputs.current_version }}"
|
|
110
|
-
major, minor, patch = map(int, current.split('.'))
|
|
111
|
-
|
|
112
|
-
if bump == "major":
|
|
113
|
-
major += 1
|
|
114
|
-
minor = 0
|
|
115
|
-
patch = 0
|
|
116
|
-
elif bump == "minor":
|
|
117
|
-
minor += 1
|
|
118
|
-
patch = 0
|
|
119
|
-
elif bump == "patch":
|
|
120
|
-
patch += 1
|
|
121
|
-
|
|
122
|
-
new_version = f"{major}.{minor}.{patch}"
|
|
123
|
-
|
|
124
|
-
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
125
|
-
f.write(f"version={new_version}\n")
|
|
126
|
-
EOF
|
|
127
|
-
|
|
128
|
-
- name: Resolve loaders
|
|
129
|
-
id: loaders
|
|
130
|
-
if: steps.changeset.outputs.found == 'true'
|
|
131
|
-
run: |
|
|
132
|
-
python - <<'EOF'
|
|
133
|
-
import json, os
|
|
134
|
-
|
|
135
|
-
changeset_loaders = '${{ steps.parse.outputs.loaders }}'
|
|
136
|
-
default_loaders = '${{ steps.config.outputs.package_as_mod_loaders }}'
|
|
137
|
-
|
|
138
|
-
if changeset_loaders != 'null':
|
|
139
|
-
loaders = json.loads(changeset_loaders)
|
|
140
|
-
else:
|
|
141
|
-
loaders = json.loads(default_loaders)
|
|
142
|
-
|
|
143
|
-
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
144
|
-
f.write(f"csv={','.join(loaders)}\n")
|
|
145
|
-
f.write(f"json={json.dumps(loaders)}\n")
|
|
146
|
-
EOF
|
|
147
|
-
|
|
148
|
-
- name: Format game versions
|
|
149
|
-
id: game_versions
|
|
150
|
-
if: steps.changeset.outputs.found == 'true'
|
|
151
|
-
run: |
|
|
152
|
-
python - <<'EOF'
|
|
153
|
-
import json, os
|
|
154
|
-
|
|
155
|
-
game_versions = json.loads('${{ steps.parse.outputs.game_versions }}')
|
|
156
|
-
|
|
157
|
-
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
158
|
-
f.write(f"csv={','.join(game_versions)}\n")
|
|
159
|
-
f.write(f"json={json.dumps(game_versions)}\n")
|
|
160
|
-
EOF
|
|
161
|
-
|
|
162
|
-
- name: Create directories
|
|
163
|
-
if: steps.changeset.outputs.found == 'true'
|
|
164
|
-
run: mkdir -p dist build-temp
|
|
165
|
-
|
|
166
|
-
- name: Copy files
|
|
167
|
-
if: steps.changeset.outputs.found == 'true'
|
|
168
|
-
run: |
|
|
169
|
-
python - <<'EOF'
|
|
170
|
-
import shutil, json
|
|
171
|
-
from pathlib import Path
|
|
172
|
-
from fnmatch import fnmatch
|
|
173
|
-
|
|
174
|
-
exclude = json.loads('${{ steps.config.outputs.exclude_patterns }}') + ['build-temp', 'dist']
|
|
175
|
-
|
|
176
|
-
def should_exclude(path):
|
|
177
|
-
for pattern in exclude:
|
|
178
|
-
if fnmatch(str(path.name), pattern) or any(fnmatch(str(p), pattern) for p in path.parents):
|
|
179
|
-
return True
|
|
180
|
-
return False
|
|
181
|
-
|
|
182
|
-
src, dst = Path('.'), Path('build-temp')
|
|
183
|
-
for item in src.rglob('*'):
|
|
184
|
-
rel = item.relative_to(src)
|
|
185
|
-
if not should_exclude(rel):
|
|
186
|
-
dest = dst / rel
|
|
187
|
-
if item.is_dir():
|
|
188
|
-
dest.mkdir(parents=True, exist_ok=True)
|
|
189
|
-
else:
|
|
190
|
-
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
191
|
-
shutil.copy2(item, dest)
|
|
192
|
-
EOF
|
|
193
|
-
|
|
194
|
-
- name: Build datapack
|
|
195
|
-
if: steps.changeset.outputs.found == 'true'
|
|
196
|
-
run: |
|
|
197
|
-
cd build-temp
|
|
198
|
-
FILENAME="${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip"
|
|
199
|
-
zip -r ../dist/${FILENAME} . -x "*.git*" "*.DS_Store"
|
|
200
|
-
cd ..
|
|
201
|
-
[ -f "dist/${FILENAME}" ] || exit 1
|
|
202
|
-
|
|
203
|
-
- name: Package as mod
|
|
204
|
-
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.package_as_mod_enabled == 'true'
|
|
205
|
-
run: |
|
|
206
|
-
npm install @voxelio/converter @voxelio/breeze @voxelio/zip
|
|
207
|
-
|
|
208
|
-
cat > convert.js <<'SCRIPT'
|
|
209
|
-
import { convertDatapack, ModPlatforms } from "@voxelio/converter";
|
|
210
|
-
import { readFile, writeFile } from "fs/promises";
|
|
211
|
-
|
|
212
|
-
const args = JSON.parse(process.argv[2]);
|
|
213
|
-
const buffer = await readFile(args.input);
|
|
214
|
-
const file = new File([buffer], "datapack.zip");
|
|
215
|
-
const platforms = args.loaders.map(l => ModPlatforms[l.toUpperCase()]).filter(Boolean);
|
|
216
|
-
|
|
217
|
-
const response = await convertDatapack(file, platforms, {
|
|
218
|
-
id: args.id,
|
|
219
|
-
version: args.version,
|
|
220
|
-
name: args.name,
|
|
221
|
-
description: "",
|
|
222
|
-
authors: args.authors
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
await writeFile(args.output, Buffer.from(await response.arrayBuffer()));
|
|
226
|
-
SCRIPT
|
|
227
|
-
|
|
228
|
-
MOD_NAME="${{ steps.config.outputs.project_name }}"
|
|
229
|
-
|
|
230
|
-
node convert.js "$(jq -n \
|
|
231
|
-
--arg input "dist/${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip" \
|
|
232
|
-
--arg output "dist/${{ steps.config.outputs.package_as_mod_filename }}-${{ steps.version.outputs.version }}.jar" \
|
|
233
|
-
--arg id "${{ steps.config.outputs.package_as_mod_id }}" \
|
|
234
|
-
--arg version "${{ steps.version.outputs.version }}" \
|
|
235
|
-
--arg name "$MOD_NAME" \
|
|
236
|
-
--argjson authors '${{ steps.config.outputs.package_as_mod_authors }}' \
|
|
237
|
-
--argjson loaders '${{ steps.loaders.outputs.json }}' \
|
|
238
|
-
'{input:$input, output:$output, id:$id, version:$version, name:$name, authors:$authors, loaders:$loaders}')"
|
|
239
|
-
|
|
240
|
-
- name: Fetch CurseForge game versions
|
|
241
|
-
id: cf_versions
|
|
242
|
-
if: steps.changeset.outputs.found == 'true' && (steps.config.outputs.curseforge_datapack_enabled == 'true' || steps.config.outputs.curseforge_mod_enabled == 'true')
|
|
243
|
-
run: |
|
|
244
|
-
curl -fsSL "https://minecraft.curseforge.com/api/game/version-types" \
|
|
245
|
-
-H "Accept: application/json" \
|
|
246
|
-
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
247
|
-
-o cf_version_types.json
|
|
248
|
-
|
|
249
|
-
curl -fsSL "https://minecraft.curseforge.com/api/game/versions" \
|
|
250
|
-
-H "Accept: application/json" \
|
|
251
|
-
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
252
|
-
-o cf_versions.json
|
|
253
|
-
|
|
254
|
-
python - <<'EOF'
|
|
255
|
-
import json, os
|
|
256
|
-
|
|
257
|
-
with open('cf_version_types.json','r') as f:
|
|
258
|
-
version_types = json.load(f)
|
|
259
|
-
|
|
260
|
-
with open('cf_versions.json','r') as f:
|
|
261
|
-
versions = json.load(f)
|
|
262
|
-
|
|
263
|
-
type_by_slug = {vt['slug']: vt['id'] for vt in version_types}
|
|
264
|
-
|
|
265
|
-
minecraft_types = [
|
|
266
|
-
tid for slug, tid in type_by_slug.items()
|
|
267
|
-
if slug.startswith('minecraft-') and 'beta' not in slug.lower()
|
|
268
|
-
]
|
|
269
|
-
|
|
270
|
-
modloader_type = type_by_slug.get('modloader')
|
|
271
|
-
environment_type = type_by_slug.get('environment')
|
|
272
|
-
java_type = type_by_slug.get('java')
|
|
273
|
-
|
|
274
|
-
print(f"Minecraft types: {minecraft_types}")
|
|
275
|
-
print(f"Modloader type: {modloader_type}")
|
|
276
|
-
print(f"Environment type: {environment_type}")
|
|
277
|
-
print(f"Java type: {java_type}")
|
|
278
|
-
|
|
279
|
-
game_versions = json.loads('${{ steps.game_versions.outputs.json }}')
|
|
280
|
-
loaders = json.loads('${{ steps.loaders.outputs.json }}')
|
|
281
|
-
java_versions = json.loads('${{ steps.config.outputs.curseforge_java_versions }}')
|
|
282
|
-
environments = json.loads('${{ steps.config.outputs.curseforge_environments }}')
|
|
283
|
-
|
|
284
|
-
by_type = {}
|
|
285
|
-
for v in versions:
|
|
286
|
-
type_id = v.get('gameVersionTypeID')
|
|
287
|
-
name = v.get('name')
|
|
288
|
-
if type_id and name:
|
|
289
|
-
if type_id not in by_type:
|
|
290
|
-
by_type[type_id] = {}
|
|
291
|
-
by_type[type_id][name] = v['id']
|
|
292
|
-
|
|
293
|
-
ids = []
|
|
294
|
-
|
|
295
|
-
for version in game_versions:
|
|
296
|
-
found = False
|
|
297
|
-
for type_id in minecraft_types:
|
|
298
|
-
if type_id in by_type and version in by_type[type_id]:
|
|
299
|
-
ids.append(by_type[type_id][version])
|
|
300
|
-
print(f"✓ Minecraft {version} -> ID {by_type[type_id][version]} (type {type_id})")
|
|
301
|
-
found = True
|
|
302
|
-
break
|
|
303
|
-
if not found:
|
|
304
|
-
print(f"✗ Minecraft version NOT FOUND: {version}")
|
|
305
|
-
|
|
306
|
-
if modloader_type:
|
|
307
|
-
for loader in [l.capitalize() for l in loaders]:
|
|
308
|
-
if modloader_type in by_type and loader in by_type[modloader_type]:
|
|
309
|
-
ids.append(by_type[modloader_type][loader])
|
|
310
|
-
print(f"✓ Loader {loader} -> ID {by_type[modloader_type][loader]}")
|
|
311
|
-
|
|
312
|
-
if java_type:
|
|
313
|
-
for java in java_versions:
|
|
314
|
-
if java_type in by_type and java in by_type[java_type]:
|
|
315
|
-
ids.append(by_type[java_type][java])
|
|
316
|
-
print(f"✓ Java {java} -> ID {by_type[java_type][java]}")
|
|
317
|
-
|
|
318
|
-
if environment_type:
|
|
319
|
-
for env in [e.capitalize() for e in environments]:
|
|
320
|
-
if environment_type in by_type and env in by_type[environment_type]:
|
|
321
|
-
ids.append(by_type[environment_type][env])
|
|
322
|
-
print(f"✓ Environment {env} -> ID {by_type[environment_type][env]}")
|
|
323
|
-
|
|
324
|
-
ids = list(dict.fromkeys(ids))
|
|
325
|
-
print(f"\n✅ Final IDs to send: {ids}")
|
|
326
|
-
|
|
327
|
-
with open(os.environ['GITHUB_OUTPUT'], 'a') as out:
|
|
328
|
-
out.write(f"ids={json.dumps(ids)}\n")
|
|
329
|
-
EOF
|
|
330
|
-
|
|
331
|
-
- name: Upload to Modrinth (Datapack)
|
|
332
|
-
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.modrinth_enabled == 'true'
|
|
333
|
-
run: |
|
|
334
|
-
FILENAME="${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip"
|
|
335
|
-
|
|
336
|
-
DATA=$(jq -n \
|
|
337
|
-
--arg pid "${{ steps.config.outputs.modrinth_project_id }}" \
|
|
338
|
-
--arg name "v${{ steps.version.outputs.version }} (Datapack)" \
|
|
339
|
-
--arg ver "${{ steps.version.outputs.version }}" \
|
|
340
|
-
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
341
|
-
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
342
|
-
--argjson gv '${{ steps.game_versions.outputs.json }}' \
|
|
343
|
-
--argjson loaders '["datapack"]' \
|
|
344
|
-
--argjson featured ${{ steps.config.outputs.modrinth_featured || 'false' }} \
|
|
345
|
-
'{name:$name, version_number:$ver, changelog:$log, game_versions:$gv, loaders:$loaders, project_id:$pid, version_type:$type, dependencies:[], featured:$featured, file_parts:["file"], primary_file:"file"}'
|
|
346
|
-
)
|
|
347
|
-
|
|
348
|
-
curl -sS -o resp.json -w "%{http_code}" \
|
|
349
|
-
-X POST "https://api.modrinth.com/v2/version" \
|
|
350
|
-
-H "Authorization: ${{ secrets.MODRINTH_TOKEN }}" \
|
|
351
|
-
-H "User-Agent: ${{ github.repository }}" \
|
|
352
|
-
-F "data=${DATA};type=application/json" \
|
|
353
|
-
-F "file=@dist/${FILENAME};filename=${FILENAME}" | tee code.txt
|
|
354
|
-
|
|
355
|
-
cat resp.json | jq .
|
|
356
|
-
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
357
|
-
|
|
358
|
-
- name: Upload to Modrinth (Mod)
|
|
359
|
-
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.modrinth_enabled == 'true' && steps.config.outputs.package_as_mod_enabled == 'true'
|
|
360
|
-
run: |
|
|
361
|
-
FILENAME="${{ steps.config.outputs.package_as_mod_filename }}-${{ steps.version.outputs.version }}.jar"
|
|
362
|
-
DATA=$(jq -n \
|
|
363
|
-
--arg pid "${{ steps.config.outputs.modrinth_project_id }}" \
|
|
364
|
-
--arg name "v${{ steps.version.outputs.version }} (Mod)" \
|
|
365
|
-
--arg ver "${{ steps.version.outputs.version }}+mod" \
|
|
366
|
-
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
367
|
-
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
368
|
-
--argjson gv '${{ steps.game_versions.outputs.json }}' \
|
|
369
|
-
--argjson loaders '${{ steps.config.outputs.package_as_mod_loaders }}' \
|
|
370
|
-
--argjson featured ${{ steps.config.outputs.modrinth_featured || 'false' }} \
|
|
371
|
-
'{name:$name, version_number:$ver, changelog:$log, game_versions:$gv, loaders:$loaders, project_id:$pid, version_type:$type, dependencies:[], featured:$featured, file_parts:["file"], primary_file:"file"}'
|
|
372
|
-
)
|
|
373
|
-
|
|
374
|
-
curl -sS -o resp.json -w "%{http_code}" \
|
|
375
|
-
-X POST "https://api.modrinth.com/v2/version" \
|
|
376
|
-
-H "Authorization: ${{ secrets.MODRINTH_TOKEN }}" \
|
|
377
|
-
-H "User-Agent: ${{ github.repository }}" \
|
|
378
|
-
-F "data=${DATA};type=application/json" \
|
|
379
|
-
-F "file=@dist/${FILENAME};filename=${FILENAME}" | tee code.txt
|
|
380
|
-
|
|
381
|
-
cat resp.json | jq .
|
|
382
|
-
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
383
|
-
|
|
384
|
-
- name: Upload to CurseForge (Datapack)
|
|
385
|
-
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.curseforge_datapack_enabled == 'true'
|
|
386
|
-
run: |
|
|
387
|
-
FILENAME="${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip"
|
|
388
|
-
|
|
389
|
-
DATA=$(jq -n \
|
|
390
|
-
--arg name "${{ steps.config.outputs.project_name }} - v${{ steps.version.outputs.version }}" \
|
|
391
|
-
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
392
|
-
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
393
|
-
--argjson ids '${{ steps.cf_versions.outputs.game_ids }}' \
|
|
394
|
-
'{displayName:$name, changelog:$log, changelogType:"markdown", releaseType:$type, gameVersions:$ids}')
|
|
395
|
-
|
|
396
|
-
curl -sS -o resp.json -w "%{http_code}" \
|
|
397
|
-
-X POST "https://minecraft.curseforge.com/api/projects/${{ steps.config.outputs.curseforge_datapack_id }}/upload-file" \
|
|
398
|
-
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
399
|
-
-H "User-Agent: ${{ github.repository }}" \
|
|
400
|
-
-F "metadata=${DATA};type=application/json" \
|
|
401
|
-
-F "file=@dist/${FILENAME}" | tee code.txt
|
|
402
|
-
|
|
403
|
-
cat resp.json | jq .
|
|
404
|
-
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
405
|
-
|
|
406
|
-
- name: Upload to CurseForge (Mod)
|
|
407
|
-
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.curseforge_mod_enabled == 'true'
|
|
408
|
-
run: |
|
|
409
|
-
FILENAME="${{ steps.config.outputs.package_as_mod_filename }}-${{ steps.version.outputs.version }}.jar"
|
|
410
|
-
|
|
411
|
-
DATA=$(jq -n \
|
|
412
|
-
--arg name "${{ steps.config.outputs.project_name }} - v${{ steps.version.outputs.version }}" \
|
|
413
|
-
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
414
|
-
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
415
|
-
--argjson ids '${{ steps.cf_versions.outputs.ids }}' \
|
|
416
|
-
'{displayName:$name, changelog:$log, changelogType:"markdown", releaseType:$type, gameVersions:$ids}')
|
|
417
|
-
|
|
418
|
-
curl -sS -o resp.json -w "%{http_code}" \
|
|
419
|
-
-X POST "https://minecraft.curseforge.com/api/projects/${{ steps.config.outputs.curseforge_mod_id }}/upload-file" \
|
|
420
|
-
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
421
|
-
-H "User-Agent: ${{ github.repository }}" \
|
|
422
|
-
-F "metadata=${DATA};type=application/json" \
|
|
423
|
-
-F "file=@dist/${FILENAME}" | tee code.txt
|
|
424
|
-
|
|
425
|
-
cat resp.json | jq .
|
|
426
|
-
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
427
|
-
|
|
428
|
-
- name: Update config
|
|
429
|
-
if: steps.changeset.outputs.found == 'true'
|
|
430
|
-
run: |
|
|
431
|
-
python - <<'EOF'
|
|
432
|
-
import re
|
|
433
|
-
|
|
434
|
-
with open('deploy.yaml', 'r') as f:
|
|
435
|
-
content = f.read()
|
|
436
|
-
|
|
437
|
-
content = re.sub(
|
|
438
|
-
r'(version:\s*["\']?)[0-9.]+(["\']?)',
|
|
439
|
-
r'\g<1>${{ steps.version.outputs.version }}\g<2>',
|
|
440
|
-
content
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
with open('deploy.yaml', 'w') as f:
|
|
444
|
-
f.write(content)
|
|
445
|
-
EOF
|
|
446
|
-
|
|
447
|
-
- name: Commit
|
|
448
|
-
if: steps.changeset.outputs.found == 'true'
|
|
449
|
-
run: |
|
|
450
|
-
rm ${{ steps.changeset.outputs.file }}
|
|
451
|
-
rm -f .changeset/*.md
|
|
452
|
-
git config user.name "github-actions[bot]"
|
|
453
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
454
|
-
git add deploy.yaml .changeset
|
|
455
|
-
git commit -m "chore: release v${{ steps.version.outputs.version }}"
|
|
456
|
-
git push
|
|
1
|
+
name: Deploy
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- '.changeset/*.md'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
deploy:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
|
|
21
|
+
- name: Setup Node.js
|
|
22
|
+
uses: actions/setup-node@v4
|
|
23
|
+
with:
|
|
24
|
+
node-version: '20'
|
|
25
|
+
|
|
26
|
+
- name: Setup Python
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: '3.11'
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: pip install pyyaml
|
|
33
|
+
|
|
34
|
+
- name: Detect changeset
|
|
35
|
+
id: changeset
|
|
36
|
+
run: |
|
|
37
|
+
CHANGESET_FILE=$(find .changeset -name "*.md" -type f | head -n 1)
|
|
38
|
+
if [ -z "$CHANGESET_FILE" ]; then
|
|
39
|
+
echo "found=false" >> $GITHUB_OUTPUT
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
echo "found=true" >> $GITHUB_OUTPUT
|
|
43
|
+
echo "file=$CHANGESET_FILE" >> $GITHUB_OUTPUT
|
|
44
|
+
|
|
45
|
+
- name: Parse changeset
|
|
46
|
+
id: parse
|
|
47
|
+
if: steps.changeset.outputs.found == 'true'
|
|
48
|
+
run: |
|
|
49
|
+
python - <<'EOF'
|
|
50
|
+
import re, json, os, yaml
|
|
51
|
+
|
|
52
|
+
with open("${{ steps.changeset.outputs.file }}", 'r') as f:
|
|
53
|
+
content = f.read()
|
|
54
|
+
|
|
55
|
+
match = re.match(r'^---\n(.*?)\n---\n(.*)$', content, re.DOTALL)
|
|
56
|
+
if not match:
|
|
57
|
+
exit(1)
|
|
58
|
+
|
|
59
|
+
frontmatter = yaml.safe_load(match.group(1))
|
|
60
|
+
changelog = match.group(2).strip()
|
|
61
|
+
|
|
62
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
63
|
+
f.write(f"game_versions={json.dumps(frontmatter.get('game_versions', []))}\n")
|
|
64
|
+
f.write(f"loaders={json.dumps(frontmatter.get('loaders', None)) if frontmatter.get('loaders') else 'null'}\n")
|
|
65
|
+
f.write(f"version_type={frontmatter.get('version_type', 'release')}\n")
|
|
66
|
+
f.write(f"version_bump={frontmatter.get('version_bump', 'patch')}\n")
|
|
67
|
+
f.write(f"changelog<<EOF\n{changelog}\nEOF\n")
|
|
68
|
+
EOF
|
|
69
|
+
|
|
70
|
+
- name: Read config
|
|
71
|
+
id: config
|
|
72
|
+
if: steps.changeset.outputs.found == 'true'
|
|
73
|
+
run: |
|
|
74
|
+
python - <<'EOF'
|
|
75
|
+
import yaml, json, os
|
|
76
|
+
|
|
77
|
+
with open('deploy.yaml', 'r') as f:
|
|
78
|
+
config = yaml.safe_load(f)
|
|
79
|
+
|
|
80
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
81
|
+
f.write(f"current_version={config['project']['version']}\n")
|
|
82
|
+
f.write(f"project_name={config['project']['name']}\n")
|
|
83
|
+
f.write(f"project_filename={config['project']['filename']}\n")
|
|
84
|
+
f.write(f"modrinth_enabled={str(config['modrinth']['enabled']).lower()}\n")
|
|
85
|
+
f.write(f"modrinth_project_id={config['modrinth']['project_id']}\n")
|
|
86
|
+
f.write(f"modrinth_featured={str(config['modrinth'].get('featured', False)).lower()}\n")
|
|
87
|
+
f.write(f"curseforge_datapack_enabled={str(config['curseforge']['datapack']['enabled']).lower()}\n")
|
|
88
|
+
f.write(f"curseforge_datapack_id={config['curseforge']['datapack'].get('project_id', '')}\n")
|
|
89
|
+
f.write(f"curseforge_mod_enabled={str(config['curseforge']['mod']['enabled']).lower()}\n")
|
|
90
|
+
f.write(f"curseforge_mod_id={config['curseforge']['mod'].get('project_id', '')}\n")
|
|
91
|
+
f.write(f"curseforge_java_versions={json.dumps(config['curseforge']['mod'].get('java_versions', []))}\n")
|
|
92
|
+
f.write(f"curseforge_environments={json.dumps(config['curseforge']['mod'].get('environments', []))}\n")
|
|
93
|
+
f.write(f"package_as_mod_enabled={str(config['package_as_mod']['enabled']).lower()}\n")
|
|
94
|
+
f.write(f"package_as_mod_loaders={json.dumps(config['package_as_mod']['loaders'])}\n")
|
|
95
|
+
f.write(f"package_as_mod_id={config['package_as_mod']['id']}\n")
|
|
96
|
+
f.write(f"package_as_mod_filename={config['package_as_mod'].get('filename', config['package_as_mod']['id'])}\n")
|
|
97
|
+
f.write(f"package_as_mod_authors={json.dumps(config['package_as_mod']['authors'])}\n")
|
|
98
|
+
f.write(f"exclude_patterns={json.dumps(config.get('build', {}).get('exclude', []))}\n")
|
|
99
|
+
EOF
|
|
100
|
+
|
|
101
|
+
- name: Increment version
|
|
102
|
+
id: version
|
|
103
|
+
if: steps.changeset.outputs.found == 'true'
|
|
104
|
+
run: |
|
|
105
|
+
python - <<'EOF'
|
|
106
|
+
import os
|
|
107
|
+
|
|
108
|
+
bump = "${{ steps.parse.outputs.version_bump }}"
|
|
109
|
+
current = "${{ steps.config.outputs.current_version }}"
|
|
110
|
+
major, minor, patch = map(int, current.split('.'))
|
|
111
|
+
|
|
112
|
+
if bump == "major":
|
|
113
|
+
major += 1
|
|
114
|
+
minor = 0
|
|
115
|
+
patch = 0
|
|
116
|
+
elif bump == "minor":
|
|
117
|
+
minor += 1
|
|
118
|
+
patch = 0
|
|
119
|
+
elif bump == "patch":
|
|
120
|
+
patch += 1
|
|
121
|
+
|
|
122
|
+
new_version = f"{major}.{minor}.{patch}"
|
|
123
|
+
|
|
124
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
125
|
+
f.write(f"version={new_version}\n")
|
|
126
|
+
EOF
|
|
127
|
+
|
|
128
|
+
- name: Resolve loaders
|
|
129
|
+
id: loaders
|
|
130
|
+
if: steps.changeset.outputs.found == 'true'
|
|
131
|
+
run: |
|
|
132
|
+
python - <<'EOF'
|
|
133
|
+
import json, os
|
|
134
|
+
|
|
135
|
+
changeset_loaders = '${{ steps.parse.outputs.loaders }}'
|
|
136
|
+
default_loaders = '${{ steps.config.outputs.package_as_mod_loaders }}'
|
|
137
|
+
|
|
138
|
+
if changeset_loaders != 'null':
|
|
139
|
+
loaders = json.loads(changeset_loaders)
|
|
140
|
+
else:
|
|
141
|
+
loaders = json.loads(default_loaders)
|
|
142
|
+
|
|
143
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
144
|
+
f.write(f"csv={','.join(loaders)}\n")
|
|
145
|
+
f.write(f"json={json.dumps(loaders)}\n")
|
|
146
|
+
EOF
|
|
147
|
+
|
|
148
|
+
- name: Format game versions
|
|
149
|
+
id: game_versions
|
|
150
|
+
if: steps.changeset.outputs.found == 'true'
|
|
151
|
+
run: |
|
|
152
|
+
python - <<'EOF'
|
|
153
|
+
import json, os
|
|
154
|
+
|
|
155
|
+
game_versions = json.loads('${{ steps.parse.outputs.game_versions }}')
|
|
156
|
+
|
|
157
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
158
|
+
f.write(f"csv={','.join(game_versions)}\n")
|
|
159
|
+
f.write(f"json={json.dumps(game_versions)}\n")
|
|
160
|
+
EOF
|
|
161
|
+
|
|
162
|
+
- name: Create directories
|
|
163
|
+
if: steps.changeset.outputs.found == 'true'
|
|
164
|
+
run: mkdir -p dist build-temp
|
|
165
|
+
|
|
166
|
+
- name: Copy files
|
|
167
|
+
if: steps.changeset.outputs.found == 'true'
|
|
168
|
+
run: |
|
|
169
|
+
python - <<'EOF'
|
|
170
|
+
import shutil, json
|
|
171
|
+
from pathlib import Path
|
|
172
|
+
from fnmatch import fnmatch
|
|
173
|
+
|
|
174
|
+
exclude = json.loads('${{ steps.config.outputs.exclude_patterns }}') + ['build-temp', 'dist']
|
|
175
|
+
|
|
176
|
+
def should_exclude(path):
|
|
177
|
+
for pattern in exclude:
|
|
178
|
+
if fnmatch(str(path.name), pattern) or any(fnmatch(str(p), pattern) for p in path.parents):
|
|
179
|
+
return True
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
src, dst = Path('.'), Path('build-temp')
|
|
183
|
+
for item in src.rglob('*'):
|
|
184
|
+
rel = item.relative_to(src)
|
|
185
|
+
if not should_exclude(rel):
|
|
186
|
+
dest = dst / rel
|
|
187
|
+
if item.is_dir():
|
|
188
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
189
|
+
else:
|
|
190
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
191
|
+
shutil.copy2(item, dest)
|
|
192
|
+
EOF
|
|
193
|
+
|
|
194
|
+
- name: Build datapack
|
|
195
|
+
if: steps.changeset.outputs.found == 'true'
|
|
196
|
+
run: |
|
|
197
|
+
cd build-temp
|
|
198
|
+
FILENAME="${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip"
|
|
199
|
+
zip -r ../dist/${FILENAME} . -x "*.git*" "*.DS_Store"
|
|
200
|
+
cd ..
|
|
201
|
+
[ -f "dist/${FILENAME}" ] || exit 1
|
|
202
|
+
|
|
203
|
+
- name: Package as mod
|
|
204
|
+
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.package_as_mod_enabled == 'true'
|
|
205
|
+
run: |
|
|
206
|
+
npm install @voxelio/converter @voxelio/breeze @voxelio/zip
|
|
207
|
+
|
|
208
|
+
cat > convert.js <<'SCRIPT'
|
|
209
|
+
import { convertDatapack, ModPlatforms } from "@voxelio/converter";
|
|
210
|
+
import { readFile, writeFile } from "fs/promises";
|
|
211
|
+
|
|
212
|
+
const args = JSON.parse(process.argv[2]);
|
|
213
|
+
const buffer = await readFile(args.input);
|
|
214
|
+
const file = new File([buffer], "datapack.zip");
|
|
215
|
+
const platforms = args.loaders.map(l => ModPlatforms[l.toUpperCase()]).filter(Boolean);
|
|
216
|
+
|
|
217
|
+
const response = await convertDatapack(file, platforms, {
|
|
218
|
+
id: args.id,
|
|
219
|
+
version: args.version,
|
|
220
|
+
name: args.name,
|
|
221
|
+
description: "",
|
|
222
|
+
authors: args.authors
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
await writeFile(args.output, Buffer.from(await response.arrayBuffer()));
|
|
226
|
+
SCRIPT
|
|
227
|
+
|
|
228
|
+
MOD_NAME="${{ steps.config.outputs.project_name }}"
|
|
229
|
+
|
|
230
|
+
node convert.js "$(jq -n \
|
|
231
|
+
--arg input "dist/${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip" \
|
|
232
|
+
--arg output "dist/${{ steps.config.outputs.package_as_mod_filename }}-${{ steps.version.outputs.version }}.jar" \
|
|
233
|
+
--arg id "${{ steps.config.outputs.package_as_mod_id }}" \
|
|
234
|
+
--arg version "${{ steps.version.outputs.version }}" \
|
|
235
|
+
--arg name "$MOD_NAME" \
|
|
236
|
+
--argjson authors '${{ steps.config.outputs.package_as_mod_authors }}' \
|
|
237
|
+
--argjson loaders '${{ steps.loaders.outputs.json }}' \
|
|
238
|
+
'{input:$input, output:$output, id:$id, version:$version, name:$name, authors:$authors, loaders:$loaders}')"
|
|
239
|
+
|
|
240
|
+
- name: Fetch CurseForge game versions
|
|
241
|
+
id: cf_versions
|
|
242
|
+
if: steps.changeset.outputs.found == 'true' && (steps.config.outputs.curseforge_datapack_enabled == 'true' || steps.config.outputs.curseforge_mod_enabled == 'true')
|
|
243
|
+
run: |
|
|
244
|
+
curl -fsSL "https://minecraft.curseforge.com/api/game/version-types" \
|
|
245
|
+
-H "Accept: application/json" \
|
|
246
|
+
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
247
|
+
-o cf_version_types.json
|
|
248
|
+
|
|
249
|
+
curl -fsSL "https://minecraft.curseforge.com/api/game/versions" \
|
|
250
|
+
-H "Accept: application/json" \
|
|
251
|
+
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
252
|
+
-o cf_versions.json
|
|
253
|
+
|
|
254
|
+
python - <<'EOF'
|
|
255
|
+
import json, os
|
|
256
|
+
|
|
257
|
+
with open('cf_version_types.json','r') as f:
|
|
258
|
+
version_types = json.load(f)
|
|
259
|
+
|
|
260
|
+
with open('cf_versions.json','r') as f:
|
|
261
|
+
versions = json.load(f)
|
|
262
|
+
|
|
263
|
+
type_by_slug = {vt['slug']: vt['id'] for vt in version_types}
|
|
264
|
+
|
|
265
|
+
minecraft_types = [
|
|
266
|
+
tid for slug, tid in type_by_slug.items()
|
|
267
|
+
if slug.startswith('minecraft-') and 'beta' not in slug.lower()
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
modloader_type = type_by_slug.get('modloader')
|
|
271
|
+
environment_type = type_by_slug.get('environment')
|
|
272
|
+
java_type = type_by_slug.get('java')
|
|
273
|
+
|
|
274
|
+
print(f"Minecraft types: {minecraft_types}")
|
|
275
|
+
print(f"Modloader type: {modloader_type}")
|
|
276
|
+
print(f"Environment type: {environment_type}")
|
|
277
|
+
print(f"Java type: {java_type}")
|
|
278
|
+
|
|
279
|
+
game_versions = json.loads('${{ steps.game_versions.outputs.json }}')
|
|
280
|
+
loaders = json.loads('${{ steps.loaders.outputs.json }}')
|
|
281
|
+
java_versions = json.loads('${{ steps.config.outputs.curseforge_java_versions }}')
|
|
282
|
+
environments = json.loads('${{ steps.config.outputs.curseforge_environments }}')
|
|
283
|
+
|
|
284
|
+
by_type = {}
|
|
285
|
+
for v in versions:
|
|
286
|
+
type_id = v.get('gameVersionTypeID')
|
|
287
|
+
name = v.get('name')
|
|
288
|
+
if type_id and name:
|
|
289
|
+
if type_id not in by_type:
|
|
290
|
+
by_type[type_id] = {}
|
|
291
|
+
by_type[type_id][name] = v['id']
|
|
292
|
+
|
|
293
|
+
ids = []
|
|
294
|
+
|
|
295
|
+
for version in game_versions:
|
|
296
|
+
found = False
|
|
297
|
+
for type_id in minecraft_types:
|
|
298
|
+
if type_id in by_type and version in by_type[type_id]:
|
|
299
|
+
ids.append(by_type[type_id][version])
|
|
300
|
+
print(f"✓ Minecraft {version} -> ID {by_type[type_id][version]} (type {type_id})")
|
|
301
|
+
found = True
|
|
302
|
+
break
|
|
303
|
+
if not found:
|
|
304
|
+
print(f"✗ Minecraft version NOT FOUND: {version}")
|
|
305
|
+
|
|
306
|
+
if modloader_type:
|
|
307
|
+
for loader in [l.capitalize() for l in loaders]:
|
|
308
|
+
if modloader_type in by_type and loader in by_type[modloader_type]:
|
|
309
|
+
ids.append(by_type[modloader_type][loader])
|
|
310
|
+
print(f"✓ Loader {loader} -> ID {by_type[modloader_type][loader]}")
|
|
311
|
+
|
|
312
|
+
if java_type:
|
|
313
|
+
for java in java_versions:
|
|
314
|
+
if java_type in by_type and java in by_type[java_type]:
|
|
315
|
+
ids.append(by_type[java_type][java])
|
|
316
|
+
print(f"✓ Java {java} -> ID {by_type[java_type][java]}")
|
|
317
|
+
|
|
318
|
+
if environment_type:
|
|
319
|
+
for env in [e.capitalize() for e in environments]:
|
|
320
|
+
if environment_type in by_type and env in by_type[environment_type]:
|
|
321
|
+
ids.append(by_type[environment_type][env])
|
|
322
|
+
print(f"✓ Environment {env} -> ID {by_type[environment_type][env]}")
|
|
323
|
+
|
|
324
|
+
ids = list(dict.fromkeys(ids))
|
|
325
|
+
print(f"\n✅ Final IDs to send: {ids}")
|
|
326
|
+
|
|
327
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as out:
|
|
328
|
+
out.write(f"ids={json.dumps(ids)}\n")
|
|
329
|
+
EOF
|
|
330
|
+
|
|
331
|
+
- name: Upload to Modrinth (Datapack)
|
|
332
|
+
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.modrinth_enabled == 'true'
|
|
333
|
+
run: |
|
|
334
|
+
FILENAME="${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip"
|
|
335
|
+
|
|
336
|
+
DATA=$(jq -n \
|
|
337
|
+
--arg pid "${{ steps.config.outputs.modrinth_project_id }}" \
|
|
338
|
+
--arg name "v${{ steps.version.outputs.version }} (Datapack)" \
|
|
339
|
+
--arg ver "${{ steps.version.outputs.version }}" \
|
|
340
|
+
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
341
|
+
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
342
|
+
--argjson gv '${{ steps.game_versions.outputs.json }}' \
|
|
343
|
+
--argjson loaders '["datapack"]' \
|
|
344
|
+
--argjson featured ${{ steps.config.outputs.modrinth_featured || 'false' }} \
|
|
345
|
+
'{name:$name, version_number:$ver, changelog:$log, game_versions:$gv, loaders:$loaders, project_id:$pid, version_type:$type, dependencies:[], featured:$featured, file_parts:["file"], primary_file:"file"}'
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
curl -sS -o resp.json -w "%{http_code}" \
|
|
349
|
+
-X POST "https://api.modrinth.com/v2/version" \
|
|
350
|
+
-H "Authorization: ${{ secrets.MODRINTH_TOKEN }}" \
|
|
351
|
+
-H "User-Agent: ${{ github.repository }}" \
|
|
352
|
+
-F "data=${DATA};type=application/json" \
|
|
353
|
+
-F "file=@dist/${FILENAME};filename=${FILENAME}" | tee code.txt
|
|
354
|
+
|
|
355
|
+
cat resp.json | jq .
|
|
356
|
+
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
357
|
+
|
|
358
|
+
- name: Upload to Modrinth (Mod)
|
|
359
|
+
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.modrinth_enabled == 'true' && steps.config.outputs.package_as_mod_enabled == 'true'
|
|
360
|
+
run: |
|
|
361
|
+
FILENAME="${{ steps.config.outputs.package_as_mod_filename }}-${{ steps.version.outputs.version }}.jar"
|
|
362
|
+
DATA=$(jq -n \
|
|
363
|
+
--arg pid "${{ steps.config.outputs.modrinth_project_id }}" \
|
|
364
|
+
--arg name "v${{ steps.version.outputs.version }} (Mod)" \
|
|
365
|
+
--arg ver "${{ steps.version.outputs.version }}+mod" \
|
|
366
|
+
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
367
|
+
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
368
|
+
--argjson gv '${{ steps.game_versions.outputs.json }}' \
|
|
369
|
+
--argjson loaders '${{ steps.config.outputs.package_as_mod_loaders }}' \
|
|
370
|
+
--argjson featured ${{ steps.config.outputs.modrinth_featured || 'false' }} \
|
|
371
|
+
'{name:$name, version_number:$ver, changelog:$log, game_versions:$gv, loaders:$loaders, project_id:$pid, version_type:$type, dependencies:[], featured:$featured, file_parts:["file"], primary_file:"file"}'
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
curl -sS -o resp.json -w "%{http_code}" \
|
|
375
|
+
-X POST "https://api.modrinth.com/v2/version" \
|
|
376
|
+
-H "Authorization: ${{ secrets.MODRINTH_TOKEN }}" \
|
|
377
|
+
-H "User-Agent: ${{ github.repository }}" \
|
|
378
|
+
-F "data=${DATA};type=application/json" \
|
|
379
|
+
-F "file=@dist/${FILENAME};filename=${FILENAME}" | tee code.txt
|
|
380
|
+
|
|
381
|
+
cat resp.json | jq .
|
|
382
|
+
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
383
|
+
|
|
384
|
+
- name: Upload to CurseForge (Datapack)
|
|
385
|
+
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.curseforge_datapack_enabled == 'true'
|
|
386
|
+
run: |
|
|
387
|
+
FILENAME="${{ steps.config.outputs.project_filename }}-${{ steps.version.outputs.version }}.zip"
|
|
388
|
+
|
|
389
|
+
DATA=$(jq -n \
|
|
390
|
+
--arg name "${{ steps.config.outputs.project_name }} - v${{ steps.version.outputs.version }}" \
|
|
391
|
+
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
392
|
+
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
393
|
+
--argjson ids '${{ steps.cf_versions.outputs.game_ids }}' \
|
|
394
|
+
'{displayName:$name, changelog:$log, changelogType:"markdown", releaseType:$type, gameVersions:$ids}')
|
|
395
|
+
|
|
396
|
+
curl -sS -o resp.json -w "%{http_code}" \
|
|
397
|
+
-X POST "https://minecraft.curseforge.com/api/projects/${{ steps.config.outputs.curseforge_datapack_id }}/upload-file" \
|
|
398
|
+
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
399
|
+
-H "User-Agent: ${{ github.repository }}" \
|
|
400
|
+
-F "metadata=${DATA};type=application/json" \
|
|
401
|
+
-F "file=@dist/${FILENAME}" | tee code.txt
|
|
402
|
+
|
|
403
|
+
cat resp.json | jq .
|
|
404
|
+
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
405
|
+
|
|
406
|
+
- name: Upload to CurseForge (Mod)
|
|
407
|
+
if: steps.changeset.outputs.found == 'true' && steps.config.outputs.curseforge_mod_enabled == 'true'
|
|
408
|
+
run: |
|
|
409
|
+
FILENAME="${{ steps.config.outputs.package_as_mod_filename }}-${{ steps.version.outputs.version }}.jar"
|
|
410
|
+
|
|
411
|
+
DATA=$(jq -n \
|
|
412
|
+
--arg name "${{ steps.config.outputs.project_name }} - v${{ steps.version.outputs.version }}" \
|
|
413
|
+
--arg log "${{ steps.parse.outputs.changelog }}" \
|
|
414
|
+
--arg type "${{ steps.parse.outputs.version_type }}" \
|
|
415
|
+
--argjson ids '${{ steps.cf_versions.outputs.ids }}' \
|
|
416
|
+
'{displayName:$name, changelog:$log, changelogType:"markdown", releaseType:$type, gameVersions:$ids}')
|
|
417
|
+
|
|
418
|
+
curl -sS -o resp.json -w "%{http_code}" \
|
|
419
|
+
-X POST "https://minecraft.curseforge.com/api/projects/${{ steps.config.outputs.curseforge_mod_id }}/upload-file" \
|
|
420
|
+
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
|
|
421
|
+
-H "User-Agent: ${{ github.repository }}" \
|
|
422
|
+
-F "metadata=${DATA};type=application/json" \
|
|
423
|
+
-F "file=@dist/${FILENAME}" | tee code.txt
|
|
424
|
+
|
|
425
|
+
cat resp.json | jq .
|
|
426
|
+
[ $(cat code.txt) -ge 200 ] && [ $(cat code.txt) -lt 300 ] || exit 1
|
|
427
|
+
|
|
428
|
+
- name: Update config
|
|
429
|
+
if: steps.changeset.outputs.found == 'true'
|
|
430
|
+
run: |
|
|
431
|
+
python - <<'EOF'
|
|
432
|
+
import re
|
|
433
|
+
|
|
434
|
+
with open('deploy.yaml', 'r') as f:
|
|
435
|
+
content = f.read()
|
|
436
|
+
|
|
437
|
+
content = re.sub(
|
|
438
|
+
r'(version:\s*["\']?)[0-9.]+(["\']?)',
|
|
439
|
+
r'\g<1>${{ steps.version.outputs.version }}\g<2>',
|
|
440
|
+
content
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
with open('deploy.yaml', 'w') as f:
|
|
444
|
+
f.write(content)
|
|
445
|
+
EOF
|
|
446
|
+
|
|
447
|
+
- name: Commit
|
|
448
|
+
if: steps.changeset.outputs.found == 'true'
|
|
449
|
+
run: |
|
|
450
|
+
rm ${{ steps.changeset.outputs.file }}
|
|
451
|
+
rm -f .changeset/*.md
|
|
452
|
+
git config user.name "github-actions[bot]"
|
|
453
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
454
|
+
git add deploy.yaml .changeset
|
|
455
|
+
git commit -m "chore: release v${{ steps.version.outputs.version }}"
|
|
456
|
+
git push
|