@makefully/adaptfully 4.3.0 → 5.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 5.0.0 — 2026-09-11
6
+
7
+ ### Changed
8
+
9
+ - **Breaking:** Wrapfully extracts always land in `output/<platform>/` (including single-platform `build` / `release` / `deploy`). Sequential runs no longer overwrite siblings. Deploy still falls back to a legacy flat `output/` artifact if present.
10
+
5
11
  ## 4.3.0 — 2026-09-11
6
12
 
7
13
  ### Added
package/README.md CHANGED
@@ -30,7 +30,7 @@ adaptfully prebuild web # deploy/ → output/web-prebuild/
30
30
  adaptfully build steam # Yap /yap/wrapfully chore → artifact zip
31
31
  adaptfully deploy web --deployment web-prod # Yap deploy chore
32
32
  adaptfully release android --encrypt # optional envelope encryption
33
- adaptfully release steam,android,ios # sequential platforms; extracts to output/<platform>/
33
+ adaptfully release steam,android,ios # sequential platforms; each → output/<platform>/
34
34
  adaptfully release --platforms steam,android # same, flag form
35
35
  adaptfully steam-publish # one-time: log in with steamcmd → assets/meta/deployments/steam/steam.json
36
36
  ```
@@ -47,7 +47,7 @@ adaptfully steam-publish # one-time: log in with steamcmd
47
47
  | `android-keystore` | One-time local setup: generate debug/release keystores and write `android` `build.json` (also updates `.gitignore`) |
48
48
  | `apple-signing` | One-time local setup: CSR → Apple `.cer` → `.p12` / provisioning profiles under `ios/apple/` (also updates `.gitignore`) |
49
49
 
50
- Comma-separated platforms (or `--platforms`) run **sequentially**. Multi-platform extracts go to `output/<platform>/` so sibling results are not overwritten; only that folder’s prior `artifacts/` / status files are cleared before each extract. A single platform still extracts to `output/` for backward compatibility.
50
+ Comma-separated platforms (or `--platforms`) run **sequentially**. Build/deploy/release extracts always go to `output/<platform>/` so sibling results are not overwritten; only that folder’s prior `artifacts/` / status files are cleared before each extract.
51
51
 
52
52
  **Server** means the Showfully Yap base (`SHOWFULLY_SERVER` / `wrapfully.json` `showfullyServer` or `server`), default `https://make.makefullystudios.com/`. Wrapfully workers claim chores with a separate service token.
53
53
 
@@ -283,7 +283,7 @@ import {
283
283
 
284
284
  ## Wrapfully deploy
285
285
 
286
- After prebuild, the build and deploy stages zip `output/<platform>-prebuild/` and POST it to a Wrapfully build server. Artifacts are saved to `./output/`.
286
+ After prebuild, the build and deploy stages zip `output/<platform>-prebuild/` and POST it to a Wrapfully build server. Artifacts are saved to `./output/<platform>/`.
287
287
 
288
288
  ## Quick start
289
289
 
@@ -322,7 +322,7 @@ npx adaptfully apple-publish [--deployment ios] [--category C] [--identity I] [-
322
322
  |----------|---------|-------------|
323
323
  | `platform` | — | Platform key from `config.platforms` (`web`, `steam`, etc.) |
324
324
  | `server` | see below | Wrapfully server base URL (`build` and `deploy` only) |
325
- | `mode` | `extract` | `extract` unpacks the response zip into `./output/`; any other value saves `./output/{name}-{version}-{builder}.zip` |
325
+ | `mode` | `extract` | `extract` unpacks the response zip into `./output/<platform>/`; any other value saves `./output/<platform>/{name}-{version}-{builder}.zip` |
326
326
 
327
327
  Examples:
328
328
 
@@ -402,7 +402,9 @@ mygame/
402
402
  │ └── index.html
403
403
  ├── output/
404
404
  │ ├── web-prebuild/ # after adaptfully prebuild web
405
- │ └── steam-prebuild/ # after adaptfully prebuild steam
405
+ │ ├── steam-prebuild/ # after adaptfully prebuild steam
406
+ │ ├── web/ # after adaptfully build/release web
407
+ │ └── steam/ # after adaptfully build/release steam
406
408
  └── assets/
407
409
  └── meta/ # shared files packaged as meta/ in the zip
408
410
  ├── icon-foreground.png
@@ -727,7 +729,7 @@ To sign the app, place your certificate at `assets/meta/deployments/<deployment>
727
729
 
728
730
  ## Response
729
731
 
730
- The server responds with a zip stream containing build artifacts (`.apk`, `.aab`, `.ipa`, `.app`, `.exe`, etc.) and optional status files. By default the client extracts this into `./output/`. Use a non-`extract` mode value to save the raw response zip instead.
732
+ The server responds with a zip stream containing build artifacts (`.apk`, `.aab`, `.ipa`, `.app`, `.exe`, etc.) and optional status files. By default the client extracts this into `./output/<platform>/`. Use a non-`extract` mode value to save the raw response zip instead.
731
733
 
732
734
  Every build also includes `wrapfully-status.json` with structured `success`, `warn`, and `error` events. The client prints these after extraction and exits with code 1 if any errors were reported, so build failures do not crash the server silently.
733
735
 
@@ -17,18 +17,17 @@ export function buildOutputDir(pkg, outputRoot = 'output') {
17
17
  }
18
18
 
19
19
  /**
20
- * Where a platform's Wrapfully zip is extracted.
21
- * Multi-platform runs use `output/<platformKey>/` so siblings are not overwritten.
22
- * Single-platform runs keep `output/` for backward compatibility.
20
+ * Where a platform's Wrapfully zip is extracted: always `output/<platformKey>/`
21
+ * so sequential single-platform and multi-platform runs share one layout.
22
+ * Without a platform key, falls back to `outputRoot`.
23
23
  *
24
24
  * @param {string} outputRoot
25
25
  * @param {string} [platformKey]
26
- * @param {{ multiPlatform?: boolean }} [options]
27
26
  * @returns {string}
28
27
  */
29
- export function resolveExtractRoot(outputRoot, platformKey, options = {}) {
28
+ export function resolveExtractRoot(outputRoot, platformKey) {
30
29
  const root = path.resolve(outputRoot);
31
- if (options.multiPlatform && platformKey) {
30
+ if (platformKey) {
32
31
  return path.join(root, platformKey);
33
32
  }
34
33
  return root;
@@ -55,9 +54,10 @@ export function clearStaleBuildExtract(extractRoot = 'output') {
55
54
 
56
55
  /**
57
56
  * Resolve the artifact directory from a prior `adaptfully build` (or compatible zip extract).
57
+ * Prefers `output/<platform>/`; still accepts a legacy flat `output/` extract.
58
58
  *
59
59
  * @param {{ name: string, version: string, config?: { outputFolder?: string } }} pkg
60
- * @param {{ outputRoot?: string, platformKey?: string, multiPlatform?: boolean }} [options]
60
+ * @param {{ outputRoot?: string, platformKey?: string }} [options]
61
61
  * @returns {string}
62
62
  */
63
63
  export function resolveBuildArtifactDir(pkg, options = {}) {
@@ -65,7 +65,7 @@ export function resolveBuildArtifactDir(pkg, options = {}) {
65
65
  const candidates = [];
66
66
 
67
67
  if (options.platformKey) {
68
- candidates.push(resolveExtractRoot(outputRoot, options.platformKey, { multiPlatform: true }));
68
+ candidates.push(resolveExtractRoot(outputRoot, options.platformKey));
69
69
  }
70
70
  candidates.push(outputRoot);
71
71
 
@@ -49,7 +49,7 @@ export function resolveWrapfullyRoute(buildSpec) {
49
49
  /**
50
50
  * @param {AdaptfullyStage} stage
51
51
  * @param {string} platformKey
52
- * @param {{ pkg: object, deployFolder: string, server?: string, mode?: string, deployment?: string, artifactPath?: string, log?: (message: string) => void, outputRoot?: string, accessToken?: string, encrypt?: boolean, encryptPublicKey?: string, wrapfullyConfig?: object, extractRoot?: string, multiPlatform?: boolean }} options
52
+ * @param {{ pkg: object, deployFolder: string, server?: string, mode?: string, deployment?: string, artifactPath?: string, log?: (message: string) => void, outputRoot?: string, accessToken?: string, encrypt?: boolean, encryptPublicKey?: string, wrapfullyConfig?: object, extractRoot?: string }} options
53
53
  */
54
54
  export async function runAdaptfullyStage(stage, platformKey, options) {
55
55
  if (!VALID_STAGES.has(stage)) {
@@ -62,7 +62,7 @@ export async function runAdaptfullyStage(stage, platformKey, options) {
62
62
  let deployments = resolveDeploymentsForPlatform(platformKey, pkg);
63
63
  const outputRoot = buildOutputDir(pkg, options.outputRoot);
64
64
  const extractRoot = options.extractRoot
65
- ?? resolveExtractRoot(outputRoot, platformKey, { multiPlatform: options.multiPlatform === true });
65
+ ?? resolveExtractRoot(outputRoot, platformKey);
66
66
 
67
67
  if (options.deployment) {
68
68
  if (!deployments.includes(options.deployment)) {
@@ -85,7 +85,6 @@ export async function runAdaptfullyStage(stage, platformKey, options) {
85
85
  artifactPath = resolveBuildArtifactDir(pkg, {
86
86
  outputRoot: options.outputRoot,
87
87
  platformKey,
88
- multiPlatform: options.multiPlatform,
89
88
  });
90
89
  }
91
90
 
@@ -198,7 +197,7 @@ export async function runAdaptfullyStage(stage, platformKey, options) {
198
197
 
199
198
  /**
200
199
  * Run a stage for one or more platforms sequentially.
201
- * Multi-platform extracts land in `output/<platformKey>/` so outputs do not overwrite.
200
+ * Each platform extracts to `output/<platformKey>/`.
202
201
  *
203
202
  * @param {AdaptfullyStage} stage
204
203
  * @param {string[]} platformKeys
@@ -206,21 +205,17 @@ export async function runAdaptfullyStage(stage, platformKey, options) {
206
205
  */
207
206
  export async function runAdaptfullyStages(stage, platformKeys, options) {
208
207
  const log = options.log ?? console.log;
209
- const multiPlatform = platformKeys.length > 1;
210
208
  /** @type {{ platformKey: string, ok: boolean, result?: object, error?: Error }[]} */
211
209
  const results = [];
212
210
 
213
- if (multiPlatform) {
211
+ if (platformKeys.length > 1) {
214
212
  log(`adaptfully: sequential ${stage} for ${platformKeys.join(', ')}`);
215
213
  }
216
214
 
217
215
  for (const platformKey of platformKeys) {
218
216
  log(`adaptfully: ——— ${stage} ${platformKey} ———`);
219
217
  try {
220
- const result = await runAdaptfullyStage(stage, platformKey, {
221
- ...options,
222
- multiPlatform,
223
- });
218
+ const result = await runAdaptfullyStage(stage, platformKey, options);
224
219
  results.push({ platformKey, ok: true, result });
225
220
  } catch (err) {
226
221
  const error = err instanceof Error ? err : new Error(String(err));
@@ -286,10 +281,10 @@ export async function adaptfullyFromCli(argv = process.argv) {
286
281
  + ' release Yap release chore (build + configured deployments)\n'
287
282
  + '\n'
288
283
  + ' Multiple platforms (comma-separated or --platforms) run sequentially.\n'
289
- + ' Multi-platform extracts go to output/<platform>/ so siblings are preserved.\n'
284
+ + ' Extracts always go to output/<platform>/ so siblings are preserved.\n'
290
285
  + '\n'
291
286
  + ' --deployment <key> Target a single named deployment.\n'
292
- + ' --artifact <path> Prior build artifact directory (deploy only; default: ./output/ after build).\n'
287
+ + ' --artifact <path> Prior build artifact directory (deploy only; default: ./output/<platform>/ after build).\n'
293
288
  + ' --encrypt Envelope-encrypt chore to Wrapfully (optional; default key embedded).\n'
294
289
  + ' --encrypt-public-key <pem|path> Override Wrapfully public key when encrypting.\n'
295
290
  + '\n'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/adaptfully",
3
- "version": "4.3.0",
3
+ "version": "5.0.0",
4
4
  "description": "Platform abstraction and Wrapfully deploy client for Makefully games",
5
5
  "type": "module",
6
6
  "main": "./lib/node/index.js",