diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index e61230f..8481731 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -149,29 +149,8 @@ jobs: run: | DEB_NAME=$(ls linux-patch-manager_*.deb) VERSION="${{ steps.version.outputs.version }}" - TOKEN="${GITHUB_TOKEN:-$GITEA_TOKEN}" - REF_NAME="${GITHUB_REF_NAME:-v${VERSION}}" - REPO="${GITHUB_REPOSITORY:-echo/linux_patch_manager}" - echo "Creating release for tag: ${REF_NAME} repo: ${REPO}" - echo "DEB: ${DEB_NAME}" - # Create release via Gitea API - HTTP_CODE=$(curl -s -o release.json -w "%{http_code}" -X POST \ - "http://192.168.2.189:3000/api/v1/repos/${REPO}/releases" \ - -H "Authorization: token ${TOKEN}" \ - -H "Content-Type: application/json" \ - -d "{\"tag_name\": \"${REF_NAME}\", \"title\": \"Release ${VERSION}\", \"body\": \"Automated build from tag ${REF_NAME}.\\n\\n## Installation\\n\\n\\\`\\\`\\\`bash\\nsudo apt install ./linux-patch-manager_${VERSION}-1_amd64.deb\\n\\\`\\\`\\\`\\\"}") - echo "Release API HTTP status: ${HTTP_CODE}" - cat release.json - if [ "${HTTP_CODE}" != "201" ]; then - echo "ERROR: Failed to create release (HTTP ${HTTP_CODE})" - exit 1 - fi - # Extract release ID and upload .deb - RELEASE_ID=$(python3 -c "import json; print(json.load(open('release.json'))['id'])") - echo "Release ID: ${RELEASE_ID}" - curl -s -X POST \ - "http://192.168.2.189:3000/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets" \ - -H "Authorization: token ${TOKEN}" \ - -F "attachment=@${DEB_NAME}" \ - -F "name=${DEB_NAME}" - echo "Release upload complete" + export GITEA_TOKEN="${GITHUB_TOKEN:-$GITEA_TOKEN}" + python3 scripts/create-release.py \ + --tag "${GITHUB_REF_NAME:-v${VERSION}}" \ + --deb "${DEB_NAME}" \ + --version "${VERSION}" diff --git a/scripts/create-release.py b/scripts/create-release.py new file mode 100755 index 0000000..85be2d5 --- /dev/null +++ b/scripts/create-release.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +"""Create a Gitea release and upload a .deb package as an asset. + +Usage: + python3 create-release.py --tag v1.0.0 --deb linux-patch-manager_1.0.0-1_amd64.deb + +Environment variables: + GITEA_TOKEN - API token (required, falls back to GITHUB_TOKEN) + GITEA_URL - Gitea base URL (default: http://192.168.2.189:3000) + GITEA_REPO - Repository path (default: echo/linux_patch_manager) +""" +import argparse +import json +import os +import sys +import urllib.request +import urllib.error + + +def create_release(base_url, repo, token, tag, title, body): + url = f"{base_url}/api/v1/repos/{repo}/releases" + data = json.dumps({ + "tag_name": tag, + "title": title, + "body": body, + }).encode() + req = urllib.request.Request( + url, + data=data, + headers={ + "Authorization": f"token {token}", + "Content-Type": "application/json", + }, + method="POST", + ) + try: + resp = urllib.request.urlopen(req) + result = json.loads(resp.read()) + return result + except urllib.error.HTTPError as e: + print(f"ERROR: Failed to create release (HTTP {e.code}): {e.read().decode()[:500]}") + sys.exit(1) + + +def upload_asset(base_url, repo, token, release_id, deb_path): + url = f"{base_url}/api/v1/repos/{repo}/releases/{release_id}/assets" + filename = os.path.basename(deb_path) + boundary = "----FormBoundary7MA4YWxkTrZu0gW" + with open(deb_path, "rb") as f: + deb_data = f.read() + body = ( + f"--{boundary}\r\n" + f'Content-Disposition: form-data; name="attachment"; filename="{filename}"\r\n' + f"Content-Type: application/octet-stream\r\n\r\n" + ).encode() + deb_data + ( + f"\r\n--{boundary}\r\n" + f'Content-Disposition: form-data; name="name"\r\n\r\n' + f"{filename}\r\n" + f"--{boundary}--\r\n" + ).encode() + req = urllib.request.Request( + url, + data=body, + headers={ + "Authorization": f"token {token}", + "Content-Type": f"multipart/form-data; boundary={boundary}", + }, + method="POST", + ) + try: + resp = urllib.request.urlopen(req) + result = json.loads(resp.read()) + return result + except urllib.error.HTTPError as e: + print(f"ERROR: Failed to upload asset (HTTP {e.code}): {e.read().decode()[:500]}") + sys.exit(1) + + +def main(): + parser = argparse.ArgumentParser(description="Create Gitea release with .deb asset") + parser.add_argument("--tag", required=True, help="Tag name (e.g. v1.0.0)") + parser.add_argument("--deb", required=True, help="Path to .deb file") + parser.add_argument("--version", required=True, help="Version string") + args = parser.parse_args() + + token = os.environ.get("GITEA_TOKEN", os.environ.get("GITHUB_TOKEN", "")) + if not token: + print("ERROR: GITEA_TOKEN or GITHUB_TOKEN not set") + sys.exit(1) + + base_url = os.environ.get("GITEA_URL", "http://192.168.2.189:3000") + repo = os.environ.get("GITEA_REPO", "echo/linux_patch_manager") + + title = f"Release {args.version}" + body = ( + f"Automated build from tag {args.tag}.\n\n" + f"## Installation\n\n" + f"```bash\n" + f"sudo apt install ./{os.path.basename(args.deb)}\n" + f"```\n" + ) + + print(f"Creating release for tag: {args.tag} repo: {repo}") + print(f"DEB: {args.deb}") + + release = create_release(base_url, repo, token, args.tag, title, body) + release_id = release["id"] + print(f"Release created! ID: {release_id}") + + asset = upload_asset(base_url, repo, token, release_id, args.deb) + print(f"Upload SUCCESS! Asset ID: {asset.get('id')}") + print(f"Download URL: {asset.get('browser_download_url', 'N/A')}") + print("Release upload complete") + + +if __name__ == "__main__": + main()