Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .github/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
# Generated by Velnor Actions 0.1.0; edit .velnor/config.toml and regenerate.
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
# Generated GitHub Workflows and Configurations

All files and subdirectories under `.github/` are generated by `velnor-actions` from [tailrocks/velnor-new](https://github.com/tailrocks/velnor-new).
`velnor-actions` from [tailrocks/velnor-new](https://github.com/tailrocks/velnor-new) owns its declared generated paths, the complete `.github/workflows/` namespace, and marked shared action definitions under `.github/actions/`. Successful generation replaces emitted owned paths and retires owned paths no longer emitted. Do not hand-edit these managed paths; change their inputs and run `velnor-actions generate`.

## Do Not Hand-Edit `.github/`
Other existing files and directories under `.github/` are repository-owned and preserved by generation, including empty directories. A directory emptied solely by retiring its managed generated outputs may be pruned. Put custom files outside `.github/workflows/`, which is reserved for generated workflows. Generation refuses to overwrite an unmarked custom action when its path collides with a generated shared action.

## Generation Inputs

- **Never hand-edit any file inside `.github/`**: Every manual change will be overwritten on the next run of `velnor-actions generate`.
- **Keep generation inputs outside `.github/`**: Repository configuration belongs in `.velnor/config.toml`, workspace manifests, and toolchain settings outside `.github/`.
- **Regenerate via CLI**: Apply configuration changes by running `velnor-actions generate`.

## Workflow Issues and Enhancements

When issues, bugs, limitations, or enhancements are observed in generated GitHub Actions workflows:

1. **Do NOT patch `.github/` directly or create repo-specific workarounds**:
- Avoid local ad-hoc patches, overrides, or shims inside `.github/`.
1. **Do NOT patch generator-owned outputs or create repo-specific workflow workarounds**:
- Avoid local patches, overrides, or shims to managed workflow, config, or action files.
2. **Research generic solutions in `velnor-actions` / `velnor-new`**:
- Investigate solutions in the upstream generator: [tailrocks/velnor-new](https://github.com/tailrocks/velnor-new).
- Verify that potential changes align with the vision and architectural invariants of Velnor Actions (generic workflow generator, strict safety invariants, zero legacy, fast CI).
Expand Down
1 change: 0 additions & 1 deletion .github/CLAUDE.md

This file was deleted.

1 change: 1 addition & 0 deletions .github/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
2 changes: 1 addition & 1 deletion .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Velnor Actions 0.1.0; edit .velnor/config.toml and regenerate.
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.

config-variables: []

Expand Down
34 changes: 34 additions & 0 deletions .github/actions/tofu-provider-admission/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
name: Admit OpenTofu provider cache
description: Restore and admit the exact OpenTofu provider cache entry.
inputs:
cache-key:
description: Provider cache cache-key
required: true
cache-path:
description: Provider cache cache-path
required: true
outputs:
cache-key:
description: Provider cache cache-key
value: ${{ inputs.cache-key }}
cache-path:
description: Provider cache cache-path
value: ${{ inputs.cache-path }}
runs:
using: composite
steps:
- name: Restore Tofu providers
id: restore
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
with:
key: ${{ inputs.cache-key }}
path: ${{ inputs.cache-path }}
- name: Discard provider bytes unless the exact restore key matched
shell: bash
env:
TOFU_CACHE_HIT: ${{ steps.restore.outputs.cache-hit }}
TOFU_EXPECTED_KEY: ${{ inputs.cache-key }}
TOFU_MATCHED_KEY: ${{ steps.restore.outputs.cache-matched-key }}
TOFU_PROVIDER_CACHE_PATH: ${{ inputs.cache-path }}
run: "set -eu\ncd -P \"$RUNNER_TEMP\"\nrt=$PWD\nv=\"$rt/velnor\"\np=\"$v/tofu-cache\"\n[ ! -L \"$v\" ] && [ ! -L \"$p\" ] || exit 1\nmkdir -p \"$p\"\ncd -P \"$p\"\n[ \"$PWD\" = \"$p\" ] || exit 1\nprefix=\"$p/\"\ncase \"$TOFU_PROVIDER_CACHE_PATH\" in\n \"$prefix\"*) slug=${TOFU_PROVIDER_CACHE_PATH#\"$prefix\"} ;;\n *) exit 1 ;;\nesac\ncase \"$slug\" in\n ''|*/*|*[!A-Za-z0-9_-]*) exit 1 ;;\nesac\nd=\"$PWD/$slug\"\n[ \"$TOFU_PROVIDER_CACHE_PATH\" = \"$d\" ] || exit 1\nif [ \"$TOFU_CACHE_HIT\" = true ] \\\n && [ -n \"$TOFU_EXPECTED_KEY\" ] \\\n && [ \"$TOFU_MATCHED_KEY\" = \"$TOFU_EXPECTED_KEY\" ] \\\n && [ -d \"$d\" ] \\\n && [ ! -L \"$d\" ]; then\n exit 0\nfi\nrm -rf \"$d\"\nmkdir -m 700 \"$d\""
40 changes: 40 additions & 0 deletions .github/actions/u26/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
name: Velnor Mise cache identity
description: Qualify the hosted image and cache roots before V2 restore.
inputs:
d:
description: Static V2 identity of the tool pins and owned paths.
required: true
outputs:
enabled:
description: Whether the image and absolute roots qualify for restore.
value: ${{ steps.v2.outputs.enabled }}
identity:
description: SHA-256 runtime fingerprint for the qualified host.
value: ${{ steps.v2.outputs.identity }}
runs:
using: composite
steps:
- name: V2 identity
id: v2
env:
ACTIONS_ID_TOKEN_REQUEST_TOKEN: ""
ACTIONS_ID_TOKEN_REQUEST_URL: ""
ACTIONS_RUNTIME_TOKEN: ""
CARGO_HOME: ${{ runner.temp }}/velnor/cargo
CARGO_REGISTRY_TOKEN: ""
GH_CONFIG_DIR: ""
GH_HOST: ""
GH_TOKEN: ""
GITHUB_TOKEN: ""
MISE_CARGO_HOME: ${{ runner.temp }}/velnor/cargo
MISE_GITHUB_TOKEN: ""
MISE_RUSTUP_HOME: ${{ runner.temp }}/velnor/rustup
NODE_AUTH_TOKEN: ""
NPM_TOKEN: ""
RUNNER_TEMP: ${{ runner.temp }}
RUSTUP_HOME: ${{ runner.temp }}/velnor/rustup
VELNOR_CACHE_LANE: ubuntu-26.04
VELNOR_CACHE_STATIC_DIGEST: ${{ inputs.d }}
shell: bash
run: "bash -c 'unset ACTIONS_ID_TOKEN_REQUEST_TOKEN ACTIONS_ID_TOKEN_REQUEST_URL ACTIONS_RUNTIME_TOKEN GITHUB_TOKEN MISE_GITHUB_TOKEN GH_TOKEN GH_HOST GH_CONFIG_DIR; bash \"$GITHUB_ACTION_PATH/../../scripts/velnor-tools-cache-identity.sh\"'"
26 changes: 26 additions & 0 deletions .github/actions/velnor-tool-seed/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
name: Restore Velnor tool seed
description: Copy a matching host tool seed into this job.
inputs:
cache_key:
description: Exact Mise cache key.
required: true
runs:
using: composite
steps:
- name: Copy matching tool seed
env:
ACTIONS_ID_TOKEN_REQUEST_TOKEN: ""
ACTIONS_ID_TOKEN_REQUEST_URL: ""
ACTIONS_RUNTIME_TOKEN: ""
CARGO_REGISTRY_TOKEN: ""
GH_CONFIG_DIR: ""
GH_HOST: ""
GH_TOKEN: ""
GITHUB_TOKEN: ""
MISE_GITHUB_TOKEN: ""
NODE_AUTH_TOKEN: ""
NPM_TOKEN: ""
SEED_KEY: ${{ inputs.cache_key }}
shell: bash
run: "bash -c 'unset ACTIONS_ID_TOKEN_REQUEST_TOKEN ACTIONS_ID_TOKEN_REQUEST_URL ACTIONS_RUNTIME_TOKEN GITHUB_TOKEN MISE_GITHUB_TOKEN GH_TOKEN GH_HOST GH_CONFIG_DIR; set -euo pipefail; seed=\"/opt/velnor/seed\"; key=\"$SEED_KEY\"; if [ -z \"$key\" ]; then echo \"tool seed disabled\"; exit 0; fi; trusted_seed_owner_root() { if [ \"${RUNNER_OS-}\" = macOS ]; then /usr/bin/stat -f %u \"$1\" | /usr/bin/grep -qx 0; else /usr/bin/stat -c %u -- \"$1\" | /usr/bin/grep -qx 0; fi; }; trusted_seed_file_matches() { local file=\"$1\" expected=\"$2\" actual=\"\" size=\"\" newline=\"\"; [ -f \"$file\" ] && [ ! -L \"$file\" ] || return 1; if [ \"${RUNNER_OS-}\" = macOS ]; then IFS= read -r size < <(/usr/bin/stat -f %z \"$file\") || return 1; else IFS= read -r size < <(/usr/bin/stat -c %s -- \"$file\") || return 1; fi; case \"$size\" in '\\'''\\''|*[!0-9]*) return 1 ;; esac; [ \"$size\" -le 512 ] || return 1; if IFS= read -r -d '\\'''\\'' actual < \"$file\"; then return 1; fi; printf -v newline '\\''\\n'\\''; [ \"$actual\" = \"$expected\" ] || [ \"$actual\" = \"$expected$newline\" ]; }; trusted_seed_path_is_real() { local current=\"$1\"; while [ \"$current\" != / ]; do [ ! -L \"$current\" ] || return 1; current=\"${current%/*}\"; [ -n \"$current\" ] || current=/; done; }; trusted_seed_mount_is_immutable() { if [ \"${RUNNER_OS-}\" = macOS ]; then /sbin/mount | /usr/bin/awk -v seed=\"$1\" '\\''index($0, \" on \") { marker=index($0, \" on \"); source=substr($0, 1, marker-1); rest=substr($0, marker+4); options_at=index(rest, \" (\"); target=substr(rest, 1, options_at-1); mount_options=substr(rest, options_at+2); targets[NR]=target; sources[NR]=source; options[NR]=mount_options; if (target == seed) { exact++; seed_source=source; if (mount_options ~ /read-only|rdonly/) readonly=1 } else if (index(target, seed \"/\") == 1) nested=1 } END { for (i=1; i<=NR; i++) if (sources[i] == seed_source && targets[i] != seed && options[i] !~ /read-only|rdonly/) writable_alias=1; exit !(exact == 1 && readonly && !nested && !writable_alias) }'\\''; else /usr/bin/findmnt -arn -o TARGET,FSTYPE,MAJ:MIN,OPTIONS | /usr/bin/awk -v seed=\"$1\" '\\''{ target=$1; targets[NR]=target; devices[NR]=$3; options[NR]=$4; if (target == seed) { exact++; device=$3; if ($2 != \"overlay\" && $2 != \"fuse.overlayfs\" && $4 ~ /(^|,)ro(,|$)/) readonly=1 } else if (index(target, seed \"/\") == 1) nested=1 } END { for (i=1; i<=NR; i++) if (devices[i] == device && targets[i] != seed && options[i] ~ /(^|,)rw(,|$)/) writable_alias=1; exit !(exact == 1 && readonly && !nested && !writable_alias) }'\\''; fi; }; trusted_seed_tree_bounded() { local root=\"$1\" count=0 entry relative depth; if ! /usr/bin/find \"$root\" -xdev -print0 | while IFS= read -r -d '\\'''\\'' entry; do ((count+=1)); [ \"$count\" -le 100000 ] || exit 1; case \"$entry\" in \"$root\") depth=0 ;; \"$root\"/*) relative=\"${entry#\"$root\"/}\"; depth=1; while [[ \"$relative\" == */* ]]; do relative=\"${relative#*/}\"; ((depth+=1)); done ;; *) exit 1 ;; esac; [ \"$depth\" -le 16 ] || exit 1; done; then return 1; fi; }; trusted_seed_tree_entries_are_safe() { if ! /usr/bin/find \"$1\" -xdev \\( ! -type d -a ! -type f -o ! -uid 0 \\) -print0 | while IFS= read -r -d '\\'''\\'' entry; do exit 1; done; then return 1; fi; }; trusted_seed_tree_is_safe() { trusted_seed_tree_bounded \"$1\" && trusted_seed_tree_entries_are_safe \"$1\"; }; trusted_seed_is_trusted() { [ -d \"$1\" ] && [ ! -L \"$1\" ] || return 1; trusted_seed_path_is_real \"$1\" || return 1; [ -f \"$1/PROVENANCE\" ] && [ ! -L \"$1/PROVENANCE\" ] || return 1; trusted_seed_owner_root \"$1\" || return 1; trusted_seed_owner_root \"$1/PROVENANCE\" || return 1; trusted_seed_file_matches \"$1/PROVENANCE\" \"velnor-host-seed-v1\" || return 1; trusted_seed_mount_is_immutable \"$1\" || return 1; trusted_seed_tree_is_safe \"$1\"; }; if [ ! -e \"$seed\" ]; then echo \"tool seed absent\"; exit 0; fi; if ! trusted_seed_is_trusted \"$seed\"; then echo \"untrusted tool seed; continuing cold\"; exit 0; fi; if [[ ! \"$key\" =~ ^mise-tools-v2-[0-9a-f]{64}$ ]] || [ ! -f \"$seed/mise/KEY\" ]; then echo \"tool seed key mismatch\"; exit 0; fi; if ! trusted_seed_file_matches \"$seed/mise/KEY\" \"$key\"; then echo \"tool seed key mismatch\"; exit 0; fi; if [ -d \"$seed/mise/tree\" ]; then /bin/mkdir -p \"$HOME/.local/share/mise\"; /bin/cp -R \"$seed/mise/tree/.\" \"$HOME/.local/share/mise/\"; echo \"tool seed restored share-dir\"; fi; if [ -d \"$seed/rustup/tree\" ]; then /bin/mkdir -p \"$RUNNER_TEMP/velnor/rustup\"; /bin/cp -R \"$seed/rustup/tree/.\" \"$RUNNER_TEMP/velnor/rustup/\"; echo \"tool seed restored toolchain-dir\"; fi'"
24 changes: 24 additions & 0 deletions .github/actions/velnor-tools-cache-restore/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
name: Velnor Mise tools cache restore
description: Restore the exact renderer-owned V2 Mise tools paths.
inputs:
key:
description: Exact runtime-qualified V2 tools key.
required: true
runs:
using: composite
steps:
- name: Restore Mise tools
id: restore
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
with:
key: ${{ inputs.key }}
path: "~/.local/share/mise\n${{ runner.temp }}/velnor/rustup\n${{ runner.temp }}/velnor/cargo/.crates.toml\n${{ runner.temp }}/velnor/cargo/.crates2.json\n${{ runner.temp }}/velnor/cargo/bin"
restore-keys: ""
- name: Discard tools bytes unless the exact restore key matched
shell: bash
env:
TOOLS_CACHE_HIT: ${{ steps.restore.outputs.cache-hit }}
TOOLS_EXPECTED_KEY: ${{ inputs.key }}
TOOLS_MATCHED_KEY: ${{ steps.restore.outputs.cache-matched-key }}
run: "set -eu;\n[ -n \"$HOME\" ] && [ -n \"$RUNNER_TEMP\" ] || exit 1;\ncase \"$HOME\" in /*) ;; *) exit 1 ;; esac;\ncase \"$RUNNER_TEMP\" in /*) ;; *) exit 1 ;; esac;\n[ \"$HOME\" != / ] && [ \"$RUNNER_TEMP\" != / ] || exit 1;\nif [ \"$TOOLS_CACHE_HIT\" = true ] && [ -n \"$TOOLS_EXPECTED_KEY\" ] && [ \"$TOOLS_MATCHED_KEY\" = \"$TOOLS_EXPECTED_KEY\" ]; then\n[ ! -L \"$HOME/.local/share/mise\" ] || exit 1;\n[ ! -L \"$RUNNER_TEMP/velnor/rustup\" ] || exit 1;\n[ ! -L \"$RUNNER_TEMP/velnor/cargo/bin\" ] || exit 1;\n[ ! -L \"$RUNNER_TEMP/velnor/cargo/.crates.toml\" ] || exit 1;\n[ ! -L \"$RUNNER_TEMP/velnor/cargo/.crates2.json\" ] || exit 1;\nexit 0;\nfi;\nfor d in \"$HOME/.local/share/mise\" \"$RUNNER_TEMP/velnor/rustup\" \"$RUNNER_TEMP/velnor/cargo/bin\"; do\n[ ! -L \"$d\" ] || exit 1;\nrm -rf \"$d\";\ndone;\nfor f in \"$RUNNER_TEMP/velnor/cargo/.crates.toml\" \"$RUNNER_TEMP/velnor/cargo/.crates2.json\"; do\n[ ! -L \"$f\" ] || exit 1;\nrm -f \"$f\";\ndone"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the trusted seed on cache misses

When the exact GitHub cache key is absent, this cleanup deletes the Mise and Rustup directories that velnor-tools-prelude-u26 populated from the trusted /opt/velnor/seed immediately before the restore step (in the actionlint, plan, and tofu-workspace jobs). Consequently, the host seed never accelerates a cold cache, while on a cache hit it is redundant; reorder the seed restoration or distinguish seed-admitted files from rejected cache files in the upstream generator and regenerate.

AGENTS.md reference: .github/AGENTS.md:L15-L20

Useful? React with 👍 / 👎.

25 changes: 25 additions & 0 deletions .github/actions/velnor-tools-prelude-u26/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
name: Velnor hosted tools prelude
description: Qualify the hosted image and copy a matching tool seed.
inputs:
d:
description: Static V2 identity of the tool pins and owned paths.
required: true
outputs:
enabled:
value: ${{ steps.v2.outputs.enabled }}
identity:
value: ${{ steps.v2.outputs.identity }}
runs:
using: composite
steps:
- name: V2 identity
id: v2
uses: ./.github/actions/u26 # zizmor: ignore[self-repository]
with:
d: ${{ inputs.d }}
- name: Restore Velnor tool seed
if: steps.v2.outputs.enabled == 'true'
uses: ./.github/actions/velnor-tool-seed # zizmor: ignore[self-repository]
with:
cache_key: mise-tools-v2-${{steps.v2.outputs.identity}}
2 changes: 2 additions & 0 deletions .github/scripts/velnor-tools-cache-identity.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Generated by Velnor Actions 0.1.6; edit .velnor/config.toml and regenerate.
export LC_ALL=C; set -eu; umask 077; : "${GITHUB_OUTPUT:?missing GITHUB_OUTPUT}"; scratch_root=; scratch_dir=; runner_os=${RUNNER_OS-}; runner_arch=${RUNNER_ARCH-}; image_os=${ImageOS-}; image_version=${ImageVersion-}; home=${HOME-}; runner_temp=${RUNNER_TEMP-}; mise_rustup=${MISE_RUSTUP_HOME-}; rustup_home=${RUSTUP_HOME-}; mise_cargo=${MISE_CARGO_HOME-}; cargo_home=${CARGO_HOME-}; valid_path() { value=$1; case "$value" in /*) ;; *) return 1 ;; esac; [ "$value" != / ] || return 1; case "$value" in *[![:print:]]*|*//*|*/./*|*/../*|*/.|*/..) return 1 ;; esac; remaining=${value#/}; prefix=; while [ -n "$remaining" ]; do case "$remaining" in */*) part=${remaining%%/*}; remaining=${remaining#*/} ;; *) part=$remaining; remaining= ;; esac; [ -n "$part" ] || return 1; prefix="$prefix/$part"; [ ! -L "$prefix" ] || return 1; done; }; cleanup_scratch() { [ -n "$scratch_dir" ] || return 0; case "$scratch_dir" in "$scratch_root"/runtime-identity.*) ;; *) return 1 ;; esac; [ -d "$scratch_dir" ] && [ ! -L "$scratch_dir" ] || return 1; rm -rf -- "$scratch_dir" || return 1; scratch_dir=; }; on_exit() { status=$1; trap - EXIT; if ! cleanup_scratch; then status=1; fi; exit "$status"; }; trap 'status=$?; on_exit "$status"' EXIT; trap 'exit 129' HUP; trap 'exit 130' INT; trap 'exit 143' TERM; disable() { reason=$1; if ! cleanup_scratch; then printf 'enabled=false\nreason=identity_scratch_cleanup_failed\n' >> "$GITHUB_OUTPUT"; exit 1; fi; printf 'enabled=false\nreason=%s\n' "$reason" >> "$GITHUB_OUTPUT"; exit 0; }; case "$VELNOR_CACHE_LANE" in scale-set:*) disable scale_set_image_unqualified ;; esac; case "$VELNOR_CACHE_LANE" in ubuntu-22.04) expected_image_os=ubuntu22 ;; ubuntu-24.04) expected_image_os=ubuntu24 ;; ubuntu-26.04) expected_image_os=ubuntu26 ;; *) disable lane_image_unqualified ;; esac; expected_arch=X64; expected_target=x86_64-unknown-linux-gnu; [ -n "$runner_os" ] || disable runner_os_missing; [ "$runner_os" = Linux ] || disable runner_os_mismatch; [ -n "$runner_arch" ] || disable runner_arch_missing; [ "$runner_arch" = "$expected_arch" ] || disable runner_arch_mismatch; [ -n "$image_os" ] || disable image_os_missing; [ "$image_os" = "$expected_image_os" ] || disable image_os_mismatch; [ -n "$image_version" ] || disable image_version_missing; case "$image_version" in *[!0-9.]*) disable image_version_invalid ;; esac; case "$image_version" in *[0-9]*) ;; *) disable image_version_invalid ;; esac; [ -n "$home" ] && [ -d "$home" ] || disable home_missing; [ -n "$runner_temp" ] && [ -d "$runner_temp" ] || disable runner_temp_missing; valid_path "$home" || disable home_aliased; valid_path "$runner_temp" || disable runner_temp_aliased; expected_mise="$home/.local/share/mise"; effective_mise=${MISE_DATA_DIR-}; if [ -z "$effective_mise" ]; then if [ -n "${XDG_DATA_HOME-}" ]; then effective_mise="$XDG_DATA_HOME/mise"; else effective_mise=$expected_mise; fi; fi; valid_path "$expected_mise" || disable mise_root_aliased; valid_path "$effective_mise" || disable mise_root_invalid; [ "$effective_mise" = "$expected_mise" ] || disable mise_root_not_archived; expected_rustup="$runner_temp/velnor/rustup"; expected_cargo="$runner_temp/velnor/cargo"; [ "$mise_rustup" = "$expected_rustup" ] || disable mise_rustup_home_mismatch; [ "$rustup_home" = "$expected_rustup" ] || disable rustup_home_mismatch; [ "$mise_cargo" = "$expected_cargo" ] || disable mise_cargo_home_mismatch; [ "$cargo_home" = "$expected_cargo" ] || disable cargo_home_mismatch; valid_path "$expected_rustup" || disable rustup_root_invalid; valid_path "$expected_cargo" || disable cargo_root_invalid; scratch_root="$runner_temp/velnor"; valid_path "$scratch_root" || disable cache_scratch_aliased; mkdir -p "$scratch_root" || disable cache_scratch_unavailable; [ -d "$scratch_root" ] && [ ! -L "$scratch_root" ] || disable cache_scratch_invalid; scratch_dir="$scratch_root/runtime-identity.$$"; if ! mkdir -m 700 "$scratch_dir"; then scratch_dir=; disable identity_scratch_unavailable; fi; case "$scratch_dir" in "$scratch_root"/runtime-identity.*) ;; *) disable cache_scratch_invalid ;; esac; valid_path "$scratch_dir" && [ -d "$scratch_dir" ] && [ ! -L "$scratch_dir" ] || disable cache_scratch_invalid; identity_file="$scratch_dir/preimage"; sum_file="$scratch_dir/digest"; set -C; if ! : > "$identity_file"; then set +C; disable identity_file_unavailable; fi; if ! : > "$sum_file"; then set +C; disable identity_file_unavailable; fi; set +C; valid_path "$identity_file" && [ -f "$identity_file" ] && [ ! -L "$identity_file" ] || disable identity_file_invalid; valid_path "$sum_file" && [ -f "$sum_file" ] && [ ! -L "$sum_file" ] || disable identity_file_invalid; for value in "velnor-tools-runtime-v2" "$VELNOR_CACHE_STATIC_DIGEST" "$VELNOR_CACHE_LANE" "$expected_target" "$runner_os" "$runner_arch" "$image_os" "$image_version" "$home" "$runner_temp" "$effective_mise" "$expected_rustup" "$expected_cargo"; do if ! printf '%s:%s\n' "${#value}" "$value" >> "$identity_file"; then disable identity_file_write_failed; fi; done; if command -v sha256sum >/dev/null 2>&1; then if ! sha256sum < "$identity_file" > "$sum_file"; then disable identity_hash_failed; fi; elif command -v shasum >/dev/null 2>&1; then if ! shasum -a 256 < "$identity_file" > "$sum_file"; then disable identity_hash_failed; fi; else disable sha256_tool_missing; fi; if ! IFS=' ' read -r fingerprint _ < "$sum_file"; then disable fingerprint_missing; fi; [ ${#fingerprint} -eq 64 ] || disable fingerprint_invalid; case "$fingerprint" in *[!0-9a-f]*) disable fingerprint_invalid ;; esac; if ! cleanup_scratch; then disable identity_scratch_cleanup_failed; fi; printf 'identity=%s\nenabled=true\nreason=qualified_hosted_image\n' "$fingerprint" >> "$GITHUB_OUTPUT"
Loading