diff --git a/.forgejo/workflows/build-windows-avalonia.yml b/.forgejo/workflows/build-windows-avalonia.yml new file mode 100644 index 0000000..f4d410a --- /dev/null +++ b/.forgejo/workflows/build-windows-avalonia.yml @@ -0,0 +1,139 @@ +name: Build Windows Avalonia + +on: + push: + branches: + - master + - develop + tags: + - '*' + workflow_dispatch: + +env: + DOTNET_VERSION: 10.0.x + PROJECT_PATH: imagecatalog/ImageCatalog 2.csproj + PUBLISH_DIR: artifacts/publish/win-x64 + ARTIFACT_NAME: imagecatalog-windows-avalonia + +jobs: + build: + runs-on: docker + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Restore + run: dotnet restore "${{ env.PROJECT_PATH }}" -r win-x64 + + - name: Publish Windows Avalonia build + run: | + set -eu + dotnet publish "${{ env.PROJECT_PATH }}" \ + -c Release \ + -r win-x64 \ + --self-contained true \ + -p:AvaloniaWindowsCrossPublish=true \ + -p:PublishSingleFile=true \ + -p:PublishTrimmed=false \ + -p:PublishReadyToRun=false \ + -o "${{ env.PUBLISH_DIR }}" + + - name: Validate published executable + run: | + set -eu + exe_count="$(find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f -iname '*.exe' | wc -l | tr -d ' ')" + if [ "${exe_count}" -eq 0 ]; then + echo "No Windows executable produced in ${{ env.PUBLISH_DIR }}" + exit 1 + fi + + - name: Upload publish artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: ${{ env.PUBLISH_DIR }} + if-no-files-found: error + + release: + if: startsWith(github.ref, 'refs/tags/') + needs: build + runs-on: docker + env: + FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + + steps: + - name: Download publish artifact + uses: actions/download-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: artifacts/release + + - name: Validate release token + run: | + set -eu + if [ -z "${FORGEJO_TOKEN}" ]; then + echo "secrets.FORGEJO_TOKEN is required for tagged releases" + exit 1 + fi + + - name: Create or reuse release + run: | + set -eu + api_base="${GITHUB_SERVER_URL%/}/api/v1/repos/${GITHUB_REPOSITORY}" + tag="${GITHUB_REF_NAME}" + + http_code="$(curl -sS -o release.json -w '%{http_code}' \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${api_base}/releases/tags/${tag}")" + + if [ "${http_code}" = "200" ]; then + release_id="$(sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p' release.json | head -n1)" + elif [ "${http_code}" = "404" ]; then + payload="$(printf '{"tag_name":"%s","name":"%s","draft":false,"prerelease":false}' "${tag}" "${tag}")" + curl -fsS \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/json" \ + -X POST \ + -d "${payload}" \ + "${api_base}/releases" \ + -o release.json + release_id="$(sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p' release.json | head -n1)" + else + echo "Unexpected response while loading release for tag ${tag}: ${http_code}" + cat release.json + exit 1 + fi + + if [ -z "${release_id}" ]; then + echo "Unable to resolve Forgejo release id" + cat release.json + exit 1 + fi + + echo "RELEASE_ID=${release_id}" >> "${GITHUB_ENV}" + + - name: Upload executable to release + run: | + set -eu + api_base="${GITHUB_SERVER_URL%/}/api/v1/repos/${GITHUB_REPOSITORY}" + executable_path="$(find artifacts/release -maxdepth 1 -type f -iname '*.exe' | head -n1)" + + if [ -z "${executable_path}" ]; then + echo "No executable found in downloaded artifact" + exit 1 + fi + + short_sha="$(printf '%s' "${GITHUB_SHA}" | cut -c1-12)" + asset_name="ImageCatalog-avalonia-win-x64-${GITHUB_REF_NAME}-${short_sha}.exe" + + curl -fsS \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @"${executable_path}" \ + "${api_base}/releases/${RELEASE_ID}/assets?name=${asset_name}" \ No newline at end of file diff --git a/imagecatalog/ImageCatalog 2.csproj b/imagecatalog/ImageCatalog 2.csproj index f87ea98..d10dce5 100644 --- a/imagecatalog/ImageCatalog 2.csproj +++ b/imagecatalog/ImageCatalog 2.csproj @@ -6,6 +6,7 @@ ImageCatalog default + false @@ -20,6 +21,15 @@ net10.0 Exe + + WinExe + win-x64 + true + true + true + false + false +