master
sh 83 lines 3.02 KB
Raw
1 #!/usr/bin/env bash
2 # Common helpers for graphql-audit scripts.
3 # Sourced from the per-action scripts; not executed directly.
4
5 set -euo pipefail
6
7 # IMPORTANT: define with $'...' so the variables contain real ESC bytes,
8 # not the literal four-character string "\033". This way both `echo -e
9 # "${GH_RED}..."` and `printf '%s' "${GH_RED}..."` render correctly --
10 # without forcing every printf format string to be the variable itself
11 # (which trips shellcheck SC2059) or %b (which adds inconsistency).
12 #
13 # Color vars are referenced by sourcing scripts; shellcheck cannot see that.
14 # shellcheck disable=SC2034
15 GH_RED=$'\033[0;31m'
16 # shellcheck disable=SC2034
17 GH_GREEN=$'\033[0;32m'
18 # shellcheck disable=SC2034
19 GH_YELLOW=$'\033[1;33m'
20 # shellcheck disable=SC2034
21 GH_GRAY=$'\033[0;90m'
22 # shellcheck disable=SC2034
23 GH_NC=$'\033[0m'
24
25 gh_repo_root() {
26 # Walk up from this _lib.sh; that's stable regardless of caller layout.
27 git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel
28 }
29
30 gh_repo_slug() {
31 # Owner/repo of the upstream remote (or origin if no upstream).
32 # Uses bash parameter expansion so repo names containing dots
33 # (e.g. "my.repo", "kubernetes-sigs/cluster-api-provider-aws.git") parse
34 # correctly. The previous regex `[^/.]+` truncated names with dots.
35 # Returns empty for non-github.com remotes (this skill is GitHub-only).
36 local root url
37 root="$(gh_repo_root)"
38 url="$(git -C "${root}" config --get remote.upstream.url 2>/dev/null \
39 || git -C "${root}" config --get remote.origin.url)"
40 # Strict github.com host match. `*github.com*` substring would
41 # accept `notgithub.com` or `github.com.attacker.example.com`.
42 # Three accepted forms cover SCP-style ssh, URL-style ssh, anonymous
43 # https, and credentialed https (`x-access-token:TOK@github.com/...`).
44 if [[ "${url}" != *@github.com:* \
45 && "${url}" != *://github.com/* \
46 && "${url}" != *@github.com/* ]]; then
47 echo ""
48 return
49 fi
50 url="${url%.git}" # strip trailing .git, if any
51 url="${url#*github.com[:/]}" # strip everything up to and including github.com:/
52 echo "${url}"
53 }
54
55 # Resolve and validate the repo slug. Returns "owner/repo" on stdout or
56 # exits non-zero if no slug could be derived.
57 gh_require_slug() {
58 local slug
59 slug="$(gh_repo_slug)"
60 if [[ -z "${slug}" || "${slug}" != */* ]]; then
61 echo -e "${GH_RED}[ERROR]${GH_NC} could not derive owner/repo from git remotes (got: '${slug}'). Fix the upstream/origin remote URL." >&2
62 return 1
63 fi
64 printf '%s' "${slug}"
65 }
66
67 gh_audit_dir() {
68 local root dir
69 root="$(gh_repo_root)"
70 dir="${root}/.local/audits/graphql"
71 mkdir -p "${dir}"
72 echo "${dir}"
73 }
74
75 # Run gh against the GitHub API. Authentication comes from `gh auth status`.
76 # No token is required in .env when using the gh CLI directly.
77 gh_api() {
78 if ! command -v gh >/dev/null; then
79 echo -e "${GH_RED}[ERROR]${GH_NC} 'gh' CLI is not installed. Install from https://cli.github.com/." >&2
80 return 1
81 fi
82 gh "$@"
83 }