mirror of
https://github.com/Mo3he/Axis_Cam_Tailscale.git
synced 2026-08-17 04:36:50 +00:00
Much of this work is AXIS OS 13 preparation. Of the OS 13 breaking
changes, all are now addressed except one: recompiled against the
updated SDK for 64-bit time (Y2038), migrated to Manifest Schema v2
with declared OS compatibility, audited all binaries for executable
stack (all clean, GNU_STACK rw-), and verified the web UI end to end
over HTTPS. The only outstanding item is signing through the Axis
ACAP Portal, pending a registered vendorId.
The four ACAP 4 variants (aarch64, armv7hf, and their ROOT versions)
carried byte-identical copies of the C bridge, run script, web UI, and
Makefile per architecture, diverging only between standard and ROOT.
Merge them into a single common/app/ tree:
- param_bridge.c: proxy-port parameters gated behind -DHAS_PROXY_PORTS
(set via EXTRA_CFLAGS in the standard Dockerfiles); ROOT builds omit
them as before
- Tailscale_VPN_run: variant passed as $1 ("standard"/"root") selects
userspace vs kernel networking, port-collision checks, and IP
forwarding for advertised routes
- index.html: detects proxy support at runtime from the settings
response, hiding the proxy card and keeping the params out of save
requests on ROOT builds (fixes ROOT UI always showing proxy fields
and falsely reporting save errors)
Standard variants move to ACAP Native SDK 12.10.0 and Manifest Schema
v2 (vendorId, compatibleOsVersions); verified installable and working
on OS 10.12, 11.11, and 12.10, so OS 13 readiness costs no backward
compatibility. ROOT variants intentionally stay on SDK 1.15.1 since
OS 12+ never runs root apps.
All builds (including arm_acap3) now use the repository root as build
context with -f <variant>/Dockerfile; CI updated accordingly and a
.dockerignore added to keep the context lean. Tailscale binaries are
no longer tracked in git; *.eap outputs are now gitignored.
README: correct the standard variant's floor to OS 10.12+ and ROOT to
10.12-11.x (both live-verified), update build/update instructions for
the shared tree, and check off completed OS 13 readiness items.
206 lines
8.1 KiB
YAML
206 lines
8.1 KiB
YAML
name: Auto Build & Release Tailscale ACAP
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "0 0 * * *" # Every Monday at 03:00 UTC
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
build-and-release:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
|
|
# 1. Checkout repo
|
|
- uses: actions/checkout@v3
|
|
with:
|
|
persist-credentials: true
|
|
fetch-depth: 0
|
|
|
|
# 2. Get latest Tailscale version
|
|
- name: Get latest Tailscale version
|
|
id: tailscale_version
|
|
run: |
|
|
# 1. Start from GitHub latest
|
|
GH_TAG=$(curl -s https://api.github.com/repos/tailscale/tailscale/releases/latest | jq -r .tag_name)
|
|
GH_VERSION=${GH_TAG#v}
|
|
|
|
echo "GitHub latest: $GH_VERSION"
|
|
|
|
# 2. See if static ARM build exists for that version
|
|
if curl -sfI "https://pkgs.tailscale.com/stable/tailscale_${GH_VERSION}_arm.tgz" > /dev/null; then
|
|
VERSION="$GH_VERSION"
|
|
echo "Using GitHub latest (has ARM package): $VERSION"
|
|
else
|
|
echo "No ARM package for $GH_VERSION, falling back to latest version on pkgs.tailscale.com"
|
|
# 3. Derive latest version that actually has an ARM tarball
|
|
VERSION=$(
|
|
curl -s https://pkgs.tailscale.com/stable/ \
|
|
| grep -o 'tailscale_[0-9.]*_arm\.tgz' \
|
|
| sed -E 's/^tailscale_([0-9.]+)_arm\.tgz$/\1/' \
|
|
| sort -V | tail -n1
|
|
)
|
|
echo "Fallback version: $VERSION"
|
|
fi
|
|
|
|
echo "RELEASE_VERSION=$VERSION" >> $GITHUB_ENV
|
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
|
|
- name: Get current repo version
|
|
id: current
|
|
run: |
|
|
CURRENT=$(find . -path "*/app/manifest.json" -exec jq -r '.acapPackageConf.setup.version' {} \; | sort -u | head -n1)
|
|
echo "CURRENT_VERSION=$CURRENT" >> $GITHUB_ENV
|
|
echo "Current repo version: $CURRENT"
|
|
|
|
- name: Compare versions
|
|
id: compare
|
|
run: |
|
|
echo "Repo version: $CURRENT_VERSION"
|
|
echo "Latest Tailscale version: $RELEASE_VERSION"
|
|
echo "Trigger: ${{ github.event_name }}"
|
|
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
echo "build_needed=true" >> $GITHUB_ENV
|
|
echo "Manual trigger — building regardless of version."
|
|
elif [ "$CURRENT_VERSION" = "$RELEASE_VERSION" ]; then
|
|
echo "build_needed=false" >> $GITHUB_ENV
|
|
echo "Already up to date. Skipping build."
|
|
else
|
|
echo "build_needed=true" >> $GITHUB_ENV
|
|
echo "New version detected. Will build."
|
|
fi
|
|
|
|
# 3. Download Tailscale binaries
|
|
- name: Download Tailscale binaries
|
|
if: env.build_needed == 'true'
|
|
run: |
|
|
mkdir -p tailscale_bins
|
|
curl -L "https://pkgs.tailscale.com/stable/tailscale_${RELEASE_VERSION}_arm.tgz" -o tailscale_arm.tgz
|
|
tar -xzf tailscale_arm.tgz -C tailscale_bins --strip-components=1
|
|
mv tailscale_bins/tailscale tailscale_bins/tailscale_arm
|
|
mv tailscale_bins/tailscaled tailscale_bins/tailscaled_arm
|
|
|
|
curl -L "https://pkgs.tailscale.com/stable/tailscale_${RELEASE_VERSION}_arm64.tgz" -o tailscale_arm64.tgz
|
|
tar -xzf tailscale_arm64.tgz -C tailscale_bins --strip-components=1
|
|
mv tailscale_bins/tailscale tailscale_bins/tailscale_arm64
|
|
mv tailscale_bins/tailscaled tailscale_bins/tailscaled_arm64
|
|
|
|
# 4. Strip binaries to reduce package size
|
|
- name: Strip binaries
|
|
if: env.build_needed == 'true'
|
|
run: |
|
|
# Install cross-architecture strip tools
|
|
sudo apt-get update
|
|
sudo apt-get install -y binutils-aarch64-linux-gnu binutils-arm-linux-gnueabihf
|
|
|
|
# Strip debug info and symbol tables (zero runtime/memory cost)
|
|
aarch64-linux-gnu-strip -s tailscale_bins/tailscale_arm64
|
|
aarch64-linux-gnu-strip -s tailscale_bins/tailscaled_arm64
|
|
arm-linux-gnueabihf-strip -s tailscale_bins/tailscale_arm
|
|
arm-linux-gnueabihf-strip -s tailscale_bins/tailscaled_arm
|
|
|
|
ls -lh tailscale_bins/
|
|
|
|
# 5. Build each folder, update manifest, and copy .eap files
|
|
- name: Build all folders
|
|
if: env.build_needed == 'true'
|
|
run: |
|
|
mkdir -p build
|
|
rm -rf releases
|
|
mkdir -p releases
|
|
|
|
for folder in */ ; do
|
|
FOLDER_NAME="${folder%/}" # remove trailing slash
|
|
[[ "$FOLDER_NAME" == "common" ]] && continue
|
|
[[ ! -d "$folder/app" ]] && continue
|
|
echo "Processing folder $FOLDER_NAME"
|
|
|
|
# aarch64/arm/aarch64_ROOT/arm_ROOT share their C source, run script,
|
|
# HTML, and Makefile via common/app/ (see Dockerfile COPY layers);
|
|
# only arm_acap3 still carries its own self-contained app/ tree.
|
|
case "$FOLDER_NAME" in
|
|
aarch64|arm|aarch64_ROOT|arm_ROOT) APP_LIB_DIR="common/app/lib" ;;
|
|
*) APP_LIB_DIR="$folder/app/lib" ;;
|
|
esac
|
|
mkdir -p "$APP_LIB_DIR"
|
|
|
|
# Detect architecture
|
|
if [[ "$FOLDER_NAME" == arm* ]]; then
|
|
cp tailscale_bins/tailscale_arm "$APP_LIB_DIR/tailscale"
|
|
cp tailscale_bins/tailscaled_arm "$APP_LIB_DIR/tailscaled"
|
|
else
|
|
cp tailscale_bins/tailscale_arm64 "$APP_LIB_DIR/tailscale"
|
|
cp tailscale_bins/tailscaled_arm64 "$APP_LIB_DIR/tailscaled"
|
|
fi
|
|
|
|
# Detect variant suffix for .eap naming
|
|
if [[ "$FOLDER_NAME" == *_ROOT ]]; then
|
|
VARIANT="_root"
|
|
elif [[ "$FOLDER_NAME" == *_acap3 ]]; then
|
|
VARIANT="_acap3"
|
|
else
|
|
VARIANT=""
|
|
fi
|
|
|
|
# Update version — manifest.json for ACAP 4, package.conf for ACAP 3
|
|
if [[ -f "$folder/app/manifest.json" ]]; then
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"${RELEASE_VERSION}\"/" "$folder/app/manifest.json"
|
|
elif [[ -f "$folder/app/package.conf" ]]; then
|
|
IFS='.' read -r MAJOR MINOR MICRO <<< "${RELEASE_VERSION}"
|
|
sed -i "s/^APPMAJORVERSION=.*/APPMAJORVERSION=${MAJOR}/" "$folder/app/package.conf"
|
|
sed -i "s/^APPMINORVERSION=.*/APPMINORVERSION=${MINOR}/" "$folder/app/package.conf"
|
|
sed -i "s/^APPMICROVERSION=.*/APPMICROVERSION=${MICRO}/" "$folder/app/package.conf"
|
|
fi
|
|
|
|
# Docker build
|
|
TAG_NAME=$(echo "$FOLDER_NAME" | tr '[:upper:]' '[:lower:]' | tr '/ ' '_') # lowercase and clean
|
|
echo "Building $TAG_NAME"
|
|
docker build -f "$folder/Dockerfile" --tag "$TAG_NAME" .
|
|
|
|
# Extract .eap files into build folder
|
|
EAP_OUTPUT="./build/${TAG_NAME}"
|
|
mkdir -p "$EAP_OUTPUT"
|
|
CID=$(docker create "$TAG_NAME")
|
|
docker cp "$CID":/opt/app "$EAP_OUTPUT"
|
|
docker rm "$CID" >/dev/null
|
|
|
|
# Move all .eap files to releases folder, append variant if needed
|
|
find "$EAP_OUTPUT" -type f -name "*.eap" | while read eap; do
|
|
BASENAME=$(basename "$eap" .eap)
|
|
if [[ -n "$VARIANT" ]]; then
|
|
mv "$eap" "releases/${BASENAME}${VARIANT}.eap"
|
|
else
|
|
mv "$eap" "releases/${BASENAME}.eap"
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Clean up
|
|
rm -rf build tailscale_bins *.tgz
|
|
|
|
# 6. Commit updated manifests and .eap files directly to main
|
|
- name: Commit updates to main
|
|
if: env.build_needed == 'true'
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
# Only commit manifests and ACAP 3 package.conf; do not track release artifacts
|
|
git add */app/manifest.json arm_acap3/app/package.conf
|
|
if git diff --cached --quiet; then
|
|
echo "No changes to commit"
|
|
else
|
|
git commit -m "Update Tailscale to v${RELEASE_VERSION}"
|
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/Mo3he/Axis_Cam_Tailscale.git main
|
|
fi
|
|
|
|
# 7. Create GitHub Release with all new .eap files
|
|
- name: Create GitHub Release
|
|
if: env.build_needed == 'true'
|
|
uses: softprops/action-gh-release@v1
|
|
with:
|
|
tag_name: v${{ env.RELEASE_VERSION }}
|
|
name: "Tailscale VPN ${{ env.RELEASE_VERSION }}"
|
|
files: releases/*
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|