@fuman/build 0.0.1

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.
Files changed (105) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +108 -0
  3. package/ci/github-actions.d.ts +3 -0
  4. package/ci/github-actions.js +28 -0
  5. package/ci/index.d.ts +1 -0
  6. package/cli/commands/_utils.d.ts +8 -0
  7. package/cli/commands/_utils.js +18 -0
  8. package/cli/commands/build.d.ts +20 -0
  9. package/cli/commands/build.js +45 -0
  10. package/cli/commands/bump-version.d.ts +18 -0
  11. package/cli/commands/bump-version.js +72 -0
  12. package/cli/commands/cr.d.ts +17 -0
  13. package/cli/commands/cr.js +76 -0
  14. package/cli/commands/find-changed-packages.d.ts +12 -0
  15. package/cli/commands/find-changed-packages.js +44 -0
  16. package/cli/commands/gen-changelog.d.ts +12 -0
  17. package/cli/commands/gen-changelog.js +49 -0
  18. package/cli/commands/gen-deps-graph.d.ts +15 -0
  19. package/cli/commands/gen-deps-graph.js +78 -0
  20. package/cli/commands/jsr.d.ts +6 -0
  21. package/cli/commands/jsr.js +79 -0
  22. package/cli/commands/publish.d.ts +48 -0
  23. package/cli/commands/publish.js +197 -0
  24. package/cli/commands/release.d.ts +34 -0
  25. package/cli/commands/release.js +226 -0
  26. package/cli/commands/validate-workspace-deps.d.ts +38 -0
  27. package/cli/commands/validate-workspace-deps.js +68 -0
  28. package/cli/index.d.ts +3 -0
  29. package/cli/main.d.ts +2 -0
  30. package/config.d.ts +32 -0
  31. package/fuman-build.d.ts +1 -0
  32. package/fuman-build.js +33 -0
  33. package/git/github.d.ts +14 -0
  34. package/git/github.js +48 -0
  35. package/git/index.d.ts +1 -0
  36. package/git/utils.d.ts +38 -0
  37. package/git/utils.js +110 -0
  38. package/index.d.ts +7 -0
  39. package/index.js +46 -0
  40. package/jsr/build-jsr.d.ts +7 -0
  41. package/jsr/build-jsr.js +145 -0
  42. package/jsr/config.d.ts +48 -0
  43. package/jsr/create-packages.d.ts +8 -0
  44. package/jsr/create-packages.js +46 -0
  45. package/jsr/deno-json.d.ts +19 -0
  46. package/jsr/deno-json.js +80 -0
  47. package/jsr/generate-workspace.d.ts +9 -0
  48. package/jsr/generate-workspace.js +174 -0
  49. package/jsr/index.d.ts +5 -0
  50. package/jsr/populate.d.ts +45 -0
  51. package/jsr/populate.js +132 -0
  52. package/jsr/utils/external-libs.d.ts +8 -0
  53. package/jsr/utils/external-libs.js +46 -0
  54. package/jsr/utils/index.d.ts +4 -0
  55. package/jsr/utils/jsr-api.d.ts +23 -0
  56. package/jsr/utils/jsr-api.js +115 -0
  57. package/jsr/utils/jsr-json.d.ts +10 -0
  58. package/jsr/utils/jsr-json.js +80 -0
  59. package/jsr/utils/jsr.d.ts +11 -0
  60. package/jsr/utils/jsr.js +74 -0
  61. package/jsr.d.ts +1 -0
  62. package/jsr.js +23 -0
  63. package/misc/_config.d.ts +1 -0
  64. package/misc/_config.js +18 -0
  65. package/misc/exec.d.ts +9 -0
  66. package/misc/exec.js +40 -0
  67. package/misc/fs.d.ts +4 -0
  68. package/misc/fs.js +32 -0
  69. package/misc/index.d.ts +4 -0
  70. package/misc/path.d.ts +1 -0
  71. package/misc/path.js +12 -0
  72. package/misc/publish-order.d.ts +3 -0
  73. package/misc/publish-order.js +56 -0
  74. package/misc/tsconfig.d.ts +2 -0
  75. package/misc/tsconfig.js +28 -0
  76. package/npm/index.d.ts +1 -0
  77. package/npm/npm-api.d.ts +7 -0
  78. package/npm/npm-api.js +18 -0
  79. package/package-json/collect-package-jsons.d.ts +8 -0
  80. package/package-json/collect-package-jsons.js +61 -0
  81. package/package-json/find-package-json.d.ts +7 -0
  82. package/package-json/find-package-json.js +28 -0
  83. package/package-json/index.d.ts +5 -0
  84. package/package-json/parse.d.ts +4 -0
  85. package/package-json/parse.js +40 -0
  86. package/package-json/process-package-json.d.ts +13 -0
  87. package/package-json/process-package-json.js +132 -0
  88. package/package-json/types.d.ts +56 -0
  89. package/package-json/types.js +57 -0
  90. package/package-json/utils.d.ts +4 -0
  91. package/package-json/utils.js +27 -0
  92. package/package.json +67 -0
  93. package/versioning/bump-version.d.ts +48 -0
  94. package/versioning/bump-version.js +129 -0
  95. package/versioning/collect-files.d.ts +22 -0
  96. package/versioning/collect-files.js +66 -0
  97. package/versioning/generate-changelog.d.ts +13 -0
  98. package/versioning/generate-changelog.js +81 -0
  99. package/versioning/types.d.ts +32 -0
  100. package/vite/build-plugin.d.ts +73 -0
  101. package/vite/build-plugin.js +170 -0
  102. package/vite/config.d.ts +34 -0
  103. package/vite/index.d.ts +2 -0
  104. package/vite.d.ts +1 -0
  105. package/vite.js +4 -0
@@ -0,0 +1,79 @@
1
+ import process from "node:process";
2
+ import { jsrCreatePackages } from "../../jsr/create-packages.js";
3
+ import { generateDenoWorkspace } from "../../jsr/generate-workspace.js";
4
+ import { populateFromUpstream } from "../../jsr/populate.js";
5
+ import { loadConfig } from "./_utils.js";
6
+ import * as bc from "@drizzle-team/brocli";
7
+ const populate = bc.command({
8
+ name: "populate",
9
+ desc: "populate a local JSR instance with packages from an upstream registry",
10
+ options: {
11
+ upstream: bc.string().desc("URL of the upstream registry (default: process.env.JSR_URL)"),
12
+ createViaApi: bc.boolean("create-via-api").desc("create packages via the API instead of manually via web UI"),
13
+ packages: bc.string().desc("comma-separated list of packages to populate (with version, e.g. `@std/fs@0.105.0`)").required(),
14
+ downstream: bc.string().desc("URL of the downstream local registry").required(),
15
+ token: bc.string().desc("API token"),
16
+ quiet: bc.boolean().alias("q").desc("suppress output"),
17
+ publishArgs: bc.string("publish-args").desc("Additional arguments to pass to `deno publish`")
18
+ },
19
+ transform: (args) => {
20
+ return {
21
+ ...args,
22
+ packages: args.packages.split(",").map((s) => s.trim()),
23
+ publishArgs: args.publishArgs?.split(" ")
24
+ };
25
+ },
26
+ handler: populateFromUpstream
27
+ });
28
+ const createPackages = bc.command({
29
+ name: "create-packages",
30
+ desc: "create missing packages from the workspace",
31
+ options: {
32
+ registry: bc.string("registry").desc("URL of the registry to publish to").default("https://jsr.io"),
33
+ root: bc.string().desc("path to the root of the workspace (default: cwd)"),
34
+ token: bc.string("token").desc("token to use for managing the packages"),
35
+ githubRepo: bc.string("github-repo").desc("github repo to set for the package (requires --token)")
36
+ },
37
+ handler: async (args) => {
38
+ const hasFailed = await jsrCreatePackages({
39
+ workspaceRoot: args.root ?? process.cwd(),
40
+ registry: args.registry,
41
+ token: args.token,
42
+ githubRepo: args.githubRepo
43
+ });
44
+ if (!hasFailed) {
45
+ console.log("βœ… \x1B[;32mall packages were published\x1B[;0m");
46
+ }
47
+ }
48
+ });
49
+ const generateDenoWorkspaceCli = bc.command({
50
+ name: "gen-deno-workspace",
51
+ options: {
52
+ workspaceRoot: bc.string("root").desc("path to the root of the workspace (default: cwd)"),
53
+ withDryRun: bc.boolean("with-dry-run").desc("whether to run `deno publish --dry-run` after generating the workspace")
54
+ },
55
+ handler: async (args) => {
56
+ const workspaceRoot = args.workspaceRoot ?? process.cwd();
57
+ const rootConfig = await loadConfig({
58
+ workspaceRoot
59
+ });
60
+ const outDir = await generateDenoWorkspace({
61
+ workspaceRoot,
62
+ rootConfig: rootConfig?.jsr,
63
+ withDryRun: args.withDryRun
64
+ });
65
+ console.log(`\x1B[;32mdeno workspace generated at ${outDir}`);
66
+ }
67
+ });
68
+ const jsrCli = bc.command({
69
+ name: "jsr",
70
+ desc: "jsr-related commands",
71
+ subcommands: [
72
+ populate,
73
+ createPackages,
74
+ generateDenoWorkspaceCli
75
+ ]
76
+ });
77
+ export {
78
+ jsrCli
79
+ };
@@ -0,0 +1,48 @@
1
+ import { WorkspacePackage } from '../../package-json/collect-package-jsons.js';
2
+ import { bc } from './_utils.js';
3
+ export interface PublishPackagesResult {
4
+ failed: string[];
5
+ tarballs: string[];
6
+ }
7
+ export declare function publishPackages(params: {
8
+ workspaceRoot?: string;
9
+ workspace?: WorkspacePackage[];
10
+ packages: string[];
11
+ unpublishExisting?: boolean;
12
+ registryUrl?: string;
13
+ token?: string;
14
+ distDir?: string;
15
+ dryRun?: boolean;
16
+ publishArgs?: string[];
17
+ withTarballs?: boolean;
18
+ withBuild?: boolean;
19
+ skipVersionCheck?: boolean;
20
+ fixedVersion?: string;
21
+ }): Promise<PublishPackagesResult>;
22
+ export declare const publishPackagesCli: bc.Command<{
23
+ root: string | undefined;
24
+ unpublishExisting: boolean | undefined;
25
+ skipVersionCheck: boolean | undefined;
26
+ registryUrl: string | undefined;
27
+ token: string | undefined;
28
+ distDir: string | undefined;
29
+ dryRun: boolean | undefined;
30
+ publishArgs: string | undefined;
31
+ packages: string;
32
+ withTarballs: boolean | undefined;
33
+ withBuild: boolean | undefined;
34
+ fixedVersion: string | undefined;
35
+ }, {
36
+ root: string | undefined;
37
+ unpublishExisting: boolean | undefined;
38
+ skipVersionCheck: boolean | undefined;
39
+ registryUrl: string | undefined;
40
+ token: string | undefined;
41
+ distDir: string | undefined;
42
+ dryRun: boolean | undefined;
43
+ publishArgs: string | undefined;
44
+ packages: string;
45
+ withTarballs: boolean | undefined;
46
+ withBuild: boolean | undefined;
47
+ fixedVersion: string | undefined;
48
+ }>;
@@ -0,0 +1,197 @@
1
+ import * as fsp from "node:fs/promises";
2
+ import { resolve, join } from "node:path";
3
+ import process from "node:process";
4
+ import { asNonNull } from "@fuman/utils";
5
+ import { isRunningInGithubActions, writeGithubActionsOutput } from "../../ci/github-actions.js";
6
+ import { exec } from "../../misc/exec.js";
7
+ import { sortWorkspaceByPublishOrder } from "../../misc/publish-order.js";
8
+ import { npmCheckVersion } from "../../npm/npm-api.js";
9
+ import { collectPackageJsons, filterPackageJsonsForPublish } from "../../package-json/collect-package-jsons.js";
10
+ import { parsePackageJsonFile } from "../../package-json/parse.js";
11
+ import * as bc from "@drizzle-team/brocli";
12
+ import { buildPackage } from "./build.js";
13
+ const DEFAULT_REGISTRY_URL = "https://registry.npmjs.org";
14
+ async function publishPackages(params) {
15
+ const {
16
+ workspaceRoot = process.cwd(),
17
+ workspace = await collectPackageJsons(workspaceRoot, true),
18
+ packages,
19
+ unpublishExisting = false,
20
+ skipVersionCheck = false,
21
+ registryUrl = DEFAULT_REGISTRY_URL,
22
+ token,
23
+ distDir = "dist",
24
+ publishArgs = [],
25
+ dryRun,
26
+ withTarballs,
27
+ withBuild,
28
+ fixedVersion
29
+ } = params;
30
+ const workspaceWithoutRoot = workspace.filter((pkg) => !pkg.root);
31
+ const ordered = filterPackageJsonsForPublish(sortWorkspaceByPublishOrder(workspaceWithoutRoot), "npm");
32
+ const toPublish = packages.length === 1 && packages[0] === ":all" ? ordered : ordered.filter((pkg) => packages.includes(asNonNull(pkg.json.name)));
33
+ const failed = [];
34
+ const tarballs = [];
35
+ if (token != null && !dryRun) {
36
+ await exec([
37
+ "npm",
38
+ "config",
39
+ "set",
40
+ "--global",
41
+ new URL(":_authToken", registryUrl).href.replace(/^https:\/\//, "//"),
42
+ token
43
+ ], { throwOnError: true });
44
+ }
45
+ if (!dryRun) {
46
+ await exec(["npm", "whoami", "--registry", registryUrl], { throwOnError: true });
47
+ }
48
+ if (isRunningInGithubActions() && process.env.ACTIONS_ID_TOKEN_REQUEST_URL != null && registryUrl === DEFAULT_REGISTRY_URL) {
49
+ if (!publishArgs.some((it) => it.startsWith("--provenance"))) {
50
+ publishArgs.push("--provenance");
51
+ }
52
+ }
53
+ for (const pkg of toPublish) {
54
+ const pkgVersion = fixedVersion ?? asNonNull(pkg.json.version);
55
+ if (!dryRun && !skipVersionCheck && await npmCheckVersion({
56
+ registry: registryUrl,
57
+ package: asNonNull(pkg.json.name),
58
+ version: pkgVersion
59
+ })) {
60
+ if (unpublishExisting) {
61
+ await exec([
62
+ "npm",
63
+ "unpublish",
64
+ "--force",
65
+ "--registry",
66
+ registryUrl,
67
+ `${asNonNull(pkg.json.name)}@${pkgVersion}`
68
+ ], {
69
+ stdio: "inherit"
70
+ });
71
+ } else {
72
+ console.log(`Skipping ${pkg.json.name}@${pkgVersion} because it is already published`);
73
+ continue;
74
+ }
75
+ }
76
+ if (withBuild) {
77
+ if (pkg.json.scripts?.build !== void 0) {
78
+ const res2 = await exec([
79
+ "npm",
80
+ "run",
81
+ "build"
82
+ ], {
83
+ cwd: join(pkg.path),
84
+ stdio: "inherit"
85
+ });
86
+ if (res2.exitCode !== 0) {
87
+ console.log("failed to build %s", pkg.json.name);
88
+ failed.push(asNonNull(pkg.json.name));
89
+ continue;
90
+ }
91
+ } else {
92
+ try {
93
+ await buildPackage({
94
+ workspaceRoot,
95
+ workspace,
96
+ packageName: asNonNull(pkg.json.name),
97
+ fixedVersion
98
+ });
99
+ } catch (err) {
100
+ console.log("failed to build %s:", pkg.json.name);
101
+ console.error(err);
102
+ failed.push(asNonNull(pkg.json.name));
103
+ continue;
104
+ }
105
+ }
106
+ }
107
+ const fullDistDir = join(pkg.path, distDir);
108
+ if (fixedVersion != null) {
109
+ const distPkgJsonPath = join(fullDistDir, "package.json");
110
+ const pkgJson = await parsePackageJsonFile(distPkgJsonPath);
111
+ pkgJson.version = fixedVersion;
112
+ await fsp.writeFile(distPkgJsonPath, JSON.stringify(pkgJson, null, 4));
113
+ }
114
+ console.log(`publishing ${pkg.json.name}@${pkgVersion}`);
115
+ if (pkg.json.name?.includes("/")) {
116
+ if (!publishArgs.some((it) => it.startsWith("--access"))) {
117
+ publishArgs.push("--access=public");
118
+ }
119
+ }
120
+ const res = await exec([
121
+ "npm",
122
+ "publish",
123
+ "--registry",
124
+ registryUrl,
125
+ ...dryRun ? ["--dry-run"] : ["-q"],
126
+ ...publishArgs
127
+ ], {
128
+ cwd: fullDistDir,
129
+ stdio: "inherit"
130
+ });
131
+ if (res.exitCode !== 0) {
132
+ failed.push(asNonNull(pkg.json.name));
133
+ }
134
+ if (withTarballs) {
135
+ const tar = await exec(["npm", "pack", "-q"], {
136
+ cwd: fullDistDir
137
+ });
138
+ if (tar.exitCode !== 0) {
139
+ console.error(tar.stderr);
140
+ } else {
141
+ tarballs.push(tar.stdout.trim());
142
+ }
143
+ }
144
+ }
145
+ return {
146
+ failed,
147
+ tarballs
148
+ };
149
+ }
150
+ const publishPackagesCli = bc.command({
151
+ name: "publish",
152
+ desc: "publish packages to npm",
153
+ options: {
154
+ root: bc.string().desc("path to the root of the workspace (default: cwd)"),
155
+ unpublishExisting: bc.boolean("unpublish-existing").desc("whether to unpublish if the version is already published (only available for certain registries, won't work with registry.npmjs.org)"),
156
+ skipVersionCheck: bc.boolean("skip-version-check").desc("whether to skip checking if the version is already published"),
157
+ registryUrl: bc.string("registry").desc("URL of the registry to publish to"),
158
+ token: bc.string("token").desc("token to use for publishing (note: this will override the global .npmrc file)"),
159
+ distDir: bc.string("dist-dir").desc("directory to publish from, relative to package root (default: dist)"),
160
+ dryRun: bc.boolean("dry-run").desc("whether to skip publishing and only print what is going to happen"),
161
+ publishArgs: bc.string("publish-args").desc("arguments to pass to `npm publish`"),
162
+ packages: bc.positional("packages").desc("name of the packages to publish (comma-separated, or :all to publish the entire workspace)").default(":all"),
163
+ withTarballs: bc.boolean("with-tarballs").desc("whether to generate tarballs in the dist directory using `npm pack` (doesn't work with jsr)"),
164
+ withBuild: bc.boolean("with-build").desc("whether to build the package before publishing using `build` npm script (or defaulting to building using fuman-build if one is not found)"),
165
+ fixedVersion: bc.string("fixed-version").desc("version to publish the package to (overrides the version in every package.json, useful for pre-releases)")
166
+ },
167
+ handler: async (options) => {
168
+ const { failed, tarballs } = await publishPackages({
169
+ ...options,
170
+ workspaceRoot: options.root != null ? resolve(process.cwd(), options.root) : process.cwd(),
171
+ packages: options.packages.split(","),
172
+ publishArgs: options.publishArgs?.split(" ")
173
+ });
174
+ if (failed.length > 0) {
175
+ console.log("failed to publish:");
176
+ for (const pkg of failed) {
177
+ console.log(` ${pkg}`);
178
+ }
179
+ process.exit(1);
180
+ }
181
+ if (tarballs.length > 0) {
182
+ if (isRunningInGithubActions()) {
183
+ console.log("written paths to tarballs to `tarballs` output");
184
+ writeGithubActionsOutput("tarballs", tarballs.join(","));
185
+ } else {
186
+ console.log("tarballs generated:");
187
+ for (const tar of tarballs) {
188
+ console.log(` ${tar}`);
189
+ }
190
+ }
191
+ }
192
+ }
193
+ });
194
+ export {
195
+ publishPackages,
196
+ publishPackagesCli
197
+ };
@@ -0,0 +1,34 @@
1
+ import { bc } from './_utils.js';
2
+ export declare const releaseCli: bc.Command<{
3
+ kind: "auto" | "major" | "minor" | "patch";
4
+ withGithubRelease: boolean;
5
+ githubToken: string | undefined;
6
+ githubRepo: string | undefined;
7
+ withJsr: boolean;
8
+ jsrRegistry: string | undefined;
9
+ jsrToken: string | undefined;
10
+ jsrPublishArgs: string | undefined;
11
+ jsrCreatePackages: boolean | undefined;
12
+ withNpm: boolean | undefined;
13
+ npmToken: string | undefined;
14
+ npmPublishArgs: string | undefined;
15
+ npmDistDir: string | undefined;
16
+ npmRegistry: string | undefined;
17
+ dryRun: boolean | undefined;
18
+ }, {
19
+ kind: "auto" | "major" | "minor" | "patch";
20
+ withGithubRelease: boolean;
21
+ githubToken: string | undefined;
22
+ githubRepo: string | undefined;
23
+ withJsr: boolean;
24
+ jsrRegistry: string | undefined;
25
+ jsrToken: string | undefined;
26
+ jsrPublishArgs: string | undefined;
27
+ jsrCreatePackages: boolean | undefined;
28
+ withNpm: boolean | undefined;
29
+ npmToken: string | undefined;
30
+ npmPublishArgs: string | undefined;
31
+ npmDistDir: string | undefined;
32
+ npmRegistry: string | undefined;
33
+ dryRun: boolean | undefined;
34
+ }>;
@@ -0,0 +1,226 @@
1
+ import { createReadStream } from "node:fs";
2
+ import { basename } from "node:path";
3
+ import process from "node:process";
4
+ import { nodeReadableToWeb } from "@fuman/node";
5
+ import { asNonNull, notImplemented } from "@fuman/utils";
6
+ import { sort } from "semver";
7
+ import { createGithubRelease } from "../../git/github.js";
8
+ import { getLatestTag, getFirstCommit } from "../../git/utils.js";
9
+ import { jsrCreatePackages } from "../../jsr/create-packages.js";
10
+ import { generateDenoWorkspace } from "../../jsr/generate-workspace.js";
11
+ import { exec } from "../../misc/exec.js";
12
+ import { collectPackageJsons } from "../../package-json/collect-package-jsons.js";
13
+ import { bumpVersion } from "../../versioning/bump-version.js";
14
+ import { generateChangelog } from "../../versioning/generate-changelog.js";
15
+ import { loadConfig } from "./_utils.js";
16
+ import { formatBumpVersionResult } from "./bump-version.js";
17
+ import { publishPackages } from "./publish.js";
18
+ import * as bc from "@drizzle-team/brocli";
19
+ const releaseCli = bc.command({
20
+ name: "release",
21
+ desc: "release packages",
22
+ options: {
23
+ kind: bc.string("kind").desc("release kind").enum("major", "minor", "patch", "auto").default("auto"),
24
+ withGithubRelease: bc.boolean("with-github-release").desc("whether to create a github release (requires GITHUB_TOKEN env var). if false, will only create a commit with the release notes").default(false),
25
+ githubToken: bc.string("github-token").desc("github token to use for creating a release (defaults to GITHUB_TOKEN env var)"),
26
+ githubRepo: bc.string("github-repo").desc("github repo to create a release for (defaults to GITHUB_REPOSITORY env var)"),
27
+ withJsr: bc.boolean("with-jsr").desc("whether to publish to jsr").default(false),
28
+ jsrRegistry: bc.string("jsr-registry").desc("URL of the jsr registry to publish to"),
29
+ jsrToken: bc.string("jsr-token").desc("jsr token to use for publishing"),
30
+ jsrPublishArgs: bc.string("jsr-publish-args").desc("additional arguments to pass to `deno publish`"),
31
+ jsrCreatePackages: bc.boolean("jsr-create-packages").desc("whether to create missing packages in jsr"),
32
+ withNpm: bc.boolean("with-npm").desc("whether to publish to npm"),
33
+ npmToken: bc.string("npm-token").desc("npm token to use for publishing (note: this will override the global .npmrc file)"),
34
+ npmPublishArgs: bc.string("npm-publish-args").desc("additional arguments to pass to `npm publish`"),
35
+ npmDistDir: bc.string("npm-dist-dir").desc("directory to publish to npm from, relative to package root (default: dist)"),
36
+ npmRegistry: bc.string("npm-registry").desc("URL of the npm registry to publish to"),
37
+ dryRun: bc.boolean("dry-run").desc("whether to skip publishing and only print what is going to happen")
38
+ },
39
+ handler: async (args) => {
40
+ const root = process.cwd();
41
+ const config = await loadConfig({
42
+ workspaceRoot: root,
43
+ configPath: "build.config.js",
44
+ require: false
45
+ });
46
+ const workspaceWithRoot = await collectPackageJsons(root, true);
47
+ const workspace = workspaceWithRoot.filter((pkg) => !pkg.root);
48
+ const prevTag = await getLatestTag(root);
49
+ if (prevTag == null) {
50
+ console.log("πŸ€” no previous tag found, assuming this is a first ever release");
51
+ } else {
52
+ console.log(`πŸ“Œ previous tag: ${prevTag}`);
53
+ }
54
+ let changedPackages;
55
+ let bumpVersionResult;
56
+ if (prevTag != null) {
57
+ bumpVersionResult = await bumpVersion({
58
+ workspace,
59
+ since: prevTag ?? await getFirstCommit(root),
60
+ type: args.kind === "auto" ? void 0 : args.kind,
61
+ cwd: root,
62
+ params: config?.versioning,
63
+ dryRun: args.dryRun
64
+ });
65
+ changedPackages = bumpVersionResult.changedPackages.map((pkg) => pkg.package);
66
+ if (bumpVersionResult.changedPackages.length === 0) {
67
+ console.log("πŸ€” no packages changed, nothing to do");
68
+ process.exit(1);
69
+ }
70
+ console.log(formatBumpVersionResult(bumpVersionResult, args.kind === "auto"));
71
+ } else {
72
+ changedPackages = workspace;
73
+ }
74
+ console.log("");
75
+ console.log("πŸ“ generating changelog...");
76
+ const changelog = prevTag != null ? await generateChangelog({
77
+ workspace: changedPackages,
78
+ cwd: root,
79
+ since: prevTag,
80
+ params: config?.versioning
81
+ }) : "Initial release";
82
+ if (args.dryRun) {
83
+ console.log("--begin changelog--");
84
+ console.log(changelog);
85
+ console.log("--end changelog--");
86
+ }
87
+ let tarballs = [];
88
+ if (args.withNpm) {
89
+ console.log("");
90
+ console.log("πŸ“€ publishing to npm...");
91
+ const publishResult = await publishPackages({
92
+ packages: changedPackages.map((pkg) => asNonNull(pkg.json.name)),
93
+ workspace: workspaceWithRoot,
94
+ workspaceRoot: root,
95
+ registryUrl: args.npmRegistry,
96
+ token: args.npmToken,
97
+ distDir: args.npmDistDir,
98
+ publishArgs: args.npmPublishArgs?.split(" "),
99
+ dryRun: args.dryRun,
100
+ withBuild: true,
101
+ withTarballs: args.withGithubRelease
102
+ });
103
+ if (publishResult.failed.length > 0) {
104
+ console.log("❌ failed to publish:");
105
+ for (const pkg of publishResult.failed) {
106
+ console.log(` ${pkg}`);
107
+ }
108
+ process.exit(1);
109
+ }
110
+ console.log("\x1B[;32mβœ… published to npm\x1B[;0m");
111
+ tarballs = publishResult.tarballs;
112
+ } else if (args.withGithubRelease) {
113
+ notImplemented("Cannot create a github release without publishing to npm (yet)");
114
+ }
115
+ if (args.withJsr) {
116
+ if (args.jsrCreatePackages) {
117
+ console.log("");
118
+ console.log("πŸ”„ creating missing packages in jsr...");
119
+ const hasMissing = await jsrCreatePackages({
120
+ workspaceRoot: root,
121
+ workspacePackages: workspaceWithRoot,
122
+ registry: args.jsrRegistry,
123
+ token: args.jsrToken,
124
+ githubRepo: args.githubRepo
125
+ });
126
+ if (hasMissing) {
127
+ console.log("\x1B[;31m ❌ some packages are missing, this might cause issues\x1B[;0m");
128
+ }
129
+ }
130
+ console.log("");
131
+ console.log("πŸ”„ generating deno workspace...");
132
+ const workspaceDir = await generateDenoWorkspace({
133
+ workspaceRoot: root,
134
+ workspacePackages: workspaceWithRoot,
135
+ rootConfig: config?.jsr
136
+ });
137
+ console.log("");
138
+ console.log("πŸ“€ publishing to jsr...");
139
+ await exec([
140
+ "deno",
141
+ "publish",
142
+ "--quiet",
143
+ "--allow-dirty",
144
+ ...args.dryRun ? ["--dry-run"] : [],
145
+ ...args.jsrPublishArgs?.split(" ") ?? []
146
+ ], {
147
+ env: {
148
+ ...process.env,
149
+ JSR_URL: args.jsrRegistry
150
+ },
151
+ cwd: workspaceDir,
152
+ stdio: "inherit",
153
+ throwOnError: true
154
+ });
155
+ console.log("\x1B[;32mβœ… published to jsr\x1B[;0m");
156
+ }
157
+ let tagName;
158
+ if (!bumpVersionResult) {
159
+ const versions = sort(workspace.map((pkg) => asNonNull(pkg.json.version)));
160
+ tagName = `v${versions[versions.length - 1]}`;
161
+ } else {
162
+ tagName = `v${bumpVersionResult.nextVersion}`;
163
+ }
164
+ if (args.dryRun) {
165
+ console.log("dry run, skipping release commit and tag");
166
+ } else {
167
+ let message = tagName;
168
+ if (!args.withGithubRelease) {
169
+ message += `
170
+
171
+ ${changelog}`;
172
+ }
173
+ await exec(["git", "commit", "-am", message, "--allow-empty"], {
174
+ cwd: root,
175
+ stdio: "inherit",
176
+ throwOnError: true
177
+ });
178
+ await exec(["git", "tag", tagName], {
179
+ cwd: root,
180
+ stdio: "inherit",
181
+ throwOnError: true
182
+ });
183
+ }
184
+ if (args.withGithubRelease) {
185
+ if (args.dryRun) {
186
+ console.log("dry run, skipping github release");
187
+ } else {
188
+ const token = args.githubToken ?? process.env.GITHUB_TOKEN;
189
+ if (token == null) {
190
+ throw new Error("github token is not set");
191
+ }
192
+ const repo = args.githubRepo ?? process.env.GITHUB_REPOSITORY;
193
+ if (repo == null) {
194
+ throw new Error("github repo is not set");
195
+ }
196
+ console.log("");
197
+ console.log("πŸ™ creating github release...");
198
+ await createGithubRelease({
199
+ token,
200
+ repo,
201
+ tag: tagName,
202
+ name: tagName,
203
+ body: changelog,
204
+ artifacts: tarballs.map((file) => ({
205
+ name: basename(file),
206
+ type: "application/gzip",
207
+ body: nodeReadableToWeb(createReadStream(file))
208
+ }))
209
+ });
210
+ console.log(`\x1B[;32mβœ…github release created: https://github.com/${repo}/releases/tag/${tagName}\x1B[;0m`);
211
+ }
212
+ }
213
+ if (!args.dryRun) {
214
+ await exec(["git", "push", "--follow-tags"], {
215
+ cwd: root,
216
+ stdio: "inherit",
217
+ throwOnError: true
218
+ });
219
+ }
220
+ console.log("");
221
+ console.log("πŸŽ‰ done!");
222
+ }
223
+ });
224
+ export {
225
+ releaseCli
226
+ };
@@ -0,0 +1,38 @@
1
+ import { bc } from './_utils.js';
2
+ export interface WorkspaceDepsError {
3
+ /** package name where the mismatch occurred */
4
+ package: string;
5
+ /** name of the mismatched dependency */
6
+ dependency: string;
7
+ /** version of the mismatched dependency */
8
+ version: string;
9
+ /** type of dependency (`dependencies`, `devDependencies`, etc) */
10
+ at: string;
11
+ /** package name where the dependency was originally declared */
12
+ otherPackage: string;
13
+ /** original version of the dependency */
14
+ otherVersion: string;
15
+ }
16
+ export declare function validateWorkspaceDeps(workspaceRoot: string | URL, params?: {
17
+ /**
18
+ * whether to also validate the root package.json
19
+ *
20
+ * @default true
21
+ */
22
+ includeRoot?: boolean;
23
+ /**
24
+ * whether to skip validating dependencies of other workspace packages
25
+ *
26
+ * @default true
27
+ */
28
+ skipWorkspaceDeps?: boolean;
29
+ }): Promise<WorkspaceDepsError[]>;
30
+ export declare const validateWorkspaceDepsCli: bc.Command<{
31
+ includeRoot: boolean;
32
+ noSkipWorkspaceDeps: boolean | undefined;
33
+ root: string | undefined;
34
+ }, {
35
+ includeRoot: boolean;
36
+ noSkipWorkspaceDeps: boolean | undefined;
37
+ root: string | undefined;
38
+ }>;