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
1 change: 1 addition & 0 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
go-${{ runner.os }}-${{ hashFiles('**/go.mod') }}
go-${{ runner.os }}-
fail-on-cache-miss: false
fallback-branch: refs/heads/branch-2
environment: dev
- name: Check Go cache hit result
run: |
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ For a feature branch `feature/new-ui`, this will search for:
| `path` | Files, directories, and wildcard patterns to cache | Yes | |
| `key` | Explicit key for restoring and saving cache | Yes | |
| `restore-keys` | Ordered list of prefix-matched keys for fallback | No | |
| `fallback-branch` | Optional maintenance branch for fallback restore keys (pattern: `branch-*`). If not set, the repository default branch is used. | No | |
| `environment` | Environment to use (dev or prod) | No | `prod` |
| `upload-chunk-size` | Chunk size for large file uploads (bytes) | No | |
| `enableCrossOsArchive` | Enable cross-OS cache compatibility | No | `false` |
Expand Down
52 changes: 9 additions & 43 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ inputs:
environment:
description: Environment to use (dev or prod)
default: prod
fallback-branch:
description: Optional maintenance branch for fallback restore keys (pattern branch-*). If not set, the repository default branch is used.

outputs:
cache-hit:
Expand Down Expand Up @@ -97,49 +99,13 @@ runs:
- name: Prepare cache keys
shell: bash
id: prepare-keys
run: |
# Use GITHUB_HEAD_REF for PR events, GITHUB_REF for push events
BRANCH_NAME="${GITHUB_HEAD_REF:-$GITHUB_REF}"
BRANCH_KEY="${BRANCH_NAME}/${{ inputs.key }}"
echo "branch-key=${BRANCH_KEY}" >> $GITHUB_OUTPUT

# Process restore keys: keep branch-specific keys and add fallback to default branch
if [ -n "${{ inputs.restore-keys }}" ]; then
RESTORE_KEYS=""
# First, add branch-specific restore keys
while IFS= read -r line; do
if [ -n "$line" ]; then
if [ -n "$RESTORE_KEYS" ]; then
RESTORE_KEYS="${RESTORE_KEYS}"$'\n'"${BRANCH_NAME}/${line}"
else
RESTORE_KEYS="${BRANCH_NAME}/${line}"
fi
fi
done <<< "${{ inputs.restore-keys }}"

# Get the default branch dynamically using GitHub API
DEFAULT_BRANCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
"https://api.github.com/repos/${{ github.repository }}" | \
jq -r '.default_branch')

# Only allow fallback to supported default branches
case "$DEFAULT_BRANCH" in
main|master|branch-*)
while IFS= read -r line; do
if [ -n "$line" ]; then
RESTORE_KEYS="${RESTORE_KEYS}"$'\n'"refs/heads/${DEFAULT_BRANCH}/${line}"
fi
done <<< "${{ inputs.restore-keys }}"
;;
*)
echo "::warning::Default branch '$DEFAULT_BRANCH' is not supported for cache fallback. Supported branches: main, master, branch-*"
;;
esac

echo "branch-restore-keys<<EOF" >> $GITHUB_OUTPUT
echo "$RESTORE_KEYS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
fi
env:
INPUT_KEY: ${{ inputs.key }}
INPUT_RESTORE_KEYS: ${{ inputs.restore-keys }}
INPUT_FALLBACK_BRANCH: ${{ inputs.fallback-branch }}
GITHUB_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: "$GITHUB_ACTION_PATH/scripts/prepare-keys.sh"

- name: Cache on S3
uses: runs-on/cache@50350ad4242587b6c8c2baa2e740b1bc11285ff4 # v4.3.0
Expand Down
71 changes: 71 additions & 0 deletions scripts/prepare-keys.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/bin/bash
set -euo pipefail

# This script prepares cache keys with branch-specific paths and fallback logic.
# All inputs are passed through environment variables for security (sanitization).
#
# Required environment variables:
# - INPUT_KEY: The primary cache key
# - GITHUB_OUTPUT: File path for GitHub Actions output
#
# Optional environment variables:
# - INPUT_RESTORE_KEYS: Multi-line list of restore key prefixes
# - INPUT_FALLBACK_BRANCH: Maintenance branch for fallback restore keys (pattern: branch-*)
# - GITHUB_HEAD_REF: Branch name for PR events
# - GITHUB_REF: Branch ref for push events
# - GITHUB_TOKEN: GitHub token for API authentication
# - GITHUB_REPOSITORY: Repository in owner/repo format

# Use GITHUB_HEAD_REF for PR events, GITHUB_REF for push events
BRANCH_NAME="${GITHUB_HEAD_REF:-$GITHUB_REF}"
BRANCH_KEY="${BRANCH_NAME}/${INPUT_KEY}"
echo "branch-key=${BRANCH_KEY}" >> "$GITHUB_OUTPUT"

# Process restore keys: keep branch-specific keys and add fallback to default branch
if [ -n "${INPUT_RESTORE_KEYS:-}" ]; then
RESTORE_KEYS=""

# First, add branch-specific restore keys
while IFS= read -r line; do
if [ -n "$line" ]; then
if [ -n "$RESTORE_KEYS" ]; then
RESTORE_KEYS="${RESTORE_KEYS}"$'\n'"${BRANCH_NAME}/${line}"
else
RESTORE_KEYS="${BRANCH_NAME}/${line}"
fi
fi
done <<< "$INPUT_RESTORE_KEYS"

FALLBACK_BRANCH_INPUT="${INPUT_FALLBACK_BRANCH:-}"

if [[ -n "$FALLBACK_BRANCH_INPUT" ]]; then
FALLBACK_BRANCH="${FALLBACK_BRANCH_INPUT#refs/heads/}"
else
# Query GitHub API to get the default branch
FALLBACK_BRANCH=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${GITHUB_REPOSITORY}" | \
jq -r '.default_branch')
fi

if [[ -n "$FALLBACK_BRANCH" && "$FALLBACK_BRANCH" != "null" ]]; then
case "$FALLBACK_BRANCH" in
main|master|branch-*)
# Add fallback branch restore keys
while IFS= read -r line; do
if [ -n "$line" ]; then
RESTORE_KEYS="${RESTORE_KEYS}"$'\n'"refs/heads/${FALLBACK_BRANCH}/${line}"
fi
done <<< "$INPUT_RESTORE_KEYS"
;;
*)
echo "::warning::Fallback branch '$FALLBACK_BRANCH' is not supported for cache fallback. Supported branches: main, master, branch-*"
;;
esac
else
echo "::warning::Unable to determine fallback branch; skipping fallback restore keys."
fi

echo "branch-restore-keys<<EOF" >> "$GITHUB_OUTPUT"
echo "$RESTORE_KEYS" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
fi
Loading