summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.github/workflows/release.py204
-rw-r--r--.github/workflows/release.yml9
2 files changed, 210 insertions, 3 deletions
diff --git a/.github/workflows/release.py b/.github/workflows/release.py
new file mode 100755
index 0000000..e1e636e
--- /dev/null
+++ b/.github/workflows/release.py
@@ -0,0 +1,204 @@
+#!/usr/bin/python3
+# -*- encoding:utf-8 -*-
+# FileName: release.py
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+__author__ = "yetist"
+__copyright__ = "Copyright (c) 2025 yetist <[email protected]>"
+__license__ = "MIT"
+
+import os
+import sys
+import json
+import requests
+import hmac
+import hashlib
+import uuid
+import datetime
+import subprocess
+import shlex
+
+URL = "https://release.mate-desktop.org/release"
+
+
+def send_post_to_url(payload):
+ headers = {}
+ nonce = str(uuid.uuid4()).replace("-", "").upper()
+ if type(payload) is str:
+ body = payload
+ else:
+ body = json.dumps(payload, indent=2, default=str)
+
+ secret = os.getenv("API_SECRET", "")
+ if not secret:
+ print('Please set the "API_SECRET" environment variable for secure transfer.')
+ else:
+ data = nonce + body
+ signature = hmac.new(
+ bytes(secret, "utf8"), msg=bytes(data, "utf8"), digestmod=hashlib.sha256
+ )
+ sign = signature.hexdigest().upper()
+ headers["X-Build-Signature"] = sign
+
+ headers["X-Build-Nonce"] = nonce
+ headers["User-Agent"] = "docker-build/0.1.2 (Travis CI)"
+ try:
+ r = requests.post(URL, data=body, headers=headers)
+ if r.status_code != 200:
+ print(f"Visit {URL} : {r.status_code} {r.reason}")
+ return False
+ else:
+ print(r.text)
+ print("%s has been notified" % URL)
+ return True
+ except requests.exceptions.ConnectionError as error:
+ print(f"Connect Error {URL} : {error}")
+ return False
+
+
+def get_git_log(repo_name: str, old_version: str, new_version: str):
+ lines = subprocess.getoutput(
+ f'git log --pretty="- %s" {old_version}..{new_version}'
+ ).splitlines()
+ lines.insert(0, f"### {repo_name} {new_version}")
+ lines.insert(1, "")
+ return lines
+
+
+def get_news_log(repo_name: str, old_version: str, new_version: str):
+ lines = []
+ if not os.path.isfile("NEWS"):
+ print('"NEWS" file lost.')
+ return lines
+ old = f"{repo_name} {old_version}"
+ new = f"{repo_name} {new_version}"
+
+ found = False
+ data = open("NEWS").read().splitlines()
+ for i in data:
+ line = i.strip()
+ if line.startswith("##") and line.endswith(new):
+ found = True
+ if not found:
+ print(f'forgot to update the "NEWS" file for {repo_name}-{new}?')
+ return lines
+
+ found = False
+ for i in data:
+ line = i.strip()
+ if line.startswith("##") and line.endswith(new):
+ found = True
+ if line.startswith("##") and line.endswith(old):
+ found = False
+ if found:
+ lines.append(line)
+ return lines
+
+
+def sha256sum(path):
+ fobj = open(path, "rb")
+ fobj.seek(0)
+ sha256sum = hashlib.sha256(fobj.read()).hexdigest()
+ fobj.close()
+
+ base_name = os.path.basename(path)
+ sum_path = os.path.join("{}.sha256sum".format(base_name))
+ sobj = open(sum_path, "w+")
+ sobj.write(f"{sha256sum} {base_name}\n")
+ sobj.close()
+
+
+def notify_server(repo: str, version: str, body: str, flist: list[str]):
+ data = {}
+ data["name"] = repo.split("/")[1]
+ data["version"] = version
+ data["tag"] = f"v{version}"
+ data["repo"] = repo
+ data["draft"] = False
+ data["news"] = body
+ data["prerelease"] = False
+ data["created_at"] = datetime.datetime.now(datetime.UTC).isoformat()
+ data["published_at"] = datetime.datetime.now(datetime.UTC).isoformat()
+ data["files"] = []
+ for i in flist:
+ file = {}
+ basename = os.path.basename(i)
+ file["name"] = basename
+ file["size"] = os.path.getsize(i)
+ file["url"] = (
+ f"https://github.com/{repo}/releases/download/v{version}/{basename}"
+ )
+ data["files"].append(file)
+ payload = json.dumps(data, indent=2, default=str)
+ if not send_post_to_url(payload):
+ print("We can not send post to the release server")
+ sys.exit(1)
+
+
+def main():
+ old_tag = subprocess.getoutput(
+ "gh release ls -L 1 --json tagName --jq '.[0].tagName'"
+ ).strip()
+ old_version = old_tag[1:]
+ new_tag = os.getenv("GITHUB_REF_NAME", "")
+ if len(new_tag.strip()) == 0:
+ print("no tag")
+ sys.exit(1)
+ if old_tag == new_tag:
+ print(f"{new_tag} already releaed")
+ sys.exit(1)
+ new_version = new_tag[1:]
+
+ repo = os.getenv("GITHUB_REPOSITORY", "")
+ repo_name = repo.split("/")[1]
+
+ logs = get_news_log(repo_name, old_version, new_version)
+ if not logs:
+ logs = get_git_log(repo_name, old_version, new_version)
+
+ logs.insert(
+ 0,
+ f"Changes since the last release: https://github.com/{repo}/compare/{old_tag}...{new_tag}",
+ )
+ logs.insert(1, "")
+
+ body = "\n".join(logs)
+
+ with open(".release.note.txt", "w") as f:
+ f.write(body)
+
+ title = f"{repo_name} {new_version} release"
+
+ # release version
+ if os.path.isfile(f"_build/meson-dist/{repo_name}-{new_version}.tar.xz"):
+ # meson dist
+ cmdline = f'gh release create {new_tag} --title "{title}" -F .release.note.txt _build/meson-dist/*'
+ x = subprocess.run(shlex.split(cmdline))
+ if x.returncode != 0:
+ sys.exit(1)
+
+ flist = [
+ f"_build/meson-dist/{repo_name}-{new_version}.tar.xz",
+ f"_build/meson-dist/{repo_name}-{new_version}.tar.xz.sha256sum",
+ ]
+ notify_server(repo, new_version, body, flist)
+ else:
+ # autotools make distcheck
+ tarfile = f"{repo_name}-{new_version}.tar.xz"
+ if not os.path.exists(f"{tarfile}.sha256sum"):
+ sha256sum(tarfile)
+
+ cmdline = f'gh release create {new_tag} --title "{title}" -F .release.note.txt {repo_name}-*.tar.xz*'
+ x = subprocess.run(shlex.split(cmdline))
+ if x.returncode != 0:
+ sys.exit(1)
+
+ flist = [
+ f"{repo_name}-{new_version}.tar.xz",
+ f"{repo_name}-{new_version}.tar.xz.sha256sum",
+ ]
+ notify_server(repo, new_version, body, flist)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index fdc5345..f11411a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,6 +12,8 @@ jobs:
release:
name: Release New Version
runs-on: ubuntu-latest
+ permissions:
+ contents: write
steps:
- name: Repository checkout
uses: actions/checkout@v4
@@ -25,12 +27,13 @@ jobs:
run: .github/workflows/builds.sh meson
- name: Install GH CLI
- uses: dev-hanz-ops/[email protected]
+ uses: dev-hanz-ops/[email protected]
with:
- gh-cli-version: 2.39.1
+ gh-cli-version: 2.72.0
- name: Create github release
run: |
- gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --generate-notes _build/meson-dist/*
+ .github/workflows/release.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ API_SECRET: ${{ secrets.API_SECRET }}