docs: add guidance for checking organization and environment secrets #8
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test Cloudflare Cache Purge | |
| on: | |
| push: | |
| branches: | |
| - test-cloudflare-purge | |
| workflow_dispatch: | |
| jobs: | |
| test_cloudflare_purge: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Print Configuration | |
| run: | | |
| echo "Branch: ${{ github.ref_name }}" | |
| echo "Commit: ${{ github.sha }}" | |
| echo "Host: polygon-docs.polygon.technology" | |
| echo "" | |
| echo "=== Secret Source Check ===" | |
| echo "If you deleted CLOUDFLARE_AUTH_KEY but it's still being read," | |
| echo "the secret might be coming from:" | |
| echo "1. Organization-level secrets (Settings → Secrets → Actions)" | |
| echo "2. Environment-level secrets (if environments are configured)" | |
| echo "3. The secret might still exist in the repository" | |
| echo "" | |
| echo "Please check ALL of these locations to fully remove the secret." | |
| - name: Verify Cloudflare Token | |
| run: | | |
| # Get raw values first (before any processing) | |
| RAW_ZONE_ID="${{ secrets.CLOUDFLARE_ZONE }}" | |
| RAW_AUTH_TOKEN="${{ secrets.CLOUDFLARE_AUTH_KEY }}" | |
| echo "=== Raw Secret Inspection ===" | |
| echo "Raw Zone ID length: ${#RAW_ZONE_ID}" | |
| echo "Raw Token length: ${#RAW_AUTH_TOKEN}" | |
| echo "Raw Token first 10 chars (hex): $(echo -n "$RAW_AUTH_TOKEN" | head -c 10 | xxd -p 2>/dev/null || echo 'xxd not available')" | |
| echo "Raw Token first 10 chars (visible): $(echo -n "$RAW_AUTH_TOKEN" | head -c 10 | cat -A)" | |
| # Process values (trim whitespace) | |
| ZONE_ID=$(echo "$RAW_ZONE_ID" | tr -d '[:space:]') | |
| AUTH_TOKEN=$(echo "$RAW_AUTH_TOKEN" | tr -d '[:space:]') | |
| echo "" | |
| echo "=== After Processing ===" | |
| echo "Zone ID length: ${#ZONE_ID}" | |
| echo "Zone ID: ${ZONE_ID:0:8}...${ZONE_ID: -8}" | |
| echo "Token length: ${#AUTH_TOKEN}" | |
| # Show token preview more safely | |
| if [ ${#AUTH_TOKEN} -ge 15 ]; then | |
| TOKEN_START="${AUTH_TOKEN:0:10}" | |
| TOKEN_END="${AUTH_TOKEN: -10}" | |
| echo "Token preview: ${TOKEN_START}...${TOKEN_END}" | |
| echo "Token starts with: ${AUTH_TOKEN:0:3}" | |
| echo "Token ends with: ${AUTH_TOKEN: -3}" | |
| else | |
| echo "⚠️ WARNING: Token seems too short (${#AUTH_TOKEN} chars). API tokens are typically 40+ characters." | |
| echo "Token preview: ${AUTH_TOKEN:0:4}...${AUTH_TOKEN: -4}" | |
| fi | |
| # Check if token matches expected start | |
| if [ "${AUTH_TOKEN:0:3}" != "fjx" ]; then | |
| echo "" | |
| echo "⚠️ WARNING: Token does not start with 'fjx' as expected!" | |
| echo " Expected: starts with 'fjx'" | |
| echo " Actual: starts with '${AUTH_TOKEN:0:3}'" | |
| echo "" | |
| echo "🔍 The secret is still being read even though you deleted it." | |
| echo "This means the secret exists in one of these locations:" | |
| echo "" | |
| echo "1. ORGANIZATION SECRETS (most likely):" | |
| echo " - Go to: https://github.com/organizations/0xPolygon/settings/secrets/actions" | |
| echo " - Or: Organization Settings → Secrets and variables → Actions" | |
| echo " - Look for CLOUDFLARE_AUTH_KEY and delete it there" | |
| echo "" | |
| echo "2. ENVIRONMENT SECRETS:" | |
| echo " - Go to: Repository Settings → Environments" | |
| echo " - Check each environment (dev, staging, prod, etc.)" | |
| echo " - Look for CLOUDFLARE_AUTH_KEY in environment secrets" | |
| echo "" | |
| echo "3. REPOSITORY SECRETS (double-check):" | |
| echo " - Go to: Settings → Secrets and variables → Actions" | |
| echo " - Verify CLOUDFLARE_AUTH_KEY is actually deleted" | |
| echo "" | |
| echo "GitHub secrets hierarchy (highest priority first):" | |
| echo " Environment secrets > Organization secrets > Repository secrets" | |
| fi | |
| # Check token type hints | |
| if [ ${#AUTH_TOKEN} -lt 45 ]; then | |
| echo "" | |
| echo "⚠️ Token length suggests it might be:" | |
| echo " - A Global API Key (~37 chars) - requires email + key authentication" | |
| echo " - An incomplete/truncated API Token" | |
| echo "" | |
| echo "For API Tokens:" | |
| echo " - Should be 40+ characters long" | |
| echo " - Created in: Cloudflare Dashboard → My Profile → API Tokens" | |
| echo " - Needs 'Zone.Cache Purge' permission" | |
| echo " - Used with: Authorization: Bearer <token>" | |
| fi | |
| echo "" | |
| echo "Testing token by fetching zone info..." | |
| VERIFY_RESPONSE=$(curl -s -w "\n%{http_code}" -X GET \ | |
| "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}" \ | |
| -H "Authorization: Bearer ${AUTH_TOKEN}" \ | |
| -H "Content-Type: application/json") | |
| VERIFY_HTTP_CODE=$(echo "$VERIFY_RESPONSE" | tail -n1) | |
| VERIFY_BODY=$(echo "$VERIFY_RESPONSE" | sed '$d') | |
| echo "Verify HTTP Status: $VERIFY_HTTP_CODE" | |
| if [ "$VERIFY_HTTP_CODE" -ne 200 ]; then | |
| echo "❌ Token verification failed!" | |
| echo "$VERIFY_BODY" | jq '.' || echo "$VERIFY_BODY" | |
| echo "" | |
| echo "=== Troubleshooting ===" | |
| ERROR_CODE=$(echo "$VERIFY_BODY" | jq -r '.errors[0].code' 2>/dev/null || echo "") | |
| if [ "$ERROR_CODE" = "9109" ]; then | |
| echo "Error 9109: Invalid access token" | |
| echo "" | |
| echo "This usually means:" | |
| echo "1. The token is not a valid API Token" | |
| echo "2. The token might be a Global API Key (requires different auth method)" | |
| echo "3. The token was incorrectly copied (check for extra spaces/newlines)" | |
| echo "4. The token is expired or revoked" | |
| echo "" | |
| echo "To create a proper API Token:" | |
| echo "1. Go to: https://dash.cloudflare.com/profile/api-tokens" | |
| echo "2. Click 'Create Token'" | |
| echo "3. Use 'Edit zone DNS' template or create custom token with:" | |
| echo " - Zone: Zone Settings:Read" | |
| echo " - Zone: Zone:Read" | |
| echo " - Zone: Cache Purge:Edit" | |
| echo "4. Copy the ENTIRE token (it's long!)" | |
| else | |
| echo "Common issues:" | |
| echo "1. Token may be invalid or expired" | |
| echo "2. Token may not have 'Zone.Read' permission" | |
| echo "3. Zone ID may be incorrect" | |
| fi | |
| exit 1 | |
| else | |
| ZONE_NAME=$(echo "$VERIFY_BODY" | jq -r '.result.name' 2>/dev/null || echo "unknown") | |
| echo "✅ Token verified! Zone: $ZONE_NAME" | |
| echo "ZONE_ID=${ZONE_ID}" >> $GITHUB_ENV | |
| echo "AUTH_TOKEN=${AUTH_TOKEN}" >> $GITHUB_ENV | |
| fi | |
| - name: Cloudflare Cache Purge | |
| run: | | |
| HOST="polygon-docs.polygon.technology" | |
| echo "Purging cache for host: $HOST" | |
| RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ | |
| "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache" \ | |
| -H "Authorization: Bearer ${AUTH_TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| --data "{\"hosts\":[\"${HOST}\"]}") | |
| HTTP_CODE=$(echo "$RESPONSE" | tail -n1) | |
| BODY=$(echo "$RESPONSE" | sed '$d') | |
| echo "HTTP Status Code: $HTTP_CODE" | |
| echo "Response:" | |
| echo "$BODY" | jq '.' || echo "$BODY" | |
| if [ "$HTTP_CODE" -eq 200 ]; then | |
| SUCCESS=$(echo "$BODY" | jq -r '.success' 2>/dev/null || echo "false") | |
| if [ "$SUCCESS" = "true" ]; then | |
| echo "✅ Cache purge successful!" | |
| exit 0 | |
| else | |
| echo "❌ Cache purge failed - success field is false" | |
| echo "$BODY" | jq -r '.errors[]? | "Error \(.code): \(.message)"' 2>/dev/null || echo "$BODY" | |
| exit 1 | |
| fi | |
| else | |
| echo "❌ HTTP request failed with status $HTTP_CODE" | |
| if [ "$HTTP_CODE" -eq 401 ]; then | |
| echo "" | |
| echo "Authentication failed. Please verify:" | |
| echo "1. The API token is valid and not expired" | |
| echo "2. The token has 'Zone.Cache Purge' permission" | |
| echo "3. The token is for the correct Cloudflare account" | |
| fi | |
| exit 1 | |
| fi | |