Commit Graph

7 Commits

Author SHA1 Message Date
Matt 40dd06b8cf scripts: add Check-Deps pre-flight (mods.toml ground truth)
Adds scripts/Check-Deps.ps1 and wires it into Deploy-Brass.ps1 as a
pre-flight gate when Stage includes Pack. The script parses each lockfile
jar's META-INF/neoforge.mods.toml directly -- the same source the loader
reads at startup -- and refuses to deploy if any [[dependencies]] block
with type=required (default) names a modId that nobody in the pack
provides.

Handles three real edge cases discovered during initial run:

1. Jar-in-jar bundled deps: Create ships Ponder, Registrate, Flywheel
   embedded under META-INF/jarjar/. The script recurses into those and
   counts their modIds as present, since the loader auto-loads them.

2. Language-provider jars (Kotlin for Forge) have no standard mods.toml
   -- they declare via a different mechanism. Tiny slugToImplicitModId
   override map (currently 1 entry) covers them.

3. Non-mod lockfile entries (shaderpacks under shaderpacks/, configs
   under config/, etc.) are skipped explicitly by path prefix check.

Vanilla deps (minecraft, neoforge, forge, fabric, java, javafml, etc.)
are pre-seeded as present.

Jars cached at /tmp/bns-check-deps-cache/<sha1>.jar; second-run cost is
~1.5s. First run downloads ~150MB.

The script would have caught the v0.15.0 -> v0.15.1 incident: Slice &
Dice's jar declares kotlinforforge required in mods.toml even though
Modrinth's dep field only lists Create. The Modrinth-only check (earlier
draft) wouldn't have helped; the mods.toml-based check does.
2026-05-23 11:55:38 +00:00
Matt 4ee4a2bb43 scripts: make Build-Pack and Deploy-Brass cross-platform
Two small fixes that surface when running the deploy pipeline on a
non-Windows host (we now do this on glados via the Telegram bridge):

- Build-Pack.ps1: fall back to launcher/ModpackLauncher.csproj <Version>
  when Get-Item.VersionInfo.FileVersion returns empty. Linux PowerShell
  can't parse PE FileVersion from a Windows .exe, so the previous code
  threw "set <Version> in ModpackLauncher.csproj and republish" -- but
  the csproj <Version> *was* set, just not readable from a foreign PE.
  Appends ".0" so the embedded value still matches the 4-part form the
  Windows compile bakes in.

- Deploy-Brass.ps1: prefer rsync where available, fall back to robocopy
  otherwise. robocopy is Windows-only and bails on Linux/macOS hosts.
2026-05-22 14:23:09 +00:00
Matt f280e107f3 Add 'local' deploy mode to Deploy-Brass.ps1
When ServerSshHost = 'local' the server-binary stage skips scp/ssh and
does an in-place Copy-Item + chmod + Move-Item on the local filesystem.
Pre-flight pgrep also runs locally. Allows running the deploy script on
the server itself (glados in our case) without setting up ssh-to-self.

Other deploy modes (remote scp/ssh) unchanged.
2026-05-22 14:08:02 +00:00
Matt Sijbers ed70ff52e9 Deploy-Brass: extend manifest verification to all fields
The previous check covered version, launcherVersion/Url, and a single
sampled self-hosted URL. Expanded to cover every field that has ever
been a foot-gun:

  Required (must always be present and match pack.lock.json):
    name, version, minecraft.version, loader.type, loader.version,
    launcherVersion, launcherUrl

  Optional but consistency-checked: if pack.lock.json declares the
  field, the manifest MUST also have it (and defaultServer must include
  a non-empty ip). Catches the case where someone removes the field
  from pack.lock or Build-Pack drops it silently:
    panelUrl, defaultShader, defaultServer

  files[]: every entry validated for path/url/sha1/size shape; every
  self-hosted (non-CDN) url checked for the expected host. Catches
  partial-update bugs where some URLs migrate hosts but others don't.

URL host checks use the configured $ManifestPublicUrl host as the
source of truth; CDN-hosted mods (modrinth/forgecdn/curseforge) are
intentionally exempt.
2026-05-20 21:37:55 +01:00
Matt Sijbers 4e31f5ab1a Deploy-Brass: prevent silent loss of launcher metadata in manifest
Two safeguards so a -Stage Pack run never strips launcherVersion/
launcherUrl from the deployed manifest (the original bug that left
old launchers unable to see upgrade prompts):

  1. Always pass -LauncherExePath to Build-Pack.ps1 when a local
     publish exists, regardless of stage. Previously this only fired
     for stages that included Launcher, so Pack-only deploys regressed
     the manifest to a version with no launcher metadata.

  2. New post-deploy verification step fetches the published manifest
     and asserts: pack version matches lockfile, launcherVersion +
     launcherUrl present, all self-hosted URLs use the configured
     manifest host. Throws on any mismatch.
2026-05-20 21:35:39 +01:00
Matt Sijbers 62c88d4895 fix(deploy): publish manifest.json on Pack-only deploys
Stage 5 of Deploy-Brass.ps1 was gated only on \$shouldRunLauncher, so a
"-Stage Pack" run regenerated the manifest locally + mirrored
pack/overrides/ to the share, but never copied the new manifest.json
itself. Result: tweak jars/configs landed on the share, but clients
fetching the (still-old) manifest never knew about the new SHA-1s and
skipped the re-sync. Caught when fixing the brassandsigil_tweaks jar:
the public manifest stayed at 0.9.2 even though local was 0.9.3.

Split into two stages -- launcher exe stays gated on \$shouldRunLauncher,
manifest.json now publishes whenever \$shouldRunPack (so any Pack, All,
or Launcher deploy includes it).
2026-05-09 22:32:01 +01:00
Matt Sijbers a1331212cb Initial commit: Brass & Sigil monorepo
Self-hosted Minecraft modpack distribution + administration system.

- launcher/  Avalonia 12 desktop client; single-file win-x64 publish.
             Microsoft auth via XboxAuthNet, manifest+SHA-1 mod sync,
             portable install path, sidecar settings.
- server/    brass-sigil-server daemon (.NET 8, linux-x64). Wraps the
             MC subprocess, embedded Kestrel admin panel with cookie
             auth + rate limiting, RCON bridge, scheduled backups,
             BlueMap CLI integration with player markers + skin proxy,
             friend-side whitelist request flow, world wipe with seed
             selection (keep current / random / custom).
- pack/      pack.lock.json (Modrinth + manual CurseForge entries),
             data-only tweak source under tweaks/, build outputs in
             overrides/ (gitignored).
- scripts/   Build-Pack / Build-Tweaks / Update-Pack / Check-Updates
             plus Deploy-Brass.ps1 unified one-shot deploy with
             version-bump pre-flight and daemon-state detection.
2026-05-05 00:19:05 +01:00