Files
thefeed/.github/workflows/build.yml
T
2026-05-03 17:18:56 +03:30

257 lines
12 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Build
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.26'
cache: true
- name: Cache Go build
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: gobuild-test-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
restore-keys: gobuild-test-${{ runner.os }}-
- name: Test + vet
run: |
go vet ./... &
go test -race -count=1 ./...
wait
build:
needs: test
runs-on: ubuntu-latest
strategy:
matrix:
include:
- goos: linux
goarch: amd64
- goos: linux
goarch: arm64
- goos: darwin
goarch: amd64
- goos: darwin
goarch: arm64
- goos: freebsd
goarch: amd64
- goos: freebsd
goarch: arm64
- goos: windows
goarch: amd64
- goos: android
goarch: arm64
- goos: android
goarch: arm
goarm: '7'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.26'
cache: true
- name: Cache Go build
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: gobuild-${{ matrix.goos }}-${{ matrix.goarch }}-${{ hashFiles('**/go.sum') }}
restore-keys: gobuild-${{ matrix.goos }}-${{ matrix.goarch }}-
- name: Install UPX
if: matrix.goos == 'linux' || matrix.goos == 'windows'
run: sudo apt-get install -y upx-ucl
- name: Build Server
if: matrix.goos != 'android'
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: '0'
run: |
VERSION=${GITHUB_REF_NAME:-dev}
COMMIT=$(git rev-parse --short HEAD)
DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
LDFLAGS="-s -w -X github.com/sartoopjj/thefeed/internal/version.Version=${VERSION} -X github.com/sartoopjj/thefeed/internal/version.Commit=${COMMIT} -X github.com/sartoopjj/thefeed/internal/version.Date=${DATE}"
ext=""
if [ "${{ matrix.goos }}" = "windows" ]; then ext=".exe"; fi
go build -trimpath -ldflags="${LDFLAGS}" -o build/thefeed-server-${{ matrix.goos }}-${{ matrix.goarch }}${ext} ./cmd/server
- name: Build Client
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarm || '' }}
CGO_ENABLED: '0'
run: |
VERSION=${GITHUB_REF_NAME:-dev}
COMMIT=$(git rev-parse --short HEAD)
DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
ext=""
BUILD_MODE=""
if [ "${{ matrix.goos }}" = "windows" ]; then ext=".exe"; fi
# AssetTemplate matches the published filename in the
# thefeed-files repo so the in-app update prompt links straight
# to the right binary. {V} is replaced at runtime with the
# version string read from the public VERSION file.
if [ "${{ matrix.goos }}" = "android" ]; then
ASSET_TEMPLATE="thefeed-client-android-${{ matrix.goarch }}"
else
ASSET_TEMPLATE="thefeed-client-{V}-${{ matrix.goos }}-${{ matrix.goarch }}${ext}"
fi
LDFLAGS="-s -w -X github.com/sartoopjj/thefeed/internal/version.Version=${VERSION} -X github.com/sartoopjj/thefeed/internal/version.Commit=${COMMIT} -X github.com/sartoopjj/thefeed/internal/version.Date=${DATE} -X github.com/sartoopjj/thefeed/internal/version.AssetTemplate=${ASSET_TEMPLATE}"
# Modern Android requires PIE for executables launched via exec(),
# and several heuristic AV engines (Kaspersky Boogr.gsh,
# several VT vendors) flag non-PIE bundled binaries as suspicious.
# Force PIE for the binaries that ship inside the APK.
if [ "${{ matrix.goos }}" = "android" ]; then
BUILD_MODE="-buildmode=pie"
fi
# Android: build with cgo so DNS resolution goes through bionic
# libc / netd instead of Go's pure-Go resolver, which on Android
# finds /etc/resolv.conf empty and dies with "[::1]:53 connection
# refused". Wire the right NDK clang per architecture.
if [ "${{ matrix.goos }}" = "android" ]; then
export CGO_ENABLED=1
case "${{ matrix.goarch }}" in
arm)
export CC="$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi26-clang"
;;
arm64)
export CC="$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang"
;;
esac
test -x "$CC" || { echo "NDK clang not found at $CC"; exit 1; }
fi
if [ "${{ matrix.goos }}" = "android" ] && [ "${{ matrix.goarch }}" = "arm64" ]; then
out="build/thefeed-client-android-arm64"
elif [ "${{ matrix.goos }}" = "android" ] && [ "${{ matrix.goarch }}" = "arm" ]; then
out="build/thefeed-client-android-arm"
else
out="build/thefeed-client-${VERSION}-${{ matrix.goos }}-${{ matrix.goarch }}${ext}"
fi
go build -trimpath -buildvcs=false $BUILD_MODE -ldflags="${LDFLAGS}" -o "$out" ./cmd/client
- name: Compress with UPX
if: matrix.goos == 'linux' || matrix.goos == 'windows'
run: |
# -9 alone (no --lzma) is ~4× faster, only ~5% larger.
# xargs -P fans out across all CPUs.
find build -maxdepth 1 -type f -print0 \
| xargs -0 -n1 -P "$(nproc)" -I{} sh -c 'upx -9 "$1" || true' _ {}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.goos }}-${{ matrix.goarch }}
path: build/
android-apk:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Stage Android client binary as JNI library
run: |
mkdir -p android/app/src/main/jniLibs/arm64-v8a
mkdir -p android/app/src/main/jniLibs/armeabi-v7a
test -f artifacts/thefeed-client-android-arm64
test -f artifacts/thefeed-client-android-arm
cp artifacts/thefeed-client-android-arm64 android/app/src/main/jniLibs/arm64-v8a/libthefeed.so
cp artifacts/thefeed-client-android-arm android/app/src/main/jniLibs/armeabi-v7a/libthefeed.so
- name: Decode signing keystore
env:
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
run: |
if [ -n "$KEYSTORE_BASE64" ]; then
echo "$KEYSTORE_BASE64" | base64 -d > android/app/keystore.jks
echo "Keystore decoded successfully"
else
echo "No KEYSTORE_BASE64 secret set — will use debug signing"
fi
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Build Android APK
working-directory: android
env:
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: |
VERSION=${GITHUB_REF_NAME:-dev}
if [ ! -x ./gradlew ]; then gradle wrapper --gradle-version 8.10.2; fi
if [ -f app/keystore.jks ]; then BT=release; TASK=assembleRelease; else BT=debug; TASK=assembleDebug; fi
# No `clean` — fresh checkout is already clean and the
# Gradle build cache can reuse work between runs.
./gradlew --no-daemon --build-cache $TASK
APK_DIR=app/build/outputs/apk/$BT
cp "$APK_DIR"/app-arm64-v8a-${BT}.apk ../artifacts/thefeed-android-${VERSION}-arm64-v8a.apk
cp "$APK_DIR"/app-armeabi-v7a-${BT}.apk ../artifacts/thefeed-android-${VERSION}-armeabi-v7a.apk
- name: Upload Android APK artifacts
uses: actions/upload-artifact@v4
with:
name: thefeed-android-apk
path: |
artifacts/thefeed-android-*-arm64-v8a.apk
artifacts/thefeed-android-*-armeabi-v7a.apk
release:
needs: [build, android-apk]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
generate_release_notes: true
prerelease: ${{ contains(github.ref_name, '-') }}
append_body: true
body: |
## Downloads
| Platform | Architecture | Download |
|----------|-------------|----------|
| Linux | amd64 | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-linux-amd64) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-linux-amd64) |
| Linux | arm64 | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-linux-arm64) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-linux-arm64) |
| macOS | amd64 (Intel) | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-darwin-amd64) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-darwin-amd64) |
| macOS | arm64 (Apple Silicon) | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-darwin-arm64) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-darwin-arm64) |
| FreeBSD | amd64 | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-freebsd-amd64) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-freebsd-amd64) |
| FreeBSD | arm64 | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-freebsd-arm64) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-freebsd-arm64) |
| Windows | amd64 | [server-سرور](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-server-windows-amd64.exe) / [client-کلاینت](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-client-${{ github.ref_name }}-windows-amd64.exe) |
| Android | arm64-v8a (most modern phones) | [thefeed-android-${{ github.ref_name }}-arm64-v8a.apk - اندروید (گوشی‌های جدید)](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-android-${{ github.ref_name }}-arm64-v8a.apk) |
| Android | armeabi-v7a (older 32-bit phones) | [thefeed-android-${{ github.ref_name }}-armeabi-v7a.apk - اندروید (دستگاه‌های قدیمی‌تر)](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/thefeed-android-${{ github.ref_name }}-armeabi-v7a.apk) |