Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions .github/workflows/build-gnome50-verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: Verify GNOME 50 Repo

on:
workflow_run:
workflows: ["GNOME 50 Distributed Build and Publish"]
types: [completed]
workflow_dispatch:

jobs:
verify-repo:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
steps:
- name: Check repomd.xml is accessible
run: |
STATUS=$(curl -sI https://repo.tunaos.org/repo/10-stream-x86_64/repodata/repomd.xml | head -1 | grep -o '[0-9]*' | head -1)
echo "HTTP status: ${STATUS}"
[[ "${STATUS}" == "200" ]] || (echo "ERROR: Repo not accessible!" && exit 1)

- name: Verify packages installable in CentOS Stream 10 container
run: |
cat > /tmp/verify.sh << 'EOF'
#!/bin/bash
set -e
dnf -y install dnf-plugins-core curl
curl -sSL https://repo.tunaos.org/install.sh | bash
dnf -y --nogpgcheck install gnome50-el10-compat glib2 gnome-shell gdm
rpm -q gnome50-el10-compat glib2 gnome-shell gdm
echo "PACKAGE VERIFICATION PASSED"
EOF
chmod +x /tmp/verify.sh
podman run --rm -v /tmp/verify.sh:/verify.sh:ro \
quay.io/centos/centos:stream10 bash /verify.sh

verify-gdm:
runs-on: ubuntu-latest
timeout-minutes: 45
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
steps:
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
ls -la /dev/kvm

- name: Install QEMU and Lima
run: |
sudo apt-get update -q
sudo apt-get install -y -q qemu-system-x86 qemu-utils ovmf
LIMA_VERSION=$(curl -s https://api.github.com/repos/lima-vm/lima/releases/latest | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])")
echo "Installing Lima ${LIMA_VERSION}"
curl -fsSL "https://github.com/lima-vm/lima/releases/download/${LIMA_VERSION}/lima-${LIMA_VERSION#v}-linux-amd64.tar.gz" | sudo tar xz -C /usr/local
limactl --version

- name: Install vncdotool
run: pip install vncdotool

- name: Create Lima VM config
run: |
cat > /tmp/gnome50-verify.yaml << 'EOF'
vmType: qemu
arch: x86_64
cpus: 2
memory: 4GiB
disk: 20GiB

video:
display: "vnc"
vga: "std"

images:
- location: "https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-x86_64-10-latest.x86_64.qcow2"
arch: x86_64

mounts: []

ssh:
localPort: 0
loadDotSSHPubKeys: false

provision:
- mode: system
script: |
#!/bin/bash
set -euxo pipefail
dnf -y install dnf-plugins-core
dnf copr enable -y jreilly1821/c10s-gnome-50
dnf -y install \
gnome-shell \
gnome-control-center \
mutter \
gdm \
gnome-session-wayland-session \
glib2
glib-compile-schemas /usr/share/glib-2.0/schemas/
printf '[daemon]\nWaylandEnable=true\n' > /etc/gdm/custom.conf
systemctl enable gdm
systemctl set-default graphical.target
EOF

- name: Start Lima VM
run: |
limactl start --name=gnome50-verify /tmp/gnome50-verify.yaml --timeout=25m
echo "VM started"

- name: Wait for GDM to become active
run: |
echo "Waiting for GDM to start (up to 5 minutes)..."
for i in $(seq 1 30); do
STATUS=$(limactl shell gnome50-verify -- systemctl is-active gdm 2>/dev/null || echo "inactive")
echo "Attempt $i/30: gdm is ${STATUS}"
[[ "${STATUS}" == "active" ]] && break
sleep 10
done
if [[ "${STATUS}" != "active" ]]; then
echo "ERROR: GDM failed to become active"
limactl shell gnome50-verify -- journalctl -u gdm --no-pager -n 50 || true
exit 1
fi

- name: Check GDM and GNOME Shell status
run: |
limactl shell gnome50-verify -- systemctl status gdm --no-pager
limactl shell gnome50-verify -- rpm -q gdm gnome-shell mutter glib2
limactl shell gnome50-verify -- gdm --version

- name: Take login screen screenshot via VNC
run: |
# Lima exposes VNC — find the port from the QEMU process
VNC_DISPLAY=$(cat /proc/$(pgrep -f 'qemu.*gnome50-verify' | head -1)/cmdline \
| tr '\0' '\n' | grep -oP '(?<=vnc=127\.0\.0\.1:)\d+' || echo "0")
VNC_PORT=$((5900 + ${VNC_DISPLAY:-0}))
echo "VNC port: ${VNC_PORT}"
# Give the display a moment to settle after GDM starts
sleep 5
python3 - <<PYEOF
from vncdotool import api
client = api.connect('127.0.0.1', password='', port=${VNC_PORT})
client.captureScreen('gdm-login-screen.png')
client.disconnect()
print("Screenshot captured")
PYEOF

- name: Upload login screen screenshot
uses: actions/upload-artifact@v4
if: always()
with:
name: gdm-login-screen
path: gdm-login-screen.png
retention-days: 7

- name: Stop Lima VM
if: always()
run: limactl stop gnome50-verify --force || true
86 changes: 54 additions & 32 deletions build-order.yml
Original file line number Diff line number Diff line change
@@ -1,101 +1,123 @@
# Build Order Manifest for GNOME 50 on CentOS Stream 10
#
# Packages within a tier build in parallel; tiers are sequential.
# Each package entry is a path relative to the repo root (directory containing
# the spec file and sources). Use `spec_override` to pick a non-default spec
# (e.g. bootstrap variants).
# Each package entry is a path relative to the repo root.

target: centos-stream-10-x86_64

tiers:
# Tier 0: packages that only need base CentOS Stream 10 + EPEL to build.
# Nothing here may depend on a package from this repo.
# Tier 0: Pure build tools with zero internal dependencies.
- name: base-tools
packages:
- path: src/deps/meson
build_tool: true
- path: src/deps/autoconf
build_tool: true
- path: src/deps/libldac
- path: src/deps/python-smartypants
build_tool: true
- path: src/deps/python-typogrify
build_tool: true
- path: src/deps/gnome50-el10-compat
- path: src/deps/selinux-policy

# Tier 1: packages that need meson or autoconf from tier 0.
# Tier 1: Needs tools from Tier 0.
- name: build-tools
packages:
- path: src/deps/wayland-protocols
- path: src/deps/icu
spec_override: libicu77-bootstrap.spec
build_tool: true
- path: src/deps/harfbuzz
build_tool: true
- path: src/deps/libxcvt
build_tool: true
- path: src/deps/shaderc
- path: src/deps/umockdev
- path: src/deps/python-dbusmock
build_tool: true
- path: src/deps/gi-docgen
- path: src/deps/avahi

- name: icu-full
packages:
- path: src/deps/icu
spec_override: libicu77.spec
build_tool: true

# Tier 3: Bootstrap GLib.
- name: glib2-bootstrap
packages:
- path: src/gnome-50/glib2
spec_override: glib2-bootstrap.spec

# Tier 4: Base libraries needing GLib bootstrap.
- name: bootstrap-libs
packages:
- path: src/deps/libei
- path: src/deps/mozjs140
- path: src/deps/libzip
- path: src/deps/fontconfig

# Tier 5: Cairo (Needs GLib bootstrap).
- name: cairo-layer
packages:
- path: src/deps/cairo

# Tier 6: GI Bootstrap (Needs Cairo).
- name: gi-bootstrap
packages:
- path: src/gnome-50/gobject-introspection
spec_override: gobject-introspection-bootstrap.spec

# Tier 7: Full GLib (Needs GI Bootstrap).
- name: glib2-full
packages:
- path: src/gnome-50/glib2

# Tier 8: Full GI (Needs Full GLib).
- name: gi-full
packages:
- path: src/gnome-50/gobject-introspection

- name: low-level-libs
# Tier 9: High-level libraries/tools needing GI/GLib full.
- name: core-libraries
packages:
- path: src/deps/fontconfig
- path: src/deps/cairo
- path: src/deps/pango
- path: src/deps/libei
- path: src/deps/mozjs140
- path: src/deps/tinysparql
- path: src/deps/pipewire

- name: gjs
# Tier 10: System Tools & GJS.
- name: system-tools
packages:
- path: src/deps/umockdev
build_tool: true
- path: src/deps/python-dbusmock
build_tool: true
- path: src/deps/avahi
- path: src/gnome-50/gjs

- name: gtk-layer
# Tier 11: GTK Core.
- name: gtk-core
packages:
- path: src/gnome-50/gsettings-desktop-schemas
- path: src/gnome-50/gnome-desktop3
- path: src/deps/gtk4
- path: src/deps/glycin

- name: libadwaita
# Tier 12: Desktop Foundations.
- name: desktop-foundations
packages:
- path: src/gnome-50/libadwaita
- path: src/gnome-50/xdg-desktop-portal
- path: src/gnome-50/nautilus
- path: src/deps/localsearch

- name: compositor
# Tier 13: Compositor & Shell.
- name: shell-foundations
packages:
- path: src/gnome-50/gnome-settings-daemon
- path: src/gnome-50/mutter
- path: src/gnome-50/xdg-desktop-portal-gnome

- name: shell
# Tier 14: The Shell and Portal integration.
- name: gnome-shell
packages:
- path: src/gnome-50/gnome-shell
- path: src/gnome-50/gnome-settings-daemon
- path: src/gnome-50/xdg-desktop-portal
- path: src/gnome-50/xdg-desktop-portal-gnome
- path: src/gnome-50/nautilus

- name: session
# Tier 15: Session & Control Center.
- name: session-layer
packages:
- path: src/gnome-50/gnome-session
- path: src/gnome-50/gnome-control-center
- path: src/gnome-50/gdm
- path: src/gnome-50/xdg-desktop-portal-gnome
52 changes: 32 additions & 20 deletions scripts/fetch_rawhide_specs.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,62 @@
import subprocess
import os
import sys
import argparse

def clone_package(package_name, dest_dir):
def clone_package(package_name, dest_dir, branch="rawhide"):
"""
Clones a package from Fedora Dist-Git via HTTPS.
Clones a package from Fedora Dist-Git via HTTPS with specific branch.
"""
pkg_dir = os.path.join(dest_dir, package_name)
if os.path.exists(pkg_dir):
print(f" Directory {pkg_dir} already exists, skipping clone.")
return True
# If it exists, try to switch branch or just pull
print(f" Directory {pkg_dir} already exists. Attempting to switch to {branch}...")
try:
subprocess.run(["git", "-C", pkg_dir, "fetch", "origin", branch, "--depth", "1"], capture_output=True)
result = subprocess.run(["git", "-C", pkg_dir, "checkout", branch], capture_output=True, text=True)
if result.returncode == 0:
return True
except Exception as e:
print(f" Error switching branch for {package_name}: {e}", file=sys.stderr)
return False

url = f"https://src.fedoraproject.org/rpms/{package_name}.git"
command = ["git", "clone", url, pkg_dir, "--depth", "1"]
command = ["git", "clone", "-b", branch, url, pkg_dir, "--depth", "1"]
try:
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode == 0:
return True
else:
print(f" Error cloning {package_name}: {result.stderr}", file=sys.stderr)
# Fallback to rawhide if branch doesn't exist?
# No, user asked for f43 specifically.
print(f" Error cloning {package_name} branch {branch}: {result.stderr}", file=sys.stderr)
return False
except Exception as e:
print(f" Exception cloning {package_name}: {e}", file=sys.stderr)
return False

def main():
if len(sys.argv) < 3:
print("Usage: python3 fetch_rawhide_specs.py <manifest_file> <dest_dir>")
sys.exit(1)
manifest_file = sys.argv[1]
dest_dir = sys.argv[2]
parser = argparse.ArgumentParser(description="Fetch Fedora specs for a list of packages.")
parser.add_argument("manifest", help="Path to a file containing package names (one per line)")
parser.add_argument("dest", help="Destination directory for cloned repositories")
parser.add_argument("-b", "--branch", default="rawhide", help="Branch to fetch (e.g., f43, f42, rawhide)")

args = parser.parse_args()

if not os.path.exists(manifest_file):
print(f"Manifest file {manifest_file} not found")
if not os.path.exists(args.manifest):
print(f"Manifest file {args.manifest} not found")
sys.exit(1)

if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
if not os.path.exists(args.dest):
os.makedirs(args.dest)

with open(manifest_file, 'r') as f:
packages = [line.strip() for line in f if line.strip()]
with open(args.manifest, 'r') as f:
packages = [line.strip() for line in f if line.strip() and not line.startswith('#')]

print(f"Fetching specifications from branch '{args.branch}'...")
for pkg in packages:
print(f"Fetching specification for {pkg}...")
clone_package(pkg, dest_dir)
print(f"Fetching {pkg}...")
clone_package(pkg, args.dest, args.branch)

if __name__ == "__main__":
main()
Loading
Loading