Add Android production release and testing builds workflows
Testing builds / test-and-build (push) Successful in 2m36s
Testing builds / test-and-build (push) Successful in 2m36s
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
name: Android production release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
test-build-publish:
|
||||
runs-on: godot
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
lfs: true
|
||||
|
||||
- name: Verify tag belongs to main
|
||||
run: |
|
||||
git fetch origin main
|
||||
git merge-base --is-ancestor "${GITHUB_SHA}" origin/main
|
||||
|
||||
- name: Show Godot version
|
||||
run: godot --version
|
||||
|
||||
- name: Import project
|
||||
run: |
|
||||
rm -rf .godot
|
||||
godot --headless --path . --editor --import --quit --verbose
|
||||
|
||||
- name: Run all tests
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mapfile -t tests < <(find tests -maxdepth 1 -type f -name 'test_*.gd' | sort)
|
||||
test "${#tests[@]}" -gt 0
|
||||
|
||||
for test_file in "${tests[@]}"; do
|
||||
echo "::group::${test_file}"
|
||||
godot --headless --path . --script "res://${test_file}"
|
||||
echo "::endgroup::"
|
||||
done
|
||||
|
||||
- name: Prepare Android signing
|
||||
env:
|
||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
run: |
|
||||
test -n "${ANDROID_KEYSTORE_BASE64}"
|
||||
printf '%s' "${ANDROID_KEYSTORE_BASE64}" | base64 --decode > "${RUNNER_TEMP}/release.keystore"
|
||||
test -s "${RUNNER_TEMP}/release.keystore"
|
||||
|
||||
- name: Configure release AAB
|
||||
env:
|
||||
RELEASE_VERSION: ${{ github.ref_name }}
|
||||
RELEASE_VERSION_CODE: ${{ github.run_number }}
|
||||
run: |
|
||||
python3 - <<'PY'
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
path = Path("export_presets.cfg")
|
||||
text = path.read_text()
|
||||
start = text.index('[preset.1.options]')
|
||||
head, android = text[:start], text[start:]
|
||||
replacements = (
|
||||
(r'gradle_build/use_gradle_build=false', 'gradle_build/use_gradle_build=true'),
|
||||
(r'gradle_build/export_format=0', 'gradle_build/export_format=1'),
|
||||
(r'package/signed=false', 'package/signed=true'),
|
||||
(r'version/code=\d+', f'version/code={100000 + int(os.environ["RELEASE_VERSION_CODE"])}'),
|
||||
(r'version/name="[^"]*"', f'version/name="{os.environ["RELEASE_VERSION"].removeprefix("v")}"'),
|
||||
)
|
||||
for pattern, replacement in replacements:
|
||||
android, count = re.subn(pattern, replacement, android, count=1)
|
||||
if count != 1:
|
||||
raise RuntimeError(f'Expected one Android preset match for {pattern!r}, got {count}')
|
||||
path.write_text(head + android)
|
||||
PY
|
||||
|
||||
- name: Build signed Android App Bundle
|
||||
env:
|
||||
GODOT_ANDROID_KEYSTORE_RELEASE_USER: ${{ secrets.ANDROID_KEYSTORE_ALIAS }}
|
||||
GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
run: |
|
||||
export GODOT_ANDROID_KEYSTORE_RELEASE_PATH="${RUNNER_TEMP}/release.keystore"
|
||||
mkdir -p build
|
||||
godot --headless --path . --export-release "Android" build/owniverse-${GITHUB_REF_NAME}.aab
|
||||
test -s "build/owniverse-${GITHUB_REF_NAME}.aab"
|
||||
ls -lh "build/owniverse-${GITHUB_REF_NAME}.aab"
|
||||
|
||||
- name: Publish to Google Play production
|
||||
uses: r0adkll/upload-google-play@v1
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
|
||||
packageName: com.KIDGameProduction.Owniverse
|
||||
releaseFiles: build/owniverse-${{ github.ref_name }}.aab
|
||||
tracks: production
|
||||
status: completed
|
||||
|
||||
- name: Upload release bundle
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: owniverse-${{ github.ref_name }}-aab
|
||||
path: build/owniverse-${{ github.ref_name }}.aab
|
||||
if-no-files-found: error
|
||||
retention-days: 90
|
||||
@@ -1,94 +0,0 @@
|
||||
name: Android
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
android:
|
||||
runs-on: godot
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
- name: Godot version
|
||||
run: godot --version
|
||||
|
||||
- name: Prepare Godot
|
||||
run: |
|
||||
rm -rf .godot
|
||||
|
||||
godot \
|
||||
--headless \
|
||||
--path . \
|
||||
--editor \
|
||||
--import \
|
||||
--quit \
|
||||
--verbose
|
||||
|
||||
|
||||
- name: Build APK
|
||||
run: |
|
||||
mkdir -p build
|
||||
|
||||
godot \
|
||||
--headless \
|
||||
--path . \
|
||||
--editor \
|
||||
--import \
|
||||
--quit
|
||||
|
||||
godot \
|
||||
--headless \
|
||||
--path . \
|
||||
--export-release "Android" \
|
||||
build/app.apk
|
||||
|
||||
|
||||
- name: Check imported resources
|
||||
run: |
|
||||
echo "=== PNG imports ==="
|
||||
find .godot/imported -iname '*habitable*' -o -iname '*civ2*'
|
||||
|
||||
echo "=== PNG files ==="
|
||||
ls -lh ui/4-life/habitable_planet.png
|
||||
ls -lh ui/4-life/civ2.png
|
||||
|
||||
|
||||
- name: Verify APK
|
||||
run: |
|
||||
test -f build/app.apk
|
||||
ls -lh build/app.apk
|
||||
|
||||
- name: Create Release
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
curl -f \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://gt.owad.ru/api/v1/repos/K/owniverse/releases" \
|
||||
-d "{
|
||||
\"tag_name\": \"${GITHUB_REF_NAME}\",
|
||||
\"name\": \"${GITHUB_REF_NAME}\",
|
||||
\"body\": \"Android build ${GITHUB_REF_NAME}\"
|
||||
}"
|
||||
|
||||
- name: Upload APK to Release
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
RELEASE_ID=$(curl -fsS \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"https://gt.owad.ru/api/v1/repos/K/owniverse/releases/tags/${GITHUB_REF_NAME}" \
|
||||
| python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
|
||||
|
||||
curl -f \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-F "attachment=@build/app.apk" \
|
||||
"https://gt.owad.ru/api/v1/repos/K/owniverse/releases/${RELEASE_ID}/assets?name=owniverse-${GITHUB_REF_NAME}.apk"
|
||||
@@ -0,0 +1,62 @@
|
||||
name: Testing builds
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- testing
|
||||
|
||||
jobs:
|
||||
test-and-build:
|
||||
runs-on: godot
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
|
||||
- name: Show Godot version
|
||||
run: godot --version
|
||||
|
||||
- name: Import project
|
||||
run: |
|
||||
rm -rf .godot
|
||||
godot --headless --path . --editor --import --quit --verbose
|
||||
|
||||
- name: Run all tests
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mapfile -t tests < <(find tests -maxdepth 1 -type f -name 'test_*.gd' | sort)
|
||||
test "${#tests[@]}" -gt 0
|
||||
|
||||
for test_file in "${tests[@]}"; do
|
||||
echo "::group::${test_file}"
|
||||
godot --headless --path . --script "res://${test_file}"
|
||||
echo "::endgroup::"
|
||||
done
|
||||
|
||||
- name: Build Android APK
|
||||
run: |
|
||||
mkdir -p build
|
||||
godot --headless --path . --export-release "Android" build/owniverse-testing.apk
|
||||
|
||||
- name: Build Windows EXE
|
||||
run: |
|
||||
godot --headless --path . --export-release "Windows Desktop" build/owniverse-testing.exe
|
||||
|
||||
- name: Verify builds
|
||||
run: |
|
||||
test -s build/owniverse-testing.apk
|
||||
test -s build/owniverse-testing.exe
|
||||
ls -lh build/owniverse-testing.apk build/owniverse-testing.exe
|
||||
|
||||
- name: Upload testing builds
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: owniverse-testing-${{ github.sha }}
|
||||
path: |
|
||||
build/owniverse-testing.apk
|
||||
build/owniverse-testing.exe
|
||||
if-no-files-found: error
|
||||
retention-days: 14
|
||||
Reference in New Issue
Block a user