name: DMS Copr Stable Release on: workflow_dispatch: inputs: version: description: 'Versioning (e.g., 0.1.14, leave empty for latest release)' required: false default: '' release: description: 'Release number (e.g., 1, 2, 3 for hotfixes)' required: false default: '1' jobs: build-and-upload: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Determine version id: version run: | # Get version from manual input or latest release if [ -n "${{ github.event.inputs.version }}" ]; then VERSION="${{ github.event.inputs.version }}" echo "Using manual version: $VERSION" else VERSION=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r '.tag_name' | sed 's/^v//') echo "Using latest release version: $VERSION" fi RELEASE="${{ github.event.inputs.release }}" if [ -z "$RELEASE" ]; then RELEASE="1" fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "release=$RELEASE" >> $GITHUB_OUTPUT echo "✅ Building DMS hotfix version: $VERSION-$RELEASE" - name: Setup build environment run: | sudo apt-get update sudo apt-get install -y rpm wget curl jq gzip mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} echo "✅ RPM build environment ready" - name: Download release assets run: | VERSION="${{ steps.version.outputs.version }}" cd ~/rpmbuild/SOURCES echo "📦 Downloading DMS QML source for v${VERSION}..." # Download DMS QML source wget "https://github.com/AvengeMedia/DankMaterialShell/releases/download/v${VERSION}/dms-qml.tar.gz" || { echo "❌ Failed to download dms-qml.tar.gz for v${VERSION}" exit 1 } echo "✅ Source downloaded" echo "Note: dms-cli and dgop binaries will be downloaded during build based on target architecture" ls -lh - name: Generate stable spec file run: | VERSION="${{ steps.version.outputs.version }}" RELEASE="${{ steps.version.outputs.release }}" CHANGELOG_DATE="$(date '+%a %b %d %Y')" cat > ~/rpmbuild/SPECS/dms.spec <<'SPECEOF' # Spec for DMS stable releases - Generated by GitHub Actions %global debug_package %{nil} %global version VERSION_PLACEHOLDER %global pkg_summary DankMaterialShell - Material 3 inspired shell for Wayland compositors Name: dms Version: %{version} Release: RELEASE_PLACEHOLDER%{?dist} Summary: %{pkg_summary} License: MIT URL: https://github.com/AvengeMedia/DankMaterialShell Source0: dms-qml.tar.gz BuildRequires: gzip BuildRequires: wget BuildRequires: systemd-rpm-macros Requires: (quickshell or quickshell-git) Requires: accountsservice Requires: dms-cli Requires: dgop Recommends: cava Recommends: cliphist Recommends: danksearch Recommends: hyprpicker Recommends: matugen Recommends: wl-clipboard Recommends: NetworkManager Recommends: qt6-qtmultimedia Suggests: qt6ct %description DankMaterialShell (DMS) is a modern Wayland desktop shell built with Quickshell and optimized for the niri and hyprland compositors. Features notifications, app launcher, wallpaper customization, and fully customizable with plugins. Includes auto-theming for GTK/Qt apps with matugen, 20+ customizable widgets, process monitoring, notification center, clipboard history, dock, control center, lock screen, and comprehensive plugin system. %package -n dms-cli Summary: DankMaterialShell CLI tool License: MIT URL: https://github.com/AvengeMedia/DankMaterialShell %description -n dms-cli Command-line interface for DankMaterialShell configuration and management. Provides native DBus bindings, NetworkManager integration, and system utilities. %package -n dgop Summary: Stateless CPU/GPU monitor for DankMaterialShell License: MIT URL: https://github.com/AvengeMedia/dgop Provides: dgop %description -n dgop DGOP is a stateless system monitoring tool that provides CPU, GPU, memory, and network statistics. Designed for integration with DankMaterialShell but can be used standalone. This package always includes the latest stable dgop release. %prep %setup -q -c -n dms-qml # Download architecture-specific binaries during build # This ensures the correct architecture is used for each build target case "%{_arch}" in x86_64) ARCH_SUFFIX="amd64" ;; aarch64) ARCH_SUFFIX="arm64" ;; *) echo "Unsupported architecture: %{_arch}" exit 1 ;; esac # Download dms-cli for target architecture wget -O %{_builddir}/dms-cli.gz "https://github.com/AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-${ARCH_SUFFIX}.gz" || { echo "Failed to download dms-cli for architecture %{_arch}" exit 1 } gunzip -c %{_builddir}/dms-cli.gz > %{_builddir}/dms-cli chmod +x %{_builddir}/dms-cli # Download dgop for target architecture wget -O %{_builddir}/dgop.gz "https://github.com/AvengeMedia/dgop/releases/latest/download/dgop-linux-${ARCH_SUFFIX}.gz" || { echo "Failed to download dgop for architecture %{_arch}" exit 1 } gunzip -c %{_builddir}/dgop.gz > %{_builddir}/dgop chmod +x %{_builddir}/dgop %build %install install -Dm755 %{_builddir}/dms-cli %{buildroot}%{_bindir}/dms install -Dm755 %{_builddir}/dgop %{buildroot}%{_bindir}/dgop # Shell completions install -d %{buildroot}%{_datadir}/bash-completion/completions install -d %{buildroot}%{_datadir}/zsh/site-functions install -d %{buildroot}%{_datadir}/fish/vendor_completions.d %{_builddir}/dms-cli completion bash > %{buildroot}%{_datadir}/bash-completion/completions/dms || : %{_builddir}/dms-cli completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || : %{_builddir}/dms-cli completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || : install -Dm644 %{_builddir}/dms-qml/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service install -dm755 %{buildroot}%{_datadir}/quickshell/dms cp -r %{_builddir}/dms-qml/* %{buildroot}%{_datadir}/quickshell/dms/ rm -rf %{buildroot}%{_datadir}/quickshell/dms/.git* rm -f %{buildroot}%{_datadir}/quickshell/dms/.gitignore rm -rf %{buildroot}%{_datadir}/quickshell/dms/.github rm -rf %{buildroot}%{_datadir}/quickshell/dms/distro %posttrans # Clean up old installation path from previous versions (only if empty) if [ -d "%{_sysconfdir}/xdg/quickshell/dms" ]; then # Remove directories only if empty (preserves any user-added files) rmdir "%{_sysconfdir}/xdg/quickshell/dms" 2>/dev/null || true rmdir "%{_sysconfdir}/xdg/quickshell" 2>/dev/null || true rmdir "%{_sysconfdir}/xdg" 2>/dev/null || true fi # Restart DMS for active users after upgrade if [ "$1" -ge 2 ]; then pkill -USR1 -x dms >/dev/null 2>&1 || true fi %files %license LICENSE %doc README.md CONTRIBUTING.md %{_datadir}/quickshell/dms/ %{_userunitdir}/dms.service %files -n dms-cli %{_bindir}/dms %{_datadir}/bash-completion/completions/dms %{_datadir}/zsh/site-functions/_dms %{_datadir}/fish/vendor_completions.d/dms.fish %files -n dgop %{_bindir}/dgop %changelog * CHANGELOG_DATE_PLACEHOLDER AvengeMedia - VERSION_PLACEHOLDER-RELEASE_PLACEHOLDER - Stable release VERSION_PLACEHOLDER - Built from GitHub release - Includes latest dms-cli and dgop binaries SPECEOF sed -i "s/VERSION_PLACEHOLDER/${VERSION}/g" ~/rpmbuild/SPECS/dms.spec sed -i "s/RELEASE_PLACEHOLDER/${RELEASE}/g" ~/rpmbuild/SPECS/dms.spec sed -i "s/CHANGELOG_DATE_PLACEHOLDER/${CHANGELOG_DATE}/g" ~/rpmbuild/SPECS/dms.spec echo "✅ Spec file generated for v${VERSION}-${RELEASE}" echo "" echo "=== Spec file preview ===" head -40 ~/rpmbuild/SPECS/dms.spec - name: Build SRPM id: build run: | cd ~/rpmbuild/SPECS echo "🔨 Building SRPM..." rpmbuild -bs dms.spec SRPM=$(ls ~/rpmbuild/SRPMS/*.src.rpm | tail -n 1) SRPM_NAME=$(basename "$SRPM") echo "srpm_path=$SRPM" >> $GITHUB_OUTPUT echo "srpm_name=$SRPM_NAME" >> $GITHUB_OUTPUT echo "✅ SRPM built: $SRPM_NAME" echo "" echo "=== SRPM Info ===" rpm -qpi "$SRPM" - name: Upload SRPM artifact uses: actions/upload-artifact@v4 with: name: dms-stable-srpm-${{ steps.version.outputs.version }} path: ${{ steps.build.outputs.srpm_path }} retention-days: 90 - name: Install Copr CLI run: | sudo apt-get install -y python3-pip pip3 install copr-cli mkdir -p ~/.config cat > ~/.config/copr << EOF [copr-cli] login = ${{ secrets.COPR_LOGIN }} username = avengemedia token = ${{ secrets.COPR_TOKEN }} copr_url = https://copr.fedorainfracloud.org EOF chmod 600 ~/.config/copr echo "✅ Copr CLI configured" - name: Upload to Copr run: | SRPM="${{ steps.build.outputs.srpm_path }}" VERSION="${{ steps.version.outputs.version }}" echo "🚀 Uploading SRPM to avengemedia/dms..." echo " SRPM: $(basename $SRPM)" echo " Version: $VERSION" BUILD_OUTPUT=$(copr-cli build avengemedia/dms "$SRPM" --nowait 2>&1) echo "$BUILD_OUTPUT" BUILD_ID=$(echo "$BUILD_OUTPUT" | grep -oP 'Build was added to.*\K[0-9]+' || echo "unknown") if [ "$BUILD_ID" != "unknown" ]; then echo "✅ Build submitted successfully!" echo "🔗 https://copr.fedorainfracloud.org/coprs/avengemedia/dms/build/$BUILD_ID/" else echo "⚠️ Could not extract build ID, but upload may have succeeded" fi - name: Build summary if: always() run: | echo "### 🎉 DMS Stable Build Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "- **Version:** ${{ steps.version.outputs.version }}-${{ steps.version.outputs.release }}" >> $GITHUB_STEP_SUMMARY echo "- **SRPM:** ${{ steps.build.outputs.srpm_name }}" >> $GITHUB_STEP_SUMMARY echo "- **Project:** https://copr.fedorainfracloud.org/coprs/avengemedia/dms/" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Stable release has been built and uploaded to Copr!" >> $GITHUB_STEP_SUMMARY