scripts: add make-release.sh #5
Reference in New Issue
Block a user
Delete Branch "jann/m2dev-client:claude/make-release-script"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds
scripts/make-release.sh— the single entry point for the v1 manual publishing flow described indocs/update-manager.md. The script wrapsmake-manifest.py+sign-manifest.pyinto one pipeline and produces a ready-to-rsync release tree.What it does
Metin2.exein the source, or into a non-empty out dir (unless--force).[1/6]runsmake-manifest.pyto producemanifest.json.[2/6]runssign-manifest.pyto producemanifest.json.sig(verifies exactly 64 bytes).[3/6]copies the signed manifest pair intomanifests/<version>.json(.sig)for historical archive.[4/6]walksmanifest.launcher + manifest.files[]viajq, buildsfiles/<hash[0:2]>/<hash>blobs, hardlinks when possible (cp -lwith copy fallback), deduplicates by hash.[5/6]prints the final layout summary.[6/6]in non-dry-run mode: prints the rsync target, waits for y/N unless--yes, rsyncs blobs+archive first (excludingmanifest.json*), then a second rsync formanifest.json+manifest.json.sigso the new release becomes visible atomically.Under 170 lines,
set -euo pipefail, small functions, meaningful[make-release] [N/6] ...prefixes.Flags:
--source,--version,--previous,--notes <file>,--key(default~/.config/metin/launcher-signing-key),--out(default/tmp/release-<version>),--force,--dry-run,--yes,--rsync-target(default VPS path).Local testing
Ran
--dry-runagainst/home/jann/metin/runtime/client-wine, version2026.04.14-dev-test:manifest.jsonis valid JSON (parsed byjq), 54439 files + launcher entry.manifest.json.sigis exactly 64 bytes.cryptography.hazmat...Ed25519PublicKeyusing the hex public key fromLauncherConfig.PublicKeyHexverifies the signature: SIGNATURE VERIFIES OK against LauncherConfig.PublicKeyHex.files/<h[:2]>/<h>— all matched the manifest.files/<h[:2]>/<h>location.End-to-end local HTTP test
Served
/tmp/release-testwithpython3 -m http.server 8765 --bind 127.0.0.1and launched the built launcher DLL against a scratch client dir containing a dummyMetin2.exeand this.updates/launcher-settings.json:Launcher log (excerpt):
So the full fetch-verify-download-hash-apply-upToDate pipeline works against a locally-served signed manifest. Signature verification passes against the baked-in
LauncherConfig.PublicKeyHex. No SSL failures, no network dependency.Note: the first run produced an SSL failure because the local
bin/Release/net8.0/Metin2Launcher.dllwas stale (predated theLauncherSettings/EffectiveManifestUrlwiring). Afterdotnet buildthe retry succeeded. Not a script issue — flagging it so others who pull this don't get caught by a stale bin./tmp/release-testand/tmp/scratch-clientcleaned up after testing.Judgment calls
--notes <file>in the spec is a file path;make-manifest.py --notestakes a string. The wrapper reads the file contents and passes them through as the string arg.cp -f(not hardlink) because the archived manifest is tiny and having a separate inode is safer.cp -l(hardlink) and falls back tocpif the out dir is on a different filesystem than the source.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.