import { interpolate, plainText } from "./segments";
import type { Segment } from "./segments";
import type { ExprContext } from "./expressions";
import type { StepSpec } from "./spec";
export type CacheMode = "both" | "restore" | "save";
export type CacheSpec = {
mode: CacheMode;
key: Segment[];
restoreKeys: Segment[][];
paths: string[];
version: string;
};
export type BuiltinStep =
| { kind: "noop"; name: string }
| { kind: "upload-artifact"; name: string; artifact: { name: string; path: string } }
| { kind: "cache"; name: string; cache: CacheSpec };
const CHECKOUT_ACTION = /^(actions\/)?checkout(@.*)?$/;
const UPLOAD_ACTION = /^(actions\/)?upload-artifact(@.*)?$/;
const SETUP_ACTION = /^(actions\/setup-node|oven-sh\/setup-bun)(@.*)?$/;
const CACHE_ACTION = /^(actions\/)?cache(\/(restore|save))?(@.*)?$/;
/** Same pattern the runners accept in artifact markers. */
const ARTIFACT_NAME = /^[A-Za-z0-9._-]{1,100}$/;
const MAX_CACHE_PATHS = 20;
const MAX_RESTORE_KEYS = 10;
const MAX_KEY_LENGTH = 512;
const FNV_OFFSET = 0x811c9dc5;
const FNV_PRIME = 0x01000193;
function lines(value: string | undefined): string[] {
return (value ?? "")
.split("\n")
.map((line) => line.trim())
.filter(Boolean);
}
/** Cache entries are only compatible when they were saved from the same set of paths. */