Skip to content
Snippets Groups Projects
Unverified Commit 148987ae authored by Mikaël Barbero's avatar Mikaël Barbero :dagger:
Browse files

feat: add script to scan github repo for deprecated workflows

parent e284b596
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
## Require GH_TOKEN to be set and exported before the script is run
## json file as generated by https://gitlab.eclipse.org/eclipsefdn/security/scripts/-/blob/main/eclipse.org/pmi_all_projects.sh
PROJECTS_JSON="${1}"
GH_PROJECTS=$(jq '[.[]|select(.state!="Archived" and (.github_repos != [] or .github.org != ""))|{"project_id": .project_id, "github_repos": [.github_repos[].url],"github_org": .github.org }]' <"${PROJECTS_JSON}")
export GH_PROJECTS
_gh() {
gh api -X GET --cache 48h --paginate "$@"
}
export -f _gh
stderr() {
(
flock -w 60 400 || {
echo "ERROR: Unable to acquire stderr.lock" >&2
return 1
}
printf "%s\n" "$@" >&2
) 400>stderr.lock
}
export -f stderr
shallow_clone() {
local repo_url=$1
# silent shallow clone in temp directory
local tmpdir
tmpdir=$(mktemp -d)
GIT_LFS_SKIP_SMUDGE=1 git clone --depth 1 --quiet "${repo_url}" "${tmpdir}"
echo "${tmpdir}"
}
export -f shallow_clone
scan_repo() {
local project=$1
local repo_url=$2
local search_pattern=$3
local tmpdir
tmpdir=$(shallow_clone "${repo_url}")
if [[ -d "${tmpdir}/.github/workflows" ]]; then
current_branch_name=$(git -C "${tmpdir}" branch --show-current)
grep -Enr "${search_pattern}" "${tmpdir}/.github/workflows" | while read -r line; do
line_number=$(cut -d: -f2 <<<"${line}")
path_in_repo=$(cut -d: -f1 <<<"${line}" | sed "s|${tmpdir}/||")
finding_url="${repo_url}/blob/${current_branch_name}/${path_in_repo}#L${line_number}"
# field 2 and onward without trailing and leading spaces
usage=$(cut -d: -f3- <<<"${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
# if usage does not start with a # or spaces and a #
if ! grep -qE '^[# ]*#' <<<"${usage}"; then
(
flock -w 60 200 || {
echo "ERROR: Unable to acquire scan_github_repos.lock" >&2
return 1
}
printf "%s;%s;%s\n" "${project}" "${finding_url}" "${usage}" | tee -a scan_github_repos.log
) 200>scan_github_repos.lock
fi
done
fi
# cleanup
rm -rf "${tmpdir}"
}
export -f scan_repo
# Define a function to scan a project.
scan_project() {
local project="${1}"
stderr "> Scanning project ${project}..."
mapfile -t repos < <(jq -r --arg project "${project}" '.[]|select(.project_id==$project).github_repos[]' <<<"${GH_PROJECTS}")
org=$(jq -r --arg project "${project}" '.[]|select(.project_id==$project).github_org' <<<"${GH_PROJECTS}")
if [[ -n "${org}" ]]; then
mapfile -t org_repos < <(_gh "orgs/${org}/repos" | jq -r '.[]|.full_name')
# prepend string 'XXX' to each entries in org_repos
for i in "${!org_repos[@]}"; do
org_repos[i]="https://github.com/${org_repos[$i]}"
done
if [[ "${#org_repos[@]}" -gt 0 ]]; then
# append org repos to the list of repos
repos+=("${org_repos[@]}")
fi
fi
# remove duplicates from repos
mapfile -t uniqu_repos < <(printf '%s\n' "${repos[@]}" | sort -u)
printf "%s\n" "${uniqu_repos[@]}" | parallel --quote --jobs 2 scan_repo "${project}" '{}' 'actions/(upload|download)-artifact'
}
export -f scan_project
printf "%s\n" "$(jq -r '.[]|.project_id' <<<"${GH_PROJECTS}")" | parallel --jobs 8 scan_project '{}'
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment