diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..7c3c70c --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,208 @@ +name: Build and Release + +on: + workflow_dispatch: + inputs: + version: + description: "Release-Version, z. B. v1.0.0" + required: true + default: "v1.0.0" + draft: + description: "Release als Entwurf erstellen" + required: true + default: "false" + type: choice + options: + - "false" + - "true" + prerelease: + description: "Release als Prerelease markieren" + required: true + default: "false" + type: choice + options: + - "false" + - "true" + +permissions: + contents: write + releases: write + +jobs: + build-release: + name: Build Windows release + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: https://gitea.com/actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITEA_TOKEN }} + + - name: Setup .NET + uses: https://github.com/actions/setup-dotnet@v4 + with: + dotnet-version: "9.0.x" + + - name: Prepare version + shell: bash + run: | + set -euo pipefail + + TAG="${{ inputs.version }}" + TAG="${TAG#v}" + TAG="v${TAG}" + VERSION="${TAG#v}" + + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]]; then + echo "Version muss SemVer sein, z. B. v1.0.0 oder v1.0.0-beta.1." + exit 1 + fi + + echo "tag=$TAG" >> "$GITHUB_ENV" + echo "version=$VERSION" >> "$GITHUB_ENV" + echo "artifact_name=LabelPrintAgent-${TAG}-win-x64.zip" >> "$GITHUB_ENV" + + - name: Restore + run: dotnet restore LabelPrintAgent.sln + + - name: Publish + shell: bash + run: | + set -euo pipefail + + dotnet publish src/LabelPrintAgent/LabelPrintAgent.csproj \ + --configuration Release \ + --runtime win-x64 \ + --self-contained true \ + --output publish/win-x64 \ + -p:PublishSingleFile=true \ + -p:IncludeNativeLibrariesForSelfExtract=true \ + -p:EnableCompressionInSingleFile=true \ + -p:Version="$version" \ + -p:InformationalVersion="$tag+$GITHUB_SHA" + + - name: Package + shell: bash + run: | + python3 <<'PY' + import os + import pathlib + import zipfile + + source = pathlib.Path("publish/win-x64") + artifact = pathlib.Path("publish") / os.environ["artifact_name"] + + with zipfile.ZipFile(artifact, "w", zipfile.ZIP_DEFLATED) as archive: + for path in sorted(source.rglob("*")): + if path.is_file(): + archive.write(path, path.relative_to(source)) + + print(f"Created {artifact}") + PY + + - name: Create and push tag + shell: bash + run: | + set -euo pipefail + + git config user.name "Gitea Actions" + git config user.email "actions@local" + + if git rev-parse "$tag" >/dev/null 2>&1; then + echo "Tag $tag existiert bereits." + exit 1 + fi + + git tag -a "$tag" -m "Release $tag" + git push origin "$tag" + + - name: Create release + id: release + shell: bash + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + DRAFT: ${{ inputs.draft }} + PRERELEASE: ${{ inputs.prerelease }} + run: | + python3 <<'PY' + import json + import os + import urllib.error + import urllib.request + + repository = os.environ["GITHUB_REPOSITORY"] + server_url = os.environ["GITHUB_SERVER_URL"].rstrip("/") + api_url = f"{server_url}/api/v1/repos/{repository}/releases" + + payload = { + "tag_name": os.environ["tag"], + "target_commitish": os.environ["GITHUB_SHA"], + "name": f"LabelPrintAgent {os.environ['tag']}", + "body": f"Automatischer Build von {os.environ['GITHUB_SHA']}.", + "draft": os.environ["DRAFT"] == "true", + "prerelease": os.environ["PRERELEASE"] == "true", + } + + request = urllib.request.Request( + api_url, + data=json.dumps(payload).encode("utf-8"), + headers={ + "Authorization": f"token {os.environ['GITEA_TOKEN']}", + "Content-Type": "application/json", + "Accept": "application/json", + }, + method="POST", + ) + + try: + with urllib.request.urlopen(request) as response: + release = json.loads(response.read().decode("utf-8")) + except urllib.error.HTTPError as error: + print(error.read().decode("utf-8")) + raise + + with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: + output.write(f"release_id={release['id']}\n") + PY + + - name: Upload release asset + shell: bash + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + RELEASE_ID: ${{ steps.release.outputs.release_id }} + run: | + python3 <<'PY' + import mimetypes + import os + import pathlib + import urllib.error + import urllib.parse + import urllib.request + + artifact = pathlib.Path("publish") / os.environ["artifact_name"] + repository = os.environ["GITHUB_REPOSITORY"] + server_url = os.environ["GITHUB_SERVER_URL"].rstrip("/") + name = urllib.parse.quote(artifact.name) + api_url = f"{server_url}/api/v1/repos/{repository}/releases/{os.environ['RELEASE_ID']}/assets?name={name}" + content_type = mimetypes.guess_type(artifact.name)[0] or "application/octet-stream" + + request = urllib.request.Request( + api_url, + data=artifact.read_bytes(), + headers={ + "Authorization": f"token {os.environ['GITEA_TOKEN']}", + "Content-Type": content_type, + "Accept": "application/json", + }, + method="POST", + ) + + try: + with urllib.request.urlopen(request) as response: + print(response.read().decode("utf-8")) + except urllib.error.HTTPError as error: + print(error.read().decode("utf-8")) + raise + PY