#!/usr/bin/env bash # Clone GitHub Actions to a local mirror directory # Usage: ./clone-actions.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ACTIONS_LIST="${SCRIPT_DIR}/actions-to-mirror.txt" if [[ $# -lt 1 ]]; then echo "Usage: $0 " echo "Example: $0 ./actions-mirror" exit 1 fi OUTPUT_DIR="$1" if [[ ! -f "$ACTIONS_LIST" ]]; then echo "Error: Actions list not found at $ACTIONS_LIST" exit 1 fi mkdir -p "$OUTPUT_DIR" clone_action() { local entry="$1" local org repo version target_dir # Parse org/repo@version org="${entry%%/*}" local repo_version="${entry#*/}" repo="${repo_version%%@*}" version="${repo_version#*@}" # Target directory: org/repo-version (e.g., actions/checkout-v4) target_dir="${OUTPUT_DIR}/${org}/${repo}-${version}" if [[ -d "$target_dir" ]]; then echo "Skipping ${org}/${repo}@${version} (already exists)" return 0 fi echo "Cloning ${org}/${repo}@${version}..." mkdir -p "$(dirname "$target_dir")" # Clone with specific tag/branch, depth 1 for speed if ! git clone --depth 1 --branch "$version" \ "https://github.com/${org}/${repo}.git" "$target_dir" 2>/dev/null; then echo "Warning: Failed to clone ${org}/${repo}@${version}" return 1 fi # Remove .git directory (we don't want submodules) rm -rf "${target_dir}/.git" echo "Done: ${org}/${repo}@${version} -> ${target_dir}" } echo "Reading actions from $ACTIONS_LIST" echo "Output directory: $OUTPUT_DIR" echo "" success=0 failed=0 while IFS= read -r line || [[ -n "$line" ]]; do # Skip empty lines and comments [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue # Trim whitespace line="$(echo "$line" | xargs)" if clone_action "$line"; then ((++success)) else ((++failed)) fi done < "$ACTIONS_LIST" echo "" echo "Complete: $success succeeded, $failed failed" if [[ $failed -gt 0 ]]; then exit 1 fi