@tutti-os/app-release-tools 0.0.7 → 0.0.9
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/README.md +9 -9
- package/bin/{build-nextop-app-catalog.mjs → build-tutti-app-catalog.mjs} +5 -5
- package/bin/{build-nextop-app-release.mjs → build-tutti-app-release.mjs} +9 -9
- package/bin/{bump-nextop-app-version.mjs → bump-tutti-app-version.mjs} +3 -3
- package/bin/{verify-nextop-app-release-artifacts.mjs → verify-tutti-app-release-artifacts.mjs} +4 -4
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
# @tutti-os/app-release-tools
|
|
2
2
|
|
|
3
|
-
Command-line tools for publishing
|
|
3
|
+
Command-line tools for publishing Tutti workspace apps into App Center release metadata.
|
|
4
4
|
|
|
5
5
|
## Commands
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
build-
|
|
9
|
-
build-
|
|
10
|
-
build-
|
|
11
|
-
bump-
|
|
12
|
-
verify-
|
|
13
|
-
verify-
|
|
8
|
+
build-tutti-app-release --app-id vibe-design --package-dir dist/tutti-app/vibe-design --base-url https://cdn.example.test/tutti-app-releases
|
|
9
|
+
build-tutti-app-catalog --release-file ./apps/vibe-design/latest.json --output ./catalog.json
|
|
10
|
+
build-tutti-app-catalog --existing-catalog ./catalog.json --release-file ./apps/vibe-design/latest.json --output ./catalog.json
|
|
11
|
+
bump-tutti-app-version --app-id vibe-design --manifest ./tutti.app.json --bump patch
|
|
12
|
+
verify-tutti-app-release-artifacts --release-file ./apps/vibe-design/latest.json
|
|
13
|
+
verify-tutti-app-release-artifacts --catalog-file ./catalog.json --release-file ./apps/vibe-design/latest.json
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The release command validates a complete
|
|
16
|
+
The release command validates a complete Tutti app package, creates a zip, writes immutable `release.json`, and writes mutable `latest.json`.
|
|
17
17
|
|
|
18
18
|
The version bump command updates an app manifest from one stable semver version
|
|
19
19
|
to the next major, minor, or patch version.
|
|
20
20
|
|
|
21
|
-
The catalog command merges one or more release files into `
|
|
21
|
+
The catalog command merges one or more release files into `tutti.app.catalog.v1`.
|
|
22
22
|
Pass `--existing-catalog` to preserve existing catalog apps and update only the
|
|
23
23
|
apps represented by the release files. With `--existing-catalog`, release files
|
|
24
24
|
are optional, which allows rewriting an existing catalog without changing its app
|
|
@@ -6,11 +6,11 @@ import path from "node:path";
|
|
|
6
6
|
import {
|
|
7
7
|
releaseToCatalogApp,
|
|
8
8
|
validateRelease
|
|
9
|
-
} from "./build-
|
|
9
|
+
} from "./build-tutti-app-release.mjs";
|
|
10
10
|
|
|
11
|
-
const catalogSchemaVersion = "
|
|
11
|
+
const catalogSchemaVersion = "tutti.app.catalog.v1";
|
|
12
12
|
|
|
13
|
-
export async function
|
|
13
|
+
export async function buildTuttiAppCatalog(options) {
|
|
14
14
|
const existingCatalogPath = options.existingCatalogPath
|
|
15
15
|
? path.resolve(String(options.existingCatalogPath))
|
|
16
16
|
: null;
|
|
@@ -18,7 +18,7 @@ export async function buildNextopAppCatalog(options) {
|
|
|
18
18
|
const outputPath = path.resolve(
|
|
19
19
|
options.outputPath
|
|
20
20
|
? String(options.outputPath)
|
|
21
|
-
: "dist/
|
|
21
|
+
: "dist/tutti-app-catalog/catalog.json"
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const seenAppIDs = new Set();
|
|
@@ -148,7 +148,7 @@ function parseArgs(argv) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
export async function main() {
|
|
151
|
-
const result = await
|
|
151
|
+
const result = await buildTuttiAppCatalog(parseArgs(process.argv.slice(2)));
|
|
152
152
|
process.stdout.write(`${JSON.stringify(result.catalog, null, 2)}\n`);
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -5,25 +5,25 @@ import { pathToFileURL } from "node:url";
|
|
|
5
5
|
import { cp, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
|
|
8
|
-
const manifestSchemaVersion = "
|
|
9
|
-
const cliManifestSchemaVersion = "
|
|
10
|
-
const releaseSchemaVersion = "
|
|
8
|
+
const manifestSchemaVersion = "tutti.app.manifest.v1";
|
|
9
|
+
const cliManifestSchemaVersion = "tutti.app.cli.v1";
|
|
10
|
+
const releaseSchemaVersion = "tutti.app.release.v1";
|
|
11
11
|
|
|
12
|
-
export async function
|
|
12
|
+
export async function buildTuttiAppRelease(options) {
|
|
13
13
|
const appId = requireNonEmpty(options.appId, "appId");
|
|
14
14
|
requireSafePathSegment(appId, "appId");
|
|
15
15
|
const packageDir = path.resolve(
|
|
16
16
|
requireNonEmpty(options.packageDir, "packageDir")
|
|
17
17
|
);
|
|
18
18
|
const outputDir = path.resolve(
|
|
19
|
-
options.outputDir ? String(options.outputDir) : "dist/
|
|
19
|
+
options.outputDir ? String(options.outputDir) : "dist/tutti-app-release"
|
|
20
20
|
);
|
|
21
21
|
const baseUrl = normalizeBaseUrl(requireNonEmpty(options.baseUrl, "baseUrl"));
|
|
22
22
|
const publishedAt =
|
|
23
23
|
options.publishedAt || new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
24
24
|
const gitSha = options.gitSha || resolveGitSha();
|
|
25
25
|
|
|
26
|
-
const manifestPath = path.join(packageDir, "
|
|
26
|
+
const manifestPath = path.join(packageDir, "tutti.app.json");
|
|
27
27
|
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
28
28
|
validateManifest(manifest, manifestPath);
|
|
29
29
|
if (manifest.appId !== appId) {
|
|
@@ -305,9 +305,9 @@ function validateCLIHandler(handler, label) {
|
|
|
305
305
|
}
|
|
306
306
|
if (
|
|
307
307
|
typeof handler.path !== "string" ||
|
|
308
|
-
!handler.path.startsWith("/
|
|
308
|
+
!handler.path.startsWith("/tutti/cli/")
|
|
309
309
|
) {
|
|
310
|
-
throw new Error(`${label}.path must start with /
|
|
310
|
+
throw new Error(`${label}.path must start with /tutti/cli/`);
|
|
311
311
|
}
|
|
312
312
|
const timeoutMs = handler.timeoutMs ?? 30000;
|
|
313
313
|
if (!Number.isInteger(timeoutMs) || timeoutMs < 1000 || timeoutMs > 300000) {
|
|
@@ -542,7 +542,7 @@ function parseArgs(argv) {
|
|
|
542
542
|
}
|
|
543
543
|
|
|
544
544
|
export async function main() {
|
|
545
|
-
const result = await
|
|
545
|
+
const result = await buildTuttiAppRelease(parseArgs(process.argv.slice(2)));
|
|
546
546
|
process.stdout.write(`${JSON.stringify(result.release, null, 2)}\n`);
|
|
547
547
|
}
|
|
548
548
|
|
|
@@ -3,11 +3,11 @@ import { readFile, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
|
|
6
|
-
import { validateManifest } from "./build-
|
|
6
|
+
import { validateManifest } from "./build-tutti-app-release.mjs";
|
|
7
7
|
|
|
8
8
|
const allowedBumps = new Set(["major", "minor", "patch"]);
|
|
9
9
|
|
|
10
|
-
export async function
|
|
10
|
+
export async function bumpTuttiAppVersion(options) {
|
|
11
11
|
const manifestPath = path.resolve(
|
|
12
12
|
requireNonEmpty(options.manifestPath, "manifestPath")
|
|
13
13
|
);
|
|
@@ -104,7 +104,7 @@ function readArgValue(argv, index, arg) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
export async function main() {
|
|
107
|
-
const result = await
|
|
107
|
+
const result = await bumpTuttiAppVersion(parseArgs(process.argv.slice(2)));
|
|
108
108
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
109
109
|
}
|
|
110
110
|
|
package/bin/{verify-nextop-app-release-artifacts.mjs → verify-tutti-app-release-artifacts.mjs}
RENAMED
|
@@ -5,11 +5,11 @@ import { readFile } from "node:fs/promises";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
7
|
|
|
8
|
-
import { validateRelease } from "./build-
|
|
8
|
+
import { validateRelease } from "./build-tutti-app-release.mjs";
|
|
9
9
|
|
|
10
|
-
const catalogSchemaVersion = "
|
|
10
|
+
const catalogSchemaVersion = "tutti.app.catalog.v1";
|
|
11
11
|
|
|
12
|
-
export async function
|
|
12
|
+
export async function verifyTuttiAppReleaseArtifacts(options) {
|
|
13
13
|
const releaseFiles = normalizeFiles(options.releaseFiles);
|
|
14
14
|
const catalogFile = options.catalogFile
|
|
15
15
|
? path.resolve(String(options.catalogFile))
|
|
@@ -293,7 +293,7 @@ function parseArgs(argv) {
|
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
export async function main() {
|
|
296
|
-
const result = await
|
|
296
|
+
const result = await verifyTuttiAppReleaseArtifacts(
|
|
297
297
|
parseArgs(process.argv.slice(2))
|
|
298
298
|
);
|
|
299
299
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutti-os/app-release-tools",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"build-
|
|
8
|
-
"build-
|
|
9
|
-
"bump-
|
|
10
|
-
"verify-
|
|
7
|
+
"build-tutti-app-release": "./bin/build-tutti-app-release.mjs",
|
|
8
|
+
"build-tutti-app-catalog": "./bin/build-tutti-app-catalog.mjs",
|
|
9
|
+
"bump-tutti-app-version": "./bin/bump-tutti-app-version.mjs",
|
|
10
|
+
"verify-tutti-app-release-artifacts": "./bin/verify-tutti-app-release-artifacts.mjs"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
|
-
"./build-
|
|
14
|
-
"./build-
|
|
15
|
-
"./bump-
|
|
16
|
-
"./verify-
|
|
13
|
+
"./build-tutti-app-release": "./bin/build-tutti-app-release.mjs",
|
|
14
|
+
"./build-tutti-app-catalog": "./bin/build-tutti-app-catalog.mjs",
|
|
15
|
+
"./bump-tutti-app-version": "./bin/bump-tutti-app-version.mjs",
|
|
16
|
+
"./verify-tutti-app-release-artifacts": "./bin/verify-tutti-app-release-artifacts.mjs"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"bin",
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "node -e \"\"",
|
|
32
|
-
"test": "node --test ../../../tools/scripts/build-
|
|
32
|
+
"test": "node --test ../../../tools/scripts/build-tutti-app-release.test.mjs"
|
|
33
33
|
}
|
|
34
34
|
}
|