# CI runs first; build only proceeds if analyze and test pass. # # Push to dev: analyze + test → build APK → upload artifact (fabledapp-dev-) # Push to main: analyze + test only (no build — wait for release tag) # Tag v26.03.11: analyze + test → build APK → upload artifact + create Forgejo Release # Pull request: analyze + test only # # To cut a release: # git tag v26.03.11 && git push origin v26.03.11 # # Required secrets (repo → Settings → Secrets → Actions): # RELEASE_TOKEN — Forgejo PAT with write:repository scope name: CI & Build on: push: branches: [main, dev] tags: ["v*"] paths: - "lib/**" - "test/**" - "pubspec.yaml" - "pubspec.lock" - "analysis_options.yaml" - "android/**" - "assets/**" - ".forgejo/workflows/ci.yml" pull_request: paths: - "lib/**" - "test/**" - "pubspec.yaml" - "pubspec.lock" - "analysis_options.yaml" - ".forgejo/workflows/ci.yml" jobs: analyze: name: Analyze & test runs-on: py3.12-node22 container: image: ghcr.io/cirruslabs/flutter:stable steps: - uses: actions/checkout@v6 - name: Install dependencies run: flutter pub get - name: Analyze run: flutter analyze - name: Test run: flutter test build: name: Build release APK needs: [analyze] # Build on dev branch pushes and version tag pushes only. # main branch pushes run CI for safety but do not build — # the release tag (v*) is the sole trigger for a production APK. if: | github.event_name == 'push' && (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) runs-on: py3.12-node22 container: image: ghcr.io/cirruslabs/flutter:stable steps: - uses: actions/checkout@v6 - name: Install dependencies run: flutter pub get - name: Build release APK run: flutter build apk --release - name: Set artifact name id: artifact run: | if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then echo "name=fabledapp-dev-${{ github.sha }}" >> $GITHUB_OUTPUT else echo "name=fabledapp-${{ github.sha }}" >> $GITHUB_OUTPUT fi - name: Upload artifact uses: actions/upload-artifact@v6 with: name: ${{ steps.artifact.outputs.name }} path: build/app/outputs/flutter-apk/app-release.apk retention-days: 30 - name: Create Forgejo release if: startsWith(github.ref, 'refs/tags/') env: RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} TAG: ${{ github.ref_name }} run: | echo "Creating release $TAG..." RESPONSE=$(curl -s -X POST \ "https://git.fabledsword.com/api/v1/repos/bvandeusen/FabledApp/releases" \ -H "Authorization: token $RELEASE_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"tag_name\": \"$TAG\", \"name\": \"$TAG\", \"body\": \"\"}") RELEASE_ID=$(echo "$RESPONSE" | grep -oE '"id":[[:space:]]*[0-9]+' | head -1 | grep -oE '[0-9]+') if [ -z "$RELEASE_ID" ]; then echo "Failed to create release. API response:" echo "$RESPONSE" exit 1 fi echo "Release created with ID $RELEASE_ID, uploading APK..." curl -s -X POST \ "https://git.fabledsword.com/api/v1/repos/bvandeusen/FabledApp/releases/$RELEASE_ID/assets" \ -H "Authorization: token $RELEASE_TOKEN" \ -F "attachment=@build/app/outputs/flutter-apk/app-release.apk" echo "Done — release $TAG is live at:" echo "https://git.fabledsword.com/bvandeusen/FabledApp/releases/tag/$TAG"