ic-memory 0.28.1

Durable stable-memory allocation governance for Internet Computer canisters
Documentation
# Parsed configuration checks. Shell owns Git inventory, file and path checks.
def full_commit: type == "string" and test("^([0-9a-f]{40}|[0-9a-f]{64})$");
def digest_image: type == "string" and test("^.+@sha256:[0-9a-f]{64}$");
def dependencies:
  [ .dependencies, .["dev-dependencies"], .["build-dependencies"],
    .workspace.dependencies,
    (.target[]? | .dependencies, .["dev-dependencies"], .["build-dependencies"]),
    .patch[]?, .replace ]
  | .[] | select(. != null) | to_entries[]
  | {name: .key, spec: (if .value | type == "string" then {version: .value} else .value end)};
def finding($file; $rule; $subject; $value; $message):
  {file: $file, rule: $rule, subject: $subject, value: $value, message: $message};
def action_refs:
  (.jobs[]? | select(has("uses")) | .uses),
  (.jobs[]?.steps[]? | select(has("uses")) | .uses),
  (.runs.steps[]? | select(has("uses")) | .uses);
def steps: .jobs[]?.steps[]?, .runs.steps[]?;
def checks:
  .file as $file | .data as $data |
  if .kind == "cargo" then
    $data | dependencies | .name as $name | .spec as $spec |
    if ($spec | type) != "object" then
      finding($file; "cargo-declaration"; $name; ($spec | tojson); "dependency must be a string or table")
    else
      (if $spec | has("git") then
        if ($spec.rev | full_commit) and ($spec | has("branch") or has("tag") | not) then empty
        else finding($file; "cargo-git"; $name; ($spec | tojson); "Git dependency requires a full commit rev, without branch or tag") end
      else empty end),
      (if $spec.version? | type == "string" then
        if $spec.version | test("(^|,)\\s*=\\s*[0-9]") then
          finding($file; "cargo-exact"; $name; $spec.version; "exact version constraint requires a documented compatibility reason")
        elif $spec.version | contains("*") then
          finding($file; "cargo-range"; $name; $spec.version; "use an explicit compatible version requirement instead of a wildcard")
        else empty end
      else empty end)
    end
  elif .kind == "workflow" or .kind == "action" then
    ($data | action_refs | . as $ref |
      if type != "string" then finding($file; "action-ref"; "uses"; ($ref | tojson); "uses must be a literal action reference")
      elif startswith("./") and (split("/") | index("..") | not) then empty
      elif startswith("docker://") and digest_image then empty
      elif test("^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+(/[^@\\s]+)?@([0-9a-f]{40}|[0-9a-f]{64})$") then empty
      else finding($file; "action-ref"; "uses"; $ref; "external action/workflow requires a full commit SHA; Docker actions require sha256") end),
    ($data | steps | select((.uses? // "") | startswith("actions/checkout@")) |
      select(.with.repository? != null and .with.repository != "${{ github.repository }}") |
      .with.repository as $repository | (.with.ref // "") as $ref |
      if $ref | full_commit then empty
      else finding($file; "checkout-ref"; $repository; $ref; "external checkout requires a full commit ref or an approved moving-input exception") end),
    ($data | .jobs[]? | (.container?, .services[]?) | select(. != null) |
      (if type == "string" then . else .image end) as $image |
      if $image | digest_image then empty
      else finding($file; "container-image"; "image"; $image; "CI container images require a sha256 digest") end),
    ($data | select(.runs.using? == "docker") | .runs.image as $image |
      if $image == "Dockerfile" or
        ($image | startswith("./") and (split("/") | index("..") | not)) or
        ($image | digest_image) then empty
      else finding($file; "container-image"; "image"; $image; "Docker action images require a sha256 digest or a local Dockerfile") end)
  else empty end;