Skip to content

feat(ui): 添加应用内使用指南 #6

feat(ui): 添加应用内使用指南

feat(ui): 添加应用内使用指南 #6

name: Release on Version Bump
on:
push:
branches: [ "main", "master" ]
paths:
- 'app/build.gradle'
- 'app/build.gradle.kts'
- 'gradle.properties'
- 'app/src/main/AndroidManifest.xml'
workflow_dispatch: {}
concurrency:
group: release-on-version-bump
cancel-in-progress: false
jobs:
release:
name: Build and Release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Java 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'
- name: Validate Gradle Wrapper (non-blocking)
uses: gradle/wrapper-validation-action@v2
continue-on-error: true
timeout-minutes: 2
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Detect version change
id: version
env:
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
run: |
python3 - <<'PY'
import os, re, subprocess
def read_file(path):
try:
with open(path, 'r', encoding='utf-8') as f:
return f.read()
except FileNotFoundError:
return None
def parse_versions(text):
if not text:
return None, None
vn = None
vc = None
m = re.search(r'versionName\s*[= ]\s*"?([0-9A-Za-z\.-_\+]+)"?', text)
if m:
vn = m.group(1)
m = re.search(r'versionCode\s*[= ]\s*"?([0-9]+)"?', text)
if m:
vc = m.group(1)
if vn is None:
m = re.search(r'(?im)^\s*(?:VERSION_NAME|versionName)\s*=\s*([^\s#]+)', text)
if m:
vn = m.group(1).strip()
if vc is None:
m = re.search(r'(?im)^\s*(?:VERSION_CODE|versionCode)\s*=\s*([0-9]+)', text)
if m:
vc = m.group(1).strip()
if vn is None:
m = re.search(r'android:versionName\s*=\s*"([^"]+)"', text)
if m:
vn = m.group(1)
if vc is None:
m = re.search(r'android:versionCode\s*=\s*"([^"]+)"', text)
if m:
vc = m.group(1)
return vn, vc
def get_file_at_rev(path, rev=None):
if rev is None:
return read_file(path)
try:
out = subprocess.check_output(['git', 'show', f'{rev}:{path}'], stderr=subprocess.STDOUT)
return out.decode('utf-8', errors='ignore')
except subprocess.CalledProcessError:
return None
paths = ['app/build.gradle', 'app/build.gradle.kts', 'gradle.properties', 'app/src/main/AndroidManifest.xml']
text_head = None
for p in paths:
content = get_file_at_rev(p, None)
if content:
text_head = content
break
vn_head, vc_head = parse_versions(text_head)
prev_rev = os.environ.get('GITHUB_EVENT_BEFORE') or 'HEAD^'
text_prev = None
for p in paths:
content = get_file_at_rev(p, prev_rev)
if content:
text_prev = content
break
vn_prev, vc_prev = parse_versions(text_prev)
changed = False
if vn_head and (vn_head != (vn_prev or '')):
changed = True
elif vc_head and (vc_head != (vc_prev or '')):
changed = True
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
f.write(f'version_name={vn_head or ""}\n')
f.write(f'version_code={vc_head or ""}\n')
f.write(f'changed={"true" if changed else "false"}\n')
PY
- name: Stop if version didn't change
if: steps.version.outputs.changed != 'true'
run: |
echo "Version did not change. Skipping release."
exit 0
- name: Set up Android SDK
uses: android-actions/setup-android@v3
with:
api-level: 34
build-tools: 34.0.0
- name: Make Gradle wrapper executable
run: |
chmod +x ./gradlew || true
sed -i -e 's/\r$//' ./gradlew || true
- name: Build debug APK (no signing keys required)
run: ./gradlew --no-daemon clean assembleDebug
continue-on-error: true
- name: Locate built APK (if any)
id: locate_apk
run: |
APK_PATH=$(ls app/build/outputs/apk/debug/*.apk 2>/dev/null || true)
if [ -n "$APK_PATH" ]; then
echo "apk_path=$APK_PATH" >> "$GITHUB_OUTPUT"
echo "Found APK: $APK_PATH"
else
echo "apk_path=" >> "$GITHUB_OUTPUT"
echo "No APK built; will release notes only."
fi
- name: Compose tag
id: tag
run: |
V="${{ steps.version.outputs.version_name }}"
if [ -z "$V" ]; then V="${{ steps.version.outputs.version_code }}"; fi
if [ -z "$V" ]; then V="$(date +%Y%m%d)-${{ github.sha }}"; fi
echo "tag=v$V" >> "$GITHUB_OUTPUT"
echo "version_display=$V" >> "$GITHUB_OUTPUT"
- name: Create GitHub release (with APK)
if: steps.locate_apk.outputs.apk_path != ''
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.tag }}
name: ${{ steps.tag.outputs.tag }}
generate_release_notes: true
files: ${{ steps.locate_apk.outputs.apk_path }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub release (notes only)
if: steps.locate_apk.outputs.apk_path == ''
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.tag }}
name: ${{ steps.tag.outputs.tag }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}