diff options
author | Xiaotian Wu <[email protected]> | 2025-05-24 17:00:00 +0800 |
---|---|---|
committer | Xiaotian Wu <[email protected]> | 2025-05-24 17:08:02 +0800 |
commit | 53ce8d9d12748b5dbb3308765aeae283d4f74dd8 (patch) | |
tree | f29067c7decd7be91eca2009dcf0f60baa240f9c | |
parent | a0aeec575ba18d1101d783d640999df117daf28f (diff) | |
download | mate-power-manager-53ce8d9d12748b5dbb3308765aeae283d4f74dd8.tar.bz2 mate-power-manager-53ce8d9d12748b5dbb3308765aeae283d4f74dd8.tar.xz |
CI: use github action
-rw-r--r-- | .github/dependabot.yml | 8 | ||||
-rwxr-xr-x | .github/workflows/archlinux.sh | 46 | ||||
-rwxr-xr-x | .github/workflows/builds.sh | 65 | ||||
-rw-r--r-- | .github/workflows/builds.yml | 100 | ||||
-rwxr-xr-x | .github/workflows/debian.sh | 54 | ||||
-rwxr-xr-x | .github/workflows/fedora.sh | 49 | ||||
-rwxr-xr-x | .github/workflows/mate-desktop.sh | 146 | ||||
-rwxr-xr-x | .github/workflows/release.py | 204 | ||||
-rw-r--r-- | .github/workflows/release.yml | 42 | ||||
-rwxr-xr-x | .github/workflows/ubuntu.sh | 52 |
10 files changed, 766 insertions, 0 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..80851cd --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +# Enable dependabot to keep our GHA pins automatically +# updated, so we don't fall too far behind in the future +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/archlinux.sh b/.github/workflows/archlinux.sh new file mode 100755 index 0000000..3824bd8 --- /dev/null +++ b/.github/workflows/archlinux.sh @@ -0,0 +1,46 @@ +#!/usr/bin/bash + +# Use grouped output messages +infobegin() { + echo "::group::${1}" +} +infoend() { + echo "::endgroup::" +} + +# Required packages on Archlinux +requires=( + ccache # Use ccache to speed up build + clang # Build with clang on Archlinux + meson # Used for meson build +) + +# https://gitlab.archlinux.org/archlinux/packaging/packages/mate-power-manager/-/blob/main/PKGBUILD +requires+=( + autoconf-archive + dbus-glib + file + gcc + git + glib2-devel + itstool + libcanberra + libgnome-keyring + libnotify + libsecret + make + mate-common + mate-panel + python + upower + which + yelp-tools +) + +infobegin "Update system" +pacman --noconfirm -Syu +infoend + +infobegin "Install dependency packages" +pacman --noconfirm -S ${requires[@]} +infoend diff --git a/.github/workflows/builds.sh b/.github/workflows/builds.sh new file mode 100755 index 0000000..c80e76a --- /dev/null +++ b/.github/workflows/builds.sh @@ -0,0 +1,65 @@ +#!/usr/bin/bash + +set -e +set -o pipefail + +CPUS=$(grep processor /proc/cpuinfo | wc -l) + +# Use grouped output messages +infobegin() { + echo "::group::${1}" +} +infoend() { + echo "::endgroup::" +} + +# Run meson first, then run autotools +# Because meson dist requires a clean git workspace +# Autotools will modify some files (such as po, etc.), making them dirty. +if [[ -f meson.build && $1 == "meson" ]]; then + + infobegin "Configure (meson)" + meson setup _build --prefix=/usr + infoend + + infobegin "Build (meson)" + meson compile -C _build + infoend + + infobegin "Test (meson)" + ninja -C _build test + infoend + + infobegin "Dist (meson)" + # Git safedirectory stop ninja dist + # https://github.com/git/git/commit/8959555cee7ec045958f9b6dd62e541affb7e7d9 + # https://git-scm.com/docs/git-config/2.35.2#Documentation/git-config.txt-safedirectory + git config --global --add safe.directory ${PWD} + ninja -C _build dist + infoend +fi + +if [[ -f autogen.sh && $1 == "autotools" ]]; then + infobegin "Configure (autotools)" + NOCONFIGURE=1 ./autogen.sh + ./configure --prefix=/usr --enable-compile-warnings=maximum || { + cat config.log + exit 1 + } + infoend + + infobegin "Build (autotools)" + make -j ${CPUS} + infoend + + infobegin "Check (autotools)" + make -j ${CPUS} check || { + find -name test-suite.log -exec cat {} \; + exit 1 + } + infoend + + infobegin "Distcheck (autotools)" + make -j ${CPUS} distcheck + infoend +fi diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml new file mode 100644 index 0000000..987c7f6 --- /dev/null +++ b/.github/workflows/builds.yml @@ -0,0 +1,100 @@ +name: CI Build + +on: + push: + branches: + - master + pull_request: + branches: + - master + workflow_dispatch: + +# cancel already running builds of the same branch or pull request +concurrency: + group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.head_ref || github.sha }} + cancel-in-progress: true + +env: + MATE_DESKTOP_VERSION: 1.28.2 + CACHE_PATH: /tmp/.cache + +jobs: + build: + name: ${{matrix.container}} (${{matrix.cc}} ${{matrix.build-system}}) + runs-on: ubuntu-latest + container: + image: ${{matrix.container}} + volumes: + - /tmp/.cache + - /var/cache/apt + + strategy: + fail-fast: false # don't cancel other jobs in the matrix if one fails + matrix: + container: + [ + "debian:testing", + "fedora:latest", + "ubuntu:rolling", + "archlinux:latest", + ] + cc: ["gcc"] + cxx: ["g++"] + build-system: ["autotools", "meson"] + include: + - container: "archlinux:latest" + build-system: "autotools" + cc: "clang" + cxx: "clang++" + - container: "archlinux:latest" + build-system: "meson" + cc: "clang" + cxx: "clang++" + + env: + # Speed up build with ccache + CC: ccache ${{ matrix.cc }} + CXX: ccache ${{ matrix.cxx }} + CONTAINER: ${{ matrix.container }} + + steps: + - name: Setup environment variables + id: distro-name + shell: bash + run: | + split=(${CONTAINER//:/ }) + distro=${split[0]} + short_sha=${SHA:0:8} + echo "DISTRO=$distro" | tee -a $GITHUB_ENV + - name: Install git command + shell: bash + run: | + echo "::group::Install git ..." + apt-get update -qq && apt-get install --assume-yes git || true + dnf update -y && dnf install -y git || true + pacman --noconfirm -Sy git || true + echo "::endgroup::" + - name: Repository checkout + uses: actions/checkout@v4 + with: + submodules: "true" + - name: Install dependency packages + run: .github/workflows/${{ env.DISTRO }}.sh + - name: Enable ccache to speed up builds + uses: hendrikmuhs/[email protected] + with: + key: ${{ env.DISTRO }}-${{ matrix.cc }} + + # INFO: M-C-C depends mate-desktop 1.27.1+, so we should install it from source. + - name: Cache mate-desktop binary packages + uses: actions/cache@v3 + id: cache-mate-desktop + with: + path: ${{ env.CACHE_PATH }} + key: ${{ env.DISTRO }}-build-mate-desktop-${{env.MATE_DESKTOP_VERSION}} + - name: Built and install mate-desktop from source + run: .github/workflows/mate-desktop.sh ${{env.MATE_DESKTOP_VERSION}} ${{ env.CACHE_PATH }} + # INFO: M-C-C depends mate-desktop 1.27.1+, install finished. + + - name: Build the source code + run: .github/workflows/builds.sh ${{ matrix.build-system }} diff --git a/.github/workflows/debian.sh b/.github/workflows/debian.sh new file mode 100755 index 0000000..a13e69c --- /dev/null +++ b/.github/workflows/debian.sh @@ -0,0 +1,54 @@ +#!/usr/bin/bash + +# Use grouped output messages +infobegin() { + echo "::group::${1}" +} +infoend() { + echo "::endgroup::" +} + +# Required packages on Debian +requires=( + ccache # Use ccache to speed up build + meson # Used for meson build +) + +# https://salsa.debian.org/debian-mate-team/mate-power-manager/-/blob/master/debian/control +requires+=( + appstream + autoconf-archive + autopoint + gcc + git + libcanberra-gtk3-dev + libdbus-glib-1-dev + libgcrypt20-dev + libglib2.0-dev + libgtk-3-dev + libmate-panel-applet-dev + libnotify-dev + libpolkit-gobject-1-dev + libsecret-1-dev + libtool-bin + libupower-glib-dev + libx11-dev + libxext-dev + libxml-parser-perl + libxrandr-dev + make + mate-common + pkg-config + xmlto + yelp-tools +) + +infobegin "Update system" +apt-get update -qq +infoend + +infobegin "Install dependency packages" +env DEBIAN_FRONTEND=noninteractive \ + apt-get install --assume-yes \ + ${requires[@]} +infoend diff --git a/.github/workflows/fedora.sh b/.github/workflows/fedora.sh new file mode 100755 index 0000000..cf6663c --- /dev/null +++ b/.github/workflows/fedora.sh @@ -0,0 +1,49 @@ +#!/usr/bin/bash + +# Use grouped output messages +infobegin() { + echo "::group::${1}" +} +infoend() { + echo "::endgroup::" +} + +# Required packages on Fedora +requires=( + ccache # Use ccache to speed up build + meson # Used for meson build +) + +# https://src.fedoraproject.org/rpms/mate-power-manager/blob/rawhide/f/mate-power-manager.spec +requires+=( + autoconf-archive + gcc + git + make + mate-common + mate-panel-devel + cairo-devel + dbus-glib-devel + desktop-file-utils + glib2-devel + gtk3-devel + libcanberra-devel + libnotify-devel + libsecret-devel + make + mate-common + mate-desktop-devel + mate-panel-devel + mesa-libGL-devel + polkit-devel + popt-devel + upower-devel +) + +infobegin "Update system" +dnf update -y +infoend + +infobegin "Install dependency packages" +dnf install -y ${requires[@]} +infoend diff --git a/.github/workflows/mate-desktop.sh b/.github/workflows/mate-desktop.sh new file mode 100755 index 0000000..f4b5fe6 --- /dev/null +++ b/.github/workflows/mate-desktop.sh @@ -0,0 +1,146 @@ +#!/usr/bin/bash + +set -e +set -o pipefail + +NAME="mate-desktop" +TEMP_DIR=$(mktemp -d) +OS=$(cat /etc/os-release | grep ^ID | head -n 1 | awk -F= '{ print $2}') +TAG=$1 +CACHE_DIR=$2 + +# Use grouped output messages +infobegin() { + echo "::group::${1}" +} +infoend() { + echo "::endgroup::" +} + +# Required packages to build mate-desktop +# https://gitlab.archlinux.org/archlinux/packaging/packages/mate-desktop +arch_requires=( + autoconf-archive + gobject-introspection + mate-common + intltool +) + +# https://salsa.debian.org/debian-mate-team/mate-desktop/-/blob/master/debian/control +debian_requires=( + autoconf-archive + gobject-introspection + gtk-doc-tools + intltool + iso-codes + libdconf-dev + libgdk-pixbuf-2.0-dev + libgirepository1.0-dev + libglib2.0-dev + libglib2.0-doc + libgtk-3-dev + libgtk-3-doc + librsvg2-bin + libstartup-notification0-dev + libx11-dev + libxml2-dev + libxrandr-dev + mate-common +) + +# https://src.fedoraproject.org/rpms/mate-desktop/blob/rawhide/f/mate-desktop.spec +fedora_requires=( + dconf-devel + desktop-file-utils + gobject-introspection-devel + make + mate-common + startup-notification-devel + gtk3-devel + iso-codes-devel + gobject-introspection-devel + cairo-gobject-devel +) + +# https://git.launchpad.net/ubuntu/+source/mate-desktop/tree/debian/control +ubuntu_requires=( + autoconf-archive + gobject-introspection + gtk-doc-tools + intltool + iso-codes + libdconf-dev + libgdk-pixbuf-2.0-dev + libgirepository1.0-dev + libglib2.0-dev + libglib2.0-doc + libgtk-3-dev + libgtk-3-doc + librsvg2-bin + libstartup-notification0-dev + libx11-dev + libxml2-dev + libxrandr-dev + mate-common +) + +requires=$(eval echo '${'"${OS}_requires[@]}") + +infobegin "Install Depends for mate-desktop" +case ${OS} in +arch) + pacman --noconfirm -Syu + pacman --noconfirm -S ${requires[@]} + ;; +debian | ubuntu) + apt-get update -qq + env DEBIAN_FRONTEND=noninteractive \ + apt-get install --assume-yes --no-install-recommends ${requires[@]} + ;; +fedora) + dnf update -y + dnf install -y ${requires[@]} + ;; +esac +infoend + +# Use cached packages first +if [ -f $CACHE_DIR/${NAME}-${TAG}.tar.xz ]; then + echo "Found cache package, reuse it" + tar -C / -Jxf $CACHE_DIR/${NAME}-${TAG}.tar.xz +else + git clone --recurse-submodules https://github.com/mate-desktop/${NAME} + + # Foldable output information + infobegin "Configure" + cd ${NAME} + git checkout v${TAG} + if [[ ${OS} == "debian" || ${OS} == "ubuntu" ]]; then + ./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu --libexecdir=/usr/lib/x86_64-linux-gnu || { + cat config.log + exit 1 + } + else + ./autogen.sh --prefix=/usr || { + cat config.log + exit 1 + } + fi + infoend + + infobegin "Build" + make -j ${JOBS} + infoend + + infobegin "Install" + make install + infoend + + # Cache this package version + infobegin "Cache" + [ -d ${CACHE_DIR} ] || mkdir -p ${CACHE_DIR} + make install DESTDIR=${TEMP_DIR} + cd $TEMP_DIR + tar -J -cf $CACHE_DIR/${NAME}-${TAG}.tar.xz * + infoend +fi 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 new file mode 100644 index 0000000..2b97dc4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Release Version +on: + push: + tags: + - "v*.*.*" + +env: + MATE_DESKTOP_VERSION: 1.28.2 + CACHE_PATH: /tmp/.cache + +jobs: + release: + name: Release New Version + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Repository checkout + uses: actions/checkout@v4 + with: + submodules: "true" + + - name: Install dependency packages + run: sudo .github/workflows/ubuntu.sh + + - name: Install higher version Mate component packages + run: sudo .github/workflows/mate-desktop.sh ${{env.MATE_DESKTOP_VERSION}} ${{ env.CACHE_PATH }} + + - name: Build the source code + run: .github/workflows/builds.sh autotools + + - name: Install GH CLI + uses: dev-hanz-ops/[email protected] + with: + gh-cli-version: 2.72.0 + + - name: Create github release + run: | + .github/workflows/release.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + API_SECRET: ${{ secrets.API_SECRET }} diff --git a/.github/workflows/ubuntu.sh b/.github/workflows/ubuntu.sh new file mode 100755 index 0000000..06ed364 --- /dev/null +++ b/.github/workflows/ubuntu.sh @@ -0,0 +1,52 @@ +#!/usr/bin/bash + +# Use grouped output messages +infobegin() { + echo "::group::${1}" +} +infoend() { + echo "::endgroup::" +} + +# Required packages on Ubuntu +requires=( + ccache # Use ccache to speed up build + meson # Used for meson build +) + +# https://git.launchpad.net/ubuntu/+source/mate-power-manager/tree/debian/control +requires+=( + autoconf-archive + autopoint + gcc + git + libcanberra-gtk3-dev + libdbus-glib-1-dev + libgcrypt20-dev + libglib2.0-dev + libgtk-3-dev + libmate-panel-applet-dev + libnotify-dev + libsecret-1-dev + libtool-bin + libupower-glib-dev + libx11-dev + libxext-dev + libxml-parser-perl + libxrandr-dev + make + mate-common + pkg-config + xmlto + yelp-tools +) + +infobegin "Update system" +apt-get update -y +infoend + +infobegin "Install dependency packages" +env DEBIAN_FRONTEND=noninteractive \ + apt-get install --assume-yes \ + ${requires[@]} +infoend |