mirror of
https://github.com/denoland/deno.git
synced 2024-12-30 02:59:11 -05:00
238 lines
7.6 KiB
TypeScript
238 lines
7.6 KiB
TypeScript
|
#!/usr/bin/env -S deno run -A --lock=tools/deno.lock.json
|
|||
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|||
|
// NOTICE: This deployment/npm folder was lifted from https://github.com/dprint/dprint/blob/0ba79811cc96d2dee8e0cf766a8c8c0fc44879c2/deployment/npm/
|
|||
|
// with permission (Copyright 2019-2023 David Sherret)
|
|||
|
import $ from "jsr:@david/dax@^0.42.0";
|
|||
|
// @ts-types="npm:@types/decompress@4.2.7"
|
|||
|
import decompress from "npm:decompress@4.2.1";
|
|||
|
import { parseArgs } from "@std/cli/parse-args";
|
|||
|
|
|||
|
interface Package {
|
|||
|
zipFileName: string;
|
|||
|
os: "win32" | "darwin" | "linux";
|
|||
|
cpu: "x64" | "arm64";
|
|||
|
libc?: "glibc" | "musl";
|
|||
|
}
|
|||
|
|
|||
|
const args = parseArgs(Deno.args, {
|
|||
|
boolean: ["publish"],
|
|||
|
});
|
|||
|
const packages: Package[] = [{
|
|||
|
zipFileName: "deno-x86_64-pc-windows-msvc.zip",
|
|||
|
os: "win32",
|
|||
|
cpu: "x64",
|
|||
|
}, {
|
|||
|
// use x64_64 until there's an arm64 build
|
|||
|
zipFileName: "deno-x86_64-pc-windows-msvc.zip",
|
|||
|
os: "win32",
|
|||
|
cpu: "arm64",
|
|||
|
}, {
|
|||
|
zipFileName: "deno-x86_64-apple-darwin.zip",
|
|||
|
os: "darwin",
|
|||
|
cpu: "x64",
|
|||
|
}, {
|
|||
|
zipFileName: "deno-aarch64-apple-darwin.zip",
|
|||
|
os: "darwin",
|
|||
|
cpu: "arm64",
|
|||
|
}, {
|
|||
|
zipFileName: "deno-x86_64-unknown-linux-gnu.zip",
|
|||
|
os: "linux",
|
|||
|
cpu: "x64",
|
|||
|
libc: "glibc",
|
|||
|
}, {
|
|||
|
zipFileName: "deno-aarch64-unknown-linux-gnu.zip",
|
|||
|
os: "linux",
|
|||
|
cpu: "arm64",
|
|||
|
libc: "glibc",
|
|||
|
}];
|
|||
|
|
|||
|
const markdownText = `# Deno
|
|||
|
|
|||
|
[Deno](https://www.deno.com)
|
|||
|
([/ˈdiːnoʊ/](http://ipa-reader.xyz/?text=%CB%88di%CB%90no%CA%8A), pronounced
|
|||
|
\`dee-no\`) is a JavaScript, TypeScript, and WebAssembly runtime with secure
|
|||
|
defaults and a great developer experience. It's built on [V8](https://v8.dev/),
|
|||
|
[Rust](https://www.rust-lang.org/), and [Tokio](https://tokio.rs/).
|
|||
|
|
|||
|
Learn more about the Deno runtime
|
|||
|
[in the documentation](https://docs.deno.com/runtime/manual).
|
|||
|
`;
|
|||
|
|
|||
|
const currentDir = $.path(import.meta.url).parentOrThrow();
|
|||
|
const rootDir = currentDir.parentOrThrow().parentOrThrow().parentOrThrow();
|
|||
|
const outputDir = currentDir.join("./dist");
|
|||
|
const scopeDir = outputDir.join("@deno");
|
|||
|
const denoDir = outputDir.join("deno");
|
|||
|
const version = resolveVersion();
|
|||
|
|
|||
|
$.logStep(`Publishing ${version}...`);
|
|||
|
|
|||
|
await $`rm -rf ${outputDir}`;
|
|||
|
await $`mkdir -p ${denoDir} ${scopeDir}`;
|
|||
|
|
|||
|
// setup Deno packages
|
|||
|
{
|
|||
|
$.logStep(`Setting up deno ${version}...`);
|
|||
|
const pkgJson = {
|
|||
|
"name": "deno",
|
|||
|
"version": version,
|
|||
|
"description": "A modern runtime for JavaScript and TypeScript.",
|
|||
|
"bin": "bin.cjs",
|
|||
|
"repository": {
|
|||
|
"type": "git",
|
|||
|
"url": "git+https://github.com/denoland/deno.git",
|
|||
|
},
|
|||
|
"keywords": [
|
|||
|
"runtime",
|
|||
|
"typescript",
|
|||
|
],
|
|||
|
"author": "the Deno authors",
|
|||
|
"license": "MIT",
|
|||
|
"bugs": {
|
|||
|
"url": "https://github.com/denoland/deno/issues",
|
|||
|
},
|
|||
|
"homepage": "https://deno.com",
|
|||
|
// for yarn berry (https://github.com/dprint/dprint/issues/686)
|
|||
|
"preferUnplugged": true,
|
|||
|
"scripts": {
|
|||
|
"postinstall": "node ./install.cjs",
|
|||
|
},
|
|||
|
optionalDependencies: packages
|
|||
|
.map((pkg) => `@deno/${getPackageNameNoScope(pkg)}`)
|
|||
|
.reduce((obj, pkgName) => ({ ...obj, [pkgName]: version }), {}),
|
|||
|
};
|
|||
|
currentDir.join("bin.cjs").copyFileToDirSync(denoDir);
|
|||
|
currentDir.join("install_api.cjs").copyFileToDirSync(denoDir);
|
|||
|
currentDir.join("install.cjs").copyFileToDirSync(denoDir);
|
|||
|
denoDir.join("package.json").writeJsonPrettySync(pkgJson);
|
|||
|
rootDir.join("LICENSE.md").copyFileSync(denoDir.join("LICENSE"));
|
|||
|
denoDir.join("README.md").writeTextSync(markdownText);
|
|||
|
// ensure the test files don't get published
|
|||
|
denoDir.join(".npmignore").writeTextSync("deno\ndeno.exe\n");
|
|||
|
|
|||
|
// setup each binary package
|
|||
|
for (const pkg of packages) {
|
|||
|
const pkgName = getPackageNameNoScope(pkg);
|
|||
|
$.logStep(`Setting up @deno/${pkgName}...`);
|
|||
|
const pkgDir = scopeDir.join(pkgName);
|
|||
|
const zipPath = pkgDir.join("output.zip");
|
|||
|
|
|||
|
await $`mkdir -p ${pkgDir}`;
|
|||
|
|
|||
|
// download and extract the zip file
|
|||
|
const zipUrl =
|
|||
|
`https://github.com/denoland/deno/releases/download/v${version}/${pkg.zipFileName}`;
|
|||
|
await $.request(zipUrl).showProgress().pipeToPath(zipPath);
|
|||
|
await decompress(zipPath.toString(), pkgDir.toString());
|
|||
|
zipPath.removeSync();
|
|||
|
|
|||
|
// create the package.json and readme
|
|||
|
pkgDir.join("README.md").writeTextSync(
|
|||
|
`# @denoland/${pkgName}\n\n${pkgName} distribution of [Deno](https://deno.land).\n`,
|
|||
|
);
|
|||
|
pkgDir.join("package.json").writeJsonPrettySync({
|
|||
|
"name": `@deno/${pkgName}`,
|
|||
|
"version": version,
|
|||
|
"description": `${pkgName} distribution of Deno`,
|
|||
|
"repository": {
|
|||
|
"type": "git",
|
|||
|
"url": "git+https://github.com/denoland/deno.git",
|
|||
|
},
|
|||
|
// force yarn to unpack
|
|||
|
"preferUnplugged": true,
|
|||
|
"author": "David Sherret",
|
|||
|
"license": "MIT",
|
|||
|
"bugs": {
|
|||
|
"url": "https://github.com/denoland/deno/issues",
|
|||
|
},
|
|||
|
"homepage": "https://deno.land",
|
|||
|
"os": [pkg.os],
|
|||
|
"cpu": [pkg.cpu],
|
|||
|
libc: pkg.libc == null ? undefined : [pkg.libc],
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// verify that the package is created correctly
|
|||
|
{
|
|||
|
$.logStep("Verifying packages...");
|
|||
|
const testPlatform = Deno.build.os == "windows"
|
|||
|
? (Deno.build.arch === "x86_64" ? "@deno/win32-x64" : "@deno/win32-arm64")
|
|||
|
: Deno.build.os === "darwin"
|
|||
|
? (Deno.build.arch === "x86_64" ? "@deno/darwin-x64" : "@deno/darwin-arm64")
|
|||
|
: "@deno/linux-x64-glibc";
|
|||
|
outputDir.join("package.json").writeJsonPrettySync({
|
|||
|
workspaces: [
|
|||
|
"deno",
|
|||
|
// There seems to be a bug with npm workspaces where this doesn't
|
|||
|
// work, so for now make some assumptions and only include the package
|
|||
|
// that works on the CI for the current operating system
|
|||
|
// ...packages.map(p => `@deno/${getPackageNameNoScope(p)}`),
|
|||
|
testPlatform,
|
|||
|
],
|
|||
|
});
|
|||
|
|
|||
|
const denoExe = Deno.build.os === "windows" ? "deno.exe" : "deno";
|
|||
|
await $`npm install`.cwd(denoDir);
|
|||
|
|
|||
|
// ensure the post-install script adds the executable to the deno package,
|
|||
|
// which is necessary for faster caching and to ensure the vscode extension
|
|||
|
// picks it up
|
|||
|
if (!denoDir.join(denoExe).existsSync()) {
|
|||
|
throw new Error("Deno executable did not exist after post install");
|
|||
|
}
|
|||
|
|
|||
|
// run once after post install created deno, once with a simulated readonly file system, once creating the cache and once with
|
|||
|
await $`node bin.cjs -v && rm ${denoExe} && DENO_SIMULATED_READONLY_FILE_SYSTEM=1 node bin.cjs -v && node bin.cjs -v && node bin.cjs -v`
|
|||
|
.cwd(denoDir);
|
|||
|
|
|||
|
if (!denoDir.join(denoExe).existsSync()) {
|
|||
|
throw new Error("Deno executable did not exist when lazily initialized");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// publish if necessary
|
|||
|
if (args.publish) {
|
|||
|
for (const pkg of packages) {
|
|||
|
const pkgName = getPackageNameNoScope(pkg);
|
|||
|
$.logStep(`Publishing @deno/${pkgName}...`);
|
|||
|
if (await checkPackagePublished(`@deno/${pkgName}`)) {
|
|||
|
$.logLight(" Already published.");
|
|||
|
continue;
|
|||
|
}
|
|||
|
const pkgDir = scopeDir.join(pkgName);
|
|||
|
await $`cd ${pkgDir} && npm publish --provenance --access public`;
|
|||
|
}
|
|||
|
|
|||
|
$.logStep(`Publishing deno...`);
|
|||
|
await $`cd ${denoDir} && npm publish --provenance --access public`;
|
|||
|
}
|
|||
|
|
|||
|
function getPackageNameNoScope(name: Package) {
|
|||
|
const libc = name.libc == null ? "" : `-${name.libc}`;
|
|||
|
return `${name.os}-${name.cpu}${libc}`;
|
|||
|
}
|
|||
|
|
|||
|
function resolveVersion() {
|
|||
|
const firstArg = args._[0];
|
|||
|
if (
|
|||
|
firstArg != null &&
|
|||
|
typeof firstArg === "string" &&
|
|||
|
firstArg.trim().length > 0
|
|||
|
) {
|
|||
|
return firstArg;
|
|||
|
}
|
|||
|
const version = (rootDir.join("cli/Cargo.toml").readTextSync().match(
|
|||
|
/version = "(.*?)"/,
|
|||
|
))?.[1];
|
|||
|
if (version == null) {
|
|||
|
throw new Error("Could not resolve version.");
|
|||
|
}
|
|||
|
return version;
|
|||
|
}
|
|||
|
|
|||
|
async function checkPackagePublished(pkgName: string) {
|
|||
|
const result = await $`npm info ${pkgName}@${version}`.quiet().noThrow();
|
|||
|
return result.code === 0;
|
|||
|
}
|