Compare commits

...

20 Commits
7.24.2 ... main

Author SHA1 Message Date
elseif
677889f569 modified: .github/workflows/patch_v6.yml
modified:   .github/workflows/patch_v7.yml
2026-09-04 20:18:19 +08:00
elseif
b6d61fff0f modified: .github/workflows/main.yml 2026-09-04 20:01:34 +08:00
elseif
c2c50f2944 modified: .github/workflows/main.yml 2026-09-04 19:59:18 +08:00
elseif
49b2bf3366 modified: .github/workflows/main.yml 2026-09-04 19:52:44 +08:00
elseif
d2e0a07d49 modified: .github/workflows/main.yml 2026-09-04 19:39:16 +08:00
elseif
6d68d3767f modified: .github/workflows/main.yml
modified:   .github/workflows/patch_v6.yml
	modified:   .github/workflows/patch_v7.yml
2026-09-04 18:16:44 +08:00
elseif
e124f5a97b modified: .github/workflows/main.yml 2026-09-04 16:40:40 +08:00
elseif
e6462f2f03 modified: .github/workflows/main.yml
modified:   .github/workflows/patch_v6.yml
	modified:   .github/workflows/patch_v7.yml
2026-09-04 16:08:42 +08:00
elseif
5499390241 modified: .github/workflows/main.yml
modified:   .github/workflows/patch_v6.yml
	modified:   .github/workflows/patch_v7.yml
2026-09-04 15:35:13 +08:00
elseif
8162e48464 modified: .github/workflows/main.yml 2026-09-03 21:20:45 +08:00
elseif
fec8972b11 modified: .github/workflows/main.yml 2026-09-03 20:26:08 +08:00
elseif
6307abfa84 modified: .github/workflows/main.yml 2026-09-03 20:25:32 +08:00
elseif
777f09760b modified: .github/workflows/main.yml 2026-09-03 20:09:47 +08:00
elseif
da9a657837 modified: .github/workflows/main.yml 2026-09-03 20:05:46 +08:00
elseif
a925bfaa51 modified: .github/workflows/main.yml 2026-09-03 19:57:16 +08:00
elseif
41e23585ef modified: .github/workflows/main.yml 2026-09-03 19:54:49 +08:00
elseif
778e0adc1d modified: .github/workflows/main.yml 2026-09-03 19:52:18 +08:00
elseif
e9d87975ac modified: .github/workflows/main.yml 2026-09-03 19:51:38 +08:00
elseif
82febfa6ae modified: .github/workflows/main.yml 2026-09-03 19:50:27 +08:00
elseif
4a4c226a47 modified: .github/workflows/main.yml 2026-09-03 19:49:09 +08:00
3 changed files with 342 additions and 325 deletions

View File

@@ -2,11 +2,40 @@
name: Patch Mikrotik RouterOS
on:
schedule:
- cron: "00 09 * * *" # At UTC 09:00 (Beijing 17:00) on every day
- cron: "25 * * * *" # Every hour at minute 25 (UTC)
workflow_dispatch:
inputs:
version:
description: 'Select Version (v6/v7/all)'
stable:
description: 'Build stable channel'
required: false
type: boolean
default: true
long_term:
description: 'Build long-term channel'
required: false
type: boolean
default: false
development:
description: 'Build development channel'
required: false
type: boolean
default: false
testing:
description: 'Build testing channel'
required: false
type: boolean
default: false
arch:
description: 'Architectures (x86, arm64)'
required: true
default: 'all'
type: choice
options:
- all
- x86
- arm64
major_version:
description: 'RouterOS major version'
required: true
default: 'all'
type: choice
@@ -14,108 +43,232 @@ on:
- all
- v6
- v7
version:
description: '(e.g. 7.xx.x), empty for latest'
required: false
default: ''
type: string
buildtime:
description: "build imestamp, leave empty for original"
required: false
default: ''
type: string
release:
description: 'Release'
required: false
default: true
default: false
type: boolean
force:
description: 'Force patch even if already patched'
required: false
default: false
type: boolean
jobs:
Check_Versions:
Prepare_Patch:
runs-on: ubuntu-latest
outputs:
upgrades_v6: ${{ steps.set-matrix.outputs.upgrades_v6 }}
upgrades_v7: ${{ steps.set-matrix.outputs.upgrades_v7 }}
upgrades_v6: ${{ steps.prepare.outputs.upgrades_v6 }}
upgrades_v7: ${{ steps.prepare.outputs.upgrades_v7 }}
patch_v6: ${{ steps.prepare.outputs.patch_v6 }}
patch_v7: ${{ steps.prepare.outputs.patch_v7 }}
archs: ${{ steps.prepare.outputs.archs }}
steps:
- name: Fetch and compare versions
id: set-matrix
- name: Prepare Patch
id: prepare
run: |
OFFICIAL_UPGRADE=$(curl -s https://upgrade.mikrotik.com/routeros/upgrade.json)
echo "$OFFICIAL_UPGRADE" | jq -e . >/dev/null 2>&1 || { echo "ERROR: OFFICIAL_UPGRADE is not valid JSON" >&2; exit 1; }
echo "=== OFFICIAL_UPGRADE ==="
echo "$OFFICIAL_UPGRADE" | jq .
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
PATCH_UPGRADE=$(curl -s https://upgrade.mikrotik.ltd/routeros/upgrade.json)
channels=()
[[ "${{ inputs.stable }}" == "true" ]] && channels+=("stable")
[[ "${{ inputs.long_term }}" == "true" ]] && channels+=("long-term")
[[ "${{ inputs.development }}" == "true" ]] && channels+=("development")
[[ "${{ inputs.testing }}" == "true" ]] && channels+=("testing")
if [ ${#channels[@]} -eq 0 ]; then
echo "ERROR: At least one channel must be selected"
exit 1
fi
CHANNELS=$(printf '%s\n' "${channels[@]}" | jq -Rsc 'split("\n")[:-1]')
VERSION_INPUT='${{ inputs.version }}'
MAJOR_VERSION='${{ inputs.major_version }}'
FORCE="${{ inputs.force || 'false' }}"
if [[ -n "$VERSION_INPUT" && "$MAJOR_VERSION" != "all" ]]; then
case "$MAJOR_VERSION" in
v6)
if [[ ! "$VERSION_INPUT" =~ ^6\. ]]; then
echo "ERROR: $VERSION_INPUT is not RouterOS v6"
exit 1
fi
;;
v7)
if [[ ! "$VERSION_INPUT" =~ ^7\. ]]; then
echo "ERROR: $VERSION_INPUT is not RouterOS v7"
exit 1
fi
;;
esac
fi
else
CHANNELS='["stable","long-term","development","testing"]'
VERSION_INPUT=""
MAJOR_VERSION="all"
FORCE="false"
fi
ARCH_INPUT="${{ inputs.arch || 'all' }}"
if [[ "$ARCH_INPUT" == "all" ]]; then
if [[ "$MAJOR_VERSION" == "v6" ]]; then
ARCHS='["x86"]'
else
ARCHS='["x86","arm64"]'
fi
else
if [[ "$ARCH_INPUT" == "arm64" && "$MAJOR_VERSION" == "v6" ]]; then
echo "ERROR: RouterOS v6 does not support arm64"
exit 1
fi
ARCHS=$(jq -c -n --arg arch "$ARCH_INPUT" '[$arch]')
fi
echo "Major Version: $MAJOR_VERSION"
echo "Force: $FORCE"
echo "Architectures:"
echo "$ARCHS" | jq .
echo "Channels:"
echo "$CHANNELS" | jq .
if [[ -n "$VERSION_INPUT" ]]; then
echo "Using fixed version: $VERSION_INPUT"
CANDIDATES=$(jq -cn --arg version "$VERSION_INPUT" --argjson channels "$CHANNELS" '
[{ version:$version, channels:$channels}]
')
else
echo "Resolving version from channels"
OFFICIAL_UPGRADE=$(curl -fsSL https://upgrade.mikrotik.com/routeros/upgrade.json) || { echo "ERROR: Failed to fetch OFFICIAL_UPGRADE" >&2; exit 1; }
echo "$OFFICIAL_UPGRADE" | jq -e . >/dev/null 2>&1 || { echo "ERROR: OFFICIAL_UPGRADE is not valid JSON" >&2; exit 1; }
CANDIDATES=$( echo "$OFFICIAL_UPGRADE" |
jq -c --argjson channels "$CHANNELS" --arg major "$MAJOR_VERSION" '
[
$channels[] as $c |
if $major == "v6" then
{
version: .upgradePaths["NEWEST6."+ $c].version,
channel: $c
}
elif $major == "v7" then
{
version: .upgradePaths["NEWESTa7."+ $c].version,
channel: $c
}
else
[
{
version: .upgradePaths["NEWEST6."+ $c].version,
channel: $c
},
{
version: .upgradePaths["NEWESTa7."+ $c].version,
channel: $c
}
]
end
] |
flatten |
map(select(.version != null)) |
sort_by(.version) |
group_by(.version) |
map({
version: .[0].version,
channels: map(.channel)
})
'
)
fi
echo "Candidates:"
echo "$CANDIDATES" | jq .
if [[ "$FORCE" == "true" ]]; then
echo "Force mode enabled: skip patched version check"
else
echo "Checking patched versions"
PATCH_UPGRADE=$(curl -fsSL https://upgrade.mikrotik.ltd/routeros/upgrade.json) || { echo "ERROR: Failed to fetch PATCH_UPGRADE" >&2; exit 1; }
echo "$PATCH_UPGRADE" | jq -e . >/dev/null 2>&1 || { echo "ERROR: PATCH_UPGRADE is not valid JSON" >&2; exit 1; }
echo "=== PATCH_UPGRADE ==="
echo "$PATCH_UPGRADE" | jq .
CANDIDATES=$(echo "$OFFICIAL_UPGRADE" | jq -c --argjson patch "$PATCH_UPGRADE" '
($patch.upgradePaths // {}) as $paths |
.upgradePaths // {} |
to_entries |
map(
.value.version as $official_version |
($paths[.key] // null) as $patch_value |
select(
$patch_value != null and
$official_version != $patch_value.version and
(any($paths[]; .version == $official_version) | not) and
(.key | test("^NEWEST6|^NEWESTa7"))
) |
{
majorVersion: (if .key | test("^NEWESTa7") then "7" else "6" end),
channel: (.key | split(".")[1]),
version: .value.version
}
)
PATCH_VERSIONS=$(echo "$PATCH_UPGRADE" | jq -c '
[.upgradePaths[].version] | unique
')
else
CANDIDATES=$(echo "$OFFICIAL_UPGRADE" | jq -c '
.upgradePaths // {}| to_entries |
map(
select((.key | test("^NEWEST6")) or (.key | test("^NEWESTa7"))) |
{
majorVersion: (if (.key | test("^NEWESTa7")) then "7" else "6" end),
channel: (.key | split(".")[1]),
version: .value.version
}
)
ALREADY_PATCHED=$(echo "$CANDIDATES" | jq -c --argjson patched "$PATCH_VERSIONS" '
map(select(
(.version as $v | ($patched | index($v))) != null
))
')
echo "Already patched:"
echo "$ALREADY_PATCHED" | jq .
CANDIDATES=$(echo "$CANDIDATES" | jq -c --argjson patched "$PATCH_VERSIONS" '
map(select(
(.version as $v | ($patched | index($v))) == null
))
')
fi
VERSION_FILTER="${{ inputs.version || 'all' }}"
if [[ "$VERSION_FILTER" == "v6" ]]; then
V6_MATRIX=$(echo "$CANDIDATES" | jq -c 'map(select(.majorVersion == "6"))')
V7_MATRIX='[]'
elif [[ "$VERSION_FILTER" == "v7" ]]; then
V6_MATRIX='[]'
V7_MATRIX=$(echo "$CANDIDATES" | jq -c 'map(select(.majorVersion == "7"))')
else
V6_MATRIX=$(echo "$CANDIDATES" | jq -c 'map(select(.majorVersion == "6"))')
V7_MATRIX=$(echo "$CANDIDATES" | jq -c 'map(select(.majorVersion == "7"))')
fi
V6_MATRIX=$(echo "$CANDIDATES" | jq -c 'map(select(.version | startswith("6.")))')
V7_MATRIX=$(echo "$CANDIDATES" | jq -c 'map(select(.version | startswith("7.")))')
echo "upgrades_v6=$V6_MATRIX" >> $GITHUB_OUTPUT
echo "upgrades_v7=$V7_MATRIX" >> $GITHUB_OUTPUT
echo "Upgrades V6: $V6_MATRIX"
echo "Upgrades V7: $V7_MATRIX"
echo "upgrades_v6=$V6_MATRIX" >> "$GITHUB_OUTPUT"
echo "upgrades_v7=$V7_MATRIX" >> "$GITHUB_OUTPUT"
echo "archs=$ARCHS" >> "$GITHUB_OUTPUT"
echo "patch_v6=$(jq 'length > 0' <<< "$V6_MATRIX")" >> "$GITHUB_OUTPUT"
echo "patch_v7=$(jq 'length > 0' <<< "$V7_MATRIX")" >> "$GITHUB_OUTPUT"
# Patch_V6:
# needs: Check_Versions
# if: ${{ needs.Check_Versions.outputs.upgrades_v6 != '[]' }}
# uses: ./.github/workflows/patch_v6.yml
# strategy:
# matrix:
# target: ${{ fromJson(needs.Check_Versions.outputs.upgrades_v6) }}
# fail-fast: false
# with:
# channel: ${{ matrix.target.channel }}
# version: ${{ matrix.target.version }}
# release: ${{ github.event_name == 'workflow_dispatch' && inputs.release || github.event_name != 'workflow_dispatch' && true }}
# secrets: inherit
echo "=== Upgrades V6 ==="
echo "$V6_MATRIX" | jq .
# Patch_V7:
# needs: Check_Versions
# if: ${{ needs.Check_Versions.outputs.upgrades_v7 != '[]' }}
# uses: ./.github/workflows/patch_v7.yml
# strategy:
# matrix:
# target: ${{ fromJson(needs.Check_Versions.outputs.upgrades_v7) }}
# fail-fast: false
# with:
# channel: ${{ matrix.target.channel }}
# version: ${{ matrix.target.version }}
# release: ${{ github.event_name == 'workflow_dispatch' && inputs.release || github.event_name != 'workflow_dispatch' && true }}
# secrets: inherit
echo "=== Upgrades V7 ==="
echo "$V7_MATRIX" | jq .
echo "=== Architectures ==="
echo "$ARCHS" | jq .
Patch_V6:
needs: Prepare_Patch
if: needs.Prepare_Patch.result == 'success' && needs.Prepare_Patch.outputs.patch_v6 == 'true'
uses: ./.github/workflows/patch_v6.yml
strategy:
matrix:
target: ${{ fromJson(needs.Prepare_Patch.outputs.upgrades_v6) }}
fail-fast: false
with:
version: ${{ matrix.target.version }}
channels: ${{ toJson(matrix.target.channels) }}
archs: ${{ needs.Prepare_Patch.outputs.archs }}
buildtime: ${{ inputs.buildtime }}
release: ${{ github.event_name != 'workflow_dispatch' || inputs.release }}
secrets: inherit
Patch_V7:
needs: Prepare_Patch
if: needs.Prepare_Patch.result == 'success' && needs.Prepare_Patch.outputs.patch_v7 == 'true'
uses: ./.github/workflows/patch_v7.yml
strategy:
matrix:
target: ${{ fromJson(needs.Prepare_Patch.outputs.upgrades_v7) }}
fail-fast: false
with:
version: ${{ matrix.target.version }}
channels: ${{ toJson(matrix.target.channels) }}
archs: ${{ needs.Prepare_Patch.outputs.archs }}
buildtime: ${{ inputs.buildtime }}
release: ${{ github.event_name != 'workflow_dispatch' || inputs.release }}
secrets: inherit

View File

@@ -1,47 +1,23 @@
name: Patch RouterOS v6
on:
workflow_dispatch:
inputs:
channel:
description: 'Channel (stable, long-term)'
required: true
default: 'stable'
type: choice
options:
- stable
- long-term
version:
description: "Specify version (e.g., 6.49.19), empty for latest"
required: false
default: ''
type: string
buildtime:
description: "Custom build time, leave empty for original"
required: false
default: ''
type: string
release:
description: "Release to Upload "
required: false
default: false
type: boolean
workflow_call:
inputs:
channel:
version:
required: true
type: string
version:
required: false
channels:
required: true
type: string
default: ''
archs:
required: true
type: string
release:
required: true
type: boolean
buildtime:
required: false
type: string
default: ''
release:
required: false
type: boolean
default: false
env:
CUSTOM_LICENSE_PRIVATE_KEY: ${{ secrets.CUSTOM_LICENSE_PRIVATE_KEY }}
@@ -64,67 +40,21 @@ env:
CUSTOM_CLOUD2_URL: ${{ secrets.CUSTOM_CLOUD2_URL }}
jobs:
Prepare_Patch:
runs-on: ubuntu-24.04
outputs:
VERSION: ${{ steps.prepare.outputs.VERSION }}
BUILD_TIME: ${{ steps.prepare.outputs.BUILD_TIME }}
ARCHS: ${{ steps.prepare.outputs.ARCHS }}
RELEASE: ${{ steps.prepare.outputs.RELEASE }}
SKIP_BUILD: ${{ steps.prepare.outputs.SKIP_BUILD }}
steps:
- name: Prepare Patch for ${{ inputs.channel }}
id: prepare
run: |
CHANNEL="${{ inputs.channel }}"
VERSION="${{ inputs.version }}"
RELEASE="${{ inputs.release }}"
BUILD_TIME="${{ inputs.buildtime }}"
ARCHS='["x86"]'
SKIP_BUILD=false
if [ -z "$VERSION" ]; then
echo "Checking latest version from $CHANNEL channel..."
TIMESTAMP=$(date +%s)
NEWEST=$(wget -nv -O - "https://${{ env.MIKRO_UPGRADE_URL }}/routeros/NEWEST6.$CHANNEL?t=$TIMESTAMP")
VERSION=$(echo "$NEWEST" | cut -d ' ' -f1)
echo "Official version: $VERSION"
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]]; then
PATCH_NEWEST=$(wget -nv -O - "https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/NEWEST6.$CHANNEL?t=$TIMESTAMP" 2>/dev/null || echo "")
PATCH_VERSION=$(echo "$PATCH_NEWEST" | cut -d ' ' -f1)
echo "Patch version: ${PATCH_VERSION:-none}"
if [ "$PATCH_VERSION" == "$VERSION" ]; then
echo "No new version for $CHANNEL, skipping..."
SKIP_BUILD=true
else
echo "New version $VERSION available, building..."
fi
fi
fi
echo "SKIP_BUILD=$SKIP_BUILD" >> $GITHUB_OUTPUT
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "BUILD_TIME=$BUILD_TIME" >> $GITHUB_OUTPUT
echo "ARCHS=$ARCHS" >> $GITHUB_OUTPUT
echo "RELEASE=$RELEASE" >> $GITHUB_OUTPUT
echo "Version: $VERSION, Archs: $ARCHS"
Patch_RouterOS:
needs: Prepare_Patch
if: needs.Prepare_Patch.outputs.SKIP_BUILD == 'false'
runs-on: ubuntu-24.04
strategy:
matrix:
arch: ${{ fromJson(needs.Prepare_Patch.outputs.ARCHS) }}
arch: ${{ fromJson( inputs.archs ) }}
fail-fast: false
env:
TZ: 'Asia/Shanghai'
CHANNEL: ${{ inputs.channel }}
CHANNELS: ${{ inputs.channels }}
ARCH: ${{ matrix.arch }}
VERSION: ${{ needs.Prepare_Patch.outputs.VERSION }}
BUILD_TIME: ${{ needs.Prepare_Patch.outputs.BUILD_TIME }}
BUILD_DIR: "/tmp/build/${{ needs.Prepare_Patch.outputs.VERSION }}"
PUBLISH_DIR: "${{ github.workspace }}/publish/${{ needs.Prepare_Patch.outputs.VERSION }}"
VERSION: ${{ inputs.version }}
BUILD_TIME: ${{ inputs.buildtime }}
RELEASE: ${{ inputs.release }}
BUILD_DIR: "/tmp/build/${{ inputs.version }}}"
PUBLISH_DIR: "${{ github.workspace }}/publish/${{ inputs.version }}"
ARCH_EXT: ""
PACKAGES: ""
steps:
@@ -157,7 +87,7 @@ jobs:
- name: Create Squashfs for Option Package
run: |
echo "Creating Option Package Squashfs for channel: $CHANNEL, arch: $ARCH"
echo "Creating Option Package Squashfs for arch: $ARCH"
mkdir -p $BUILD_DIR/option-root/bin/
cp ./busybox/busybox_$ARCH $BUILD_DIR/option-root/bin/busybox
chmod +x $BUILD_DIR/option-root/bin/busybox
@@ -428,7 +358,7 @@ jobs:
rm $BUILD_DIR/chr-$VERSION$ARCH_EXT.*
- name: Upload Files as Artifact (No Release)
if: needs.Prepare_Patch.outputs.RELEASE == 'false'
if: env.RELEASE == 'false'
uses: actions/upload-artifact@v7
with:
name: mikrotik-${{ env.VERSION }}${{ env.ARCH_EXT }}
@@ -437,7 +367,7 @@ jobs:
${{ env.PUBLISH_DIR }}/*.iso
- name: Generate SHA256 checksum files
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
(
cd $PUBLISH_DIR
@@ -450,7 +380,7 @@ jobs:
)
- name: Delete Release tag ${{ env.VERSION }}${{ env.ARCH_EXT }}
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
sed -i "1i Build Time:$BUILD_TIME" $PUBLISH_DIR/CHANGELOG
HEADER="Authorization: token ${{ secrets.GITHUB_TOKEN }}"
@@ -469,7 +399,7 @@ jobs:
fi
- name: Create Release tag ${{ env.VERSION }}${{ env.ARCH_EXT }}
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
uses: softprops/action-gh-release@v3
with:
name: "RouterOS ${{ env.VERSION }}${{ env.ARCH_EXT }}"
@@ -488,7 +418,7 @@ jobs:
${{env.PUBLISH_DIR}}/routeros*.npk.sha256
- name: Upload Files
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
sudo apt-get install -y knockd lftp > /dev/null
knock -4 ${{ secrets.SSH_SERVER }} ${{ secrets.SSH_KNOCK_PORT }}
@@ -510,7 +440,11 @@ jobs:
rm -f $PUBLISH_DIR/*.iso.sha256
sed -i '1d' $PUBLISH_DIR/CHANGELOG
echo $VERSION $BUILD_TIME | tee $PUBLISH_DIR/info
touch $PUBLISH_DIR/$CHANNEL
echo "$CHANNELS" | jq -r '.[]' | while read -r CHANNEL
do
touch "$PUBLISH_DIR/$CHANNEL"
done
REMOTE_PATH=${{ secrets.SSH_DIRECTORY }}/$VERSION
SERVER=${{ secrets.SSH_SERVER }}
USER=${{ secrets.SSH_USERNAME }}
@@ -524,7 +458,7 @@ jobs:
EOF
- name: Clear Cloudflare cache
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
curl --request POST --url "https://api.cloudflare.com/client/v4/zones/fe6831ed6dc9e6235e69ef2a31f2e7fe/purge_cache" \
--header "Authorization: Bearer 9GDQkzU51QXaqzp1qMjyFKpyeJyOdnNoG9GZQaGP" \
@@ -533,15 +467,12 @@ jobs:
Update_Release:
needs: [Prepare_Patch,Patch_RouterOS]
if: |
needs.Prepare_Patch.outputs.SKIP_BUILD == 'false' &&
needs.Patch_RouterOS.result == 'success' &&
needs.Prepare_Patch.outputs.RELEASE == 'true'
needs: [Patch_RouterOS]
if: needs.Patch_RouterOS.result == 'success' && inputs.release == true
runs-on: ubuntu-24.04
env:
CHANNEL: ${{ inputs.channel }}
VERSION: ${{ needs.Prepare_Patch.outputs.VERSION }}
CHANNELS: ${{ inputs.channels }}
VERSION: ${{ inputs.version }}
steps:
- name: Update Release
run: |
@@ -564,8 +495,19 @@ jobs:
USER=${{ secrets.SSH_USERNAME }}
PASS=${{ secrets.SSH_PASSWORD }}
PORT=${{ secrets.SSH_PORT }}
sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER \
"ln -sf /root/$REMOTE_PATH/$VERSION/info /rw/disk/$REMOTE_PATH/NEWEST6.$CHANNEL; \
ln -sf /root/$REMOTE_PATH/$VERSION/info /rw/disk/$REMOTE_PATH/NEWESTa6.$CHANNEL; \
chown -R 32768:32768 /rw/disk/$REMOTE_PATH"
REMOTE_CMD="
while read -r CHANNEL
do
REMOTE_CMD="$REMOTE_CMD
ln -sfn /root/$REMOTE_PATH/$VERSION/info /rw/disk/$REMOTE_PATH/NEWEST6.$CHANNEL"
ln -sfn /root/$REMOTE_PATH/$VERSION/info /rw/disk/$REMOTE_PATH/NEWESTa6.$CHANNEL"
done < <(echo "$CHANNELS" | jq -r '.[]')
REMOTE_CMD="$REMOTE_CMD
chown -R 32768:32768 /rw/disk/$REMOTE_PATH
"
sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER "$REMOTE_CMD"
echo "✅ Updated release info."

View File

@@ -1,62 +1,23 @@
name: Patch RouterOS v7
on:
workflow_dispatch:
inputs:
channel:
description: 'Channel (stable, long-term, development)'
required: true
default: 'stable'
type: choice
options:
- stable
- long-term
- development
arch:
description: 'Architecture (x86, arm64)'
required: true
default: 'all'
type: choice
options:
- all
- x86
- arm64
version:
description: "Specify version (e.g., 7.xx.x), empty for latest"
required: false
default: ''
type: string
buildtime:
description: "Custom build time, leave empty for original"
required: false
default: ''
type: string
release:
description: "Release to Upload "
required: false
default: false
type: boolean
workflow_call:
inputs:
channel:
version:
required: true
type: string
arch:
required: false
channels:
required: true
type: string
default: 'all'
version:
required: false
archs:
required: true
type: string
default: ''
release:
required: true
type: boolean
buildtime:
required: false
type: string
default: ''
release:
required: false
type: boolean
default: false
env:
CUSTOM_LICENSE_PRIVATE_KEY: ${{ secrets.CUSTOM_LICENSE_PRIVATE_KEY }}
@@ -79,77 +40,26 @@ env:
CUSTOM_CLOUD2_URL: ${{ secrets.CUSTOM_CLOUD2_URL }}
jobs:
Prepare_Patch:
runs-on: ubuntu-24.04
outputs:
VERSION: ${{ steps.prepare.outputs.VERSION }}
BUILD_TIME: ${{ steps.prepare.outputs.BUILD_TIME }}
ARCHS: ${{ steps.prepare.outputs.ARCHS }}
RELEASE: ${{ steps.prepare.outputs.RELEASE }}
SKIP_BUILD: ${{ steps.prepare.outputs.SKIP_BUILD }}
steps:
- name: Prepare Patch for ${{ inputs.channel }}
id: prepare
run: |
CHANNEL="${{ inputs.channel }}"
ARCH_INPUT="${{ inputs.arch }}"
VERSION="${{ inputs.version }}"
RELEASE="${{ inputs.release }}"
BUILD_TIME="${{ inputs.buildtime }}"
if [ "$ARCH_INPUT" == "all" ]; then
ARCHS='["x86", "arm64"]'
else
ARCHS=$(jq -c -n --arg arch "$ARCH_INPUT" '[$arch]')
fi
SKIP_BUILD=false
if [ -z "$VERSION" ]; then
echo "Checking latest version from $CHANNEL channel..."
TIMESTAMP=$(date +%s)
NEWEST=$(wget -nv -O - "https://${{ env.MIKRO_UPGRADE_URL }}/routeros/NEWESTa7.$CHANNEL?t=$TIMESTAMP")
VERSION=$(echo "$NEWEST" | cut -d ' ' -f1)
echo "Official version: $VERSION"
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]]; then
PATCH_NEWEST=$(wget -nv -O - "https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/NEWESTa7.$CHANNEL?t=$TIMESTAMP" 2>/dev/null || echo "")
PATCH_VERSION=$(echo "$PATCH_NEWEST" | cut -d ' ' -f1)
echo "Patch version: ${PATCH_VERSION:-none}"
if [ "$PATCH_VERSION" == "$VERSION" ]; then
echo "No new version for $CHANNEL, skipping..."
SKIP_BUILD=true
else
echo "New version $VERSION available, building..."
fi
fi
fi
echo "SKIP_BUILD=$SKIP_BUILD" >> $GITHUB_OUTPUT
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "BUILD_TIME=$BUILD_TIME" >> $GITHUB_OUTPUT
echo "ARCHS=$ARCHS" >> $GITHUB_OUTPUT
echo "RELEASE=$RELEASE" >> $GITHUB_OUTPUT
echo "Version: $VERSION, Archs: $ARCHS"
Patch_RouterOS:
needs: Prepare_Patch
if: needs.Prepare_Patch.outputs.SKIP_BUILD == 'false'
runs-on: ubuntu-24.04
strategy:
matrix:
arch: ${{ fromJson(needs.Prepare_Patch.outputs.ARCHS) }}
arch: ${{ fromJson( inputs.archs ) }}
fail-fast: false
env:
TZ: 'Asia/Shanghai'
CHANNEL: ${{ inputs.channel }}
CHANNELS: ${{ inputs.channels }}
ARCH: ${{ matrix.arch }}
VERSION: ${{ needs.Prepare_Patch.outputs.VERSION }}
BUILD_TIME: ${{ needs.Prepare_Patch.outputs.BUILD_TIME }}
BUILD_DIR: "/tmp/build/${{ needs.Prepare_Patch.outputs.VERSION }}"
PUBLISH_DIR: "${{ github.workspace }}/publish/${{ needs.Prepare_Patch.outputs.VERSION }}"
VERSION: ${{ inputs.version }}
BUILD_TIME: ${{ inputs.buildtime }}
RELEASE: ${{ inputs.release }}
BUILD_DIR: "/tmp/build/${{ inputs.version }}"
PUBLISH_DIR: "${{ github.workspace }}/publish/${{ inputs.version }}"
ARCH_EXT: ""
PACKAGES: ""
steps:
- uses: actions/checkout@v6
- name: Setup environment
- name: Setup environment
run: |
sudo apt-get update > /dev/null
sudo apt-get install -y zip unzip squashfs-tools jq > /dev/null
@@ -182,7 +92,7 @@ jobs:
- name: Build Squashfs for Option and Python Package
run: |
echo "Creating Option Package Squashfs for channel: $CHANNEL, arch: $ARCH"
echo "Creating Option Package Squashfs for arch: $ARCH"
mkdir -p $BUILD_DIR/option-root/bin/
install -m 755 ./busybox/busybox_$ARCH $BUILD_DIR/option-root/bin/busybox
install -m 755 ./keygen/keygen_$ARCH $BUILD_DIR/option-root/bin/keygen
@@ -341,7 +251,7 @@ jobs:
rm -rf $BUILD_DIR/all_packages
- name: Cache NetInstall ${{ env.VERSION }}
if: matrix.arch == 'x86' && needs.Prepare_Patch.outputs.RELEASE == 'true'
if: matrix.arch == 'x86' && env.RELEASE == 'true'
id: cache-netinstall
uses: actions/cache@v5
with:
@@ -351,12 +261,12 @@ jobs:
- name: Get netinstall ${{ env.VERSION }}
if: |
steps.cache-netinstall.outputs.cache-hit != 'true' &&
matrix.arch == 'x86' && needs.Prepare_Patch.outputs.RELEASE == 'true'
matrix.arch == 'x86' && env.RELEASE == 'true'
run: |
wget -nv -O $BUILD_DIR/netinstall-$VERSION.zip https://download.mikrotik.com/routeros/$VERSION/netinstall-$VERSION.zip
- name: Patch netinstall ${{ env.VERSION }}
if: matrix.arch == 'x86' && needs.Prepare_Patch.outputs.RELEASE == 'true'
if: matrix.arch == 'x86' && env.RELEASE == 'true'
run: |
unzip $BUILD_DIR/netinstall-$VERSION.zip -d $BUILD_DIR/
python3 patch.py netinstall $BUILD_DIR/netinstall.exe
@@ -886,7 +796,7 @@ jobs:
rm -rf $BUILD_DIR/chr
- name: Upload Files as Artifact (No Release)
if: needs.Prepare_Patch.outputs.RELEASE == 'false'
if: env.RELEASE == 'false'
uses: actions/upload-artifact@v7
with:
name: mikrotik-${{ env.VERSION }}${{ env.ARCH_EXT }}
@@ -895,7 +805,7 @@ jobs:
${{ env.PUBLISH_DIR }}/*.iso
- name: Generate SHA256 checksum files
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
(
cd $PUBLISH_DIR
@@ -908,7 +818,7 @@ jobs:
)
- name: Delete Release tag ${{ env.VERSION }}${{ env.ARCH_EXT }}
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
HEADER="Authorization: token ${{ secrets.GITHUB_TOKEN }}"
RELEASE_INFO=$(curl -s -H "$HEADER" https://api.github.com/repos/${{ github.repository }}/releases/tags/$VERSION$ARCH_EXT)
@@ -926,7 +836,7 @@ jobs:
fi
- name: Generate Release Body
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
RELEASE_BODY="$BUILD_DIR/RELEASE_BODY.md"
BASE_URL="https://github.com/${{ github.repository }}/releases/download/$VERSION$ARCH_EXT"
@@ -945,7 +855,7 @@ jobs:
cat > "$RELEASE_BODY" << EOF
**Build Time**: $BUILD_TIME_UTC ($BUILD_TIME)
**Architecture**: $ARCH
**Channel**: $CHANNEL
**Channel**: $CHANNELS
<details open><summary><strong>RouterOS</strong></summary>
@@ -1010,7 +920,7 @@ jobs:
cat "$RELEASE_BODY"
- name: Create Release tag ${{ env.VERSION }}${{ env.ARCH_EXT }}
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
uses: softprops/action-gh-release@v3
with:
name: "RouterOS ${{ env.VERSION }}${{ env.ARCH_EXT }}"
@@ -1018,8 +928,8 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
body_path: ${{env.BUILD_DIR}}/RELEASE_BODY.md
tag_name: ${{ env.VERSION }}${{ env.ARCH_EXT }}
make_latest: ${{ env.CHANNEL == 'stable' && matrix.arch == 'x86'}}
prerelease: ${{ env.CHANNEL == 'development' || env.CHANNEL == 'testing'}}
make_latest: ${{ contains(env.CHANNELS, 'stable') && matrix.arch == 'x86' }}
prerelease: ${{ contains(env.CHANNELS,'development') || contains(env.CHANNELS,'testing') }}
files: |
${{env.PUBLISH_DIR}}/*.zip
${{env.PUBLISH_DIR}}/*.zip.sha256
@@ -1029,7 +939,7 @@ jobs:
${{env.PUBLISH_DIR}}/routeros*.npk.sha256
- name: Upload Files
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
sudo apt-get install -y knockd lftp > /dev/null
knock -4 ${{ secrets.SSH_SERVER }} ${{ secrets.SSH_KNOCK_PORT }}
@@ -1050,7 +960,10 @@ jobs:
rm -f $PUBLISH_DIR/*.zip.sha256
rm -f $PUBLISH_DIR/*.iso.sha256
echo $VERSION $BUILD_TIME | tee $PUBLISH_DIR/info
touch $PUBLISH_DIR/$CHANNEL
echo "$CHANNELS" | jq -r '.[]' | while read -r CHANNEL
do
touch "$PUBLISH_DIR/$CHANNEL"
done
REMOTE_PATH=${{ secrets.SSH_DIRECTORY }}/$VERSION
SERVER=${{ secrets.SSH_SERVER }}
USER=${{ secrets.SSH_USERNAME }}
@@ -1064,7 +977,7 @@ jobs:
EOF
- name: Clear Cloudflare cache
if: needs.Prepare_Patch.outputs.RELEASE == 'true'
if: env.RELEASE == 'true'
run: |
curl --request POST --url "https://api.cloudflare.com/client/v4/zones/fe6831ed6dc9e6235e69ef2a31f2e7fe/purge_cache" \
--header "Authorization: Bearer 9GDQkzU51QXaqzp1qMjyFKpyeJyOdnNoG9GZQaGP" \
@@ -1072,15 +985,12 @@ jobs:
--data '{"purge_everything": true}'
Update_Release:
needs: [Prepare_Patch,Patch_RouterOS]
if: |
needs.Prepare_Patch.outputs.SKIP_BUILD == 'false' &&
needs.Patch_RouterOS.result == 'success' &&
needs.Prepare_Patch.outputs.RELEASE == 'true'
needs: [Patch_RouterOS]
if: needs.Patch_RouterOS.result == 'success' && inputs.release == true
runs-on: ubuntu-24.04
env:
CHANNEL: ${{ inputs.channel }}
VERSION: ${{ needs.Prepare_Patch.outputs.VERSION }}
CHANNELS: ${{ inputs.channels }}
VERSION: ${{ inputs.version }}
steps:
- name: Update Release
run: |
@@ -1103,9 +1013,21 @@ jobs:
USER=${{ secrets.SSH_USERNAME }}
PASS=${{ secrets.SSH_PASSWORD }}
PORT=${{ secrets.SSH_PORT }}
sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER \
"bash /rw/disk/$REMOTE_PATH/packages.sh /rw/disk/$REMOTE_PATH/$VERSION; \
ln -sf /root/$REMOTE_PATH/$VERSION/info /rw/disk/$REMOTE_PATH/NEWESTa7.$CHANNEL; \
chown -R 32768:32768 /rw/disk/$REMOTE_PATH"
REMOTE_CMD="
set -e
bash /rw/disk/$REMOTE_PATH/packages.sh /rw/disk/$REMOTE_PATH/$VERSION
"
while read -r CHANNEL
do
REMOTE_CMD="$REMOTE_CMD
ln -sfn /root/$REMOTE_PATH/$VERSION/info /rw/disk/$REMOTE_PATH/NEWESTa7.$CHANNEL"
done < <(echo "$CHANNELS" | jq -r '.[]')
REMOTE_CMD="$REMOTE_CMD
chown -R 32768:32768 /rw/disk/$REMOTE_PATH
"
sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER "$REMOTE_CMD"
echo "✅ Updated: packages.csv"