Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 145 additions & 69 deletions .github/actions/publish-preview/dist/index.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// GENERATED by scripts/build-action.mjs — do not edit. Run `pnpm build:action`.

// .github/actions/publish-preview/src/index.ts
import { relative } from "node:path";

// node_modules/.pnpm/nanotar@0.3.0/node_modules/nanotar/dist/index.mjs
var tarItemTypeMap = {
// Standard
Expand Down Expand Up @@ -320,9 +323,6 @@ var PREVIEW_PACKAGES = /* @__PURE__ */ new Set([
"@voidzero-dev/vite-plus-core",
"vite-plus"
]);
function isPreviewPackage(name) {
return PREVIEW_PACKAGES.has(name);
}
function isWorkspacePackage(name, env) {
const patterns = (env.WORKSPACE_PACKAGES ?? "").split(",").map((s) => s.trim()).filter(Boolean);
if (patterns.length === 0) return PREVIEW_PACKAGES.has(name);
Expand All @@ -343,14 +343,17 @@ function commitVersion(sha) {
function shaToVersion(ref) {
return /^[0-9a-f]{7,40}$/i.test(ref) ? commitVersion(ref) : null;
}
function parsePreviewVersion(version) {
const commit = version.match(/^0\.0\.0-commit\.([0-9a-f]{7,40})$/i);
if (commit) return { type: "commit", ref: commit[1] };
return null;
}

// src/tarball/rewritePackageJson.ts
var DEPENDENCY_FIELDS = [
"dependencies",
"peerDependencies",
"optionalDependencies"
];
function pkgPrNewUrlToVersion(spec, env) {
if (!env.PKG_PR_NEW_BASE || !env.PREVIEW_OWNER || !env.PREVIEW_REPO) {
return null;
}
const prefix = `${env.PKG_PR_NEW_BASE}/${env.PREVIEW_OWNER}/${env.PREVIEW_REPO}/`;
if (!spec.startsWith(prefix)) return null;
const rest = spec.slice(prefix.length);
Expand All @@ -360,11 +363,11 @@ function pkgPrNewUrlToVersion(spec, env) {
if (!isWorkspacePackage(name, env)) return null;
return shaToVersion(rest.slice(at + 1));
}
function rewriteDependencies(deps, version, env) {
function rewriteDependencies(deps, version, env, pinned) {
if (!deps) return deps;
const next = { ...deps };
for (const [name, spec] of Object.entries(deps)) {
if (PREVIEW_PACKAGES.has(name)) {
if (pinned.has(name)) {
next[name] = version;
continue;
}
Expand All @@ -373,22 +376,15 @@ function rewriteDependencies(deps, version, env) {
}
return next;
}
function rewritePackageJson(pkg, packageName, version, env) {
function rewritePackageJson(pkg, packageName, version, env, batch) {
const pinned = batch ?? PREVIEW_PACKAGES;
const next = { ...pkg };
next.name = packageName;
next.version = version;
if (next.dependencies) {
next.dependencies = rewriteDependencies(next.dependencies, version, env);
}
if (next.peerDependencies) {
next.peerDependencies = rewriteDependencies(next.peerDependencies, version, env);
}
if (next.optionalDependencies) {
next.optionalDependencies = rewriteDependencies(
next.optionalDependencies,
version,
env
);
for (const field of DEPENDENCY_FIELDS) {
if (next[field]) {
next[field] = rewriteDependencies(next[field], version, env, pinned);
}
}
return next;
}
Expand Down Expand Up @@ -471,9 +467,9 @@ async function parsePackageJson(gzippedTarball) {
throw new HttpError(422, "Invalid package/package.json in upstream tarball");
}
}
async function buildPreviewTarball(gzippedTarball, packageName, version, env) {
async function buildPreviewTarball(gzippedTarball, packageName, version, env, batch) {
const { files, pkgEntry, pkg } = await parsePackageJson(gzippedTarball);
const rewritten = rewritePackageJson(pkg, packageName, version, env);
const rewritten = rewritePackageJson(pkg, packageName, version, env, batch);
const rewrittenBytes = encodePackageJson(rewritten);
const out = [];
for (const file of files) {
Expand All @@ -490,13 +486,6 @@ async function buildPreviewTarball(gzippedTarball, packageName, version, env) {
return { tarball, packageJson: rewritten, shasum, integrity };
}

// src/preview/toPkgPrNewUrl.ts
function toPkgPrNewUrl(env, packageName, version) {
const preview = parsePreviewVersion(version);
if (!preview) return null;
return `${env.PKG_PR_NEW_BASE}/${env.PREVIEW_OWNER}/${env.PREVIEW_REPO}/${packageName}@${preview.ref}`;
}

// src/preview/parseConfiguredPreviewRefs.ts
function parseSingleRef(value) {
const commit = value.match(/^commit\.([0-9a-f]{7,40})$/i);
Expand All @@ -523,7 +512,103 @@ function parseConfiguredPreviewRefs(input2) {
});
}

// .github/actions/publish-preview/src/localPack.ts
import { execFile } from "node:child_process";
import {
mkdtempSync,
readdirSync,
readFileSync,
rmSync,
statSync
} from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { promisify } from "node:util";
var execFileAsync = promisify(execFile);
function parsePackagesInput(raw) {
return raw.split(/[\n,]/).map((s) => s.trim()).filter(Boolean);
}
function hasPackageJson(dir) {
try {
return statSync(join(dir, "package.json")).isFile();
} catch {
return false;
}
}
function expandPackageDirs(patterns, cwd) {
const dirs = [];
for (const pattern of patterns) {
if (pattern.endsWith("/*")) {
const parent = resolve(cwd, pattern.slice(0, -2));
let entries;
try {
entries = readdirSync(parent);
} catch {
throw new Error(`packages pattern matched no directory: ${pattern}`);
}
for (const entry of entries.sort()) {
const dir = join(parent, entry);
if (hasPackageJson(dir)) dirs.push(dir);
}
} else {
const dir = resolve(cwd, pattern);
if (!hasPackageJson(dir)) {
throw new Error(`not a package directory (no package.json): ${pattern}`);
}
dirs.push(dir);
}
}
return [...new Set(dirs)];
}
function readManifest(dir) {
return JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
}
function assertValidBatch(packages, env) {
if (packages.length === 0) {
throw new Error("packages matched no package directories");
}
const batch = /* @__PURE__ */ new Set();
for (const { dir, manifest } of packages) {
const name = manifest.name;
if (!name || !isWorkspacePackage(name, env)) {
throw new Error(`not an allowed workspace package: ${name} (${dir})`);
}
if (batch.has(name)) throw new Error(`duplicate package in batch: ${name}`);
batch.add(name);
}
for (const { manifest } of packages) {
for (const field of DEPENDENCY_FIELDS) {
for (const dep of Object.keys(manifest[field] ?? {})) {
if (isWorkspacePackage(dep, env) && !batch.has(dep)) {
throw new Error(
`${manifest.name} ${field} needs ${dep}, which is not in this publish batch`
);
}
}
}
}
return batch;
}
async function packDirectory(dir) {
const dest = mkdtempSync(join(tmpdir(), "bridge-pack-"));
try {
await execFileAsync("pnpm", ["pack", "--pack-destination", dest], {
cwd: dir
});
const tgzs = readdirSync(dest).filter((f) => f.endsWith(".tgz"));
if (tgzs.length !== 1) {
throw new Error(
`expected pnpm pack to produce one tarball for ${dir}, found ${tgzs.length}`
);
}
return new Uint8Array(readFileSync(join(dest, tgzs[0])));
} finally {
rmSync(dest, { recursive: true, force: true });
}
}

// .github/actions/publish-preview/src/index.ts
var DEFAULT_PACKAGES = "packages/cli,packages/core,packages/prompts,packages/cli/npm/*,packages/cli/cli-npm/*";
function input(name, required = false) {
const value = (process.env[`INPUT_${name.toUpperCase()}`] ?? "").trim();
if (required && !value) throw new Error(`missing required input: ${name}`);
Expand All @@ -543,15 +628,6 @@ async function withRetry(label, fn, attempts = 4) {
}
var TRANSFER_TIMEOUT_MS = 12e4;
var PUBLISH_TIMEOUT_MS = 3e4;
async function fetchUpstream(env, name, version) {
const url = toPkgPrNewUrl(env, name, version);
if (!url) throw new Error(`cannot build pkg.pr.new url for ${name}@${version}`);
return withRetry(`download ${name}`, async () => {
const res = await fetch(url, { signal: AbortSignal.timeout(TRANSFER_TIMEOUT_MS) });
if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`);
return new Uint8Array(await res.arrayBuffer());
});
}
async function uploadTarball(bridge, token, name, version, bytes) {
await withRetry(`upload ${name}`, async () => {
const res = await fetch(`${bridge}/-/tarball/${name}/${version}.tgz`, {
Expand All @@ -571,15 +647,18 @@ async function main() {
const bridge = (input("bridge-url") || "https://registry-bridge.viteplus.dev").replace(/\/+$/, "");
const token = input("admin-token", true);
const prUrl = input("pr-url") || void 0;
const cwd = process.cwd();
const dirs = expandPackageDirs(
parsePackagesInput(input("packages") || DEFAULT_PACKAGES),
cwd
);
const packages = dirs.map((dir) => ({ dir, manifest: readManifest(dir) }));
const env = {
PUBLIC_BASE_URL: bridge,
PKG_PR_NEW_BASE: (input("pkg-pr-new-base") || "https://pkg.pr.new").replace(/\/+$/, ""),
PREVIEW_OWNER: input("owner") || "voidzero-dev",
PREVIEW_REPO: input("repo") || "vite-plus",
WORKSPACE_PACKAGES: input("workspace-packages") || "vite-plus,@voidzero-dev/vite-plus-*"
};
console.log(`publishing ${version} to ${bridge}`);
let published = 0;
const batch = assertValidBatch(packages, env);
console.log(`publishing ${version} (${packages.length} packages) to ${bridge}`);
const post = (path, body, label) => withRetry(label, async () => {
const res = await fetch(`${bridge}${path}`, {
method: "POST",
Expand All @@ -589,36 +668,33 @@ async function main() {
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text().catch(() => "")}`);
});
const publishPackage = async (name, ver) => {
const upstream = await fetchUpstream(env, name, ver);
const build = await buildPreviewTarball(upstream, name, ver, env);
await uploadTarball(bridge, token, name, ver, build.tarball);
const startPack = (i) => {
const packed = packDirectory(packages[i].dir);
packed.catch(() => {
});
return packed;
};
let nextPack = startPack(0);
for (let i = 0; i < packages.length; i++) {
const { dir, manifest } = packages[i];
const packed = await nextPack;
if (i + 1 < packages.length) nextPack = startPack(i + 1);
const build = await buildPreviewTarball(packed, manifest.name, version, env, batch);
await uploadTarball(bridge, token, manifest.name, version, build.tarball);
const pkg = {
name,
version: ver,
name: manifest.name,
version,
packageJson: build.packageJson,
integrity: build.integrity,
shasum: build.shasum
};
await post("/-/publish", { ref, packages: [pkg] }, `publish ${name}`);
published++;
console.log(` \u2713 ${name}@${ver} (${build.tarball.byteLength} bytes)`);
return pkg;
};
let vitePlusPackageJson;
for (const name of PREVIEW_PACKAGES) {
const pkg = await publishPackage(name, version);
if (name === "vite-plus") vitePlusPackageJson = pkg.packageJson;
}
const optionalDeps = vitePlusPackageJson?.optionalDependencies ?? {};
const binaries = Object.entries(optionalDeps).filter(
([name]) => isWorkspacePackage(name, env) && !isPreviewPackage(name)
);
for (const [name, depVersion] of binaries) {
await publishPackage(name, depVersion);
await post("/-/publish", { ref, packages: [pkg] }, `publish ${manifest.name}`);
console.log(
` \u2713 ${manifest.name}@${version} (${build.tarball.byteLength} bytes, from ${relative(cwd, dir)})`
);
}
await post("/-/register", { ref, prUrl }, "register ref");
console.log(`published ${published} packages, registered ${ref}`);
console.log(`published ${packages.length} packages, registered ${ref}`);
const out = process.env.GITHUB_OUTPUT;
if (out) {
const { appendFileSync } = await import("node:fs");
Expand Down
Loading