Skip to content

Build and Release

Build and Release #9

Workflow file for this run

name: Build and Release
on:
push:
tags:
- 'v*.*.*' # Official release tags (e.g., v3.1.1)
- 'v*.*.*-beta*' # Beta releases (e.g., v3.1.1-beta1)
- 'v*.*.*-alpha*' # Alpha releases (e.g., v3.1.1-alpha1)
- 'v*.*.*-rc*' # Release candidates (e.g., v3.1.1-rc1)
workflow_dispatch:
inputs:
version:
description: 'Version number to build (e.g., v3.1.1 or v3.1.1-beta1). Tag does not need to exist — this is a dry-run: artifacts are saved in the workflow run only, nothing is published.'
required: true
type: string
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
validate-and-release:
name: Validate Version and Build Release
runs-on: ubuntu-latest
permissions:
contents: write # Required for creating releases and uploading artifacts
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup NDK
uses: nttld/setup-ndk@v1.4.2
id: setup-ndk
with:
ndk-version: r27c
link-to-sdk: true
add-to-path: true
- name: Install build tools
run: sudo apt-get update && sudo apt-get install -y ninja-build jq rsync binutils unzip
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle
- name: Cache NDK and CMake builds
uses: actions/cache@v4
with:
path: |
~/.android/build-cache
library/.cxx
library/build
key: ${{ runner.os }}-ndk-${{ hashFiles('**/*.gradle*', '**/CMakeLists.txt') }}
restore-keys: |
${{ runner.os }}-ndk-
- name: Grant execute permission for scripts
run: chmod +x gradlew tasks.sh publish.sh
- name: Extract tag version
id: tag_version
env:
EVENT_NAME: ${{ github.event_name }}
INPUT_VERSION: ${{ github.event.inputs.version }}
run: |
# Determine if this is a manual trigger or tag push
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
# Manual trigger - accept tag name (with or without leading v)
RAW_VERSION="$INPUT_VERSION"
RAW_VERSION="${RAW_VERSION#${RAW_VERSION%%[![:space:]]*}}"
RAW_VERSION="${RAW_VERSION%${RAW_VERSION##*[![:space:]]}}"
if [ -z "$RAW_VERSION" ]; then
echo "❌ Version input cannot be empty"
exit 1
fi
# Accept either "v3.1.1-beta1" or "3.1.1-beta1"
VERSION="${RAW_VERSION#v}"
TAG_NAME="v$VERSION"
IS_MANUAL="true"
IS_PUBLISH="false"
echo "🔧 Dry-run triggered manually (artifacts only, nothing published)"
else
# Tag push - extract from ref
TAG_NAME="${GITHUB_REF#refs/tags/}"
IS_MANUAL="false"
IS_PUBLISH="true"
fi
# Extract and validate version numbers supporting prerelease tags
# e.g., v3.1.1-beta1 -> base=3.1.1, version=3.1.1-beta1
if [[ $TAG_NAME =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)(-[a-zA-Z0-9\.]+)?$ ]]; then
BASE_VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
PRERELEASE_SUFFIX="${BASH_REMATCH[4]}"
VERSION="${BASE_VERSION}${PRERELEASE_SUFFIX}"
if [ -n "$PRERELEASE_SUFFIX" ]; then
IS_PRERELEASE="true"
echo "🧪 Prerelease detected: $PRERELEASE_SUFFIX"
else
IS_PRERELEASE="false"
fi
else
echo "❌ Invalid tag format: $TAG_NAME"
echo "Tag must be: v{major}.{minor}.{patch}[-prerelease] (e.g., v3.1.1 or v3.1.1-beta1)"
exit 1
fi
# Validate base version format
if [[ ! $BASE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid base version format: $BASE_VERSION"
echo "Version must be in format: \${major}.\${minor}.\${patch} (e.g., 3.1.1)"
exit 1
fi
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "base_version=$BASE_VERSION" >> $GITHUB_OUTPUT
echo "is_manual=$IS_MANUAL" >> $GITHUB_OUTPUT
echo "is_publish=$IS_PUBLISH" >> $GITHUB_OUTPUT
echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
echo "✅ Valid version: $VERSION (tag: $TAG_NAME, prerelease: $IS_PRERELEASE, manual: $IS_MANUAL, publish: $IS_PUBLISH)"
- name: Validate tag is on master branch (official releases only)
if: steps.tag_version.outputs.is_prerelease == 'false' && steps.tag_version.outputs.is_manual == 'false'
run: |
TAG_NAME="${{ steps.tag_version.outputs.tag_name }}"
echo "🔍 Validating that $TAG_NAME points to a commit on the master branch..."
# Resolve the commit the tag points to (dereference annotated tags)
if ! TAG_COMMIT=$(git rev-parse "${TAG_NAME}^{commit}" 2>/dev/null); then
echo "❌ Could not resolve tag commit for $TAG_NAME — does the tag exist in this repo?"
exit 1
fi
echo "Tag commit: $TAG_COMMIT"
# Fetch latest master to ensure our ref is up to date (full fetch, no shallow boundary)
if ! git fetch origin master; then
echo "❌ Failed to fetch origin/master. Cannot validate that $TAG_NAME is on the master branch."
exit 1
fi
# Check whether TAG_COMMIT is reachable from origin/master
if git merge-base --is-ancestor "$TAG_COMMIT" origin/master; then
echo "✅ $TAG_NAME is on the master branch"
else
echo "❌ $TAG_NAME is NOT on the master branch!"
echo "Official release tags must point to a commit that exists in master."
echo "Tag commit : $TAG_COMMIT"
echo "Please create the tag from the master branch and try again."
exit 1
fi
- name: Validate version matches project version
run: |
PROJECT_VERSION=$(grep -E 'versionName\s*:' build.gradle | sed -E 's/.*versionName\s*:\s*"([^"]+)".*/\1/')
TAG_VERSION="${{ steps.tag_version.outputs.version }}"
BASE_VERSION="${{ steps.tag_version.outputs.base_version }}"
echo "Project version (build.gradle): $PROJECT_VERSION"
echo "Tag full version: $TAG_VERSION"
echo "Tag base version: $BASE_VERSION"
# For prerelease tags (e.g., v3.1.1-beta1), only the base version (3.1.1)
# needs to match build.gradle. This allows tagging prereleases without
# updating build.gradle every time.
if [ "$PROJECT_VERSION" = "$TAG_VERSION" ]; then
echo "✅ Exact version match: $TAG_VERSION"
elif [ "$PROJECT_VERSION" = "$BASE_VERSION" ] && [ "$TAG_VERSION" != "$BASE_VERSION" ]; then
echo "✅ Base version match for prerelease: build.gradle=$PROJECT_VERSION, tag=$TAG_VERSION"
else
echo "❌ Version mismatch!"
echo "build.gradle versionName ($PROJECT_VERSION) does not match tag version ($TAG_VERSION) or base version ($BASE_VERSION)"
echo "Please ensure build.gradle versionName matches the tag's base version."
exit 1
fi
- name: Setup local.properties for publishing
run: |
# Create local.properties with necessary configurations
mkdir -p /tmp/maven-repo
cat > local.properties << EOF
usingCMakeCompile=true
usingCMakeCompileDebug=false
deployArtifacts=true
localRepoDir=/tmp/maven-repo
EOF
echo "✅ local.properties configured for publishing"
cat local.properties
- name: Build all artifact variants
id: build_variants
run: |
BUILD_START=$(date +%s)
echo "🔨 Building all 4 artifact variants..."
bash -e ./publish.sh
BUILD_END=$(date +%s)
BUILD_TIME=$((BUILD_END - BUILD_START))
echo "✅ All artifacts built successfully"
echo "⏱️ Build time: $((BUILD_TIME / 60)) minutes $((BUILD_TIME % 60)) seconds"
echo "📦 Generated artifacts:"
find /tmp/maven-repo -type f \( -name "*.aar" -o -name "*.pom" \) | sort
echo "build_time=$BUILD_TIME" >> $GITHUB_OUTPUT
- name: Build demo APK with video module
run: |
echo "🔨 Building demo APK with video module..."
./tasks.sh --enable-cmake --release --enable-video-module --enable-16kb-page-size --build
# Find and copy the APK (look specifically for release build output)
APK_PATH=$(find "cgeDemo/build/outputs/apk/release" \( -name "*-release.apk" -o -name "*-release-unsigned.apk" \) | head -1)
if [ -z "$APK_PATH" ]; then
# Fallback: search in build directory
APK_PATH=$(find "cgeDemo/build" -path "*/release/*" -name "*.apk" | head -1)
fi
if [ -z "$APK_PATH" ]; then
echo "❌ APK not found!"
echo "Searched locations:"
find "cgeDemo/build" -name "*.apk" || echo "No APK files found"
exit 1
fi
mkdir -p /tmp/release-artifacts
cp "$APK_PATH" /tmp/release-artifacts/cgeDemo-${{ steps.tag_version.outputs.version }}.apk
echo "✅ Demo APK built successfully"
ls -lh /tmp/release-artifacts/
- name: Validate APK size and properties
run: |
echo "🔍 Checking APK size and basic properties..."
APK_FILE=$(ls /tmp/release-artifacts/*.apk | head -1)
APK_SIZE=$(stat -c%s "$APK_FILE" 2>/dev/null || stat -f%z "$APK_FILE")
APK_SIZE_MB=$((APK_SIZE / 1024 / 1024))
echo "📦 APK size: ${APK_SIZE_MB} MB"
# Warn if APK is unusually large
if [ $APK_SIZE -gt 104857600 ]; then # 100MB
echo "::warning::APK size (${APK_SIZE_MB} MB) exceeds 100MB, consider optimization"
fi
# Warn if APK is unusually small (might indicate build issue)
if [ $APK_SIZE -lt 5242880 ]; then # 5MB
echo "::warning::APK size (${APK_SIZE_MB} MB) is unusually small, please verify"
fi
echo "✅ APK validation passed"
- name: Validate native libs max page size (16KB)
run: |
echo "🔍 Validating native library max page size in APK..."
APK_FILE=$(ls /tmp/release-artifacts/*.apk | head -1)
EXTRACT_DIR="/tmp/apk-native-check"
rm -rf "$EXTRACT_DIR"
mkdir -p "$EXTRACT_DIR"
unzip -q "$APK_FILE" "lib/*.so" -d "$EXTRACT_DIR"
SO_COUNT=$(find "$EXTRACT_DIR/lib" -type f -name "*.so" | wc -l | tr -d ' ')
if [ "$SO_COUNT" -eq 0 ]; then
echo "❌ No native libraries found in APK: $APK_FILE"
exit 1
fi
while IFS= read -r so_file; do
max_align=0
while IFS= read -r align_hex; do
align_hex=${align_hex#0x}
if [ -z "$align_hex" ]; then
continue
fi
align_dec=$((16#$align_hex))
if [ "$align_dec" -gt "$max_align" ]; then
max_align="$align_dec"
fi
done < <(readelf -l "$so_file" | awk '/LOAD/ {print $NF}')
if [ "$max_align" -lt 16384 ]; then
echo "❌ Invalid max page size in $(basename "$so_file"): ${max_align} bytes (< 16384)"
readelf -l "$so_file"
exit 1
fi
printf " ✓ %s max LOAD align: %d bytes\n" "$(basename "$so_file")" "$max_align"
done < <(find "$EXTRACT_DIR/lib" -type f -name "*.so" | sort)
echo "✅ Native library max page size validation passed"
- name: Package AAR artifacts
run: |
echo "📦 Packaging AAR artifacts..."
VERSION="${{ steps.tag_version.outputs.version }}"
MAVEN_REPO="/tmp/maven-repo"
ARTIFACTS_DIR="/tmp/release-artifacts"
# Find and copy all AAR files from the maven repository
# Expected structure: /tmp/maven-repo/org/wysaid/gpuimage-plus/{version}/gpuimage-plus-{version}.aar
while IFS= read -r aar_file; do
if [ -n "$aar_file" ]; then
filename=$(basename "$aar_file")
cp "$aar_file" "$ARTIFACTS_DIR/$filename"
echo " ✓ Packaged: $filename"
fi
done < <(find "$MAVEN_REPO/org/wysaid/gpuimage-plus" -name "*.aar")
# Validate that we have exactly 4 AAR files
AAR_COUNT=$(find "$ARTIFACTS_DIR" -name "*.aar" | wc -l)
if [ "$AAR_COUNT" -ne 4 ]; then
echo "❌ Expected 4 AAR files but found $AAR_COUNT"
exit 1
fi
echo "✅ All AAR artifacts packaged ($AAR_COUNT files)"
echo "📦 Final artifacts:"
ls -lh "$ARTIFACTS_DIR/"
- name: Generate artifact checksums
run: |
echo "🔐 Generating SHA256 checksums for all artifacts..."
cd /tmp/release-artifacts
# Generate checksums for all files
sha256sum *.apk *.aar > SHA256SUMS.txt 2>/dev/null || shasum -a 256 *.apk *.aar > SHA256SUMS.txt
echo "✅ Checksums generated:"
cat SHA256SUMS.txt
# Also create individual checksum files for convenience
for file in *.apk *.aar; do
if [ -f "$file" ]; then
sha256sum "$file" > "${file}.sha256" 2>/dev/null || shasum -a 256 "$file" > "${file}.sha256"
fi
done
echo "✅ Individual checksum files created"
- name: Sync artifacts to maven repo
if: steps.tag_version.outputs.is_publish == 'true'
id: sync_maven_repo
env:
ARTIFACT_REPO_TOKEN: ${{ secrets.ARTIFACT_REPO_TOKEN }}
run: |
set -euo pipefail
VERSION="${{ steps.tag_version.outputs.version }}"
TAG_NAME="${{ steps.tag_version.outputs.tag_name }}"
if [[ -z "${ARTIFACT_REPO_TOKEN:-}" ]]; then
echo "::error::ARTIFACT_REPO_TOKEN is not configured. This secret is required to publish artifacts to the Maven repository."
echo "Please add ARTIFACT_REPO_TOKEN to the repository secrets: Settings → Secrets and variables → Actions → New repository secret"
exit 1
fi
ARTIFACT_REPO="wysaid/android-gpuimage-plus-maven"
WORKDIR="/tmp/maven-repo-target"
SOURCE_REPO="/tmp/maven-repo"
echo "🔄 Cloning artifact repo..."
git clone --depth 1 "https://${ARTIFACT_REPO_TOKEN}@github.com/${ARTIFACT_REPO}.git" "$WORKDIR"
echo "🚚 Syncing generated Maven artifacts..."
mkdir -p "$WORKDIR/org/wysaid/gpuimage-plus"
if [ ! -d "${SOURCE_REPO}/org/wysaid/gpuimage-plus" ]; then
echo "❌ Source artifacts not found: ${SOURCE_REPO}/org/wysaid/gpuimage-plus"
exit 1
fi
# Additive sync: keep previously published versions in artifact repo.
rsync -av "${SOURCE_REPO}/org/wysaid/gpuimage-plus/" "$WORKDIR/org/wysaid/gpuimage-plus/"
echo "🧭 Regenerating index pages"
pushd "$WORKDIR"
chmod +x genSites.sh
./genSites.sh
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add org/wysaid/gpuimage-plus || true
echo "artifact_commit_url=" >> $GITHUB_OUTPUT
if git diff --cached --quiet; then
echo "ℹ️ No changes to publish; skipping commit."
popd
exit 0
fi
git commit -m "Publish artifacts ${TAG_NAME}"
# Retry push up to 3 times to handle transient non-fast-forward conflicts
PUSH_ATTEMPTS=0
until git push origin master; do
PUSH_ATTEMPTS=$((PUSH_ATTEMPTS + 1))
if [ "$PUSH_ATTEMPTS" -ge 3 ]; then
echo "::error::Maven artifact push failed after $PUSH_ATTEMPTS attempts (possible concurrent push). Re-run the sync step manually for tag $TAG_NAME."
exit 1
fi
echo "⚠️ Push attempt $PUSH_ATTEMPTS failed; retrying after fetch+rebase..."
git fetch origin master && git rebase origin/master
done
COMMIT_SHA=$(git rev-parse HEAD)
COMMIT_URL="https://github.com/${ARTIFACT_REPO}/commit/${COMMIT_SHA}"
echo "✅ Artifacts pushed to maven repo: $COMMIT_URL"
echo "artifact_commit_url=$COMMIT_URL" >> $GITHUB_OUTPUT
popd
- name: Generate release notes
id: release_notes
run: |
VERSION="${{ steps.tag_version.outputs.version }}"
TAG_NAME="${{ steps.tag_version.outputs.tag_name }}"
cat > /tmp/release_notes.md << EOF
## 🚀 Android GPUImage Plus $TAG_NAME
### 📦 Downloads
**Demo APK:**
- \`cgeDemo-$VERSION.apk\` - Demo application with full video features
**AAR Library Artifacts:**
Four variants are available for different use cases:
1. **gpuimage-plus-$VERSION.aar**
- Page size: 4KB (default)
- Full-featured with FFmpeg bundled
- Architectures: armeabi-v7a, arm64-v8a, x86, x86_64
2. **gpuimage-plus-$VERSION-16k.aar**
- Page size: 16KB
- Full-featured with FFmpeg bundled
- Architectures: armeabi-v7a, arm64-v8a, x86, x86_64
3. **gpuimage-plus-$VERSION-min.aar**
- Page size: 4KB (default)
- Image-only version (no video features or FFmpeg)
- Architectures: armeabi-v7a, arm64-v8a, x86, x86_64
4. **gpuimage-plus-$VERSION-16k-min.aar**
- Page size: 16KB
- Image-only version (no video features or FFmpeg)
- Architectures: armeabi-v7a, arm64-v8a, x86, x86_64
### 🔧 Gradle Dependency
\`\`\`gradle
allprojects {
repositories {
maven {
url 'https://maven.wysaid.org/'
}
}
}
dependencies {
// Choose one of the following based on your needs:
// Full-featured with FFmpeg (4KB page size)
implementation 'org.wysaid:gpuimage-plus:$VERSION'
// Full-featured with FFmpeg (16KB page size)
implementation 'org.wysaid:gpuimage-plus:$VERSION-16k'
// Image-only, no video (4KB page size)
implementation 'org.wysaid:gpuimage-plus:$VERSION-min'
// Image-only, no video (16KB page size)
implementation 'org.wysaid:gpuimage-plus:$VERSION-16k-min'
}
\`\`\`
### 📋 System Requirements
- **Minimum Android SDK**: API 21 (Android 5.0)
- **Target Android SDK**: API 25
- **NDK Version**: r27c
- **Supported Architectures**: armeabi-v7a, arm64-v8a, x86, x86_64
### 📚 Documentation
- **GitHub Repository**: https://github.com/wysaid/android-gpuimage-plus
- **Build & Integration Guide**: https://github.com/wysaid/android-gpuimage-plus/blob/master/docs/build.md
- **Filter Rule Documentation**: https://github.com/wysaid/android-gpuimage-plus/blob/master/docs/filter-rules.md
---
For complete changelog, see the auto-generated content below.
EOF
echo "✅ Release notes generated"
- name: Create GitHub Release
if: steps.tag_version.outputs.is_publish == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag_version.outputs.tag_name }}
name: Release ${{ steps.tag_version.outputs.tag_name }}
body_path: /tmp/release_notes.md
files: |
/tmp/release-artifacts/*.apk
/tmp/release-artifacts/*.aar
/tmp/release-artifacts/SHA256SUMS.txt
/tmp/release-artifacts/*.sha256
draft: true
prerelease: ${{ steps.tag_version.outputs.is_prerelease == 'true' }}
generate_release_notes: true
make_latest: ${{ steps.tag_version.outputs.is_prerelease != 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifacts (build-only mode)
if: steps.tag_version.outputs.is_publish != 'true'
uses: actions/upload-artifact@v4
with:
name: release-artifacts-${{ steps.tag_version.outputs.version }}
path: /tmp/release-artifacts/
retention-days: 7
- name: Build-only mode success message
if: steps.tag_version.outputs.is_publish != 'true'
run: |
echo "🎉 ============================================"
echo "🎉 Build completed successfully (artifacts only)!"
echo "🎉 ============================================"
echo ""
echo "📦 Version: ${{ steps.tag_version.outputs.version }}"
echo "📦 Artifacts are available for download from the workflow run."
echo ""
echo "ℹ️ This was a manual dry-run — nothing was published."
echo "ℹ️ To make a real release, push the tag from master:"
echo " git tag ${{ steps.tag_version.outputs.tag_name }} && git push origin ${{ steps.tag_version.outputs.tag_name }}"
echo ""
echo "📦 Built artifacts:"
ls -lh /tmp/release-artifacts/
- name: Summary
run: |
IS_PUBLISH="${{ steps.tag_version.outputs.is_publish }}"
IS_MANUAL="${{ steps.tag_version.outputs.is_manual }}"
VERSION="${{ steps.tag_version.outputs.version }}"
TAG_NAME="${{ steps.tag_version.outputs.tag_name }}"
if [ "$IS_PUBLISH" != "true" ]; then
echo "## 🔧 Dry-Run Build Completed Successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version**: $VERSION" >> $GITHUB_STEP_SUMMARY
echo "**Trigger**: Manual dry-run (workflow_dispatch)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ℹ️ Nothing was published" >> $GITHUB_STEP_SUMMARY
echo "Artifacts are retained in this workflow run for **7 days**." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "To make a real release, push the tag from master:" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "git tag $TAG_NAME && git push origin $TAG_NAME" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Built Artifacts (available for download):" >> $GITHUB_STEP_SUMMARY
else
echo "## 🎉 Release Draft Created Successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Release**: $TAG_NAME" >> $GITHUB_STEP_SUMMARY
echo "**Version**: $VERSION" >> $GITHUB_STEP_SUMMARY
echo "**Trigger**: Tag push" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ✅ Version Validation" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Tag format validated: v\${major}.\${minor}.\${patch}" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Version matches project version in build.gradle" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Released Artifacts:" >> $GITHUB_STEP_SUMMARY
fi
echo "**Demo APK:**" >> $GITHUB_STEP_SUMMARY
echo "- cgeDemo-$VERSION.apk (video enabled)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**AAR Libraries:**" >> $GITHUB_STEP_SUMMARY
echo "- gpuimage-plus-$VERSION.aar (4KB, with video)" >> $GITHUB_STEP_SUMMARY
echo "- gpuimage-plus-$VERSION-16k.aar (16KB, with video)" >> $GITHUB_STEP_SUMMARY
echo "- gpuimage-plus-$VERSION-min.aar (4KB, image-only)" >> $GITHUB_STEP_SUMMARY
echo "- gpuimage-plus-$VERSION-16k-min.aar (16KB, image-only)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "$IS_PUBLISH" = "true" ]; then
echo "Review and publish the draft release: ${{ github.server_url }}/${{ github.repository }}/releases" >> $GITHUB_STEP_SUMMARY
echo "(Draft tag: $TAG_NAME)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**⚠️ Action required**: Go to the releases page, review the draft, then click *Publish release* to make it public." >> $GITHUB_STEP_SUMMARY
fi
ARTIFACT_COMMIT_URL="${{ steps.sync_maven_repo.outputs.artifact_commit_url }}"
if [ -n "$ARTIFACT_COMMIT_URL" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Maven Artifact Repository" >> $GITHUB_STEP_SUMMARY
echo "- Commit: $ARTIFACT_COMMIT_URL" >> $GITHUB_STEP_SUMMARY
echo "- Browse: https://maven.wysaid.org/org/wysaid/gpuimage-plus/" >> $GITHUB_STEP_SUMMARY
fi
# Add build time if available
BUILD_TIME="${{ steps.build_variants.outputs.build_time }}"
if [ -n "$BUILD_TIME" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ⏱️ Build Performance" >> $GITHUB_STEP_SUMMARY
echo "- Total build time: $((BUILD_TIME / 60)) minutes $((BUILD_TIME % 60)) seconds" >> $GITHUB_STEP_SUMMARY
fi
- name: Build failure notification
if: failure()
env:
FAILURE_VERSION: ${{ steps.tag_version.outputs.version || github.event.inputs.version || 'unknown' }}
FAILURE_TAG: ${{ steps.tag_version.outputs.tag_name || github.ref_name || 'unknown' }}
run: |
echo "::error::Release build failed for version ${FAILURE_VERSION}"
echo "" >> $GITHUB_STEP_SUMMARY
echo "## ❌ Build Failed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version**: ${FAILURE_VERSION}" >> $GITHUB_STEP_SUMMARY
echo "**Tag**: ${FAILURE_TAG}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Please check the workflow logs for details." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔍 Common Issues" >> $GITHUB_STEP_SUMMARY
echo "- Version mismatch between tag and build.gradle" >> $GITHUB_STEP_SUMMARY
echo "- NDK/CMake configuration issues" >> $GITHUB_STEP_SUMMARY
echo "- Missing dependencies or build tools" >> $GITHUB_STEP_SUMMARY
echo "- Network issues during artifact sync" >> $GITHUB_STEP_SUMMARY