#!/usr/bin/env bash # Scan git repositories for GitHub/Gitea/Forgejo Actions used in workflows # Usage: ./scripts/scan-actions.sh /var/lib/gitea/repositories set -euo pipefail # Wrapper to handle safe.directory issues when running as root git_cmd() { git -c safe.directory='*' "$@" } if [[ $# -ne 1 ]]; then echo "Usage: $0 " >&2 echo "Example: $0 /var/lib/gitea/repositories" >&2 exit 1 fi BASE_DIR="$1" if [[ ! -d "$BASE_DIR" ]]; then echo "Error: Directory '$BASE_DIR' does not exist" >&2 exit 1 fi # Find all bare git repositories find "$BASE_DIR" -type d -name "*.git" -print0 2>/dev/null | while IFS= read -r -d '' repo; do # Get all branch refs branches=$(git_cmd -C "$repo" for-each-ref --format='%(refname:short)' refs/heads/ 2>/dev/null || true) if [[ -z "$branches" ]]; then continue fi for branch in $branches; do # Check all workflow directories for workflow_dir in ".github/workflows" ".gitea/workflows" ".forgejo/workflows"; do # List files in the workflow directory files=$(git_cmd -C "$repo" ls-tree --name-only "$branch":"$workflow_dir" 2>/dev/null || true) for file in $files; do # Only process .yml and .yaml files case "$file" in *.yml|*.yaml) # Read the file content and extract uses: statements git_cmd -C "$repo" show "$branch:$workflow_dir/$file" 2>/dev/null || true ;; esac done done done done | \ # Extract uses: values - match owner/repo@ref or owner/repo/path@ref pattern grep -oE 'uses:\s*["'"'"']?[a-zA-Z0-9_.-]+/[a-zA-Z0-9_./-]+@[a-zA-Z0-9_.-]+' | \ # Remove the uses: prefix and any quotes sed -E 's/uses:\s*["'"'"']?//' | \ # Sort and deduplicate sort -u