Build AdGuardHome for Root #84
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: Build AdGuardHome for Root | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| schedule: | |
| # Run daily at 2 AM UTC to check for new releases | |
| - cron: '0 2 * * *' | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| arch: [arm64] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check for new releases in last 24 hours | |
| id: check_new_release | |
| run: | | |
| echo "Checking if there's a new AdGuardHome release in the last 24 hours..." | |
| # Get current timestamp and 24 hours ago timestamp | |
| CURRENT_TIME=$(date +%s) | |
| TIME_24H_AGO=$((CURRENT_TIME - 86400)) | |
| # Fetch all releases (including pre-releases) | |
| RELEASE_JSON=$(curl -s -f -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/AdguardTeam/AdGuardHome/releases" 2>/dev/null || echo "") | |
| if [ -z "$RELEASE_JSON" ] || [ "$RELEASE_JSON" = "null" ]; then | |
| echo "Failed to fetch releases from API" | |
| echo "has_new_release=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Check if any release was published in the last 24 hours | |
| HAS_NEW_RELEASE=false | |
| LATEST_RELEASE_TIME="" | |
| # Get the published_at timestamp of the latest release | |
| LATEST_RELEASE_TIME=$(echo "$RELEASE_JSON" | jq -r '.[0].published_at' 2>/dev/null) | |
| if [ -n "$LATEST_RELEASE_TIME" ] && [ "$LATEST_RELEASE_TIME" != "null" ]; then | |
| # Convert ISO 8601 timestamp to Unix timestamp | |
| RELEASE_TIMESTAMP=$(date -d "$LATEST_RELEASE_TIME" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LATEST_RELEASE_TIME" +%s 2>/dev/null) | |
| if [ -n "$RELEASE_TIMESTAMP" ]; then | |
| echo "Latest release time: $LATEST_RELEASE_TIME" | |
| echo "Latest release timestamp: $RELEASE_TIMESTAMP" | |
| echo "24 hours ago timestamp: $TIME_24H_AGO" | |
| if [ "$RELEASE_TIMESTAMP" -gt "$TIME_24H_AGO" ]; then | |
| HAS_NEW_RELEASE=true | |
| echo "✅ New release found within the last 24 hours!" | |
| else | |
| echo "❌ No new release in the last 24 hours" | |
| TIME_DIFF=$((CURRENT_TIME - RELEASE_TIMESTAMP)) | |
| HOURS_AGO=$((TIME_DIFF / 3600)) | |
| echo "Latest release was $HOURS_AGO hours ago" | |
| fi | |
| fi | |
| fi | |
| echo "has_new_release=$HAS_NEW_RELEASE" >> $GITHUB_OUTPUT | |
| # If running on schedule and no new release, we'll skip the rest | |
| if [ "${{ github.event_name }}" = "schedule" ] && [ "$HAS_NEW_RELEASE" = "false" ]; then | |
| echo "⏭️ Skipping build as there's no new release in the last 24 hours" | |
| fi | |
| - name: Get latest AdGuardHome release | |
| id: get_release | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| run: | | |
| # Get the latest release (including pre-releases) from AdGuardHome repository | |
| echo "Fetching latest AdGuardHome release information..." | |
| # Method 1: Try GitHub API | |
| RELEASE_JSON=$(curl -s -f -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/AdguardTeam/AdGuardHome/releases" 2>/dev/null || echo "") | |
| if [ -n "$RELEASE_JSON" ] && [ "$RELEASE_JSON" != "Blocked by DNS monitoring proxy" ]; then | |
| TAG_NAME=$(echo "$RELEASE_JSON" | jq -r '.[0].tag_name' 2>/dev/null) | |
| if [ "$TAG_NAME" != "null" ] && [ -n "$TAG_NAME" ]; then | |
| echo "Successfully fetched latest release from API: $TAG_NAME" | |
| else | |
| TAG_NAME="" | |
| fi | |
| else | |
| TAG_NAME="" | |
| fi | |
| # Method 2: Fallback to releases page scraping | |
| if [ -z "$TAG_NAME" ] || [ "$TAG_NAME" = "null" ]; then | |
| echo "API method failed, trying web scraping..." | |
| TAG_NAME=$(curl -s "https://github.com/AdguardTeam/AdGuardHome/releases" | grep -oP 'href="/AdguardTeam/AdGuardHome/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+[^"]*"' | head -1 | sed 's/.*tag\/\(v[^"]*\)".*/\1/' || echo "") | |
| fi | |
| # Method 3: Final fallback to known working release | |
| if [ -z "$TAG_NAME" ] || [ "$TAG_NAME" = "null" ]; then | |
| echo "All methods failed, using fallback release" | |
| TAG_NAME="v0.107.52" | |
| fi | |
| # Set architecture specific download URL | |
| DOWNLOAD_URL="https://github.com/AdguardTeam/AdGuardHome/releases/download/${TAG_NAME}/AdGuardHome_linux_arm64.tar.gz" | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| echo "download_url=$DOWNLOAD_URL" >> $GITHUB_OUTPUT | |
| echo "Using AdGuardHome release: $TAG_NAME" | |
| echo "Download URL: $DOWNLOAD_URL" | |
| echo "Architecture: ${{ matrix.arch }}" | |
| - name: Download and extract AdGuardHome | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| run: | | |
| # Create temporary directory | |
| mkdir -p temp_extract | |
| # Set filename for arm64 architecture only | |
| FILENAME="AdGuardHome_linux_arm64.tar.gz" | |
| # Download the latest AdGuardHome release with retries | |
| echo "Downloading AdGuardHome from: ${{ steps.get_release.outputs.download_url }}" | |
| DOWNLOAD_SUCCESS=false | |
| for i in {1..3}; do | |
| echo "Download attempt $i..." | |
| if curl -L -f -o "$FILENAME" "${{ steps.get_release.outputs.download_url }}"; then | |
| if [ -s "$FILENAME" ]; then | |
| echo "Download successful on attempt $i" | |
| DOWNLOAD_SUCCESS=true | |
| break | |
| else | |
| echo "Downloaded file is empty, retrying..." | |
| rm -f "$FILENAME" | |
| fi | |
| else | |
| echo "Download failed on attempt $i" | |
| fi | |
| sleep 5 | |
| done | |
| if [ "$DOWNLOAD_SUCCESS" != "true" ]; then | |
| echo "Error: Failed to download AdGuardHome after 3 attempts" | |
| exit 1 | |
| fi | |
| # Verify file size | |
| FILESIZE=$(stat -c%s "$FILENAME") | |
| echo "Downloaded file size: $FILESIZE bytes" | |
| if [ "$FILESIZE" -lt 1000000 ]; then | |
| echo "Warning: Downloaded file seems too small (less than 1MB)" | |
| fi | |
| # Extract the tar.gz file | |
| echo "Extracting $FILENAME..." | |
| tar -xzf "$FILENAME" -C temp_extract | |
| # Check if extraction was successful | |
| if [ -f "temp_extract/AdGuardHome/AdGuardHome" ]; then | |
| echo "AdGuardHome binary extracted successfully" | |
| ls -la temp_extract/AdGuardHome/ | |
| file temp_extract/AdGuardHome/AdGuardHome | |
| else | |
| echo "Error: AdGuardHome binary not found after extraction" | |
| echo "Contents of temp_extract:" | |
| find temp_extract -type f | |
| exit 1 | |
| fi | |
| - name: Copy AdGuardHome binary to bin directory | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| run: | | |
| # Ensure bin directory exists | |
| mkdir -p src/bin | |
| # Copy the AdGuardHome binary to the bin directory | |
| cp temp_extract/AdGuardHome/AdGuardHome src/bin/ | |
| # Make it executable | |
| chmod +x src/bin/AdGuardHome | |
| # Verify the binary was copied | |
| echo "AdGuardHome binary copied to src/bin/" | |
| ls -la src/bin/AdGuardHome | |
| # Show file size and type | |
| file src/bin/AdGuardHome | |
| du -h src/bin/AdGuardHome | |
| - name: Create release archive | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| run: | | |
| # Create cache directory for output | |
| mkdir -p cache | |
| # Create zip archive with all src files including the AdGuardHome binary | |
| cd src | |
| zip -r ../cache/AdGuardHomeForRoot_${{ matrix.arch }}_${{ steps.get_release.outputs.tag_name }}.zip . | |
| cd .. | |
| echo "Archive created successfully" | |
| ls -la cache/ | |
| # Show contents of the archive | |
| echo "Contents of AdGuardHomeForRoot_${{ matrix.arch }}_${{ steps.get_release.outputs.tag_name }}.zip:" | |
| unzip -l cache/AdGuardHomeForRoot_${{ matrix.arch }}_${{ steps.get_release.outputs.tag_name }}.zip | |
| - name: Upload build artifacts | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: AdGuardHomeForRoot_${{ matrix.arch }}_${{ steps.get_release.outputs.tag_name }} | |
| path: cache/AdGuardHomeForRoot_${{ matrix.arch }}_${{ steps.get_release.outputs.tag_name }}.zip | |
| retention-days: 30 | |
| - name: Clean up | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| run: | | |
| # Clean up temporary files | |
| rm -rf temp_extract | |
| rm -f AdGuardHome_linux_*.tar.gz | |
| echo "Cleanup completed" | |
| release: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && needs.build.result == 'success' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check for new releases in last 24 hours | |
| id: check_new_release | |
| run: | | |
| echo "Checking if there's a new AdGuardHome release in the last 24 hours..." | |
| # Get current timestamp and 24 hours ago timestamp | |
| CURRENT_TIME=$(date +%s) | |
| TIME_24H_AGO=$((CURRENT_TIME - 86400)) | |
| # Fetch all releases (including pre-releases) | |
| RELEASE_JSON=$(curl -s -f -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/AdguardTeam/AdGuardHome/releases" 2>/dev/null || echo "") | |
| if [ -z "$RELEASE_JSON" ] || [ "$RELEASE_JSON" = "null" ]; then | |
| echo "Failed to fetch releases from API" | |
| echo "has_new_release=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Check if any release was published in the last 24 hours | |
| HAS_NEW_RELEASE=false | |
| # Get the published_at timestamp of the latest release | |
| LATEST_RELEASE_TIME=$(echo "$RELEASE_JSON" | jq -r '.[0].published_at' 2>/dev/null) | |
| if [ -n "$LATEST_RELEASE_TIME" ] && [ "$LATEST_RELEASE_TIME" != "null" ]; then | |
| RELEASE_TIMESTAMP=$(date -d "$LATEST_RELEASE_TIME" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LATEST_RELEASE_TIME" +%s 2>/dev/null) | |
| if [ -n "$RELEASE_TIMESTAMP" ] && [ "$RELEASE_TIMESTAMP" -gt "$TIME_24H_AGO" ]; then | |
| HAS_NEW_RELEASE=true | |
| echo "✅ New release found within the last 24 hours!" | |
| else | |
| echo "❌ No new release in the last 24 hours" | |
| fi | |
| fi | |
| echo "has_new_release=$HAS_NEW_RELEASE" >> $GITHUB_OUTPUT | |
| - name: Get latest AdGuardHome release tag | |
| id: get_tag | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| run: | | |
| # Get the latest release tag (same logic as build job) | |
| RELEASE_JSON=$(curl -s -f -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/AdguardTeam/AdGuardHome/releases" 2>/dev/null || echo "") | |
| if [ -n "$RELEASE_JSON" ] && [ "$RELEASE_JSON" != "Blocked by DNS monitoring proxy" ]; then | |
| TAG_NAME=$(echo "$RELEASE_JSON" | jq -r '.[0].tag_name' 2>/dev/null) | |
| if [ "$TAG_NAME" != "null" ] && [ -n "$TAG_NAME" ]; then | |
| echo "Successfully fetched latest release from API: $TAG_NAME" | |
| else | |
| TAG_NAME="" | |
| fi | |
| else | |
| TAG_NAME="" | |
| fi | |
| if [ -z "$TAG_NAME" ] || [ "$TAG_NAME" = "null" ]; then | |
| echo "API method failed, trying web scraping..." | |
| TAG_NAME=$(curl -s "https://github.com/AdguardTeam/AdGuardHome/releases" | grep -oP 'href="/AdguardTeam/AdGuardHome/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+[^"]*"' | head -1 | sed 's/.*tag\/\(v[^"]*\)".*/\1/' || echo "") | |
| fi | |
| if [ -z "$TAG_NAME" ] || [ "$TAG_NAME" = "null" ]; then | |
| echo "All methods failed, using fallback release" | |
| TAG_NAME="v0.107.52" | |
| fi | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| echo "Using AdGuardHome release: $TAG_NAME" | |
| - name: Download artifacts | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: AdGuardHomeForRoot_*_${{ steps.get_tag.outputs.tag_name }} | |
| path: artifacts | |
| merge-multiple: true | |
| - name: Create Release | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| id: create_release | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: "adguard-${{ steps.get_tag.outputs.tag_name }}-${{ github.run_number }}" | |
| release_name: "AdGuardHome for Root (${{ steps.get_tag.outputs.tag_name }})" | |
| body: | | |
| ## AdGuardHome for Root | |
| 基于 AdGuardHome ${{ steps.get_tag.outputs.tag_name }} 构建 | |
| ### 安装说明 | |
| 1. 下载 ARM64 设备适用的 zip 文件:AdGuardHomeForRoot_arm64_${TAG}.zip(其中 ${TAG} 为 ${{ steps.get_tag.outputs.tag_name }}) | |
| 2. 在 Magisk/KernelSU/APatch 中安装模块 | |
| 3. 重启设备 | |
| 4. 访问 http://127.0.0.1:3000 进入管理界面 | |
| ### 默认账户 | |
| - 用户名: root | |
| - 密码: root | |
| ### 特性 | |
| - 支持 ARM64 设备 | |
| - 集成秋风广告规则 | |
| - 自动转发本机 DNS 请求 | |
| - Web 管理界面 | |
| ### 架构说明 | |
| - ARM64: 适用于大多数现代 Android 设备 | |
| draft: false | |
| prerelease: false | |
| - name: Upload ARM64 Release Asset | |
| if: steps.check_new_release.outputs.has_new_release == 'true' || github.event_name != 'schedule' | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ steps.create_release.outputs.upload_url }} | |
| asset_path: artifacts/AdGuardHomeForRoot_arm64_${{ steps.get_tag.outputs.tag_name }}.zip | |
| asset_name: AdGuardHomeForRoot_arm64_${{ steps.get_tag.outputs.tag_name }}.zip | |
| asset_content_type: application/zip |