diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 48f4c25..b794ed5 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -19,7 +19,7 @@ jobs: run: | apt-get update apt-get install -y --no-install-recommends \ - cmake g++ pkg-config dpkg-dev libgtk-3-dev libcurl4-openssl-dev \ + cmake g++ pkg-config python3 dpkg-dev libgtk-3-dev libcurl4-openssl-dev \ libgstreamer1.0-dev gstreamer1.0-plugins-good libsecret-1-dev \ libjson-glib-dev wtype xdotool - name: Configure @@ -29,28 +29,25 @@ jobs: - name: Package run: | cmake --build build --target package --parallel 2 - mkdir -p dist - cp build/*.deb dist/ - - name: Store package - if: ${{ gitea.event_name == 'workflow_dispatch' }} - uses: actions/upload-artifact@v4 - with: - name: transui-deb-amd64 - path: dist/*.deb - if-no-files-found: error - - name: Upload release package - if: ${{ gitea.event_name == 'release' }} + mkdir -p artifacts + cp build/*.deb artifacts/ + sha256sum artifacts/*.deb > artifacts/SHA256SUMS + - name: Attach packages to the Gitea release + if: gitea.event_name == 'release' + shell: bash env: + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - RELEASE_ID: ${{ gitea.event.release.id }} - RELEASE_URL: ${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/${{ gitea.event.release.id }}/assets - run: | - for package in dist/*.deb; do - curl --fail-with-body --request POST \ - --header "Authorization: token ${GITEA_TOKEN}" \ - --form "attachment=@${package}" \ - "${RELEASE_URL}" - done + GITEA_RELEASE_TAG: ${{ gitea.event.release.tag_name }} + run: scripts/publish-release-assets.sh + - name: Upload Debian packages + if: always() + uses: christopherhx/gitea-upload-artifact@v4 + with: + name: transui-debian-amd64 + path: artifacts/ + if-no-files-found: error build-arm64: runs-on: debian-latest-arm64 @@ -65,7 +62,7 @@ jobs: run: | apt-get update apt-get install -y --no-install-recommends \ - cmake g++ pkg-config dpkg-dev libgtk-3-dev libcurl4-openssl-dev \ + cmake g++ pkg-config python3 dpkg-dev libgtk-3-dev libcurl4-openssl-dev \ libgstreamer1.0-dev gstreamer1.0-plugins-good libsecret-1-dev \ libjson-glib-dev wtype xdotool - name: Configure @@ -75,25 +72,22 @@ jobs: - name: Package run: | cmake --build build --target package --parallel 2 - mkdir -p dist - cp build/*.deb dist/ - - name: Store package - if: ${{ gitea.event_name == 'workflow_dispatch' }} - uses: actions/upload-artifact@v4 - with: - name: transui-deb-arm64 - path: dist/*.deb - if-no-files-found: error - - name: Upload release package - if: ${{ gitea.event_name == 'release' }} + mkdir -p artifacts + cp build/*.deb artifacts/ + sha256sum artifacts/*.deb > artifacts/SHA256SUMS + - name: Attach packages to the Gitea release + if: gitea.event_name == 'release' + shell: bash env: + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - RELEASE_ID: ${{ gitea.event.release.id }} - RELEASE_URL: ${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/${{ gitea.event.release.id }}/assets - run: | - for package in dist/*.deb; do - curl --fail-with-body --request POST \ - --header "Authorization: token ${GITEA_TOKEN}" \ - --form "attachment=@${package}" \ - "${RELEASE_URL}" - done + GITEA_RELEASE_TAG: ${{ gitea.event.release.tag_name }} + run: scripts/publish-release-assets.sh + - name: Upload Debian packages + if: always() + uses: christopherhx/gitea-upload-artifact@v4 + with: + name: transui-debian-arm64 + path: artifacts/ + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 84c048a..1f7d35e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /build/ +/artifacts/ diff --git a/scripts/publish-release-assets.sh b/scripts/publish-release-assets.sh new file mode 100755 index 0000000..a3c4683 --- /dev/null +++ b/scripts/publish-release-assets.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +set -euo pipefail + +root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +artifact_dir="${ARTIFACT_DIR:-$root_dir/artifacts}" +GITEA_SERVER_URL="${GITEA_SERVER_URL:?GITEA_SERVER_URL is required}" +GITEA_REPOSITORY="${GITEA_REPOSITORY:?GITEA_REPOSITORY is required}" +GITEA_RELEASE_TAG="${GITEA_RELEASE_TAG:?GITEA_RELEASE_TAG is required}" +GITEA_TOKEN="${GITEA_TOKEN:?GITEA_TOKEN is required}" + +[[ "$GITEA_REPOSITORY" =~ ^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$ ]] || { + echo "Invalid GITEA_REPOSITORY: $GITEA_REPOSITORY" >&2 + exit 1 +} + +owner="${GITEA_REPOSITORY%%/*}" +repository="${GITEA_REPOSITORY#*/}" +api="${GITEA_SERVER_URL%/}/api/v1/repos/$owner/$repository" +metadata="$(mktemp)" +response="$(mktemp)" +existing_names="$(mktemp)" +trap 'rm -f "$metadata" "$response" "$existing_names"' EXIT + +auth_header="Authorization: token $GITEA_TOKEN" +status="$(curl --silent --show-error --output "$metadata" --write-out '%{http_code}' \ + --header "$auth_header" "$api/releases/tags/$GITEA_RELEASE_TAG")" +[[ "$status" == 200 ]] || { + echo "Unable to find release $GITEA_RELEASE_TAG (HTTP $status)" >&2 + cat "$metadata" >&2 + exit 1 +} + +release_id="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' < "$metadata")" +python3 -c 'import json,sys; [print(a["name"]) for a in json.load(sys.stdin).get("assets", [])]' \ + < "$metadata" > "$existing_names" + +shopt -s nullglob +assets=("$artifact_dir"/*.deb) +[[ -f "$artifact_dir/SHA256SUMS" ]] && assets+=("$artifact_dir/SHA256SUMS") +((${#assets[@]} > 0)) || { + echo "No release assets found in $artifact_dir" >&2 + exit 1 +} + +for asset in "${assets[@]}"; do + name="$(basename "$asset")" + if grep -Fxq -- "$name" "$existing_names"; then + echo "Release asset already exists; keeping it: $name" + continue + fi + encoded_name="$(python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$name")" + echo "Uploading release asset: $name" + status="$(curl --silent --show-error --output "$response" --write-out '%{http_code}' \ + --request POST --header "$auth_header" --form "attachment=@$asset" \ + "$api/releases/$release_id/assets?name=$encoded_name")" + [[ "$status" == 201 ]] || { + echo "Gitea returned HTTP $status while uploading $name" >&2 + cat "$response" >&2 + exit 1 + } + : > "$response" +done