name: Update GeoLite2 Checksum on: schedule: - cron: '0 2 * * 1' # Weekly on Mondays at 2 AM UTC workflow_dispatch: permissions: contents: write pull-requests: write issues: write jobs: update-checksum: runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Download and calculate checksum id: checksum run: | set -euo pipefail echo "📥 Downloading GeoLite2-Country.mmdb..." DOWNLOAD_URL="https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb" # Download with retry logic for i in {1..3}; do if curl -fsSL "$DOWNLOAD_URL" -o /tmp/geolite2.mmdb; then echo "✅ Download successful on attempt $i" break else echo "❌ Download failed on attempt $i" if [ "$i" -eq 3 ]; then echo "error=download_failed" >> "$GITHUB_OUTPUT" exit 1 fi sleep 5 fi done # Calculate checksum CURRENT=$(sha256sum /tmp/geolite2.mmdb | cut -d' ' -f1) # Validate checksum format (64 hex characters) if ! [[ "$CURRENT" =~ ^[a-f0-9]{64}$ ]]; then echo "❌ Invalid checksum format: $CURRENT" echo "error=invalid_checksum_format" >> "$GITHUB_OUTPUT" exit 1 fi # Extract current checksum from Dockerfile OLD=$(grep "ARG GEOLITE2_COUNTRY_SHA256=" Dockerfile | cut -d'=' -f2) # Validate old checksum format if ! [[ "$OLD" =~ ^[a-f0-9]{64}$ ]]; then echo "❌ Invalid old checksum format in Dockerfile: $OLD" echo "error=invalid_dockerfile_checksum" >> "$GITHUB_OUTPUT" exit 1 fi echo "🔍 Checksum comparison:" echo " Current (Dockerfile): $OLD" echo " Latest (Downloaded): $CURRENT" echo "current=$CURRENT" >> "$GITHUB_OUTPUT" echo "old=$OLD" >> "$GITHUB_OUTPUT" if [ "$CURRENT" != "$OLD" ]; then echo "needs_update=true" >> "$GITHUB_OUTPUT" echo "⚠️ Checksum mismatch detected - update required" else echo "needs_update=false" >> "$GITHUB_OUTPUT" echo "✅ Checksum matches - no update needed" fi - name: Update Dockerfile if: steps.checksum.outputs.needs_update == 'true' run: | set -euo pipefail echo "📝 Updating Dockerfile with new checksum..." sed -i "s/ARG GEOLITE2_COUNTRY_SHA256=.*/ARG GEOLITE2_COUNTRY_SHA256=${{ steps.checksum.outputs.current }}/" Dockerfile # Verify the change was applied if ! grep -q "ARG GEOLITE2_COUNTRY_SHA256=${{ steps.checksum.outputs.current }}" Dockerfile; then echo "❌ Failed to update Dockerfile" exit 1 fi echo "✅ Dockerfile updated successfully" - name: Verify Dockerfile syntax if: steps.checksum.outputs.needs_update == 'true' run: | set -euo pipefail echo "🔍 Verifying Dockerfile syntax..." # Use BuildKit's --check flag for syntax validation (no actual build) DOCKER_BUILDKIT=1 docker build --check -f Dockerfile . 2>&1 || { echo "❌ Dockerfile syntax validation failed" exit 1 } echo "✅ Dockerfile syntax is valid" - name: Create Pull Request if: steps.checksum.outputs.needs_update == 'true' uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: title: "chore(docker): update GeoLite2-Country.mmdb checksum" body: | 🤖 **Automated GeoLite2 Database Checksum Update** The GeoLite2-Country.mmdb database has been updated upstream. ### Changes - **Old checksum:** `${{ steps.checksum.outputs.old }}` - **New checksum:** `${{ steps.checksum.outputs.current }}` - **File modified:** `Dockerfile` (line 352) ### Verification Required - [ ] Local build passes: `docker build --no-cache -t test .` - [ ] Container starts successfully - [ ] API health check responds: `curl http://localhost:8080/api/v1/health` - [ ] CI build passes ### Testing Commands ```bash # Verify checksum locally curl -fsSL "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb" | sha256sum # Build and test docker build --no-cache --pull -t charon:test-geolite2 . docker run --rm charon:test-geolite2 /app/charon --version ``` ### Related Documentation - [Dockerfile](/Dockerfile#L352) - [Implementation Plan](/docs/plans/current_spec.md) --- **Auto-generated by:** `.github/workflows/update-geolite2.yml` **Trigger:** Scheduled weekly check (Mondays 2 AM UTC) branch: bot/update-geolite2-checksum delete-branch: true commit-message: | chore(docker): update GeoLite2-Country.mmdb checksum Automated checksum update for GeoLite2-Country.mmdb database. Old: ${{ steps.checksum.outputs.old }} New: ${{ steps.checksum.outputs.current }} Auto-generated by: .github/workflows/update-geolite2.yml labels: | dependencies automated docker - name: Report failure via GitHub Issue if: failure() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | const errorType = '${{ steps.checksum.outputs.error }}' || 'unknown'; const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; const errorMessages = { 'download_failed': '❌ Failed to download GeoLite2-Country.mmdb after 3 attempts', 'invalid_checksum_format': '❌ Downloaded file produced invalid checksum format', 'invalid_dockerfile_checksum': '❌ Current Dockerfile contains invalid checksum format', 'unknown': '❌ Workflow failed with unknown error' }; const title = `🚨 GeoLite2 Checksum Update Failed (${errorType})`; const body = ` ## Automated GeoLite2 Update Workflow Failed **Error Type:** \`${errorType}\` **Error Message:** ${errorMessages[errorType] || errorMessages.unknown} ### Workflow Details - **Run URL:** ${runUrl} - **Triggered:** ${context.eventName === 'schedule' ? 'Scheduled (weekly)' : 'Manual dispatch'} - **Timestamp:** ${new Date().toISOString()} ### Required Actions 1. Review workflow logs: ${runUrl} 2. Check upstream source availability: https://github.com/P3TERX/GeoLite.mmdb 3. Verify network connectivity from GitHub Actions runners 4. If upstream is unavailable, consider alternative sources ### Manual Update (if needed) \`\`\`bash # Download and verify checksum curl -fsSL "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb" | sha256sum # Update Dockerfile line 352 vim Dockerfile # or use sed # Test build docker build --no-cache -t test . \`\`\` ### Related Documentation - [Implementation Plan](/docs/plans/current_spec.md) - [Workflow File](/.github/workflows/update-geolite2.yml) --- **Auto-generated by:** \`.github/workflows/update-geolite2.yml\` `; await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: title, body: body, labels: ['bug', 'automated', 'ci-cd', 'docker'] });