|
1 | 1 | name: Universal Contracts Analytics |
2 | 2 |
|
3 | 3 | on: |
| 4 | + schedule: |
| 5 | + - cron: "0 0 * * *" # scheduled to run every day at midnight |
4 | 6 | workflow_dispatch: |
5 | 7 |
|
6 | 8 | permissions: |
|
10 | 12 | count-contracts: |
11 | 13 | runs-on: ubuntu-latest |
12 | 14 | steps: |
13 | | - - name: Run curl and list repos |
| 15 | + - name: Count repos using GitHub Code Search |
| 16 | + id: count |
14 | 17 | run: | |
15 | | - curl -s -H "Accept: application/vnd.github+json" \ |
16 | | - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ |
17 | | - "https://api.github.com/search/code?q=@zetachain/protocol-contracts/contracts/zevm/GatewayZEVM.sol+in:file" \ |
18 | | - | jq -r '.items[].repository.html_url' | sort -u |
| 18 | + set -euo pipefail |
| 19 | +
|
| 20 | + # Base search query; quote the import path to avoid parse errors |
| 21 | + BASE_QUERY='"@zetachain/protocol-contracts/contracts/zevm/GatewayZEVM.sol" in:file' |
| 22 | + echo "Base query: $BASE_QUERY" |
| 23 | +
|
| 24 | + PER_PAGE=100 |
| 25 | + TMP=$(mktemp) |
| 26 | + trap 'rm -f "$TMP"' EXIT |
| 27 | + : > "$TMP" |
| 28 | + echo "Using per_page=$PER_PAGE" |
| 29 | + echo "Temp file: $TMP" |
| 30 | +
|
| 31 | + fetch_repos() { |
| 32 | + local query="$1" |
| 33 | + local out="$2" |
| 34 | + local page=1 |
| 35 | + echo "Fetching repos for query: $query" |
| 36 | + while :; do |
| 37 | + local encoded |
| 38 | + encoded=$(jq -rn --arg q "$query" '$q|@uri') |
| 39 | + local resp |
| 40 | + local url="https://api.github.com/search/code?q=${encoded}&per_page=${PER_PAGE}&page=${page}" |
| 41 | + echo "Requesting page ${page}: ${url}" |
| 42 | + resp=$(curl -sS \ |
| 43 | + -H "Accept: application/vnd.github+json" \ |
| 44 | + -H "X-GitHub-Api-Version: 2022-11-28" \ |
| 45 | + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ |
| 46 | + "$url") |
| 47 | +
|
| 48 | + # If the API returns an error with a message, surface it for debugging |
| 49 | + local message |
| 50 | + message=$(echo "$resp" | jq -r '.message // empty') |
| 51 | + if [ -n "$message" ]; then |
| 52 | + echo "GitHub API message: $message" >&2 |
| 53 | + fi |
| 54 | +
|
| 55 | + local items_len |
| 56 | + items_len=$(echo "$resp" | jq '(.items // []) | length') |
| 57 | + echo "Items on page ${page}: ${items_len}" |
| 58 | + if [ "$items_len" -eq 0 ]; then |
| 59 | + echo "No items returned; stopping pagination for this query." |
| 60 | + break |
| 61 | + fi |
| 62 | +
|
| 63 | + echo "$resp" | jq -r '.items[].repository.html_url' >> "$out" |
| 64 | + local page_repos |
| 65 | + page_repos=$(echo "$resp" | jq -r '.items[].repository.html_url' | sort -u | wc -l | tr -d ' ') |
| 66 | + echo "Collected ${page_repos} repo URLs from page ${page}." |
| 67 | +
|
| 68 | + # Stop if fewer than PER_PAGE items returned |
| 69 | + if [ "$items_len" -lt "$PER_PAGE" ]; then |
| 70 | + echo "Last page reached (items < per_page)." |
| 71 | + break |
| 72 | + fi |
| 73 | +
|
| 74 | + page=$((page+1)) |
| 75 | + done |
| 76 | + } |
| 77 | +
|
| 78 | + # Execute search (including forks) |
| 79 | + echo "Executing search query (including forks)" |
| 80 | + fetch_repos "$BASE_QUERY" "$TMP" |
| 81 | + COUNT=$(sort -u "$TMP" | grep -c . || true) |
| 82 | + echo "Unique repositories: $COUNT" |
| 83 | +
|
| 84 | + sort -u "$TMP" |
| 85 | +
|
| 86 | + echo "Repositories using GatewayZEVM.sol: $COUNT" |
| 87 | + echo "count=$COUNT" >> "$GITHUB_OUTPUT" |
| 88 | +
|
| 89 | + - name: Send count to PostHog |
| 90 | + if: ${{ success() && steps.count.outputs.count != '' }} |
| 91 | + env: |
| 92 | + POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} |
| 93 | + POSTHOG_HOST: ${{ vars.POSTHOG_HOST }} |
| 94 | + run: | |
| 95 | + if [ -z "$POSTHOG_API_KEY" ]; then |
| 96 | + echo "POSTHOG_API_KEY is not set; skipping PostHog capture." >&2 |
| 97 | + exit 0 |
| 98 | + fi |
| 99 | +
|
| 100 | + HOST="${POSTHOG_HOST:-https://us.i.posthog.com}" |
| 101 | + COUNT="${{ steps.count.outputs.count }}" |
| 102 | +
|
| 103 | + # Build JSON with jq to ensure valid formatting and numeric count |
| 104 | + jq -n \ |
| 105 | + --arg api_key "$POSTHOG_API_KEY" \ |
| 106 | + --arg event "Universal contract count" \ |
| 107 | + --arg distinct_id "github_actions/${{ github.repository }}" \ |
| 108 | + --argjson count "$COUNT" \ |
| 109 | + '{api_key:$api_key, event:$event, distinct_id:$distinct_id, properties:{count:$count}}' \ |
| 110 | + | curl -s -f -X POST "$HOST/i/v0/e/" -H "Content-Type: application/json" --data-binary @- |
0 commit comments