mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-08-31 02:41:44 +00:00
chore(repo): forbid tracked generated artifacts
This commit is contained in:
@@ -8,6 +8,12 @@ permissions:
|
||||
env:
|
||||
HYPERFRAMES_NO_TELEMETRY: "1"
|
||||
|
||||
# Graphite can update a branch and its PR base separately for the same head
|
||||
# SHA. Keep only the newest expensive regression run for each PR/ref.
|
||||
concurrency:
|
||||
group: regression-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
@@ -111,7 +117,10 @@ jobs:
|
||||
load: true
|
||||
tags: hyperframes-producer:test
|
||||
cache-from: type=gha,scope=regression-test-image
|
||||
cache-to: type=gha,mode=max,scope=regression-test-image
|
||||
# PR matrices can fan out across many stacked branches at once. Let
|
||||
# them consume the shared cache, but keep a single writer on main so
|
||||
# concurrent exports cannot exhaust the Actions cache service.
|
||||
cache-to: ${{ github.event_name == 'push' && 'type=gha,mode=max,scope=regression-test-image' || '' }}
|
||||
|
||||
- name: "Run regression shard: ${{ matrix.shard }}"
|
||||
run: |
|
||||
|
||||
@@ -38,6 +38,11 @@ pre-commit:
|
||||
# split paths containing spaces. It skips files under the limit, anything
|
||||
# routed through LFS, and registry/ assets. Tune via HF_MAX_NONLFS_KB.
|
||||
run: ./scripts/check-large-files.sh
|
||||
tracked-artifacts:
|
||||
# Keep ignored dependency trees and platform metadata out of commits.
|
||||
# `git ls-files` observes the staged index, so staged removals pass and
|
||||
# an accidental force-add fails before the commit is created.
|
||||
run: bun run check:tracked-artifacts
|
||||
filesize:
|
||||
# Scoped to packages/studio — the 600 LOC limit is a studio architecture
|
||||
# standard enforced as part of the App.tsx decomposition work. Player and
|
||||
|
||||
+3
-2
@@ -24,15 +24,16 @@
|
||||
"changelog:weekly": "tsx scripts/changelog-weekly.ts",
|
||||
"sync-schemas": "tsx scripts/sync-schemas.ts",
|
||||
"sync-schemas:check": "tsx scripts/sync-schemas.ts --check",
|
||||
"lint": "oxlint . && tsx scripts/lint-skills.ts",
|
||||
"lint": "bun run check:tracked-artifacts && oxlint . && tsx scripts/lint-skills.ts",
|
||||
"lint:skills": "tsx scripts/lint-skills.ts",
|
||||
"lint:fix": "oxlint --fix .",
|
||||
"check:tracked-artifacts": "node scripts/check-tracked-artifacts.mjs",
|
||||
"format": "oxfmt .",
|
||||
"test": "bun run --filter '*' test",
|
||||
"player:perf": "bun run --filter @hyperframes/player perf",
|
||||
"format:check": "oxfmt --check .",
|
||||
"knip": "knip",
|
||||
"test:scripts": "node --import tsx --test scripts/validate-release-channel.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/verify-packed-manifests.test.mjs",
|
||||
"test:scripts": "node --import tsx --test scripts/check-tracked-artifacts.test.mjs scripts/validate-release-channel.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/verify-packed-manifests.test.mjs",
|
||||
"test:skills": "node --test 'skills/**/*.test.mjs'",
|
||||
"generate:previews": "tsx scripts/generate-template-previews.ts",
|
||||
"generate:catalog-previews": "tsx scripts/generate-catalog-previews.ts",
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const FORBIDDEN_BASENAMES = new Set([".DS_Store"]);
|
||||
|
||||
export function isForbiddenTrackedPath(filePath) {
|
||||
const normalized = filePath.replaceAll("\\", "/");
|
||||
const segments = normalized.split("/");
|
||||
return segments.includes("node_modules") || FORBIDDEN_BASENAMES.has(segments.at(-1));
|
||||
}
|
||||
|
||||
export function findForbiddenTrackedPaths(filePaths) {
|
||||
return filePaths.filter(isForbiddenTrackedPath).sort();
|
||||
}
|
||||
|
||||
export function readTrackedPaths(cwd = process.cwd()) {
|
||||
const result = spawnSync("git", ["ls-files", "-z"], {
|
||||
cwd,
|
||||
encoding: "utf8",
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
if (result.status !== 0) {
|
||||
throw new Error(result.stderr.trim() || `git ls-files exited with status ${result.status}`);
|
||||
}
|
||||
return result.stdout.split("\0").filter(Boolean);
|
||||
}
|
||||
|
||||
export function checkTrackedArtifacts(cwd = process.cwd()) {
|
||||
return findForbiddenTrackedPaths(readTrackedPaths(cwd));
|
||||
}
|
||||
|
||||
function main() {
|
||||
const forbidden = checkTrackedArtifacts();
|
||||
if (forbidden.length === 0) {
|
||||
console.log("Tracked artifact check passed.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.error("Forbidden generated artifacts are tracked by Git:");
|
||||
for (const filePath of forbidden) console.error(`- ${filePath}`);
|
||||
console.error("Remove these paths from the index; .gitignore already excludes them.");
|
||||
process.exitCode = 1;
|
||||
}
|
||||
|
||||
const entryPath = process.argv[1] ? resolve(process.argv[1]) : null;
|
||||
if (entryPath === fileURLToPath(import.meta.url)) main();
|
||||
@@ -0,0 +1,32 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
import { findForbiddenTrackedPaths, isForbiddenTrackedPath } from "./check-tracked-artifacts.mjs";
|
||||
|
||||
describe("tracked artifact check", () => {
|
||||
it("rejects node_modules at any directory depth", () => {
|
||||
assert.equal(isForbiddenTrackedPath("node_modules/pkg/index.js"), true);
|
||||
assert.equal(isForbiddenTrackedPath("packages/producer/node_modules/pkg"), true);
|
||||
assert.equal(isForbiddenTrackedPath("packages\\producer\\node_modules\\pkg"), true);
|
||||
});
|
||||
|
||||
it("rejects platform metadata by basename", () => {
|
||||
assert.equal(isForbiddenTrackedPath(".DS_Store"), true);
|
||||
assert.equal(isForbiddenTrackedPath("packages/producer/tests/.DS_Store"), true);
|
||||
});
|
||||
|
||||
it("does not reject similarly named source paths", () => {
|
||||
assert.equal(isForbiddenTrackedPath("docs/node_modules-policy.md"), false);
|
||||
assert.equal(isForbiddenTrackedPath("packages/producer/src/DS_Store.ts"), false);
|
||||
});
|
||||
|
||||
it("returns a deterministic sorted list", () => {
|
||||
assert.deepEqual(
|
||||
findForbiddenTrackedPaths([
|
||||
"packages/z/.DS_Store",
|
||||
"packages/producer/src/index.ts",
|
||||
"packages/a/node_modules/pkg",
|
||||
]),
|
||||
["packages/a/node_modules/pkg", "packages/z/.DS_Store"],
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user