217 lines · 8.3 KB
import { withStore } from "../../git/store";
import type { ActionsPolicy, RepoRow } from "~/lib/types";
import { isBuiltinAction } from "../builtin-actions";
import type { WorkflowSpec } from "../spec";
import { archiveKey, archiveManifest, ensureArchive, resolveActionRef, verifyPin } from "./archive";
import { ActionSourceError, withGithubToken } from "./github";
import { loadSecretRows } from "../config-values";
import { decryptRepoSecret } from "../../secrets";
import { GITHUB_COM_TOKEN_SECRET } from "./compile-action";
import { parseActionManifest } from "./manifest";
import type { ActionManifest } from "./manifest";
import { isPinned, looksLikeShortSha, parseActionReference } from "./uses";
import { isDigestPinned, parseImageRef, resolveImage } from "./images";
import type { ResolvedImage } from "./images";
import { enforceRateLimit } from "../../limits";

const MAX_ACTIONS_PER_WORKFLOW = 25;
const MAX_MANIFEST_BYTES = 256 * 1024;
const MANIFEST_NAMES = ["action.yml", "action.yaml"];

/** A `uses:` resolved at scheduling time and stored with the run, so recompiles and retries never refetch. */
export type ResolvedAction = {
  uses: string;
  local: boolean;
  /** `owner/repo` as written, for logs and `GITHUB_ACTION_REPOSITORY`. */
  repository: string | null;
  ref: string | null;
  sha: string | null;
  /** Directory of action.yml inside the archive (remote) or the workspace (local); '' is the root. */
  path: string;
  archive: { key: string; sha256: string } | null;
  manifest: ActionManifest;
  /** The registry image a Docker action runs, pinned to a digest when the run was scheduled. */
  image?: ResolvedImage | null;
};

export type ResolvedActions = Record<string, ResolvedAction>;

export class ActionPolicyError extends Error {}