vouchington-tooling 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +16 -1
  2. package/dist/cli/commands/gha-artifacts-cleanup.d.mts +6 -0
  3. package/dist/cli/commands/gha-artifacts-cleanup.mjs +50 -0
  4. package/dist/cli/commands/http-origin.d.mts +2 -0
  5. package/dist/cli/commands/http-origin.mjs +14 -0
  6. package/dist/cli/index.mjs +11 -0
  7. package/dist/cli/parse-gha-artifacts-cleanup.d.mts +15 -0
  8. package/dist/cli/parse-gha-artifacts-cleanup.mjs +74 -0
  9. package/dist/cli/parse.d.mts +7 -2
  10. package/dist/cli/parse.mjs +36 -0
  11. package/dist/cli/usage.d.mts +1 -1
  12. package/dist/cli/usage.mjs +9 -0
  13. package/dist/gha-artifacts-cleanup/classify.d.mts +14 -0
  14. package/dist/gha-artifacts-cleanup/classify.mjs +32 -0
  15. package/dist/gha-artifacts-cleanup/commands.d.mts +23 -0
  16. package/dist/gha-artifacts-cleanup/commands.mjs +55 -0
  17. package/dist/gha-artifacts-cleanup/github.d.mts +16 -0
  18. package/dist/gha-artifacts-cleanup/github.mjs +100 -0
  19. package/dist/gha-artifacts-cleanup/index.d.mts +8 -0
  20. package/dist/gha-artifacts-cleanup/index.mjs +4 -0
  21. package/dist/gha-artifacts-cleanup/plan.d.mts +17 -0
  22. package/dist/gha-artifacts-cleanup/plan.mjs +40 -0
  23. package/dist/gha-selected-files/index.d.mts +6 -0
  24. package/dist/gha-selected-files/index.mjs +38 -0
  25. package/dist/http-origin/index.d.mts +1 -0
  26. package/dist/http-origin/index.mjs +23 -0
  27. package/dist/index.d.mts +7 -2
  28. package/dist/index.mjs +5 -1
  29. package/dist/pnpm-install/native-health.d.mts +4 -0
  30. package/dist/pnpm-install/native-health.mjs +84 -0
  31. package/dist/pnpm-install/runner.mjs +8 -3
  32. package/dist/process-line-buffer/index.d.mts +7 -0
  33. package/dist/process-line-buffer/index.mjs +28 -0
  34. package/dist/shared-context/{fake-git.test-helpers.d.mts → fake-git.d.mts} +1 -0
  35. package/dist/shared-context/{fake-git.test-helpers.mjs → fake-git.mjs} +4 -1
  36. package/dist/shared-context/index.d.mts +2 -0
  37. package/dist/shared-context/index.mjs +1 -0
  38. package/package.json +27 -1
  39. package/scripts/allocate-browser-safe-ports.py +113 -1
  40. package/scripts/gha/diagnose-port-collision.sh +232 -0
  41. package/scripts/gha/prepare-trivy-db.sh +32 -0
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env bash
2
+
3
+ PORTS="${PORTS:-}"
4
+ OUTPUT_DIR="${OUTPUT_DIR:-${RUNNER_TEMP:-/tmp}/port-diagnostics}"
5
+
6
+ if [ "${PORT_DIAGNOSTICS_BOUNDED_CHILD:-}" != 1 ]; then
7
+ PORT_DIAGNOSTICS_BOUNDED_CHILD=1 python3 - \
8
+ "${PORT_DIAGNOSTICS_TIMEOUT_SECONDS:-45}" "$0" "$@" <<'PY'
9
+ import os
10
+ import signal
11
+ import subprocess
12
+ import sys
13
+
14
+ try:
15
+ timeout_seconds = float(sys.argv[1])
16
+ if timeout_seconds <= 0 or timeout_seconds > 300:
17
+ raise ValueError
18
+ except ValueError:
19
+ timeout_seconds = 45
20
+
21
+ try:
22
+ process = subprocess.Popen(
23
+ ["bash", sys.argv[2], *sys.argv[3:]],
24
+ env=os.environ.copy(),
25
+ start_new_session=True,
26
+ )
27
+ except OSError as error:
28
+ print(f"::warning::Could not start port diagnostics: {error}", file=sys.stderr)
29
+ sys.exit(0)
30
+
31
+ try:
32
+ process.wait(timeout=timeout_seconds)
33
+ except subprocess.TimeoutExpired:
34
+ os.killpg(process.pid, signal.SIGTERM)
35
+ try:
36
+ process.wait(timeout=2)
37
+ except subprocess.TimeoutExpired:
38
+ os.killpg(process.pid, signal.SIGKILL)
39
+ process.wait()
40
+ print(
41
+ f"::warning::Port diagnostics collector exceeded {timeout_seconds:g}s; uploading partial evidence",
42
+ file=sys.stderr,
43
+ )
44
+ PY
45
+ exit 0
46
+ fi
47
+
48
+ usage() {
49
+ cat <<'USAGE'
50
+ Usage: diagnose-port-collision [--ports "2200 2216"] [--output-dir PATH]
51
+
52
+ Best-effort, non-masking diagnostics for a failed workflow that allocated localhost ports.
53
+ The script never returns a failure for an unavailable probe or an occupied port.
54
+ USAGE
55
+ }
56
+
57
+ while [ "$#" -gt 0 ]; do
58
+ case "$1" in
59
+ --ports)
60
+ [ "$#" -ge 2 ] || { usage >&2; exit 0; }
61
+ PORTS="$2"
62
+ shift
63
+ ;;
64
+ --output-dir)
65
+ [ "$#" -ge 2 ] || { usage >&2; exit 0; }
66
+ OUTPUT_DIR="$2"
67
+ shift
68
+ ;;
69
+ -h|--help)
70
+ usage
71
+ exit 0
72
+ ;;
73
+ *)
74
+ echo "::warning::Ignoring unknown diagnostics argument: $1" >&2
75
+ ;;
76
+ esac
77
+ shift
78
+ done
79
+
80
+ if ! mkdir -p "$OUTPUT_DIR" 2>/dev/null; then
81
+ echo "::warning::Could not create port diagnostics directory: $OUTPUT_DIR" >&2
82
+ exit 0
83
+ fi
84
+
85
+ REPORT="$OUTPUT_DIR/summary.txt"
86
+ LISTENERS="$OUTPUT_DIR/listeners.txt"
87
+ DOCKER_REPORT="$OUTPUT_DIR/docker.txt"
88
+ KERNEL_REPORT="$OUTPUT_DIR/kernel.txt"
89
+ RUNNER_REPORT="$OUTPUT_DIR/runner.txt"
90
+
91
+ write_report_header() {
92
+ local path="$1"
93
+ {
94
+ echo "generated_at=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo unavailable)"
95
+ echo "workflow=${GITHUB_WORKFLOW:-unavailable}"
96
+ echo "job=${GITHUB_JOB:-unavailable}"
97
+ echo "run_id=${GITHUB_RUN_ID:-unavailable}"
98
+ echo "run_attempt=${GITHUB_RUN_ATTEMPT:-unavailable}"
99
+ echo "runner_name=${RUNNER_NAME:-unavailable}"
100
+ echo "runner_os=${RUNNER_OS:-unavailable}"
101
+ echo "workspace=${GITHUB_WORKSPACE:-unavailable}"
102
+ echo "allocated_ports=${PORTS:-none}"
103
+ } > "$path" 2>/dev/null || true
104
+ }
105
+
106
+ write_report_header "$REPORT"
107
+
108
+ run_bounded() {
109
+ local seconds="$1"
110
+ shift
111
+ python3 - "$seconds" "$@" <<'PY'
112
+ import subprocess
113
+ import sys
114
+ try:
115
+ subprocess.run(sys.argv[2:], check=False, timeout=float(sys.argv[1]))
116
+ except subprocess.TimeoutExpired:
117
+ print(f'probe=timed-out after {sys.argv[1]}s', file=sys.stderr)
118
+ except OSError as error:
119
+ print(f'probe=unavailable ({error})', file=sys.stderr)
120
+ PY
121
+ }
122
+
123
+ valid_ports=()
124
+ invalid_ports=()
125
+ read -r -a requested_ports <<< "$PORTS"
126
+ for port in "${requested_ports[@]}"; do
127
+ case "$port" in
128
+ ''|*[!0-9]*) invalid_ports+=("$port") ;;
129
+ *)
130
+ if [ "$port" -ge 1 ] && [ "$port" -le 65535 ]; then
131
+ valid_ports+=("$port")
132
+ else
133
+ invalid_ports+=("$port")
134
+ fi
135
+ ;;
136
+ esac
137
+ done
138
+
139
+ {
140
+ echo "requested_port_count=${#requested_ports[@]}"
141
+ echo "valid_port_count=${#valid_ports[@]}"
142
+ echo "invalid_ports=${invalid_ports[*]:-none}"
143
+ } >> "$REPORT" 2>/dev/null || true
144
+
145
+ {
146
+ echo "# Linux kernel port contract (best effort)"
147
+ if command -v sysctl >/dev/null 2>&1; then
148
+ echo "ip_local_reserved_ports=$(sysctl -n net.ipv4.ip_local_reserved_ports 2>/dev/null || echo unavailable)"
149
+ echo "ip_local_port_range=$(sysctl -n net.ipv4.ip_local_port_range 2>/dev/null || echo unavailable)"
150
+ else
151
+ echo "sysctl=unavailable"
152
+ fi
153
+ for path in /proc/sys/net/ipv4/ip_local_reserved_ports /proc/sys/net/ipv4/ip_local_port_range; do
154
+ if [ -r "$path" ]; then
155
+ echo "$path=$(tr -d '\n' < "$path" 2>/dev/null || true)"
156
+ fi
157
+ done
158
+ } > "$KERNEL_REPORT" 2>/dev/null || true
159
+
160
+ {
161
+ echo "# TCP socket diagnostics (best effort)"
162
+ lsof_available=false
163
+ ss_available=false
164
+ lsof_output=''
165
+ if command -v lsof >/dev/null 2>&1; then
166
+ lsof_available=true
167
+ lsof_output=$(run_bounded 10 lsof -nP -iTCP 2>&1 || true)
168
+ elif command -v ss >/dev/null 2>&1; then
169
+ ss_available=true
170
+ fi
171
+ for port in "${valid_ports[@]}"; do
172
+ occupied=false
173
+ echo "port=$port"
174
+ if [ "$lsof_available" = true ]; then
175
+ if lsof_filtered=$(printf '%s\n' "$lsof_output" | awk -v port="$port" '
176
+ /^probe=/ { print; next }
177
+ $1 == "COMMAND" { header = $0; next }
178
+ {
179
+ local_endpoint = $9
180
+ sub(/->.*/, "", local_endpoint)
181
+ if (local_endpoint ~ (":" port "$")) {
182
+ if (!printed_header && header != "") {
183
+ print header
184
+ printed_header = 1
185
+ }
186
+ print
187
+ found = 1
188
+ }
189
+ }
190
+ END { exit found ? 0 : 1 }
191
+ '); then
192
+ occupied=true
193
+ fi
194
+ [ -z "$lsof_filtered" ] || printf '%s\n' "$lsof_filtered"
195
+ elif [ "$ss_available" = true ]; then
196
+ ss -ntp "( sport = :$port )" 2>&1 || true
197
+ if ss -nt "( sport = :$port )" 2>/dev/null | tail -n +2 | grep -q .; then
198
+ occupied=true
199
+ fi
200
+ else
201
+ echo "probe=unavailable (neither lsof nor ss is installed)"
202
+ fi
203
+ echo "status=$([ "$occupied" = true ] && echo occupied || echo free-or-unobserved)"
204
+ echo
205
+ done
206
+ } > "$LISTENERS" 2>/dev/null || true
207
+
208
+ {
209
+ echo "# Docker diagnostics (best effort)"
210
+ if command -v docker >/dev/null 2>&1; then
211
+ run_bounded 10 docker version --format 'server={{.Server.Version}}' 2>&1 || true
212
+ docker_ps_output=$(run_bounded 10 docker ps --no-trunc --format 'container={{.ID}} names={{.Names}} ports={{.Ports}}' 2>&1 || true)
213
+ for port in "${valid_ports[@]}"; do
214
+ echo "published_port=$port"
215
+ printf '%s\n' "$docker_ps_output" | awk -v port="$port" '/^probe=/ || $0 ~ "(^|[^0-9])" port "->"' || true
216
+ done
217
+ else
218
+ echo "docker=unavailable"
219
+ fi
220
+ } > "$DOCKER_REPORT" 2>/dev/null || true
221
+
222
+ {
223
+ echo "# Runner context (deliberately excludes the process environment)"
224
+ uname -a 2>&1 || true
225
+ hostname 2>&1 || true
226
+ id 2>&1 || true
227
+ echo "runner_temp=${RUNNER_TEMP:-unavailable}"
228
+ echo "github_actions=${GITHUB_ACTIONS:-unavailable}"
229
+ } > "$RUNNER_REPORT" 2>/dev/null || true
230
+
231
+ echo "::notice::Port diagnostics captured under $OUTPUT_DIR"
232
+ exit 0
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ mirror_repository="${TRIVY_DB_MIRROR_REPOSITORY:-mirror.gcr.io/aquasec/trivy-db:2}"
5
+ official_repository="${TRIVY_DB_OFFICIAL_REPOSITORY:-ghcr.io/aquasecurity/trivy-db:2}"
6
+ download_timeout="${TRIVY_DB_TIMEOUT:-75s}"
7
+
8
+ download_database() {
9
+ trivy image \
10
+ --download-db-only \
11
+ --no-progress \
12
+ --timeout "$download_timeout" \
13
+ --db-repository "$1"
14
+ }
15
+
16
+ mirror_exit=0
17
+ download_database "$mirror_repository" || mirror_exit=$?
18
+ if [ "$mirror_exit" -eq 0 ]; then
19
+ echo "Trivy vulnerability database prepared from the Google mirror"
20
+ exit 0
21
+ fi
22
+
23
+ echo "Trivy database mirror failed with exit ${mirror_exit}; retrying from official GHCR"
24
+ official_exit=0
25
+ download_database "$official_repository" || official_exit=$?
26
+ if [ "$official_exit" -eq 0 ]; then
27
+ echo "Trivy vulnerability database prepared from official GHCR"
28
+ exit 0
29
+ fi
30
+
31
+ echo "Trivy vulnerability database download failed from the Google mirror (exit ${mirror_exit}) and official GHCR (exit ${official_exit})" >&2
32
+ exit "$official_exit"