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 NUGET_SOURCE_NAME: Nuget-Forgejo-AIFotoONLUS NUGET_SOURCE_URL: ${{ vars.AIFOTOONLUS_NUGET_SOURCE_URL || format('{0}/api/packages/{1}/nuget/index.json', github.server_url, vars.AIFOTOONLUS_PACKAGE_OWNER || github.repository_owner) }} jobs: build: runs-on: docker env: FORGEJO_PACKAGE_USERNAME: ${{ secrets.FORGEJO_PACKAGE_USERNAME }} FORGEJO_PACKAGE_TOKEN: ${{ secrets.FORGEJO_PACKAGE_TOKEN }} steps: - name: Checkout uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} - name: Validate NuGet secrets run: | set -eu if [ -z "${FORGEJO_PACKAGE_USERNAME}" ]; then echo "secrets.FORGEJO_PACKAGE_USERNAME is required" exit 1 fi if [ -z "${FORGEJO_PACKAGE_TOKEN}" ]; then echo "secrets.FORGEJO_PACKAGE_TOKEN is required" exit 1 fi - name: Configure private NuGet source run: | set -eu temp_config="${RUNNER_TEMP}/nuget.config" cp NuGet.Config "${temp_config}" dotnet nuget update source "${{ env.NUGET_SOURCE_NAME }}" \ --source "${{ env.NUGET_SOURCE_URL }}" \ --username "${FORGEJO_PACKAGE_USERNAME}" \ --password "${FORGEJO_PACKAGE_TOKEN}" \ --store-password-in-clear-text \ --configfile "${temp_config}" echo "NUGET_CONFIG_PATH=${temp_config}" >> "${GITHUB_ENV}" - name: Restore run: dotnet restore "${{ env.PROJECT_PATH }}" -r win-x64 --configfile "${NUGET_CONFIG_PATH}" - name: Publish Windows Avalonia build run: | set -eu dotnet publish "${{ env.PROJECT_PATH }}" \ -c Release \ -r win-x64 \ --self-contained true \ --no-restore \ -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}"