Skip to content

Commit cee516d

Browse files
JayNightmareCopilot
andcommitted
fix: ship public launcher config and dedicated profile page in 1.4.2
Load only approved public .env.prod/.env.dev values into native builds, retain production defaults in CI, and keep account pages exclusive. Add regression tests and support repair of an existing signed pack with verified staged payloads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 34ae0b7 commit cee516d

23 files changed

Lines changed: 1729 additions & 77 deletions

‎.env.example‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ CURSEFORGE_API_URL=https://api.curseforge.com
77
# MARS_OVERRIDE_BASE_URL=https://raw.githubusercontent.com/OWNER/REPO/COMMIT/modpack/Mars%20Client/overrides
88

99
# Batch 3 community/account public deployment configuration.
10-
# Export these to the Rust build environment (or runtime process environment).
11-
# This .env file is NOT automatically loaded by the desktop account commands.
10+
# Native builds read approved public settings from .env.dev (debug) / .env.prod (release).
11+
# Process environment overrides the local file; versioned config/production.env supplies CI defaults.
12+
# Do not package dotenv files or put JWT/provider/private signing secrets into the client.
1213
# API server origin/base WITHOUT /api, including Batch 3 /api/community/capsules.
1314
# Desktop streams JARs with its Rust-held session bearer; no upload keys are needed here.
1415
# Client ceiling: 64 MiB. Backend operator limits are authoritative (defaults 64 MiB/10 active/7 days).
@@ -20,9 +21,15 @@ MARS_WEBSITE_BASE=https://mars.nexusgit.info
2021
# Explicit recipient required; no default and no client-side role grants.
2122
MARS_SPONSORS_URL=
2223

23-
# Public updater key only. Export to the Rust build environment; .env is not loaded.
24+
# Pack endpoint and Ed25519 public verification key.
25+
MARS_MANIFEST_BASE_URL=https://api.nexusgit.info/api/v1
26+
MARS_MANIFEST_PUBLIC_KEY=a88e7dc70a1227cbc3decac967664e3bea75da9d72550e14f2c6a4ea8118391e
27+
# Legacy MARS_COMMAND_API_URL=<origin> is accepted and resolves to <origin>/api/v1.
28+
29+
# Public updater key only. Native builds embed this allowlisted setting.
2430
# Use the literal outer-base64 contents of the Tauri .pub file, not a path.
25-
# Release builds require this; debug builds without it cannot check/install updates.
26-
MARS_UPDATER_PUBLIC_KEY=
31+
# Leave this line commented to retain the versioned production public key.
32+
# An explicit empty override disables debug updates; release builds reject it.
33+
# MARS_UPDATER_PUBLIC_KEY=
2734
# Never put TAURI_SIGNING_PRIVATE_KEY or its password in this file.
2835
# Keep the updater private key outside the repository and in protected CI secrets.

‎.github/workflows/publish-manifest.yml‎

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ on:
1010
description: "Repository path containing the small CurseForge manifest.json (overrides optional)"
1111
required: true
1212
default: "modpack/Mars"
13+
source_release:
14+
description: "Optional existing release tag containing an already signed manifest pair"
15+
required: false
16+
default: ""
17+
payload_asset:
18+
description: "Optional JAR asset in that release, installed under mods after hash verification"
19+
required: false
20+
default: ""
1321
prerelease:
1422
description: "Publish as a pre-release (not served to users)"
1523
type: boolean
@@ -30,6 +38,54 @@ jobs:
3038
steps:
3139
- uses: actions/checkout@v4
3240

41+
- name: Test staged payload deployment
42+
run: python3 -m unittest discover -s scripts -p test_deploy_pack_release.py
43+
44+
- name: Download existing signed pack
45+
if: ${{ inputs.source_release != '' }}
46+
env:
47+
GH_TOKEN: ${{ github.token }}
48+
SOURCE_RELEASE: ${{ inputs.source_release }}
49+
PACK_VERSION: ${{ inputs.pack_version }}
50+
PAYLOAD_ASSET: ${{ inputs.payload_asset }}
51+
shell: bash
52+
run: |
53+
set -euo pipefail
54+
[[ "$SOURCE_RELEASE" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$ ]]
55+
[[ "$PACK_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
56+
mkdir -p manifest-dist
57+
gh release download "$SOURCE_RELEASE" --repo "$GITHUB_REPOSITORY" \
58+
--pattern manifest.json --pattern manifest.json.sig --dir manifest-dist
59+
python3 - <<'PY'
60+
import json, os
61+
from pathlib import Path
62+
path = Path("manifest-dist/manifest.json")
63+
assert path.stat().st_size <= 8 * 1024 * 1024, "Manifest exceeds 8 MiB"
64+
manifest = json.loads(path.read_text(encoding="utf-8"))
65+
assert manifest["packVersion"] == os.environ["PACK_VERSION"], "Pack version differs"
66+
assert manifest["minecraftVersion"] == "1.21.1", "Minecraft version differs"
67+
assert manifest["loader"] == "neoforge" and manifest["loaderVersion"] == "21.1.250", "Loader differs"
68+
PY
69+
if [[ -n "$PAYLOAD_ASSET" ]]; then
70+
[[ "$PAYLOAD_ASSET" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*\.jar$ ]]
71+
mkdir -p release-payload
72+
gh release download "$SOURCE_RELEASE" --repo "$GITHUB_REPOSITORY" \
73+
--pattern "$PAYLOAD_ASSET" --dir release-payload
74+
python3 - <<'PY'
75+
import hashlib, json, os
76+
from pathlib import Path
77+
name = os.environ["PAYLOAD_ASSET"]
78+
entries = json.loads(Path("manifest-dist/manifest.json").read_text(encoding="utf-8"))["files"]
79+
matches = [entry for entry in entries if entry["path"] == "mods/" + name]
80+
assert len(matches) == 1, "Payload must be declared exactly once"
81+
entry = matches[0]
82+
path = Path("release-payload") / name
83+
assert path.stat().st_size <= 64 * 1024 * 1024, "Payload exceeds 64 MiB"
84+
assert path.stat().st_size == entry["size"], "Payload size differs"
85+
assert hashlib.sha256(path.read_bytes()).hexdigest() == entry["sha256"], "Payload hash differs"
86+
PY
87+
fi
88+
3389
- uses: dtolnay/rust-toolchain@stable
3490

3591
- name: Install Tauri Linux dependencies
@@ -53,6 +109,7 @@ jobs:
53109
workspaces: src-tauri
54110

55111
- name: Build manifest from CurseForge export
112+
if: ${{ inputs.source_release == '' }}
56113
working-directory: src-tauri
57114
env:
58115
CURSEFORGE_API_KEY: ${{ secrets.CURSEFORGE_API_KEY }}
@@ -72,6 +129,7 @@ jobs:
72129
../manifest-dist/manifest.json
73130
74131
- name: Sign manifest
132+
if: ${{ inputs.source_release == '' }}
75133
working-directory: src-tauri
76134
env:
77135
MARS_SIGNING_KEY: ${{ secrets.MARS_SIGNING_KEY }}
@@ -90,6 +148,7 @@ jobs:
90148
run: cargo run --release --example manifest_tool -- verify ../manifest-dist/manifest.json
91149

92150
- name: Publish release
151+
if: ${{ inputs.source_release == '' }}
93152
uses: softprops/action-gh-release@v2
94153
with:
95154
tag_name: pack-v${{ inputs.pack_version }}-manifest-${{ github.run_number }}
@@ -107,6 +166,7 @@ jobs:
107166
MARS_DEPLOY_USER: ${{ secrets.MARS_DEPLOY_USER }}
108167
MARS_DEPLOY_SSH_KEY: ${{ secrets.MARS_DEPLOY_SSH_KEY }}
109168
MARS_DEPLOY_KNOWN_HOSTS: ${{ secrets.MARS_DEPLOY_KNOWN_HOSTS }}
169+
PAYLOAD_ASSET: ${{ inputs.payload_asset }}
110170
run: |
111171
set -euo pipefail
112172
: "${MARS_DEPLOY_HOST:?MARS_DEPLOY_HOST secret is not set}"
@@ -155,11 +215,19 @@ jobs:
155215
manifest-dist/manifest.json.sig \
156216
"${REMOTE}:${STAGING_DIR}/"
157217
218+
if [[ -n "$PAYLOAD_ASSET" ]]; then
219+
[[ "$PAYLOAD_ASSET" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*\.jar$ ]]
220+
ssh "${SSH_ARGS[@]}" "$REMOTE" "mkdir -p '$STAGING_DIR/mods'"
221+
scp -i "$KEY_FILE" -P 22 \
222+
-o IdentitiesOnly=yes \
223+
-o BatchMode=yes \
224+
-o StrictHostKeyChecking=yes \
225+
-o "UserKnownHostsFile=$KNOWN_HOSTS_FILE" \
226+
"release-payload/$PAYLOAD_ASSET" "${REMOTE}:${STAGING_DIR}/mods/"
227+
fi
228+
158229
ssh "${SSH_ARGS[@]}" "$REMOTE" \
159-
"install -m 0644 '$STAGING_DIR/manifest.json.sig' '$RELEASE_DIR/.manifest.json.sig.next-${RUN_SUFFIX}' && \
160-
install -m 0644 '$STAGING_DIR/manifest.json' '$RELEASE_DIR/.manifest.json.next-${RUN_SUFFIX}' && \
161-
mv -f '$RELEASE_DIR/.manifest.json.sig.next-${RUN_SUFFIX}' '$RELEASE_DIR/manifest.json.sig' && \
162-
mv -f '$RELEASE_DIR/.manifest.json.next-${RUN_SUFFIX}' '$RELEASE_DIR/manifest.json'"
230+
"python3 - '$RELEASE_DIR' '$STAGING_DIR' '$RUN_SUFFIX'" < scripts/deploy-pack-release.py
163231
ssh "${SSH_ARGS[@]}" "$REMOTE" \
164232
"sudo -n systemctl restart mars-package-api"
165233

‎.github/workflows/release-client.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ jobs:
1717
environment: client-release
1818
env:
1919
MARS_UPDATER_PUBLIC_KEY: ${{ vars.MARS_UPDATER_PUBLIC_KEY }}
20-
MARS_MANIFEST_PUBLIC_KEY: a88e7dc70a1227cbc3decac967664e3bea75da9d72550e14f2c6a4ea8118391e
2120
strategy:
2221
fail-fast: false
2322
matrix:
@@ -63,6 +62,8 @@ jobs:
6362

6463
- run: npm run test:updater
6564

65+
- run: npm run test:ui
66+
6667
- name: Require updater public key
6768
shell: bash
6869
run: |
@@ -110,7 +111,9 @@ jobs:
110111
run: cargo test --locked --manifest-path src-tauri/Cargo.toml client_update_policy::tests
111112

112113
- name: Test pack manifest signing key
113-
run: cargo test --locked --manifest-path src-tauri/Cargo.toml --lib manifest::tests
114+
run: |
115+
cargo test --locked --manifest-path src-tauri/Cargo.toml --lib manifest::tests
116+
cargo test --locked --manifest-path src-tauri/Cargo.toml --test build_configuration
114117
115118
- name: Build signed Linux packages
116119
if: runner.os == 'Linux'

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ dist
152152

153153
# Stores Visual Studio Code versions used for testing Visual Studio Code extensions
154154
.vscode-test
155+
__pycache__/
155156

156157
# pnpm
157158
.pnpm-store

0 commit comments

Comments
 (0)