Skip to content

isInitialRun

isInitialRun #6

Workflow file for this run

name: Multi-Platform-Build
on:
push:
branches: [ main, master ]
workflow_dispatch:
inputs:
use_ai:
description: 'KI Analyse aktivieren?'
required: true
default: 'true'
type: boolean
permissions:
contents: write # WICHTIG: Erlaubt dem Bot, Releases zu erstellen & README zu pushen
env:
# HIER DAS ZIEL-REPO FÜR RELEASES ANPASSEN
# Leer lassen, um das aktuelle Repo zu verwenden
RELEASE_OWNER: '' # z.B. pono1012
RELEASE_REPO: '' # z.B. techana
jobs:
# --- JOB 1: KI ANALYSE ---
analyze_changes:
name: 🧠 AI Analysis
runs-on: ubuntu-latest
outputs:
full_notes: ${{ steps.generate_notes.outputs.full_notes || '⚠️ KI-Analyse momentan nicht verfügbar.' }}
summary: ${{ steps.generate_notes.outputs.summary || 'Update' }}
run_status: ${{ steps.generate_notes.outputs.run_status || 'skipped' }}
update_type: ${{ steps.generate_notes.outputs.update_type || 'patch' }}
install_text: ${{ steps.read_install.outputs.content }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Wichtig für die KI-Historie
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '16'
# Lädt die Installationsanleitung in eine Variable
- name: 📄 Read Install Template
id: read_install
run: |
# Prüfen ob Datei existiert, sonst Fallback
if [ -f .github/templates/INSTALLATION.md ]; then
content=$(cat .github/templates/INSTALLATION.md)
else
content="Installation instructions not found."
fi
echo "content<<EOF" >> $GITHUB_OUTPUT
echo "$content" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: 🧠 Generate Notes (Gemini)
id: generate_notes
continue-on-error: true
uses: actions/github-script@v6
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
USE_AI: ${{ github.event_name == 'push' && 'true' || inputs.use_ai }}
with:
script: |
const script = require('./.github/scripts/generate_notes.js')
await script({github, context, core})
# Changelog und Status aktualisieren (nur wenn KI lief)
- name: 📝 Update Changelog & State
if: steps.generate_notes.outputs.run_status == 'success'
env:
FULL_NOTES: ${{ steps.generate_notes.outputs.full_notes }}
UPDATE_TYPE: ${{ steps.generate_notes.outputs.update_type }}
run: |
# Wenn CHANGELOG.md noch nicht existiert, erstellen
touch CHANGELOG.md
DATE=$(date +'%Y-%m-%d')
# LOGIK: Release = Neuer Eintrag oben. Patch = Unten anhängen.
if [ "$UPDATE_TYPE" == "patch" ]; then
# PATCH: Wir hängen den neuen Punkt einfach an die Datei an (oder unter den letzten Header)
# Da wir es einfach halten wollen: Wir fügen eine Trennlinie ein, falls noch keine da ist, oder hängen direkt an.
# Prüfen ob "### Patches" schon existiert im letzten Block?
# Einfachste Lösung: Einfach unten an CHANGELOG.md anhängen.
# Aber wir wollen es sauber. Wir fügen es oben unter den aktuellen Eintrag ein?
# Nein, User wollte "einfach unten dran hängen".
echo "" >> CHANGELOG.md
echo "$FULL_NOTES" >> CHANGELOG.md
else
# RELEASE: Neuer Eintrag ganz oben
{
echo "### $DATE - Update"
echo ""
echo "$FULL_NOTES"
echo ""
echo "---"
echo ""
} > new_entry.md
cat new_entry.md CHANGELOG.md > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md
rm new_entry.md
fi
# State File committen (wird im nächsten Job gepusht oder hier)
git config --global user.name "TechAna Bot"
git config --global user.email "bot@techana.app"
# WICHTIG: Auch die Patch-Notes Datei adden
git add CHANGELOG.md .github/ai_state.json .github/current_patch_notes.md
git commit -m "docs: Update Changelog & AI State [skip ci]" || echo "No changes"
git push
# --- JOB 2: BUILD & RELEASE (Shorebird) ---
build:
needs: analyze_changes
name: 🚀 Build ${{ matrix.platform }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- platform: android
os: ubuntu-latest
artifact-path: TechAna-android.apk
- platform: ios
os: macos-latest
artifact-path: TechAna-iOS.ipa
- platform: windows
os: windows-latest
artifact-path: TechAna-windows.zip
- platform: macos
os: macos-latest
artifact-path: TechAna-macos.zip
- platform: linux
os: ubuntu-latest
artifact-path: TechAna-linux.zip
steps:
- uses: actions/checkout@v3
- name: 🐦 Setup Shorebird
uses: shorebirdtech/setup-shorebird@v1
with:
cache: true
- name: Get Version
id: get_version
run: echo "VERSION=$(grep 'version:' pubspec.yaml | cut -d ' ' -f 2)" >> $GITHUB_ENV
shell: bash
# Linux Dependencies
- name: Install Linux dependencies
if: matrix.platform == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev zip \
libsecret-1-dev libjsoncpp-dev libnotify-dev
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true
- run: flutter pub get
- run: flutter clean
# --- SHOREBIRD BUILD LOGIK ---
- name: 🏗 Build Platform via Shorebird
id: shorebird_build
env:
SHOREBIRD_TOKEN: ${{ secrets.SHOREBIRD_TOKEN }}
run: |
echo "SHOULD_UPLOAD=false" >> $GITHUB_ENV
echo "🚀 Starting Shorebird logic for ${{ matrix.platform }}..."
# Android
if [ "${{ matrix.platform }}" == "android" ]; then
if shorebird patch android --no-confirm --release-version=${{ env.VERSION }}; then
echo "✅ Patch successfully."
else
shorebird release android --artifact=apk --no-confirm
echo "SHOULD_UPLOAD=true" >> $GITHUB_ENV
fi
# iOS
elif [ "${{ matrix.platform }}" == "ios" ]; then
if shorebird patch ios --no-codesign --no-confirm --release-version=${{ env.VERSION }}; then
echo "✅ Patch successfully."
else
shorebird release ios --no-codesign --no-confirm
echo "SHOULD_UPLOAD=true" >> $GITHUB_ENV
fi
# Windows
elif [ "${{ matrix.platform }}" == "windows" ]; then
if shorebird patch windows --no-confirm --release-version=${{ env.VERSION }}; then
echo "✅ Patch successfully."
else
shorebird release windows --no-confirm
echo "SHOULD_UPLOAD=true" >> $GITHUB_ENV
fi
# macOS
elif [ "${{ matrix.platform }}" == "macos" ]; then
if shorebird patch macos --no-confirm --release-version=${{ env.VERSION }}; then
echo "✅ Patch successfully."
else
shorebird release macos --no-confirm
echo "SHOULD_UPLOAD=true" >> $GITHUB_ENV
fi
# Linux
elif [ "${{ matrix.platform }}" == "linux" ]; then
if shorebird patch linux --no-confirm --release-version=${{ env.VERSION }}; then
echo "✅ Patch successfully."
else
shorebird release linux --no-confirm
echo "SHOULD_UPLOAD=true" >> $GITHUB_ENV
fi
fi
shell: bash
# --- PACKAGING ---
- name: 📦 Prepare Artifacts
if: env.SHOULD_UPLOAD == 'true'
run: |
if [ "${{ matrix.platform }}" == "android" ]; then
cp build/app/outputs/apk/release/app-release.apk ./TechAna-android.apk
elif [ "${{ matrix.platform }}" == "ios" ]; then
cd build/ios/archive/Runner.xcarchive/Products/Applications/
mkdir Payload && cp -r Runner.app Payload/
zip -qq -r TechAna-iOS.ipa Payload && mv TechAna-iOS.ipa $GITHUB_WORKSPACE/
elif [ "${{ matrix.platform }}" == "windows" ]; then
powershell -Command "Compress-Archive -Path build/windows/x64/runner/Release/* -DestinationPath TechAna-windows.zip"
elif [ "${{ matrix.platform }}" == "macos" ]; then
cd build/macos/Build/Products/Release/ && zip -qq -r TechAna-macos.zip *.app && mv TechAna-macos.zip $GITHUB_WORKSPACE/
elif [ "${{ matrix.platform }}" == "linux" ]; then
cd build/linux/x64/release/bundle/
zip -r TechAna-linux.zip .
mv TechAna-linux.zip $GITHUB_WORKSPACE/
fi
shell: bash
- name: 📄 Create Version JSON
if: matrix.platform == 'linux' && env.SHOULD_UPLOAD == 'true'
run: |
echo '{ "version": "${{ env.VERSION }}", "release_notes": "Update verfügbar" }' > version.json
shell: bash
- name: 📝 Prepare Upload Files
if: env.SHOULD_UPLOAD == 'true'
run: |
echo "FILES_TO_UPLOAD<<EOF" >> $GITHUB_ENV
if [ "${{ matrix.platform }}" == "android" ]; then echo "TechAna-android.apk" >> $GITHUB_ENV; fi
if [ "${{ matrix.platform }}" == "ios" ]; then echo "TechAna-iOS.ipa" >> $GITHUB_ENV; fi
if [ "${{ matrix.platform }}" == "windows" ]; then echo "TechAna-windows.zip" >> $GITHUB_ENV; fi
if [ "${{ matrix.platform }}" == "macos" ]; then echo "TechAna-macos.zip" >> $GITHUB_ENV; fi
if [ "${{ matrix.platform }}" == "linux" ]; then
echo '{TechAna-linux.zip,version.json}' >> $GITHUB_ENV
fi
echo "EOF" >> $GITHUB_ENV
shell: bash
- name: 📤 Upload to Release
if: env.SHOULD_UPLOAD == 'true'
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ env.FILES_TO_UPLOAD }}
tag: v${{ env.VERSION }}
overwrite: true
file_glob: true
body: |
## 🚀 TechAna v${{ env.VERSION }}
### 🤖 AI Update Report
${{ needs.analyze_changes.outputs.full_notes }}
---
${{ needs.analyze_changes.outputs.install_text }}
# --- JOB 3: UPDATE RELEASE ON PATCH ---
update_release_on_patch:
name: 📝 Update Release on Patch
needs: [analyze_changes, build]
if: success() && needs.analyze_changes.outputs.update_type == 'patch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3 # Lädt den Code-Stand, der den Workflow gestartet hat
- name: 🔄 Sync with remote changes from analysis job
run: git pull origin ${{ github.ref_name }}
shell: bash
- name: 📄 Read Patch Notes
id: read_patch_notes
run: |
if [ -f .github/current_patch_notes.md ]; then
content=$(cat .github/current_patch_notes.md)
else
content="Keine Patch-Notes gefunden."
fi
echo "content<<EOF" >> $GITHUB_OUTPUT
echo "$content" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: 🚀 Update Latest Release Body
uses: actions/github-script@v6
env:
PATCH_NOTES: ${{ steps.read_patch_notes.outputs.content }}
INSTALL_NOTES: ${{ needs.analyze_changes.outputs.install_text }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const owner = process.env.RELEASE_OWNER || context.repo.owner;
const repo = process.env.RELEASE_REPO || context.repo.repo;
// 1. Get the latest release
const { data: latestRelease } = await github.rest.repos.getLatestRelease({
owner,
repo,
});
if (!latestRelease) {
core.setFailed("Kein Release gefunden zum Aktualisieren.");
return;
}
console.log(`Aktualisiere Release: ${latestRelease.name} (ID: ${latestRelease.id})`);
// 2. Lade die neuen und alten Inhalte
const patchNotes = process.env.PATCH_NOTES;
const installNotes = process.env.INSTALL_NOTES;
const originalBody = latestRelease.body;
// 3. Zerlege den Body in seine Teile: Basis-Notes, alte Patches, Installation
const separator = "---";
const installHeader = "### 🛠 Installation & Downloads";
const patchHeader = "### 🩹 Patch vom";
// Finde die Installations-Sektion. Alles danach wird ignoriert.
const installSectionIndex = originalBody.indexOf(installHeader);
const topPart = installSectionIndex !== -1 ? originalBody.substring(0, installSectionIndex).trim() : originalBody.trim();
// Entferne den Separator am Ende des oberen Teils, falls vorhanden
const cleanTopPart = topPart.endsWith(separator) ? topPart.substring(0, topPart.length - separator.length).trim() : topPart;
// Finde den Start der alten Patch-Sektion im oberen Teil
const firstPatchIndex = cleanTopPart.indexOf(patchHeader);
// Die "Basis-Notes" sind alles vor dem ersten Patch.
const baseNotes = firstPatchIndex !== -1 ? cleanTopPart.substring(0, firstPatchIndex).trim() : cleanTopPart;
// Die Installations-Sektion kommt direkt aus dem Template (inkl. Header).
const installSection = installNotes.trim();
// 4. Baue den neuen Body in der gewünschten Reihenfolge zusammen: Basis + Installation + Patches
const newBody = `${baseNotes}\n\n${separator}\n\n${installSection}\n\n${patchNotes.trim()}`;
// 5. Update the release
await github.rest.repos.updateRelease({ owner, repo, release_id: latestRelease.id, body: newBody });
console.log("✅ Release Body wurde erfolgreich mit Patch-Informationen aktualisiert.");
update_readme_on_release:
name: 📚 Update README on Release
needs: [analyze_changes]
if: success() && needs.analyze_changes.outputs.update_type == 'release'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 🏗 Assemble README.md
run: |
# Inputs holen
SUMMARY="${{ needs.analyze_changes.outputs.summary }}"
DATE=$(date +'%d.%m.%Y')
# Prüfen ob Templates existieren
if [ ! -f .github/templates/README_BASE.md ]; then
echo "WARNUNG: .github/templates/README_BASE.md fehlt! Breche ab."
exit 1
fi
# 1. Base laden (Alles überschreiben)
cat .github/templates/README_BASE.md > README.md
# 2. KI Sektion einbauen
echo -e "\n---\n" >> README.md
echo -e "## 🚀 Neuestes Update ($DATE)\n" >> README.md
echo -e "$SUMMARY\n" >> README.md
echo -e "👉 [**Komplette Update-Historie ansehen**](CHANGELOG.md)\n" >> README.md
# 3. Installation anhängen
if [ -f .github/templates/INSTALLATION.md ]; then
echo -e "---\n" >> README.md
cat .github/templates/INSTALLATION.md >> README.md
fi
- name: 🚀 Commit & Push changes
run: |
git config --global user.name "TechAna Bot"
git config --global user.email "bot@techana.app"
# Fix: Ensure we are on the correct branch and sync with remote changes from the previous job
git checkout ${{ github.ref_name }}
git pull origin ${{ github.ref_name }}
if [[ -n $(git status -s README.md) ]]; then
git add README.md
git commit -m "docs: Rebuild README with latest changes [skip ci]"
git push
else
echo "No changes in README."
fi