Skip to content

Auto update packages v3 #184

Auto update packages v3

Auto update packages v3 #184

#
# Copyright (c) 2022-2026 SMALLPROGRAM <https://github.com/smallprogram>
# Description: Auto update packages v3
#
name: "Auto update packages v3"
on:
repository_dispatch:
workflow_dispatch:
inputs:
ssh:
description: 'SSH connection to Actions'
required: false
default: 'false'
is_update_geodata:
description: 'is update geodata'
required: false
default: 'false'
is_update_from_prerelease:
description: 'is update from prerelease'
required: false
default: 'false'
schedule:
- cron: "0 */4 * * *"
env:
TZ: Asia/Shanghai
permissions:
contents: write
actions: write
pull-requests: write
jobs:
job_init:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
- name: Initialization environment
run: |
sudo timedatectl set-timezone "$TZ"
- name: Delete workflow runs
uses: Mattraks/delete-workflow-runs@main
with:
token: ${{ github.token }}
repository: ${{ github.repository }}
retain_days: 1
keep_minimum_runs: 0
delete_workflow_pattern: 'Auto update packages v2'
- name: SSH connection to Actions
uses: mxschmitt/action-tmate@v3.13
if: (github.event.inputs.ssh == 'true' && github.event.inputs.ssh != 'false') || contains(github.event.action, 'ssh')
job_auto_update_packages:
if: ${{ always() }}
needs: job_init
runs-on: ubuntu-latest
name: Auto-update-${{ matrix.pakcages }}
strategy:
fail-fast: false
matrix:
pakcages:
- chinadns-ng
- geoview
- hysteria
- ipt2socks
- microsocks
- naiveproxy
- shadow-tls
- shadowsocks-rust
- sing-box
- v2ray-plugin
- xray-core
- xray-plugin
- v2ray-geoip
- v2ray-geosite
include:
- pakcages: chinadns-ng
update_type: multi_arch_pkg
folder: chinadns-ng
version_head: PKG_VERSION:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/zfl9/chinadns-ng/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/zfl9/chinadns-ng/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
base_download_url: https://github.com/zfl9/chinadns-ng/releases/download/
- pakcages: geoview
update_type: single
folder: geoview
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/snowie2000/geoview/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/snowie2000/geoview/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/snowie2000/geoview/tar.gz/
- pakcages: hysteria
update_type: single
folder: hysteria
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/apernet/hysteria/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/apernet/hysteria/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/apernet/hysteria/tar.gz/app/v
- pakcages: ipt2socks
update_type: single
folder: ipt2socks
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/zfl9/ipt2socks/tags" | jq -r 'first | .name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/zfl9/ipt2socks/tags" | jq -r 'first | .name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/zfl9/ipt2socks/tar.gz/v
- pakcages: microsocks
update_type: single
folder: microsocks
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/rofl0r/microsocks/tags" | jq -r 'first | .name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/rofl0r/microsocks/tags" | jq -r 'first | .name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/rofl0r/microsocks/tar.gz/v
- pakcages: naiveproxy
update_type: multi_arch_ifeq
folder: naiveproxy
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/klzgrad/naiveproxy/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/klzgrad/naiveproxy/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
- pakcages: shadow-tls
update_type: single
folder: shadow-tls
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/ihciah/shadow-tls/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/ihciah/shadow-tls/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/ihciah/shadow-tls/tar.gz/v
- pakcages: shadowsocks-rust
update_type: single
folder: shadowsocks-rust
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/shadowsocks/shadowsocks-rust/tar.gz/v
- pakcages: sing-box
update_type: single
folder: sing-box
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/SagerNet/sing-box/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/SagerNet/sing-box/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/SagerNet/sing-box/tar.gz/v
- pakcages: v2ray-plugin
update_type: single
folder: v2ray-plugin
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/teddysun/v2ray-plugin/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/teddysun/v2ray-plugin/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/teddysun/v2ray-plugin/tar.gz/v
- pakcages: xray-core
update_type: single
folder: xray-core
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/XTLS/Xray-core/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/XTLS/Xray-core/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/XTLS/Xray-core/tar.gz/v
- pakcages: xray-plugin
update_type: single
folder: xray-plugin
version_head: PKG_VERSION:=
hash_head: PKG_HASH:=
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/teddysun/xray-plugin/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/teddysun/xray-plugin/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://codeload.github.com/teddysun/xray-plugin/tar.gz/v
- pakcages: v2ray-geoip
update_type: single
is_geodata: 'true'
folder: v2ray-geodata
version_head: GEOIP_VER:=
hash_head: \ HASH:=
hash_line: 21
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/Loyalsoldier/geoip/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/Loyalsoldier/geoip/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://github.com/Loyalsoldier/geoip/releases/download/
file_name: /geoip.dat
- pakcages: v2ray-geosite
update_type: single
is_geodata: 'true'
folder: v2ray-geodata
version_head: GEOSITE_VER:=
hash_head: \ HASH:=
hash_line: 30
release_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases" | jq -r 'map(select(.prerelease|not)) | first | .tag_name' | sed -e 's/.*v//'
prerelease_api_command: >
curl -sL -H "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases" | jq -r 'first | .tag_name' | sed -e 's/.*v//'
release_download_url: https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/
file_name: /geosite.dat
steps:
- name: Checkout
uses: actions/checkout@main
- name: Initialization environment
run: |
cd && mkdir -p packages && cd packages
sudo timedatectl set-timezone "$TZ"
- name: Check ${{ matrix.pakcages }}
id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
is_continue=true
if [ "${{ github.event.inputs.is_update_geodata }}" != "true" ] && [ "${{ matrix.is_geodata }}" == "true" ]; then
is_continue=false
fi
if [ "$is_continue" = "true" ]; then
cd && cd $GITHUB_WORKSPACE/${{ matrix.folder }}
if [ "${{ matrix.update_type }}" == "multi_arch_ifeq" ]; then
VER=$(sed -n '/^PKG_VERSION:=/p' Makefile | awk -F '=' '{print $2}')
REL=$(sed -n '/^PKG_RELEASE:=/p' Makefile | awk -F '=' '{print $2}')
Old_PKG_VERSION="${VER}-${REL}"
else
Old_PKG_VERSION=$(sed -n '/^${{ matrix.version_head }}/p' Makefile | awk -F '=' '{print $2}')
fi
if [ "${{ github.event.inputs.is_update_from_prerelease }}" = "true" ]; then
New_PKG_VERSION=$(${{ matrix.prerelease_api_command }})
else
New_PKG_VERSION=$(${{ matrix.release_api_command }})
fi
if [ -z "$New_PKG_VERSION" ] || [ "$New_PKG_VERSION" == "null" ]; then
echo "⚠️ Warning: Unable to retrieve the latest version number for ${{ matrix.pakcages }} (possibly due to API rate limits or network failure). Skipping this update."
echo "status=failure" >> $GITHUB_OUTPUT
exit 0
fi
echo "Current version of ${{ matrix.pakcages }}: $Old_PKG_VERSION"
echo "Latest release version of ${{ matrix.pakcages }}: $New_PKG_VERSION"
result=0
ver1="$Old_PKG_VERSION"
ver2="$New_PKG_VERSION"
if [[ "$(printf "%s\n%s" "$ver1" "$ver2" | sort -V | head -n 1)" == "$ver1" && "$ver1" != "$ver2" ]]; then
result=1
elif [[ "$ver1" == "$ver2" ]]; then
result=0
else
result=2
fi
echo "Version comparison result: $result"
if [[ $result -eq 0 ]]; then
echo "status=failure" >> $GITHUB_OUTPUT
echo "${{ matrix.pakcages }} is already the latest version ($New_PKG_VERSION), no update required"
elif [[ $result -eq 1 ]]; then
echo "New_PKG_VERSION=$New_PKG_VERSION" >> $GITHUB_OUTPUT
echo "status=success" >> $GITHUB_OUTPUT
else
echo "status=failure" >> $GITHUB_OUTPUT
echo "Local version is higher than the latest release version, stopping update"
fi
else
echo "status=failure" >> $GITHUB_OUTPUT
fi
- name: Update Single Package
if: steps.check.outputs.status == 'success' && matrix.update_type == 'single' && !cancelled()
run: |
cd && cd $GITHUB_WORKSPACE/${{ matrix.folder }}
New_PKG_VERSION=${{ steps.check.outputs.New_PKG_VERSION }}
sed -i "/^${{ matrix.version_head }}/c\${{ matrix.version_head }}$New_PKG_VERSION" Makefile
cd && cd packages && mkdir -p ${{ matrix.pakcages }} && cd ${{ matrix.pakcages }}
DOWNLOAD_URL="${{ matrix.release_download_url }}$New_PKG_VERSION${{ matrix.file_name }}"
if wget -P / "$DOWNLOAD_URL"; then
echo "✅ Download successful: $DOWNLOAD_URL"
file_name=${{ matrix.file_name }}
is_v=$(echo ${{ matrix.release_download_url }} | awk -F/ '{print $NF}')
if [ ! -n "${{ matrix.file_name }}" ]; then
PKG_HASH=$(sha256sum $is_v$New_PKG_VERSION) && PKG_HASH=${PKG_HASH%% *}
else
PKG_HASH=$(sha256sum ${file_name##*/}) && PKG_HASH=${PKG_HASH%% *}
fi
cd && cd $GITHUB_WORKSPACE/${{ matrix.folder }}
if [ ! -n "${{ matrix.hash_line }}" ] ; then
sed -i "/^${{ matrix.hash_head }}/c\${{ matrix.hash_head }}$PKG_HASH" Makefile
else
sed -i "${{ matrix.hash_line }}c ${{ matrix.hash_head }}$PKG_HASH" Makefile
fi
echo "Updated single package ${{ matrix.pakcages }} version to: $New_PKG_VERSION"
else
echo "❌ Download failed: $DOWNLOAD_URL"
exit 1
fi
- name: Update Multi-Arch Package (PKG_ARCH)
if: steps.check.outputs.status == 'success' && matrix.update_type == 'multi_arch_pkg' && !cancelled()
run: |
cd && cd $GITHUB_WORKSPACE/${{ matrix.folder }}
New_PKG_VERSION=${{ steps.check.outputs.New_PKG_VERSION }}
sed -i "/^${{ matrix.version_head }}/c\${{ matrix.version_head }}$New_PKG_VERSION" Makefile
ARCHS=$(grep -oP '(?<=PKG_ARCH:=)\S+' Makefile)
for arch in $ARCHS; do
echo "Processing architecture: $arch..."
DOWNLOAD_URL="${{ matrix.base_download_url }}$New_PKG_VERSION/$arch"
if wget -qO "/tmp/$arch" "$DOWNLOAD_URL"; then
HASH=$(sha256sum "/tmp/$arch" | awk '{print $1}')
sed -i "/PKG_ARCH:=$arch/{n;s/PKG_HASH:=.*/PKG_HASH:=$HASH/}" Makefile
echo "✅ $arch Hash updated to: $HASH"
else
echo "⚠️ Download failed (might be an alias or removed arch): $DOWNLOAD_URL, skipping..."
continue
fi
rm -f "/tmp/$arch"
done
echo "Updated multi-arch package ${{ matrix.pakcages }} version to: $New_PKG_VERSION"
- name: Update Multi-Arch Package (IFEQ)
if: steps.check.outputs.status == 'success' && matrix.update_type == 'multi_arch_ifeq' && !cancelled()
run: |
cd && cd $GITHUB_WORKSPACE/${{ matrix.folder }}
New_PKG_VERSION=${{ steps.check.outputs.New_PKG_VERSION }}
VER=$(echo "$New_PKG_VERSION" | cut -d'-' -f1)
REL=$(echo "$New_PKG_VERSION" | cut -d'-' -f2)
sed -i "/^PKG_VERSION:=/c\PKG_VERSION:=$VER" Makefile
sed -i "/^PKG_RELEASE:=/c\PKG_RELEASE:=$REL" Makefile
ARCHS=$(grep -oP '(?<=ifeq \(\$\(ARCH_PREBUILT\),)[^)]+' Makefile)
for arch in $ARCHS; do
echo "Processing architecture: $arch..."
DOWNLOAD_URL="https://github.com/klzgrad/naiveproxy/releases/download/v${VER}-${REL}/naiveproxy-v${VER}-${REL}-openwrt-${arch}.tar.xz"
if wget -qO "/tmp/$arch.tar.xz" "$DOWNLOAD_URL"; then
HASH=$(sha256sum "/tmp/$arch.tar.xz" | awk '{print $1}')
sed -i "/ifeq (\$(ARCH_PREBUILT),$arch)/{n;s/PKG_HASH:=.*/PKG_HASH:=$HASH/}" Makefile
echo "✅ $arch Hash updated to: $HASH"
else
echo "⚠️ Download failed (might be an alias or removed arch): $DOWNLOAD_URL, skipping..."
continue
fi
rm -f "/tmp/$arch.tar.xz"
done
echo "Updated naiveproxy to version: $New_PKG_VERSION"
- name: Update Multi-Arch Package (TUIC)
if: steps.check.outputs.status == 'success' && matrix.update_type == 'multi_arch_tuic' && !cancelled()
run: |
cd && cd $GITHUB_WORKSPACE/${{ matrix.folder }}
New_PKG_VERSION=${{ steps.check.outputs.New_PKG_VERSION }}
sed -i "/^${{ matrix.version_head }}/c\${{ matrix.version_head }}$New_PKG_VERSION" Makefile
ARCHS=$(grep -oP '(?<=TUIC_ARCH:=)\S+' Makefile)
for arch in $ARCHS; do
echo "Processing architecture: $arch..."
DOWNLOAD_URL="${{ matrix.base_download_url }}$New_PKG_VERSION/$arch"
if wget -qO "/tmp/$arch" "$DOWNLOAD_URL"; then
HASH=$(sha256sum "/tmp/$arch" | awk '{print $1}')
sed -i "/TUIC_ARCH:=$arch/{n;s/PKG_HASH:=.*/PKG_HASH:=$HASH/}" Makefile
echo "✅ $arch Hash updated to: $HASH"
else
echo "⚠️ Download failed: $DOWNLOAD_URL, skipping..."
continue
fi
rm -f "/tmp/$arch"
done
echo "Updated TUIC package ${{ matrix.pakcages }} version to: $New_PKG_VERSION"
- name: Finalize Output
id: update
if: steps.check.outputs.status == 'success' && steps.check.outputs.New_PKG_VERSION != '' && !cancelled()
run: |
New_PKG_VERSION=${{ steps.check.outputs.New_PKG_VERSION }}
cd && cd packages
echo ":white_check_mark: ${{ matrix.pakcages }}: update to $New_PKG_VERSION" >> commit_messages.txt
echo "version=$New_PKG_VERSION" >> $GITHUB_OUTPUT
cd && cd $GITHUB_WORKSPACE
echo "branch_exists=$(git ls-remote --heads origin patches-${{ matrix.pakcages }}-$New_PKG_VERSION | tr -d '\n')" >> $GITHUB_OUTPUT
- name: Create Pull Request
id: cpr
if: steps.check.outputs.status == 'success' && steps.check.outputs.New_PKG_VERSION != '' && steps.update.outputs.branch_exists == '' && !cancelled()
env:
GH_TOKEN: ${{ secrets.PKG_TOKEN }}
run: |
branch="patches-${{ matrix.pakcages }}-${{ steps.update.outputs.version }}"
title="${{ matrix.pakcages }}: update to ${{ steps.update.outputs.version }}"
EXISTING=$(gh pr list \
--state open \
--base main \
--json number,title \
--jq ".[] | select(.title == \"$title\") | .number" \
|| echo "")
if [ -n "$EXISTING" ]; then
echo "Duplicate PR with title '$title' already exists: #$EXISTING"
else
git config --global user.email "smallprogramzhusir@gmail.com"
git config --global user.name "David Mandy"
echo "No duplicate found, will create PR."
git checkout -b "$branch"
git add .
git commit -m "${{ matrix.pakcages }}: update to ${{ steps.update.outputs.version }}"
git push origin $branch
gh label create "automated-pr" --color "1D76DB" --description "Created automatically by GitHub Actions" || true
gh pr create \
--title "$title" \
--body "$title" \
--base main \
--head "$branch" \
--label "automated-pr"
fi