port: refuse dst inside src (realpath-normalized) + workflow clones omp repo outside checkout
All checks were successful
port-to-omp / port (push) Successful in 13s
All checks were successful
port-to-omp / port (push) Successful in 13s
This commit is contained in:
@@ -33,24 +33,28 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
URL="https://oauth2:${PORTING_TOKEN}@git.freno.me/Mike/${OMP_REPO}.git"
|
URL="https://oauth2:${PORTING_TOKEN}@git.freno.me/Mike/${OMP_REPO}.git"
|
||||||
|
# The omp checkout lives in $RUNNER_TEMP, outside the pi checkout:
|
||||||
|
# the port script refuses to write into a subdirectory of its own
|
||||||
|
# source (cpSync would recurse into itself).
|
||||||
|
PORT_DIR="${RUNNER_TEMP:-/tmp}/omp-port"
|
||||||
|
|
||||||
if git ls-remote "$URL" HEAD >/dev/null 2>&1; then
|
if git ls-remote "$URL" HEAD >/dev/null 2>&1; then
|
||||||
git clone --depth 1 "$URL" omp-port
|
git clone --depth 1 "$URL" "$PORT_DIR"
|
||||||
git -C omp-port config user.name "omp-port"
|
git -C "$PORT_DIR" config user.name "omp-port"
|
||||||
git -C omp-port config user.email "omp-port@freno.me"
|
git -C "$PORT_DIR" config user.email "omp-port@freno.me"
|
||||||
else
|
else
|
||||||
git init -b main omp-port
|
git init -b main "$PORT_DIR"
|
||||||
git -C omp-port remote add origin "$URL"
|
git -C "$PORT_DIR" remote add origin "$URL"
|
||||||
git -C omp-port config user.name "omp-port"
|
git -C "$PORT_DIR" config user.name "omp-port"
|
||||||
git -C omp-port config user.email "omp-port@freno.me"
|
git -C "$PORT_DIR" config user.email "omp-port@freno.me"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Regenerate the port directly into the omp checkout. The script
|
# Regenerate the port directly into the omp checkout. The script
|
||||||
# preserves .git, asserts every patch rule, and runs `bun install`
|
# preserves .git, asserts every patch rule, and runs `bun install`
|
||||||
# (refreshing bun.lock + node_modules).
|
# (refreshing bun.lock + node_modules).
|
||||||
bun "$GITHUB_WORKSPACE/port-to-omp.mjs" --out "$PWD/omp-port"
|
bun "$GITHUB_WORKSPACE/port-to-omp.mjs" --out "$PORT_DIR"
|
||||||
|
|
||||||
cd omp-port
|
cd "$PORT_DIR"
|
||||||
# The port must compile against the pinned @oh-my-pi SDK before it
|
# The port must compile against the pinned @oh-my-pi SDK before it
|
||||||
# ships to users.
|
# ships to users.
|
||||||
bun run typecheck
|
bun run typecheck
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ import {
|
|||||||
mkdirSync,
|
mkdirSync,
|
||||||
readdirSync,
|
readdirSync,
|
||||||
readFileSync,
|
readFileSync,
|
||||||
|
realpathSync,
|
||||||
rmSync,
|
rmSync,
|
||||||
writeFileSync,
|
writeFileSync,
|
||||||
} from "node:fs";
|
} from "node:fs";
|
||||||
import { join } from "node:path";
|
import { join, relative, resolve, isAbsolute, dirname, basename } from "node:path";
|
||||||
import { execSync } from "node:child_process";
|
import { execSync } from "node:child_process";
|
||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
|
|
||||||
@@ -113,7 +114,33 @@ function mirrorTree(srcDir, dstDir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function walk(dir) {
|
function real(p) {
|
||||||
|
try {
|
||||||
|
return realpathSync(p);
|
||||||
|
} catch {
|
||||||
|
// walk to the nearest existing ancestor and realpath it, then re-append
|
||||||
|
const tail = [];
|
||||||
|
let cur = resolve(p);
|
||||||
|
for (;;) {
|
||||||
|
try {
|
||||||
|
return join(realpathSync(cur), ...tail);
|
||||||
|
} catch {}
|
||||||
|
const parent = dirname(cur);
|
||||||
|
if (parent === cur) return resolve(p);
|
||||||
|
tail.unshift(basename(cur));
|
||||||
|
cur = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertDstOutsideSrc(srcDir, dstDir) {
|
||||||
|
const rel = relative(real(srcDir), real(dstDir));
|
||||||
|
if (rel === "" || (!rel.startsWith("..") && !isAbsolute(rel))) {
|
||||||
|
throw new Error(
|
||||||
|
`refusing to port into a subdirectory of the source: ${dstDir} is inside ${srcDir}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}function walk(dir) {
|
||||||
const out = [];
|
const out = [];
|
||||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||||
if (SKIP.has(entry.name)) continue;
|
if (SKIP.has(entry.name)) continue;
|
||||||
@@ -288,6 +315,7 @@ function portExtension() {
|
|||||||
if (!dstDir) throw new Error("--out requires a directory argument");
|
if (!dstDir) throw new Error("--out requires a directory argument");
|
||||||
if (!existsSync(srcDir)) throw new Error(`no base extension at ${srcDir}`);
|
if (!existsSync(srcDir)) throw new Error(`no base extension at ${srcDir}`);
|
||||||
|
|
||||||
|
assertDstOutsideSrc(srcDir, dstDir);
|
||||||
console.log(`== ${srcDir} -> ${dstDir}`);
|
console.log(`== ${srcDir} -> ${dstDir}`);
|
||||||
mirrorTree(srcDir, dstDir);
|
mirrorTree(srcDir, dstDir);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user