diff --git a/build.yml b/build.yml new file mode 100644 index 0000000..66b3c33 --- /dev/null +++ b/build.yml @@ -0,0 +1,194 @@ +name: Build and Release .NET WPF + +on: + push: + branches: + - main + tags: + - 'v*' # optional: reagiere auf Tag-Pushes wie v1.0.0 + +env: + SOLUTION_PATH: "FileBrowser.sln" # anpassen falls dein .sln anders heißt + CONFIGURATION: "Release" + RUNTIME: "win-x64" # WPF benötigt Windows runtime; wir publishen framework-dependent/native + OUTPUT_DIR: "publish_out" + ZIP_NAME_PREFIX: "FileBrowser" + # Default Gitea API base; du kannst dies als Repository-Secret überschreiben + BASE_URL: "https://git.out.jafre.li/api/v1" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v3 + with: + dotnet-version: '8.0.x' # anpassen an dein TargetFramework (z.B. 7.0, 8.0) + + - name: Restore + run: dotnet restore "$SOLUTION_PATH" + + - name: Build + run: dotnet build "$SOLUTION_PATH" --configuration $CONFIGURATION --no-restore + + - name: Publish WPF project + # Passe Pfad zu deinem WPF-Projekt (.csproj) an, z.B. src/FileBrowser/FileBrowser.csproj + run: | + PROJECT_PATH=$(find . -maxdepth 3 -type f -name "*.csproj" | head -n 1) + if [ -z "$PROJECT_PATH" ]; then + echo "No .csproj found - aborting" + exit 1 + fi + echo "Publishing project: $PROJECT_PATH" + rm -rf $OUTPUT_DIR + dotnet publish "$PROJECT_PATH" \ + --configuration $CONFIGURATION \ + --runtime $RUNTIME \ + --self-contained false \ + -o $OUTPUT_DIR + + - name: Create zip of publish output + run: | + TIMESTAMP=$(date -u +"%Y%m%dT%H%M%SZ") + ZIP_FILE="${ZIP_NAME_PREFIX}-${TIMESTAMP}.zip" + if [ ! -d "$OUTPUT_DIR" ]; then + echo "Publish output not found in $OUTPUT_DIR" + exit 1 + fi + zip -r "$ZIP_FILE" "$OUTPUT_DIR" + echo "ZIP_FILE=$ZIP_FILE" >> $GITHUB_OUTPUT + # NOTE: Gitea Actions environment may not provide $GITHUB_OUTPUT; as fallback set env var: + env: + ZIP_TMP: /tmp + - name: Set ZIP filename variable (fallback) + if: always() + run: | + TIMESTAMP=$(date -u +"%Y%m%dT%H%M%SZ") + echo "ZIP_FILE=${ZIP_NAME_PREFIX}-${TIMESTAMP}.zip" > zipname.txt + shell: bash + + - name: Retrieve ZIP filename + id: getzip + run: | + if [ -f zipname.txt ]; then + ZIP_FILE=$(cat zipname.txt) + else + ZIP_FILE=$(ls ${ZIP_NAME_PREFIX}-*.zip | head -n1 || true) + fi + if [ -z "$ZIP_FILE" ]; then + echo "Could not determine zip file" + exit 1 + fi + echo "zip=$ZIP_FILE" >> $GITHUB_OUTPUT + echo "::set-output name=zip::$ZIP_FILE" + shell: bash + + - name: Prepare release metadata + id: meta + run: | + # Determine tag: use pushed tag if present, else use commit SHA-based tag + if [ -n "${{ github.ref }}" ] && [[ "${{ github.ref }}" == refs/tags/* ]]; then + TAG="${{ github.ref#refs/tags/ }}" + else + SHORT_SHA=$(git rev-parse --short HEAD) + TAG="build-${SHORT_SHA}" + fi + NAME="Automated build ${TAG}" + BODY="Automated build created by CI for tag ${TAG}." + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "name=$NAME" >> $GITHUB_OUTPUT + echo "body=$BODY" >> $GITHUB_OUTPUT + echo "::set-output name=tag::$TAG" + echo "::set-output name=name::$NAME" + echo "::set-output name=body::$BODY" + shell: bash + + - name: Create or get release ID + id: release + env: + BASE_URL: ${{ env.BASE_URL }} + TOKEN: ${{ secrets.GITEA_TOKEN }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + run: | + TAG="${{ steps.meta.outputs.tag }}" + # Check if release exists + API="${BASE_URL}/repos/${OWNER}/${REPO}/releases/tags/${TAG}" + echo "Checking for existing release at $API" + HTTP_STATUS=$(curl -s -o /tmp/release.json -w "%{http_code}" \ + -H "Authorization: token ${TOKEN}" \ + "$API" || true) + if [ "$HTTP_STATUS" -eq 200 ]; then + RELEASE_ID=$(jq -r .id /tmp/release.json) + echo "Found existing release id=$RELEASE_ID" + echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT + echo "::set-output name=release_id::$RELEASE_ID" + exit 0 + fi + + # Create release + CREATE_API="${BASE_URL}/repos/${OWNER}/${REPO}/releases" + echo "Creating release via $CREATE_API" + PAYLOAD=$(jq -n \ + --arg tag "$TAG" \ + --arg name "${{ steps.meta.outputs.name }}" \ + --arg body "${{ steps.meta.outputs.body }}" \ + '{tag_name:$tag, name:$name, body:$body, draft:false, prerelease:false}') + RESP=$(curl -s -w "\n%{http_code}" -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: token ${TOKEN}" \ + -d "$PAYLOAD" \ + "$CREATE_API") + HTTP_STATUS=$(echo "$RESP" | tail -n1) + BODY_RESP=$(echo "$RESP" | sed '$d') + if [ "$HTTP_STATUS" -ne 201 ] && [ "$HTTP_STATUS" -ne 200 ]; then + echo "Failed to create release: HTTP $HTTP_STATUS - $BODY_RESP" + exit 1 + fi + echo "$BODY_RESP" > /tmp/release.json + RELEASE_ID=$(jq -r .id /tmp/release.json) + echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT + echo "::set-output name=release_id::$RELEASE_ID" + shell: bash + + - name: Upload asset to release + env: + BASE_URL: ${{ env.BASE_URL }} + TOKEN: ${{ secrets.GITEA_TOKEN }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + run: | + RELEASE_ID="${{ steps.release.outputs.release_id }}" + ZIP_FILE="${{ steps.getzip.outputs.zip }}" + if [ -z "$RELEASE_ID" ]; then + echo "Release ID is empty" + exit 1 + fi + if [ ! -f "$ZIP_FILE" ]; then + # try to find zip file in repo root + ZIP_FILE=$(ls ${ZIP_NAME_PREFIX}-*.zip | head -n1 || true) + fi + if [ ! -f "$ZIP_FILE" ]; then + echo "Zip file not found: $ZIP_FILE" + ls -la + exit 1 + fi + echo "Uploading $ZIP_FILE to release $RELEASE_ID" + UPLOAD_API="${BASE_URL}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}/assets?name=$(basename "$ZIP_FILE")" + HTTP_STATUS=$(curl -s -o /tmp/upload_resp.json -w "%{http_code}" \ + -X POST \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/zip" \ + --data-binary @"$ZIP_FILE" \ + "$UPLOAD_API" || true) + if [ "$HTTP_STATUS" -ne 201 ] && [ "$HTTP_STATUS" -ne 200 ]; then + echo "Upload failed: HTTP $HTTP_STATUS" + cat /tmp/upload_resp.json || true + exit 1 + fi + echo "Upload successful" + cat /tmp/upload_resp.json + shell: bash \ No newline at end of file