diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 1d192c2..9b4c1f9 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -16,143 +16,9 @@ env: DOTNET_CLI_TELEMETRY_OPTOUT: true jobs: - # Build Android on Linux (fastest for Android builds) - build-android: - name: Build Android - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Determine version - id: version - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - echo "VERSION=${{ inputs.version }}" >> $GITHUB_OUTPUT - else - # Extract version from tag (remove 'v' prefix) - VERSION="${GITHUB_REF_NAME#v}" - echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - fi - - - name: Decode Android Keystore - run: | - echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > ${{ runner.temp }}/keystore.jks - - - name: Build Android Release - run: | - dotnet publish BuyMeCofee.Maui/BuyMeCofee.Maui.csproj \ - -f net10.0-android \ - -c Release \ - -p:Version=${{ steps.version.outputs.VERSION }} \ - -p:AndroidKeyStore=true \ - -p:AndroidSigningKeyStore=${{ runner.temp }}/keystore.jks \ - -p:AndroidSigningKeyAlias=${{ secrets.ANDROID_KEY_ALIAS }} \ - -p:AndroidSigningKeyPass=${{ secrets.ANDROID_KEY_PASSWORD }} \ - -p:AndroidSigningStorePass=${{ secrets.ANDROID_KEYSTORE_PASSWORD }} \ - -o ${{ runner.temp }}/android-output - - - name: Clean up keystore - if: always() - run: rm -f ${{ runner.temp }}/keystore.jks - - - name: Upload Android artifacts - uses: actions/upload-artifact@v3 - with: - name: android-release - path: | - ${{ runner.temp }}/android-output/*.apk - ${{ runner.temp }}/android-output/*.aab - retention-days: 30 - - # Build iOS and macOS on macOS runner - build-apple: - name: Build iOS & macOS - runs-on: macos-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Determine version - id: version - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - echo "VERSION=${{ inputs.version }}" >> $GITHUB_OUTPUT - else - # Extract version from tag (remove 'v' prefix) - VERSION="${GITHUB_REF_NAME#v}" - echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - fi - - - name: Setup Apple certificates - run: | - # Create temporary keychain - KEYCHAIN_PATH=${{ runner.temp }}/app-signing.keychain-db - KEYCHAIN_PASSWORD=$(openssl rand -base64 32) - - security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" - security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - - # Decode and import iOS certificate - echo "${{ secrets.IOS_CERTIFICATE_BASE64 }}" | base64 -d > ${{ runner.temp }}/ios_cert.p12 - security import ${{ runner.temp }}/ios_cert.p12 -P "${{ secrets.IOS_CERTIFICATE_PASSWORD }}" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" - - # Decode and import Apple (macOS) certificate - echo "${{ secrets.APPLE_CERTIFICATE_BASE64 }}" | base64 -d > ${{ runner.temp }}/apple_cert.p12 - security import ${{ runner.temp }}/apple_cert.p12 -P "${{ secrets.APPLE_CERTIFICATE_PASSWORD }}" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" - - # Set key partition list - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - - # Add keychain to search list - security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain - - # Clean up certificate files - rm -f ${{ runner.temp }}/ios_cert.p12 ${{ runner.temp }}/apple_cert.p12 - - - name: Build iOS Release - run: | - dotnet publish BuyMeCofee.Maui/BuyMeCofee.Maui.csproj \ - -f net10.0-ios \ - -c Release \ - -p:Version=${{ steps.version.outputs.VERSION }} \ - -p:CodesignKey="${{ secrets.IOS_SIGNING_IDENTITY }}" \ - -p:ArchiveOnBuild=true \ - -o ${{ runner.temp }}/ios-output - - - name: Build macOS Catalyst Release - run: | - dotnet publish BuyMeCofee.Maui/BuyMeCofee.Maui.csproj \ - -f net10.0-maccatalyst \ - -c Release \ - -p:Version=${{ steps.version.outputs.VERSION }} \ - -p:CodesignKey="${{ secrets.APPLE_SIGNING_IDENTITY }}" \ - -p:CreatePackage=true \ - -o ${{ runner.temp }}/macos-output - - - name: Cleanup keychain - if: always() - run: | - security delete-keychain ${{ runner.temp }}/app-signing.keychain-db || true - - - name: Upload iOS artifacts - uses: actions/upload-artifact@v3 - with: - name: ios-release - path: ${{ runner.temp }}/ios-output/*.ipa - retention-days: 30 - - - name: Upload macOS artifacts - uses: actions/upload-artifact@v3 - with: - name: macos-release - path: ${{ runner.temp }}/macos-output/*.pkg - retention-days: 30 - - # Build Windows on Windows runner - build-windows: - name: Build Windows + # Build + pack on Windows (covers android + windows TFMs) + build-and-pack: + name: Build & Pack runs-on: windows-latest steps: - name: Checkout repository @@ -169,32 +35,47 @@ jobs: "VERSION=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append } - - name: Build Windows Release + - name: Build shell: pwsh run: | - dotnet publish BuyMeCofee.Maui/BuyMeCofee.Maui.csproj ` - -f net10.0-windows10.0.19041.0 ` + dotnet build BuyMeCofee.Maui/BuyMeCofee.Maui.csproj ` -c Release ` + -p:Version=${{ steps.version.outputs.VERSION }} + + - name: Pack NuGet + shell: pwsh + run: | + dotnet pack BuyMeCofee.Maui/BuyMeCofee.Maui.csproj ` + -c Release ` + --no-build ` -p:Version=${{ steps.version.outputs.VERSION }} ` - -p:WindowsPackageType=None ` - -o ${{ runner.temp }}/windows-output + -p:PackageVersion=${{ steps.version.outputs.VERSION }} ` + -o ${{ runner.temp }}/nupkg - # TODO: Windows code signing with Certum certificate - # The CERTUM_CERT_NAME secret is available but additional setup may be required - # for cloud-based HSM signing or local certificate installation - - - name: Upload Windows artifacts + - name: Upload NuGet artifact uses: actions/upload-artifact@v3 with: - name: windows-release - path: ${{ runner.temp }}/windows-output/ + name: nupkg + path: ${{ runner.temp }}/nupkg/*.nupkg retention-days: 30 - # Create release and upload assets - create-release: - name: Create Release + # Verify Apple TFMs build on macOS + build-apple: + name: Verify Apple Build + runs-on: macos-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Build iOS & macCatalyst + run: | + dotnet build BuyMeCofee.Maui/BuyMeCofee.Maui.csproj -c Release + + # Publish NuGet + create Gitea release + publish: + name: Publish runs-on: ubuntu-latest - needs: [build-android, build-apple, build-windows] + needs: [build-and-pack, build-apple] steps: - name: Checkout repository uses: actions/checkout@v3 @@ -211,96 +92,60 @@ jobs: echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_OUTPUT fi - - name: Download Android artifacts + - name: Download NuGet artifact uses: actions/download-artifact@v3 with: - name: android-release - path: ${{ runner.temp }}/artifacts/android + name: nupkg + path: ${{ runner.temp }}/nupkg - - name: Download iOS artifacts - uses: actions/download-artifact@v3 - with: - name: ios-release - path: ${{ runner.temp }}/artifacts/ios - - - name: Download macOS artifacts - uses: actions/download-artifact@v3 - with: - name: macos-release - path: ${{ runner.temp }}/artifacts/macos - - - name: Download Windows artifacts - uses: actions/download-artifact@v3 - with: - name: windows-release - path: ${{ runner.temp }}/artifacts/windows - - - name: Prepare release assets + - name: Publish to Gitea NuGet feed run: | - mkdir -p ${{ runner.temp }}/release-assets - - # Copy Android artifacts - find ${{ runner.temp }}/artifacts/android -name "*.apk" -exec cp {} ${{ runner.temp }}/release-assets/ \; - find ${{ runner.temp }}/artifacts/android -name "*.aab" -exec cp {} ${{ runner.temp }}/release-assets/ \; - - # Copy iOS artifacts - find ${{ runner.temp }}/artifacts/ios -name "*.ipa" -exec cp {} ${{ runner.temp }}/release-assets/ \; - - # Copy macOS artifacts - find ${{ runner.temp }}/artifacts/macos -name "*.pkg" -exec cp {} ${{ runner.temp }}/release-assets/ \; - - # Create Windows zip - cd ${{ runner.temp }}/artifacts/windows - zip -r ${{ runner.temp }}/release-assets/BuyMeCofee.Maui-windows-${{ steps.version.outputs.VERSION }}.zip . - - # List all release assets - echo "Release assets:" - ls -la ${{ runner.temp }}/release-assets/ + dotnet nuget push ${{ runner.temp }}/nupkg/*.nupkg \ + --source "https://git.marketally.com/api/packages/misc/nuget/index.json" \ + --api-key "${{ secrets.GITEATOKEN }}" - name: Get or create release id: release run: | - # Get repository info from GITHUB_REPOSITORY REPO="${{ github.repository }}" TAG="${{ steps.version.outputs.TAG }}" API_URL="${{ github.server_url }}/api/v1" - - # Check if release exists for this tag + RELEASE_RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ "${API_URL}/repos/${REPO}/releases/tags/${TAG}") - + RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id // empty') - + if [ -z "$RELEASE_ID" ]; then echo "Creating new release for tag ${TAG}..." RELEASE_RESPONSE=$(curl -s -X POST \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -H "Content-Type: application/json" \ - -d "{\"tag_name\": \"${TAG}\", \"name\": \"Release ${TAG}\", \"body\": \"Release ${TAG} of BuyMeCofee.Maui\", \"draft\": false, \"prerelease\": false}" \ + -d "{\"tag_name\": \"${TAG}\", \"name\": \"v${{ steps.version.outputs.VERSION }}\", \"body\": \"## BuyMeCofee.Maui v${{ steps.version.outputs.VERSION }}\n\nInstall from NuGet:\n\`\`\`\ndotnet add package BuyMeCofee.Maui --version ${{ steps.version.outputs.VERSION }}\n\`\`\`\", \"draft\": false, \"prerelease\": false}" \ "${API_URL}/repos/${REPO}/releases") RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id') fi - + echo "RELEASE_ID=$RELEASE_ID" >> $GITHUB_OUTPUT echo "Release ID: $RELEASE_ID" - - name: Upload release assets + - name: Upload nupkg to release run: | REPO="${{ github.repository }}" RELEASE_ID="${{ steps.release.outputs.RELEASE_ID }}" API_URL="${{ github.server_url }}/api/v1" - - for file in ${{ runner.temp }}/release-assets/*; do + + for file in ${{ runner.temp }}/nupkg/*.nupkg; do if [ -f "$file" ]; then FILENAME=$(basename "$file") echo "Uploading $FILENAME..." - + curl -s -X POST \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -H "Content-Type: application/octet-stream" \ --data-binary "@$file" \ "${API_URL}/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${FILENAME}" - + echo "Uploaded $FILENAME" fi done diff --git a/BuyMeCofee.Maui/BuyMeCofee.Maui.csproj b/BuyMeCofee.Maui/BuyMeCofee.Maui.csproj index e9e8ae6..8a4b9bc 100644 --- a/BuyMeCofee.Maui/BuyMeCofee.Maui.csproj +++ b/BuyMeCofee.Maui/BuyMeCofee.Maui.csproj @@ -18,6 +18,21 @@ (force runtime inflation) --> SourceGen + + BuyMeCofee.Maui + Buy Me a Coffee MAUI Controls + Branded Buy Me a Coffee controls for .NET MAUI — button, support widget, and QR code with official BMC branding. + David H Friedel Jr + MarketAlly + Copyright © 2026 MarketAlly LLC + MIT + https://git.marketally.com/misc/bmc.maui + https://git.marketally.com/misc/bmc.maui + git + maui;buymeacoffee;bmc;donation;tip;controls + README.md + false + 15.0 15.0 21.0