diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d9102d6..49dd3c99 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -386,6 +386,68 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + trigger-obs-update: + runs-on: ubuntu-latest + needs: release + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install OSC + run: | + sudo apt-get update + sudo apt-get install -y osc + + mkdir -p ~/.config/osc + cat > ~/.config/osc/oscrc << EOF + [general] + apiurl = https://api.opensuse.org + + [https://api.opensuse.org] + user = ${{ secrets.OBS_USERNAME }} + pass = ${{ secrets.OBS_PASSWORD }} + EOF + chmod 600 ~/.config/osc/oscrc + + - name: Update OBS packages + run: | + VERSION="${{ github.ref_name }}" + cd distro + bash scripts/obs-upload.sh dms "Update to $VERSION" + + trigger-ppa-update: + runs-on: ubuntu-latest + needs: release + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + debhelper \ + devscripts \ + dput \ + lftp \ + build-essential \ + fakeroot \ + dpkg-dev + + - name: Configure GPG + env: + GPG_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + run: | + echo "$GPG_KEY" | gpg --import + GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | awk '{print $2}' | cut -d'/' -f2) + echo "DEBSIGN_KEYID=$GPG_KEY_ID" >> $GITHUB_ENV + + - name: Upload to PPA + run: | + VERSION="${{ github.ref_name }}" + cd distro/ubuntu/ppa + bash create-and-upload.sh ../dms dms questing + copr-build: runs-on: ubuntu-latest needs: release diff --git a/.github/workflows/copr-release.yml b/.github/workflows/run-copr.yml similarity index 100% rename from .github/workflows/copr-release.yml rename to .github/workflows/run-copr.yml diff --git a/.github/workflows/run-obs.yml b/.github/workflows/run-obs.yml new file mode 100644 index 00000000..8e249c44 --- /dev/null +++ b/.github/workflows/run-obs.yml @@ -0,0 +1,108 @@ +name: Update OBS Packages + +on: + workflow_dispatch: + inputs: + package: + description: 'Package to update (dms, dms-git, or all)' + required: false + default: 'all' + push: + tags: + - 'v*' + schedule: + - cron: '0 */3 * * *' # Every 3 hours for dms-git builds + +jobs: + update-obs: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine packages to update + id: packages + run: | + if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" =~ ^refs/tags/ ]]; then + echo "packages=dms" >> $GITHUB_OUTPUT + VERSION="${GITHUB_REF#refs/tags/}" + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Triggered by tag: $VERSION" + elif [[ "${{ github.event_name }}" == "schedule" ]]; then + echo "packages=dms-git" >> $GITHUB_OUTPUT + echo "Triggered by schedule: updating git package" + elif [[ -n "${{ github.event.inputs.package }}" ]]; then + echo "packages=${{ github.event.inputs.package }}" >> $GITHUB_OUTPUT + echo "Manual trigger: ${{ github.event.inputs.package }}" + else + echo "packages=all" >> $GITHUB_OUTPUT + fi + + - name: Update version in packaging files + if: steps.packages.outputs.version != '' + run: | + VERSION="${{ steps.packages.outputs.version }}" + VERSION_NO_V="${VERSION#v}" + echo "Updating packaging to version $VERSION_NO_V" + + # Update openSUSE spec files + sed -i "s/^Version:.*/Version: $VERSION_NO_V/" distro/opensuse/*.spec + + # Update Debian _service files + for service in distro/debian/*/_service; do + if [[ -f "$service" ]]; then + sed -i "s|v[0-9.]*|$VERSION|" "$service" + fi + done + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add distro/ + git commit -m "chore: update packaging to $VERSION" || echo "No changes to commit" + + - name: Install OSC + run: | + sudo apt-get update + sudo apt-get install -y osc + + mkdir -p ~/.config/osc + cat > ~/.config/osc/oscrc << EOF + [general] + apiurl = https://api.opensuse.org + + [https://api.opensuse.org] + user = ${{ secrets.OBS_USERNAME }} + pass = ${{ secrets.OBS_PASSWORD }} + EOF + chmod 600 ~/.config/osc/oscrc + + - name: Upload to OBS + run: | + PACKAGES="${{ steps.packages.outputs.packages }}" + MESSAGE="Automated update from GitHub Actions" + + if [[ -n "${{ steps.packages.outputs.version }}" ]]; then + MESSAGE="Update to ${{ steps.packages.outputs.version }}" + fi + + cd distro + + if [[ "$PACKAGES" == "all" ]]; then + bash scripts/obs-upload.sh dms "$MESSAGE" + bash scripts/obs-upload.sh dms-git "Automated git update" + else + bash scripts/obs-upload.sh "$PACKAGES" "$MESSAGE" + fi + + - name: Summary + run: | + echo "### OBS Package Update Complete" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Packages**: ${{ steps.packages.outputs.packages }}" >> $GITHUB_STEP_SUMMARY + if [[ -n "${{ steps.packages.outputs.version }}" ]]; then + echo "- **Version**: ${{ steps.packages.outputs.version }}" >> $GITHUB_STEP_SUMMARY + fi + echo "- **Project**: https://build.opensuse.org/project/show/home:AvengeMedia" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/run-ppa.yml b/.github/workflows/run-ppa.yml new file mode 100644 index 00000000..bef8f70c --- /dev/null +++ b/.github/workflows/run-ppa.yml @@ -0,0 +1,101 @@ +name: Update PPA Packages + +on: + workflow_dispatch: + inputs: + package: + description: 'Package to upload (dms, dms-git, or all)' + required: false + default: 'dms-git' + schedule: + - cron: '0 */3 * * *' # Every 3 hours for dms-git builds + +jobs: + upload-ppa: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + debhelper \ + devscripts \ + dput \ + lftp \ + build-essential \ + fakeroot \ + dpkg-dev + + - name: Configure GPG + env: + GPG_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + run: | + echo "$GPG_KEY" | gpg --import + GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | awk '{print $2}' | cut -d'/' -f2) + echo "DEBSIGN_KEYID=$GPG_KEY_ID" >> $GITHUB_ENV + + - name: Determine packages to upload + id: packages + run: | + if [[ "${{ github.event_name }}" == "schedule" ]]; then + echo "packages=dms-git" >> $GITHUB_OUTPUT + echo "Triggered by schedule: uploading git package" + elif [[ -n "${{ github.event.inputs.package }}" ]]; then + echo "packages=${{ github.event.inputs.package }}" >> $GITHUB_OUTPUT + echo "Manual trigger: ${{ github.event.inputs.package }}" + else + echo "packages=dms-git" >> $GITHUB_OUTPUT + fi + + - name: Upload to PPA + run: | + PACKAGES="${{ steps.packages.outputs.packages }}" + + cd distro/ubuntu/ppa + + if [[ "$PACKAGES" == "all" ]]; then + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "Uploading dms to PPA..." + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + bash create-and-upload.sh "../dms" dms questing + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "Uploading dms-git to PPA..." + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + bash create-and-upload.sh "../dms-git" dms-git questing + else + PPA_NAME="$PACKAGES" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "Uploading $PACKAGES to PPA..." + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + bash create-and-upload.sh "../$PACKAGES" "$PPA_NAME" questing + fi + + - name: Summary + run: | + echo "### PPA Package Upload Complete" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Packages**: ${{ steps.packages.outputs.packages }}" >> $GITHUB_STEP_SUMMARY + + PACKAGES="${{ steps.packages.outputs.packages }}" + if [[ "$PACKAGES" == "all" ]]; then + echo "- **PPA dms**: https://launchpad.net/~avengemedia/+archive/ubuntu/dms/+packages" >> $GITHUB_STEP_SUMMARY + echo "- **PPA dms-git**: https://launchpad.net/~avengemedia/+archive/ubuntu/dms-git/+packages" >> $GITHUB_STEP_SUMMARY + elif [[ "$PACKAGES" == "dms" ]]; then + echo "- **PPA**: https://launchpad.net/~avengemedia/+archive/ubuntu/dms/+packages" >> $GITHUB_STEP_SUMMARY + elif [[ "$PACKAGES" == "dms-git" ]]; then + echo "- **PPA**: https://launchpad.net/~avengemedia/+archive/ubuntu/dms-git/+packages" >> $GITHUB_STEP_SUMMARY + fi + + if [[ -n "${{ steps.packages.outputs.version }}" ]]; then + echo "- **Version**: ${{ steps.packages.outputs.version }}" >> $GITHUB_STEP_SUMMARY + fi + echo "" >> $GITHUB_STEP_SUMMARY + echo "Builds will appear once Launchpad processes the uploads." >> $GITHUB_STEP_SUMMARY diff --git a/distro/debian/dms-git/_service b/distro/debian/dms-git/_service new file mode 100644 index 00000000..3d6a6791 --- /dev/null +++ b/distro/debian/dms-git/_service @@ -0,0 +1,24 @@ + + + + git + https://github.com/AvengeMedia/DankMaterialShell.git + master + dms-git-source + + + *.tar + gz + + + + https + github.com + /AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-amd64.gz + + + https + github.com + /AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-arm64.gz + + diff --git a/distro/debian/dms-git/debian/changelog b/distro/debian/dms-git/debian/changelog new file mode 100644 index 00000000..7579c3a8 --- /dev/null +++ b/distro/debian/dms-git/debian/changelog @@ -0,0 +1,8 @@ +dms-git (0.6.2+git) nightly; urgency=medium + + * Build dms binary from source for true git version strings + * Match Fedora COPR git build behavior + * Now shows proper git version (e.g., v0.6.2-11-g12e91534) + * Add golang-go and make as build dependencies + + -- Avenge Media Fri, 22 Nov 2025 00:00:00 -0500 diff --git a/distro/debian/dms-git/debian/control b/distro/debian/dms-git/debian/control new file mode 100644 index 00000000..197c8360 --- /dev/null +++ b/distro/debian/dms-git/debian/control @@ -0,0 +1,50 @@ +Source: dms-git +Section: x11 +Priority: optional +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 +Homepage: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Browser: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Git: https://github.com/AvengeMedia/DankMaterialShell.git + +Package: dms-git +Architecture: amd64 arm64 +Depends: ${misc:Depends}, + quickshell-git | quickshell, + accountsservice, + cava, + cliphist, + danksearch, + dgop, + matugen, + qml6-module-qtcore, + qml6-module-qtmultimedia, + qml6-module-qtqml, + qml6-module-qtquick, + qml6-module-qtquick-controls, + qml6-module-qtquick-dialogs, + qml6-module-qtquick-effects, + qml6-module-qtquick-layouts, + qml6-module-qtquick-templates, + qml6-module-qtquick-window, + qt6ct, + wl-clipboard +Provides: dms +Conflicts: dms +Replaces: dms +Description: DankMaterialShell - Modern Wayland Desktop Shell (git nightly) + DMS (DankMaterialShell) is a feature-rich desktop shell built on + Quickshell, providing a modern and customizable user interface for + Wayland compositors like niri, hyprland, and sway. + . + This is the nightly/git version built from the latest master branch. + . + Features include: + - Material Design inspired UI + - Customizable themes and appearance + - Built-in application launcher + - System tray and notifications + - Network and Bluetooth management + - Audio controls + - Systemd integration diff --git a/distro/debian/dms-git/debian/copyright b/distro/debian/dms-git/debian/copyright new file mode 100644 index 00000000..1e7bce73 --- /dev/null +++ b/distro/debian/dms-git/debian/copyright @@ -0,0 +1,27 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dms +Upstream-Contact: Avenge Media LLC +Source: https://github.com/AvengeMedia/DankMaterialShell + +Files: * +Copyright: 2025 Avenge Media LLC +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/distro/debian/dms-git/debian/files b/distro/debian/dms-git/debian/files new file mode 100644 index 00000000..55b5f32b --- /dev/null +++ b/distro/debian/dms-git/debian/files @@ -0,0 +1 @@ +dms-git_0.6.0+git2061.5ddea836ppa1_source.buildinfo x11 optional diff --git a/distro/debian/dms-git/debian/rules b/distro/debian/dms-git/debian/rules new file mode 100755 index 00000000..3d5cf6fc --- /dev/null +++ b/distro/debian/dms-git/debian/rules @@ -0,0 +1,54 @@ +#!/usr/bin/make -f + +DEB_VERSION := $(shell dpkg-parsechangelog -S Version) +UPSTREAM_VERSION := $(shell echo $(DEB_VERSION) | sed 's/-[^-]*$$//') +DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) + +%: + dh $@ + +override_dh_auto_build: + if [ "$(DEB_HOST_ARCH)" = "amd64" ]; then \ + if [ -f dms-distropkg-amd64.gz ]; then \ + gunzip -c dms-distropkg-amd64.gz > dms; \ + elif [ -f ../SOURCES/dms-distropkg-amd64.gz ]; then \ + gunzip -c ../SOURCES/dms-distropkg-amd64.gz > dms; \ + else \ + echo "ERROR: dms-distropkg-amd64.gz not found!" && exit 1; \ + fi \ + elif [ "$(DEB_HOST_ARCH)" = "arm64" ]; then \ + if [ -f dms-distropkg-arm64.gz ]; then \ + gunzip -c dms-distropkg-arm64.gz > dms; \ + elif [ -f ../SOURCES/dms-distropkg-arm64.gz ]; then \ + gunzip -c ../SOURCES/dms-distropkg-arm64.gz > dms; \ + else \ + echo "ERROR: dms-distropkg-arm64.gz not found!" && exit 1; \ + fi \ + else \ + echo "Unsupported architecture: $(DEB_HOST_ARCH)" && exit 1; \ + fi + chmod +x dms + +override_dh_auto_install: + install -Dm755 dms debian/dms-git/usr/bin/dms + + mkdir -p debian/dms-git/usr/share/quickshell/dms debian/dms-git/usr/lib/systemd/user + if [ -d quickshell ]; then \ + cp -r quickshell/* debian/dms-git/usr/share/quickshell/dms/; \ + install -Dm644 quickshell/assets/systemd/dms.service debian/dms-git/usr/lib/systemd/user/dms.service; \ + elif [ -d dms-git-source/quickshell ]; then \ + cp -r dms-git-source/quickshell/* debian/dms-git/usr/share/quickshell/dms/; \ + install -Dm644 dms-git-source/quickshell/assets/systemd/dms.service debian/dms-git/usr/lib/systemd/user/dms.service; \ + else \ + echo "ERROR: quickshell directory not found (checked root and dms-git-source/)!" && \ + echo "Contents of current directory:" && ls -la && \ + exit 1; \ + fi + + rm -rf debian/dms-git/usr/share/quickshell/dms/core \ + debian/dms-git/usr/share/quickshell/dms/distro + +override_dh_auto_clean: + rm -f dms + [ ! -d dms-git-source ] || rm -rf dms-git-source + dh_auto_clean diff --git a/distro/debian/dms-git/debian/source/format b/distro/debian/dms-git/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/distro/debian/dms-git/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/distro/debian/dms-git/debian/source/include-binaries b/distro/debian/dms-git/debian/source/include-binaries new file mode 100644 index 00000000..77d7423a --- /dev/null +++ b/distro/debian/dms-git/debian/source/include-binaries @@ -0,0 +1 @@ +dms-distropkg-amd64.gz diff --git a/distro/debian/dms-git/debian/source/options b/distro/debian/dms-git/debian/source/options new file mode 100644 index 00000000..ec74bb70 --- /dev/null +++ b/distro/debian/dms-git/debian/source/options @@ -0,0 +1,4 @@ +# Include files that are normally excluded by .gitignore +# These are needed for the build process on Launchpad +tar-ignore = !dms-distropkg-amd64.gz +tar-ignore = !dms-git-repo diff --git a/distro/debian/dms/_service b/distro/debian/dms/_service new file mode 100644 index 00000000..16d5ac5f --- /dev/null +++ b/distro/debian/dms/_service @@ -0,0 +1,21 @@ + + + + https + github.com + /AvengeMedia/DankMaterialShell/archive/refs/tags/v0.6.2.tar.gz + dms-source.tar.gz + + + + https + github.com + /AvengeMedia/DankMaterialShell/releases/download/v0.6.2/dms-distropkg-amd64.gz + + + + https + github.com + /AvengeMedia/DankMaterialShell/releases/download/v0.6.2/dms-distropkg-arm64.gz + + diff --git a/distro/debian/dms/debian/changelog b/distro/debian/dms/debian/changelog new file mode 100644 index 00000000..5cea7c04 --- /dev/null +++ b/distro/debian/dms/debian/changelog @@ -0,0 +1,7 @@ +dms (0.6.2) stable; urgency=medium + + * Update to v0.6.2 release + * Fix binary download paths for OBS builds + * Native format: removed revisions + + -- Avenge Media Tue, 19 Nov 2025 10:00:00 -0500 diff --git a/distro/debian/dms/debian/control b/distro/debian/dms/debian/control new file mode 100644 index 00000000..91e63601 --- /dev/null +++ b/distro/debian/dms/debian/control @@ -0,0 +1,47 @@ +Source: dms +Section: x11 +Priority: optional +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 +Homepage: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Browser: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Git: https://github.com/AvengeMedia/DankMaterialShell.git + +Package: dms +Architecture: amd64 +Depends: ${misc:Depends}, + quickshell-git | quickshell, + accountsservice, + cava, + cliphist, + danksearch, + dgop, + matugen, + qml6-module-qtcore, + qml6-module-qtmultimedia, + qml6-module-qtqml, + qml6-module-qtquick, + qml6-module-qtquick-controls, + qml6-module-qtquick-dialogs, + qml6-module-qtquick-effects, + qml6-module-qtquick-layouts, + qml6-module-qtquick-templates, + qml6-module-qtquick-window, + qt6ct, + wl-clipboard +Conflicts: dms-git +Replaces: dms-git +Description: DankMaterialShell - Modern Wayland Desktop Shell + DMS (DankMaterialShell) is a feature-rich desktop shell built on + Quickshell, providing a modern and customizable user interface for + Wayland compositors like niri, hyprland, and sway. + . + Features include: + - Material Design inspired UI + - Customizable themes and appearance + - Built-in application launcher + - System tray and notifications + - Network and Bluetooth management + - Audio controls + - Systemd integration diff --git a/distro/debian/dms/debian/copyright b/distro/debian/dms/debian/copyright new file mode 100644 index 00000000..1e7bce73 --- /dev/null +++ b/distro/debian/dms/debian/copyright @@ -0,0 +1,27 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dms +Upstream-Contact: Avenge Media LLC +Source: https://github.com/AvengeMedia/DankMaterialShell + +Files: * +Copyright: 2025 Avenge Media LLC +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/distro/debian/dms/debian/files b/distro/debian/dms/debian/files new file mode 100644 index 00000000..1ff65a54 --- /dev/null +++ b/distro/debian/dms/debian/files @@ -0,0 +1 @@ +dms_0.6.0ppa2_source.buildinfo x11 optional diff --git a/distro/debian/dms/debian/rules b/distro/debian/dms/debian/rules new file mode 100755 index 00000000..cbcd12c3 --- /dev/null +++ b/distro/debian/dms/debian/rules @@ -0,0 +1,64 @@ +#!/usr/bin/make -f + +DEB_VERSION := $(shell dpkg-parsechangelog -S Version) +UPSTREAM_VERSION := $(shell echo $(DEB_VERSION) | sed 's/-[^-]*$$//') +DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) + +%: + dh $@ + +override_dh_auto_build: + if [ "$(DEB_HOST_ARCH)" = "amd64" ]; then \ + if [ -f dms-distropkg-amd64.gz ]; then \ + gunzip -c dms-distropkg-amd64.gz > dms; \ + elif [ -f ../SOURCES/dms-distropkg-amd64.gz ]; then \ + gunzip -c ../SOURCES/dms-distropkg-amd64.gz > dms; \ + elif [ -f ../../SOURCES/dms-distropkg-amd64.gz ]; then \ + gunzip -c ../../SOURCES/dms-distropkg-amd64.gz > dms; \ + else \ + echo "ERROR: dms-distropkg-amd64.gz not found!" && exit 1; \ + fi \ + elif [ "$(DEB_HOST_ARCH)" = "arm64" ]; then \ + if [ -f dms-distropkg-arm64.gz ]; then \ + gunzip -c dms-distropkg-arm64.gz > dms; \ + elif [ -f ../SOURCES/dms-distropkg-arm64.gz ]; then \ + gunzip -c ../SOURCES/dms-distropkg-arm64.gz > dms; \ + elif [ -f ../../SOURCES/dms-distropkg-arm64.gz ]; then \ + gunzip -c ../../SOURCES/dms-distropkg-arm64.gz > dms; \ + else \ + echo "ERROR: dms-distropkg-arm64.gz not found!" && exit 1; \ + fi \ + else \ + echo "Unsupported architecture: $(DEB_HOST_ARCH)" && exit 1; \ + fi + chmod +x dms + + if [ ! -d DankMaterialShell-$(UPSTREAM_VERSION) ]; then \ + if [ -f ../SOURCES/dms-source.tar.gz ]; then \ + tar -xzf ../SOURCES/dms-source.tar.gz; \ + elif [ -f dms-source.tar.gz ]; then \ + tar -xzf dms-source.tar.gz; \ + fi; \ + fi + + +override_dh_auto_install: + install -Dm755 dms debian/dms/usr/bin/dms + + mkdir -p debian/dms/usr/share/quickshell/dms debian/dms/usr/lib/systemd/user + if [ -d DankMaterialShell-$(UPSTREAM_VERSION) ]; then \ + cp -r DankMaterialShell-$(UPSTREAM_VERSION)/quickshell/* debian/dms/usr/share/quickshell/dms/; \ + install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/quickshell/assets/systemd/dms.service debian/dms/usr/lib/systemd/user/dms.service; \ + else \ + echo "ERROR: DankMaterialShell-$(UPSTREAM_VERSION) directory not found!" && \ + echo "Contents of current directory:" && ls -la && \ + exit 1; \ + fi + + rm -rf debian/dms/usr/share/quickshell/dms/core \ + debian/dms/usr/share/quickshell/dms/distro + +override_dh_auto_clean: + rm -f dms + rm -rf DankMaterialShell-$(UPSTREAM_VERSION) + dh_auto_clean diff --git a/distro/debian/dms/debian/source/format b/distro/debian/dms/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/distro/debian/dms/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/distro/debian/dms/debian/source/include-binaries b/distro/debian/dms/debian/source/include-binaries new file mode 100644 index 00000000..bac25ab7 --- /dev/null +++ b/distro/debian/dms/debian/source/include-binaries @@ -0,0 +1,2 @@ +dms-distropkg-amd64.gz +dms-source.tar.gz diff --git a/distro/debian/dms/debian/source/options b/distro/debian/dms/debian/source/options new file mode 100644 index 00000000..27bae919 --- /dev/null +++ b/distro/debian/dms/debian/source/options @@ -0,0 +1,4 @@ +# Include files that are normally excluded by .gitignore +# These are needed for the build process on Launchpad +tar-ignore = !dms-distropkg-amd64.gz +tar-ignore = !dms-source.tar.gz diff --git a/distro/opensuse/_service b/distro/opensuse/_service new file mode 100644 index 00000000..47192af1 --- /dev/null +++ b/distro/opensuse/_service @@ -0,0 +1,24 @@ + + + + git + https://github.com/AvengeMedia/DankMaterialShell.git + master + dms-git-source + + + *.tar + gz + + + + https + github.com + /AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-amd64.gz + + + https + github.com + /AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-arm64.gz + + diff --git a/distro/opensuse/dms-git.spec b/distro/opensuse/dms-git.spec new file mode 100644 index 00000000..e1cc8951 --- /dev/null +++ b/distro/opensuse/dms-git.spec @@ -0,0 +1,107 @@ +%global debug_package %{nil} + +Name: dms-git +Version: 0.6.2+git +Release: 5%{?dist} +Epoch: 1 +Summary: DankMaterialShell - Material 3 inspired shell (git nightly) + +License: MIT +URL: https://github.com/AvengeMedia/DankMaterialShell +Source0: dms-git-source.tar.gz +Source1: dms-distropkg-amd64.gz +Source2: dms-distropkg-arm64.gz + +BuildRequires: gzip +BuildRequires: systemd-rpm-macros + +Requires: (quickshell-git or quickshell) +Requires: accountsservice +Requires: dgop + +Recommends: cava +Recommends: cliphist +Recommends: danksearch +Recommends: matugen +Recommends: quickshell-git +Recommends: wl-clipboard + +Recommends: NetworkManager +Recommends: qt6-qtmultimedia +Suggests: qt6ct + +Provides: dms +Conflicts: dms +Obsoletes: dms + +%description +DankMaterialShell (DMS) is a modern Wayland desktop shell built with Quickshell +and optimized for niri, Hyprland, Sway, and other wlroots compositors. + +This git version tracks the master branch and includes the latest features +and fixes. Includes pre-built dms CLI binary and QML shell files. + +%prep +%setup -q -n dms-git-source + +%ifarch x86_64 +gunzip -c %{SOURCE1} > dms +%endif +%ifarch aarch64 +gunzip -c %{SOURCE2} > dms +%endif +chmod +x dms + +%build + +%install +install -Dm755 dms %{buildroot}%{_bindir}/dms + +install -d %{buildroot}%{_datadir}/bash-completion/completions +install -d %{buildroot}%{_datadir}/zsh/site-functions +install -d %{buildroot}%{_datadir}/fish/vendor_completions.d +./dms completion bash > %{buildroot}%{_datadir}/bash-completion/completions/dms || : +./dms completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || : +./dms completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || : + +install -Dm644 quickshell/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service + +install -dm755 %{buildroot}%{_datadir}/quickshell/dms +cp -r quickshell/* %{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 +rm -rf %{buildroot}%{_datadir}/quickshell/dms/core + +%posttrans +if [ -d "%{_sysconfdir}/xdg/quickshell/dms" ]; then + rmdir "%{_sysconfdir}/xdg/quickshell/dms" 2>/dev/null || true + rmdir "%{_sysconfdir}/xdg/quickshell" 2>/dev/null || true +fi + +if [ "$1" -ge 2 ]; then + pkill -USR1 -x dms >/dev/null 2>&1 || true +fi + +%files +%license LICENSE +%doc CONTRIBUTING.md +%doc quickshell/README.md +%{_bindir}/dms +%dir %{_datadir}/fish +%dir %{_datadir}/fish/vendor_completions.d +%{_datadir}/fish/vendor_completions.d/dms.fish +%dir %{_datadir}/zsh +%dir %{_datadir}/zsh/site-functions +%{_datadir}/zsh/site-functions/_dms +%{_datadir}/bash-completion/completions/dms +%dir %{_datadir}/quickshell +%{_datadir}/quickshell/dms/ +%{_userunitdir}/dms.service + +%changelog +* Fri Nov 22 2025 AvengeMedia - 0.6.2+git-5 +- Git nightly build from master branch +- Multi-arch support (x86_64, aarch64) diff --git a/distro/opensuse/dms.spec b/distro/opensuse/dms.spec new file mode 100644 index 00000000..e6a6babd --- /dev/null +++ b/distro/opensuse/dms.spec @@ -0,0 +1,107 @@ +# Spec for DMS for OpenSUSE/OBS + +%global debug_package %{nil} + +Name: dms +Version: 0.6.2 +Release: 1%{?dist} +Summary: DankMaterialShell - Material 3 inspired shell for Wayland compositors + +License: MIT +URL: https://github.com/AvengeMedia/DankMaterialShell +Source0: dms-source.tar.gz +Source1: dms-distropkg-amd64.gz +Source2: dms-distropkg-arm64.gz + +BuildRequires: gzip +BuildRequires: systemd-rpm-macros + +# Core requirements +Requires: (quickshell-git or quickshell) +Requires: accountsservice +Requires: dgop + +# Core utilities (Highly recommended for DMS functionality) +Recommends: cava +Recommends: cliphist +Recommends: danksearch +Recommends: matugen +Recommends: NetworkManager +Recommends: qt6-qtmultimedia +Recommends: wl-clipboard +Suggests: qt6ct + +%description +DankMaterialShell (DMS) is a modern Wayland desktop shell built with Quickshell +and optimized for niri, Hyprland, Sway, and other wlroots compositors. Features +notifications, app launcher, wallpaper customization, and plugin system. + +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. + +%prep +%setup -q -n DankMaterialShell-%{version} + +%ifarch x86_64 +gunzip -c %{SOURCE1} > dms +%endif +%ifarch aarch64 +gunzip -c %{SOURCE2} > dms +%endif +chmod +x dms + +%build + +%install +install -Dm755 dms %{buildroot}%{_bindir}/dms + +install -d %{buildroot}%{_datadir}/bash-completion/completions +install -d %{buildroot}%{_datadir}/zsh/site-functions +install -d %{buildroot}%{_datadir}/fish/vendor_completions.d +./dms completion bash > %{buildroot}%{_datadir}/bash-completion/completions/dms || : +./dms completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || : +./dms completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || : + +install -Dm644 quickshell/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service + +install -dm755 %{buildroot}%{_datadir}/quickshell/dms +cp -r quickshell/* %{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 +rm -rf %{buildroot}%{_datadir}/quickshell/dms/core + +%posttrans +if [ -d "%{_sysconfdir}/xdg/quickshell/dms" ]; then + 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 + +if [ "$1" -ge 2 ]; then + pkill -USR1 -x dms >/dev/null 2>&1 || true +fi + +%files +%license LICENSE +%doc CONTRIBUTING.md +%doc quickshell/README.md +%{_bindir}/dms +%dir %{_datadir}/fish +%dir %{_datadir}/fish/vendor_completions.d +%{_datadir}/fish/vendor_completions.d/dms.fish +%dir %{_datadir}/zsh +%dir %{_datadir}/zsh/site-functions +%{_datadir}/zsh/site-functions/_dms +%{_datadir}/bash-completion/completions/dms +%dir %{_datadir}/quickshell +%{_datadir}/quickshell/dms/ +%{_userunitdir}/dms.service + +%changelog +* Fri Nov 22 2025 AvengeMedia - 0.6.2-1 +- Stable release build with pre-built binaries +- Multi-arch support (x86_64, aarch64) diff --git a/distro/scripts/obs-status.sh b/distro/scripts/obs-status.sh new file mode 100644 index 00000000..f4952350 --- /dev/null +++ b/distro/scripts/obs-status.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Unified OBS status checker for dms packages +# Checks all platforms (Debian, OpenSUSE) and architectures (x86_64, aarch64) +# Only pulls logs if build failed +# Usage: ./distro/scripts/obs-status.sh [package-name] +# +# Examples: +# ./distro/scripts/obs-status.sh # Check all packages +# ./distro/scripts/obs-status.sh dms # Check specific package + +OBS_BASE_PROJECT="home:AvengeMedia" +OBS_BASE="$HOME/.cache/osc-checkouts" + +ALL_PACKAGES=(dms dms-git) + +REPOS=("Debian_13" "openSUSE_Tumbleweed" "16.0") +ARCHES=("x86_64" "aarch64") + +if [[ -n "$1" ]]; then + PACKAGES=("$1") +else + PACKAGES=("${ALL_PACKAGES[@]}") +fi + +cd "$OBS_BASE" + +for pkg in "${PACKAGES[@]}"; do + case "$pkg" in + dms) + PROJECT="$OBS_BASE_PROJECT:dms" + ;; + dms-git) + PROJECT="$OBS_BASE_PROJECT:dms-git" + ;; + *) + echo "Error: Unknown package '$pkg'" + continue + ;; + esac + + echo "==========================================" + echo "=== $pkg ===" + echo "==========================================" + + # Checkout if needed + if [[ ! -d "$PROJECT/$pkg" ]]; then + osc co "$PROJECT/$pkg" 2>&1 | tail -1 + fi + + cd "$PROJECT/$pkg" + + ALL_RESULTS=$(osc results 2>&1) + + # Check each repository and architecture + FAILED_BUILDS=() + for repo in "${REPOS[@]}"; do + for arch in "${ARCHES[@]}"; do + STATUS=$(echo "$ALL_RESULTS" | grep "$repo.*$arch" | awk '{print $NF}' | head -1) + + if [[ -n "$STATUS" ]]; then + # Color code status + case "$STATUS" in + succeeded) + COLOR="\033[0;32m" # Green + SYMBOL="✅" + ;; + failed) + COLOR="\033[0;31m" # Red + SYMBOL="❌" + FAILED_BUILDS+=("$repo $arch") + ;; + unresolvable) + COLOR="\033[0;33m" # Yellow + SYMBOL="⚠️" + ;; + *) + COLOR="\033[0;37m" # White + SYMBOL="⏳" + ;; + esac + echo -e " $SYMBOL $repo $arch: ${COLOR}$STATUS\033[0m" + fi + done + done + + # Pull logs for failed builds + if [[ ${#FAILED_BUILDS[@]} -gt 0 ]]; then + echo "" + echo " 📋 Fetching logs for failed builds..." + for build in "${FAILED_BUILDS[@]}"; do + read -r repo arch <<< "$build" + echo "" + echo " ────────────────────────────────────────────" + echo " Build log: $repo $arch" + echo " ────────────────────────────────────────────" + osc remotebuildlog "$PROJECT" "$pkg" "$repo" "$arch" 2>&1 | tail -100 + done + fi + + echo "" + cd - > /dev/null +done + +echo "==========================================" +echo "Status check complete!" + diff --git a/distro/scripts/obs-upload.sh b/distro/scripts/obs-upload.sh new file mode 100644 index 00000000..0ed13f3d --- /dev/null +++ b/distro/scripts/obs-upload.sh @@ -0,0 +1,733 @@ +#!/bin/bash +# Unified OBS upload script for dms packages +# Handles Debian and OpenSUSE builds for both x86_64 and aarch64 +# Usage: ./distro/scripts/obs-upload.sh [distro] [commit-message] +# +# Examples: +# ./distro/scripts/obs-upload.sh dms "Update to v0.6.2" +# ./distro/scripts/obs-upload.sh debian dms +# ./distro/scripts/obs-upload.sh opensuse dms-git + +set -e + +UPLOAD_DEBIAN=true +UPLOAD_OPENSUSE=true +PACKAGE="" +MESSAGE="" + +for arg in "$@"; do + case "$arg" in + debian) + UPLOAD_DEBIAN=true + UPLOAD_OPENSUSE=false + ;; + opensuse) + UPLOAD_DEBIAN=false + UPLOAD_OPENSUSE=true + ;; + *) + if [[ -z "$PACKAGE" ]]; then + PACKAGE="$arg" + elif [[ -z "$MESSAGE" ]]; then + MESSAGE="$arg" + fi + ;; + esac +done + +OBS_BASE_PROJECT="home:AvengeMedia" +OBS_BASE="$HOME/.cache/osc-checkouts" + +# Available packages +AVAILABLE_PACKAGES=(dms dms-git) + +if [[ -z "$PACKAGE" ]]; then + echo "Available packages:" + echo "" + echo " 1. dms - Stable DMS" + echo " 2. dms-git - Nightly DMS" + echo " a. all" + echo "" + read -p "Select package (1-${#AVAILABLE_PACKAGES[@]}, a): " selection + + if [[ "$selection" == "a" ]] || [[ "$selection" == "all" ]]; then + PACKAGE="all" + elif [[ "$selection" =~ ^[0-9]+$ ]] && [[ "$selection" -ge 1 ]] && [[ "$selection" -le ${#AVAILABLE_PACKAGES[@]} ]]; then + PACKAGE="${AVAILABLE_PACKAGES[$((selection-1))]}" + else + echo "Error: Invalid selection" + exit 1 + fi + +fi + +if [[ -z "$MESSAGE" ]]; then + MESSAGE="Update packaging" +fi + +# Get repo root (2 levels up from distro/scripts/) +REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +cd "$REPO_ROOT" + +# Ensure we're in repo root +if [[ ! -d "distro/debian" ]]; then + echo "Error: Run this script from the repository root" + exit 1 +fi + +# Handle "all" option +if [[ "$PACKAGE" == "all" ]]; then + echo "==> Uploading all packages" + DISTRO_ARG="" + if [[ "$UPLOAD_DEBIAN" == true && "$UPLOAD_OPENSUSE" == false ]]; then + DISTRO_ARG="debian" + elif [[ "$UPLOAD_DEBIAN" == false && "$UPLOAD_OPENSUSE" == true ]]; then + DISTRO_ARG="opensuse" + fi + echo "" + FAILED=() + for pkg in "${AVAILABLE_PACKAGES[@]}"; do + if [[ -d "distro/debian/$pkg" ]]; then + echo "==========================================" + echo "Uploading $pkg..." + echo "==========================================" + if [[ -n "$DISTRO_ARG" ]]; then + if bash "$0" "$DISTRO_ARG" "$pkg" "$MESSAGE"; then + echo "✅ $pkg uploaded successfully" + else + echo "❌ $pkg failed to upload" + FAILED+=("$pkg") + fi + else + if bash "$0" "$pkg" "$MESSAGE"; then + echo "✅ $pkg uploaded successfully" + else + echo "❌ $pkg failed to upload" + FAILED+=("$pkg") + fi + fi + echo "" + else + echo "⚠️ Skipping $pkg (not found in distro/debian/)" + fi + done + + if [[ ${#FAILED[@]} -eq 0 ]]; then + echo "✅ All packages uploaded successfully!" + exit 0 + else + echo "❌ Some packages failed: ${FAILED[*]}" + exit 1 + fi +fi + +# Check if package exists +if [[ ! -d "distro/debian/$PACKAGE" ]]; then + echo "Error: Package '$PACKAGE' not found in distro/debian/" + exit 1 +fi + +case "$PACKAGE" in + dms) + PROJECT="dms" + ;; + dms-git) + PROJECT="dms-git" + ;; + *) + echo "Error: Unknown package '$PACKAGE'" + exit 1 + ;; +esac + +OBS_PROJECT="${OBS_BASE_PROJECT}:${PROJECT}" + +echo "==> Target: $OBS_PROJECT / $PACKAGE" +echo "==> Message: $MESSAGE" +if [[ "$UPLOAD_DEBIAN" == true && "$UPLOAD_OPENSUSE" == true ]]; then + echo "==> Distributions: Debian + OpenSUSE" +elif [[ "$UPLOAD_DEBIAN" == true ]]; then + echo "==> Distribution: Debian only" +elif [[ "$UPLOAD_OPENSUSE" == true ]]; then + echo "==> Distribution: OpenSUSE only" +fi + +# Create .obs directory if it doesn't exist +mkdir -p "$OBS_BASE" + +# Check out package if not already present +if [[ ! -d "$OBS_BASE/$OBS_PROJECT/$PACKAGE" ]]; then + echo "Checking out $OBS_PROJECT/$PACKAGE..." + cd "$OBS_BASE" + osc co "$OBS_PROJECT/$PACKAGE" + cd "$REPO_ROOT" +fi + +WORK_DIR="$OBS_BASE/$OBS_PROJECT/$PACKAGE" + +echo "==> Preparing $PACKAGE for OBS upload" + +# Clean working directory (keep osc metadata) +find "$WORK_DIR" -maxdepth 1 -type f \( -name "*.tar.gz" -o -name "*.spec" -o -name "_service" -o -name "*.dsc" \) -delete 2>/dev/null || true + +if [[ -f "distro/debian/$PACKAGE/_service" ]]; then + echo " - Copying _service (for binary downloads)" + cp "distro/debian/$PACKAGE/_service" "$WORK_DIR/" +fi + +# Copy OpenSUSE spec if it exists and handle auto-increment +if [[ "$UPLOAD_OPENSUSE" == true ]] && [[ -f "distro/opensuse/$PACKAGE.spec" ]]; then + echo " - Copying $PACKAGE.spec for OpenSUSE" + cp "distro/opensuse/$PACKAGE.spec" "$WORK_DIR/" + + # Auto-increment Release if same Version is being rebuilt + if [[ -f "$WORK_DIR/.osc/$PACKAGE.spec" ]]; then + NEW_VERSION=$(grep "^Version:" "$WORK_DIR/$PACKAGE.spec" | awk '{print $2}' | head -1) + NEW_RELEASE=$(grep "^Release:" "$WORK_DIR/$PACKAGE.spec" | sed 's/^Release:[[:space:]]*//' | sed 's/%{?dist}//' | head -1) + + OLD_VERSION=$(grep "^Version:" "$WORK_DIR/.osc/$PACKAGE.spec" | awk '{print $2}' | head -1) + OLD_RELEASE=$(grep "^Release:" "$WORK_DIR/.osc/$PACKAGE.spec" | sed 's/^Release:[[:space:]]*//' | sed 's/%{?dist}//' | head -1) + + if [[ "$NEW_VERSION" == "$OLD_VERSION" ]]; then + # Same version - increment release number + if [[ "$OLD_RELEASE" =~ ^([0-9]+) ]]; then + BASE_RELEASE="${BASH_REMATCH[1]}" + NEXT_RELEASE=$((BASE_RELEASE + 1)) + echo " - Detected rebuild of same version $NEW_VERSION (release $OLD_RELEASE -> $NEXT_RELEASE)" + sed -i "s/^Release:[[:space:]]*${NEW_RELEASE}%{?dist}/Release: ${NEXT_RELEASE}%{?dist}/" "$WORK_DIR/$PACKAGE.spec" + fi + else + echo " - New version detected: $OLD_VERSION -> $NEW_VERSION (keeping release $NEW_RELEASE)" + fi + else + echo " - First upload to OBS (no previous spec found)" + fi +elif [[ "$UPLOAD_OPENSUSE" == true ]]; then + echo " - Warning: OpenSUSE spec file not found, skipping OpenSUSE upload" +fi + +# Handle OpenSUSE-only uploads (create tarball without Debian processing) +if [[ "$UPLOAD_OPENSUSE" == true ]] && [[ "$UPLOAD_DEBIAN" == false ]] && [[ -f "distro/opensuse/$PACKAGE.spec" ]]; then + echo " - OpenSUSE-only upload: creating source tarball" + + TEMP_DIR=$(mktemp -d) + trap "rm -rf $TEMP_DIR" EXIT + + # Check _service file to determine how to get source + if [[ -f "distro/debian/$PACKAGE/_service" ]]; then + # Check for tar_scm (git source) + if grep -q "tar_scm" "distro/debian/$PACKAGE/_service"; then + GIT_URL=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "url" | sed 's/.*\(.*\)<\/param>.*/\1/') + GIT_REVISION=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "revision" | sed 's/.*\(.*\)<\/param>.*/\1/') + + if [[ -n "$GIT_URL" ]]; then + echo " Cloning git source from: $GIT_URL (revision: ${GIT_REVISION:-master})" + SOURCE_DIR="$TEMP_DIR/dms-git-source" + if git clone --depth 1 --branch "${GIT_REVISION:-master}" "$GIT_URL" "$SOURCE_DIR" 2>/dev/null || \ + git clone --depth 1 "$GIT_URL" "$SOURCE_DIR" 2>/dev/null; then + cd "$SOURCE_DIR" + if [[ -n "$GIT_REVISION" ]]; then + git checkout "$GIT_REVISION" 2>/dev/null || true + fi + SOURCE_DIR=$(pwd) + cd "$REPO_ROOT" + fi + fi + fi + fi + + if [[ -n "$SOURCE_DIR" && -d "$SOURCE_DIR" ]]; then + # Extract Source0 from spec file + SOURCE0=$(grep "^Source0:" "distro/opensuse/$PACKAGE.spec" | awk '{print $2}' | head -1) + + if [[ -n "$SOURCE0" ]]; then + OBS_TARBALL_DIR=$(mktemp -d -t obs-tarball-XXXXXX) + cd "$OBS_TARBALL_DIR" + + case "$PACKAGE" in + dms) + DMS_VERSION=$(grep "^Version:" "$REPO_ROOT/distro/opensuse/$PACKAGE.spec" | sed 's/^Version:[[:space:]]*//' | head -1) + EXPECTED_DIR="DankMaterialShell-${DMS_VERSION}" + ;; + dms-git) + EXPECTED_DIR="dms-git-source" + ;; + *) + EXPECTED_DIR=$(basename "$SOURCE_DIR") + ;; + esac + + echo " Creating $SOURCE0 (directory: $EXPECTED_DIR)" + cp -r "$SOURCE_DIR" "$EXPECTED_DIR" + tar -czf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + rm -rf "$EXPECTED_DIR" + echo " Created $SOURCE0 ($(stat -c%s "$WORK_DIR/$SOURCE0" 2>/dev/null || echo 0) bytes)" + + cd "$REPO_ROOT" + rm -rf "$OBS_TARBALL_DIR" + fi + else + echo " - Warning: Could not obtain source for OpenSUSE tarball" + fi +fi + +# Generate .dsc file and handle source format (for Debian only) +if [[ "$UPLOAD_DEBIAN" == true ]] && [[ -d "distro/debian/$PACKAGE/debian" ]]; then + # Get version from changelog + CHANGELOG_VERSION=$(grep -m1 "^$PACKAGE" distro/debian/$PACKAGE/debian/changelog 2>/dev/null | sed 's/.*(\([^)]*\)).*/\1/' || echo "0.1.11") + + # Determine source format + SOURCE_FORMAT=$(cat "distro/debian/$PACKAGE/debian/source/format" 2>/dev/null || echo "3.0 (quilt)") + + # Handle native format (3.0 native) + if [[ "$SOURCE_FORMAT" == *"native"* ]]; then + echo " - Native format detected: creating combined tarball" + + VERSION="$CHANGELOG_VERSION" + + # Create temp directory for building combined tarball + TEMP_DIR=$(mktemp -d) + trap "rm -rf $TEMP_DIR" EXIT + + # Determine tarball name for native format (use version without revision) + COMBINED_TARBALL="${PACKAGE}_${VERSION}.tar.gz" + + SOURCE_DIR="" + + # Check _service file to determine how to get source + if [[ -f "distro/debian/$PACKAGE/_service" ]]; then + # Check for tar_scm first (git source) - this takes priority for git packages + if grep -q "tar_scm" "distro/debian/$PACKAGE/_service"; then + # For dms-git, use tar_scm to get git source + GIT_URL=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "url" | sed 's/.*\(.*\)<\/param>.*/\1/') + GIT_REVISION=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "revision" | sed 's/.*\(.*\)<\/param>.*/\1/') + + if [[ -n "$GIT_URL" ]]; then + echo " Cloning git source from: $GIT_URL (revision: ${GIT_REVISION:-master})" + SOURCE_DIR="$TEMP_DIR/dms-git-source" + if git clone --depth 1 --branch "${GIT_REVISION:-master}" "$GIT_URL" "$SOURCE_DIR" 2>/dev/null || \ + git clone --depth 1 "$GIT_URL" "$SOURCE_DIR" 2>/dev/null; then + cd "$SOURCE_DIR" + if [[ -n "$GIT_REVISION" ]]; then + git checkout "$GIT_REVISION" 2>/dev/null || true + fi + SOURCE_DIR=$(pwd) + cd "$REPO_ROOT" + else + echo "Error: Failed to clone git repository" + exit 1 + fi + fi + elif grep -q "download_url" "distro/debian/$PACKAGE/_service" && [[ "$PACKAGE" != "dms-git" ]]; then + # Extract download_url for source (skip binary downloads) + # Look for download_url with "source" in path or .tar.gz/.tar.xz archives + # Skip binaries (distropkg, standalone .gz files, etc.) + + # Extract all paths from download_url services + ALL_PATHS=$(grep -A 5 '' "distro/debian/$PACKAGE/_service" | \ + grep '' | \ + sed 's/.*\(.*\)<\/param>.*/\1/') + + # Find source path (has "source" or ends with .tar.gz/.tar.xz, but not distropkg) + SOURCE_PATH="" + for path in $ALL_PATHS; do + if echo "$path" | grep -qE "(source|archive|\.tar\.(gz|xz|bz2))" && \ + ! echo "$path" | grep -qE "(distropkg|binary)"; then + SOURCE_PATH="$path" + break + fi + done + + # If no source found, try first path that ends with .tar.gz/.tar.xz + if [[ -z "$SOURCE_PATH" ]]; then + for path in $ALL_PATHS; do + if echo "$path" | grep -qE "\.tar\.(gz|xz|bz2)$"; then + SOURCE_PATH="$path" + break + fi + done + fi + + if [[ -n "$SOURCE_PATH" ]]; then + # Extract the service block containing this path + SOURCE_BLOCK=$(awk -v target="$SOURCE_PATH" ' + // { in_block=1; block="" } + in_block { block=block"\n"$0 } + /<\/service>/ { + if (in_block && block ~ target) { + print block + exit + } + in_block=0 + } + ' "distro/debian/$PACKAGE/_service") + + URL_PROTOCOL=$(echo "$SOURCE_BLOCK" | grep "protocol" | sed 's/.*\(.*\)<\/param>.*/\1/' | head -1) + URL_HOST=$(echo "$SOURCE_BLOCK" | grep "host" | sed 's/.*\(.*\)<\/param>.*/\1/' | head -1) + URL_PATH="$SOURCE_PATH" + fi + + if [[ -n "$URL_PROTOCOL" && -n "$URL_HOST" && -n "$URL_PATH" ]]; then + SOURCE_URL="${URL_PROTOCOL}://${URL_HOST}${URL_PATH}" + echo " Downloading source from: $SOURCE_URL" + + if wget -q -O "$TEMP_DIR/source-archive" "$SOURCE_URL"; then + cd "$TEMP_DIR" + if [[ "$SOURCE_URL" == *.tar.xz ]]; then + tar -xJf source-archive + elif [[ "$SOURCE_URL" == *.tar.gz ]] || [[ "$SOURCE_URL" == *.tgz ]]; then + tar -xzf source-archive + fi + # GitHub archives extract to DankMaterialShell-VERSION/ or similar + SOURCE_DIR=$(find . -maxdepth 1 -type d -name "DankMaterialShell-*" | head -1) + if [[ -z "$SOURCE_DIR" ]]; then + # Try to find any extracted directory + SOURCE_DIR=$(find . -maxdepth 1 -type d ! -name "." | head -1) + fi + if [[ -z "$SOURCE_DIR" || ! -d "$SOURCE_DIR" ]]; then + echo "Error: Failed to extract source archive or find source directory" + echo "Contents of $TEMP_DIR:" + ls -la "$TEMP_DIR" + cd "$REPO_ROOT" + exit 1 + fi + # Convert to absolute path + SOURCE_DIR=$(cd "$SOURCE_DIR" && pwd) + cd "$REPO_ROOT" + else + echo "Error: Failed to download source from $SOURCE_URL" + exit 1 + fi + fi + fi + fi + + if [[ -z "$SOURCE_DIR" || ! -d "$SOURCE_DIR" ]]; then + echo "Error: Could not determine or obtain source for $PACKAGE" + echo "SOURCE_DIR: $SOURCE_DIR" + if [[ -d "$TEMP_DIR" ]]; then + echo "Contents of temp directory:" + ls -la "$TEMP_DIR" + fi + exit 1 + fi + + echo " Found source directory: $SOURCE_DIR" + + # Create OpenSUSE-compatible source tarballs BEFORE adding debian/ directory + # (OpenSUSE doesn't need debian/ directory) + if [[ "$UPLOAD_OPENSUSE" == true ]] && [[ -f "distro/opensuse/$PACKAGE.spec" ]]; then + # If SOURCE_DIR is not set (OpenSUSE-only upload), detect source now + if [[ -z "$SOURCE_DIR" || ! -d "$SOURCE_DIR" ]]; then + echo " - Detecting source for OpenSUSE-only upload" + if [[ -z "$TEMP_DIR" ]]; then + TEMP_DIR=$(mktemp -d) + trap "rm -rf $TEMP_DIR" EXIT + fi + + # Check _service file to determine how to get source + if [[ -f "distro/debian/$PACKAGE/_service" ]]; then + # Check for tar_scm first (git source) - this takes priority for git packages + if grep -q "tar_scm" "distro/debian/$PACKAGE/_service"; then + # For dms-git, use tar_scm to get git source + GIT_URL=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "url" | sed 's/.*\(.*\)<\/param>.*/\1/') + GIT_REVISION=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "revision" | sed 's/.*\(.*\)<\/param>.*/\1/') + + if [[ -n "$GIT_URL" ]]; then + echo " Cloning git source from: $GIT_URL (revision: ${GIT_REVISION:-master})" + SOURCE_DIR="$TEMP_DIR/dms-git-source" + if git clone --depth 1 --branch "${GIT_REVISION:-master}" "$GIT_URL" "$SOURCE_DIR" 2>/dev/null || \ + git clone --depth 1 "$GIT_URL" "$SOURCE_DIR" 2>/dev/null; then + cd "$SOURCE_DIR" + if [[ -n "$GIT_REVISION" ]]; then + git checkout "$GIT_REVISION" 2>/dev/null || true + fi + SOURCE_DIR=$(pwd) + cd "$REPO_ROOT" + else + echo "Error: Failed to clone git repository" + exit 1 + fi + fi + elif grep -q "download_url" "distro/debian/$PACKAGE/_service" && [[ "$PACKAGE" != "dms-git" ]]; then + # Extract download_url for source (skip binary downloads) + ALL_PATHS=$(grep -A 5 '' "distro/debian/$PACKAGE/_service" | \ + grep '' | \ + sed 's/.*\(.*\)<\/param>.*/\1/') + + # Find source path (has "source" or ends with .tar.gz/.tar.xz, but not distropkg) + SOURCE_PATH="" + for path in $ALL_PATHS; do + if echo "$path" | grep -qE "(source|archive|\.tar\.(gz|xz|bz2))" && \ + ! echo "$path" | grep -qE "(distropkg|binary)"; then + SOURCE_PATH="$path" + break + fi + done + + # If no source found, try first path that ends with .tar.gz/.tar.xz + if [[ -z "$SOURCE_PATH" ]]; then + for path in $ALL_PATHS; do + if echo "$path" | grep -qE "\.tar\.(gz|xz|bz2)$"; then + SOURCE_PATH="$path" + break + fi + done + fi + + if [[ -n "$SOURCE_PATH" ]]; then + # Extract the service block containing this path + SOURCE_BLOCK=$(awk -v target="$SOURCE_PATH" ' + // { in_block=1; block="" } + in_block { block=block"\n"$0 } + /<\/service>/ { + if (in_block && block ~ target) { + print block + exit + } + in_block=0 + } + ' "distro/debian/$PACKAGE/_service") + + URL_PROTOCOL=$(echo "$SOURCE_BLOCK" | grep "protocol" | sed 's/.*\(.*\)<\/param>.*/\1/' | head -1) + URL_HOST=$(echo "$SOURCE_BLOCK" | grep "host" | sed 's/.*\(.*\)<\/param>.*/\1/' | head -1) + URL_PATH="$SOURCE_PATH" + fi + + if [[ -n "$URL_PROTOCOL" && -n "$URL_HOST" && -n "$URL_PATH" ]]; then + SOURCE_URL="${URL_PROTOCOL}://${URL_HOST}${URL_PATH}" + echo " Downloading source from: $SOURCE_URL" + + if wget -q -O "$TEMP_DIR/source-archive" "$SOURCE_URL"; then + cd "$TEMP_DIR" + if [[ "$SOURCE_URL" == *.tar.xz ]]; then + tar -xJf source-archive + elif [[ "$SOURCE_URL" == *.tar.gz ]] || [[ "$SOURCE_URL" == *.tgz ]]; then + tar -xzf source-archive + fi + # GitHub archives extract to DankMaterialShell-VERSION/ or similar + SOURCE_DIR=$(find . -maxdepth 1 -type d -name "DankMaterialShell-*" | head -1) + if [[ -z "$SOURCE_DIR" ]]; then + # Try to find any extracted directory + SOURCE_DIR=$(find . -maxdepth 1 -type d ! -name "." | head -1) + fi + if [[ -z "$SOURCE_DIR" || ! -d "$SOURCE_DIR" ]]; then + echo "Error: Failed to extract source archive or find source directory" + echo "Contents of $TEMP_DIR:" + ls -la "$TEMP_DIR" + cd "$REPO_ROOT" + exit 1 + fi + # Convert to absolute path + SOURCE_DIR=$(cd "$SOURCE_DIR" && pwd) + cd "$REPO_ROOT" + else + echo "Error: Failed to download source from $SOURCE_URL" + exit 1 + fi + fi + fi + fi + + if [[ -z "$SOURCE_DIR" || ! -d "$SOURCE_DIR" ]]; then + echo "Error: Could not determine or obtain source for $PACKAGE (OpenSUSE-only upload)" + echo "SOURCE_DIR: $SOURCE_DIR" + if [[ -d "$TEMP_DIR" ]]; then + echo "Contents of temp directory:" + ls -la "$TEMP_DIR" + fi + exit 1 + fi + + echo " Found source directory: $SOURCE_DIR" + fi + echo " - Creating OpenSUSE-compatible source tarballs" + + # Extract Source0 from spec file + SOURCE0=$(grep "^Source0:" "distro/opensuse/$PACKAGE.spec" | awk '{print $2}' | head -1); if [[ -z "$SOURCE0" && "$PACKAGE" == "dms-git" ]]; then SOURCE0="dms-git-source.tar.gz"; fi + + if [[ -n "$SOURCE0" ]]; then + # Create a separate temporary directory for OpenSUSE tarball creation to avoid conflicts + OBS_TARBALL_DIR=$(mktemp -d -t obs-tarball-XXXXXX) + cd "$OBS_TARBALL_DIR" + + case "$PACKAGE" in + dms) + # dms spec expects DankMaterialShell-%{version} directory (from %setup -q -n DankMaterialShell-%{version}) + # Extract version from spec file + DMS_VERSION=$(grep "^Version:" "$REPO_ROOT/distro/opensuse/$PACKAGE.spec" | sed 's/^Version:[[:space:]]*//' | head -1) + EXPECTED_DIR="DankMaterialShell-${DMS_VERSION}" + echo " Creating $SOURCE0 (directory: $EXPECTED_DIR)" + cp -r "$SOURCE_DIR" "$EXPECTED_DIR" + if [[ "$SOURCE0" == *.tar.xz ]]; then + tar -cJf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + elif [[ "$SOURCE0" == *.tar.bz2 ]]; then + tar -cjf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + else + tar -czf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + fi + rm -rf "$EXPECTED_DIR" + echo " Created $SOURCE0 ($(stat -c%s "$WORK_DIR/$SOURCE0" 2>/dev/null || echo 0) bytes)" + ;; + dms-git) + # dms-git spec expects dms-git-source directory (from %setup -q -n dms-git-source) + EXPECTED_DIR="dms-git-source" + echo " Creating $SOURCE0 (directory: $EXPECTED_DIR)" + cp -r "$SOURCE_DIR" "$EXPECTED_DIR" + if [[ "$SOURCE0" == *.tar.xz ]]; then + tar -cJf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + elif [[ "$SOURCE0" == *.tar.bz2 ]]; then + tar -cjf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + else + tar -czf "$WORK_DIR/$SOURCE0" "$EXPECTED_DIR" + fi + rm -rf "$EXPECTED_DIR" + echo " Created $SOURCE0 ($(stat -c%s "$WORK_DIR/$SOURCE0" 2>/dev/null || echo 0) bytes)" + ;; + *) + # Generic handling + DIR_NAME=$(basename "$SOURCE_DIR") + echo " Creating $SOURCE0 (directory: $DIR_NAME)" + cp -r "$SOURCE_DIR" "$DIR_NAME" + if [[ "$SOURCE0" == *.tar.xz ]]; then + tar -cJf "$WORK_DIR/$SOURCE0" "$DIR_NAME" + elif [[ "$SOURCE0" == *.tar.bz2 ]]; then + tar -cjf "$WORK_DIR/$SOURCE0" "$DIR_NAME" + else + tar -czf "$WORK_DIR/$SOURCE0" "$DIR_NAME" + fi + rm -rf "$DIR_NAME" + echo " Created $SOURCE0 ($(stat -c%s "$WORK_DIR/$SOURCE0" 2>/dev/null || echo 0) bytes)" + ;; + esac + # Clean up the tarball work directory + cd "$REPO_ROOT" + rm -rf "$OBS_TARBALL_DIR" + echo " - OpenSUSE source tarballs created" + fi + + # Copy spec file + cp "distro/opensuse/$PACKAGE.spec" "$WORK_DIR/" + fi + + # Copy debian/ directory into source (for Debian builds only) + if [[ "$UPLOAD_DEBIAN" == true ]]; then + echo " Copying debian/ directory into source" + cp -r "distro/debian/$PACKAGE/debian" "$SOURCE_DIR/" + + # Create combined tarball + echo " Creating combined tarball: $COMBINED_TARBALL" + cd "$(dirname "$SOURCE_DIR")" + TARBALL_BASE=$(basename "$SOURCE_DIR") + tar -czf "$WORK_DIR/$COMBINED_TARBALL" "$TARBALL_BASE" + cd "$REPO_ROOT" + + # Generate .dsc file for native format + TARBALL_SIZE=$(stat -c%s "$WORK_DIR/$COMBINED_TARBALL" 2>/dev/null || stat -f%z "$WORK_DIR/$COMBINED_TARBALL" 2>/dev/null) + TARBALL_MD5=$(md5sum "$WORK_DIR/$COMBINED_TARBALL" | cut -d' ' -f1) + + # Extract Build-Depends from control file + BUILD_DEPS="debhelper-compat (= 13)" + if [[ -f "distro/debian/$PACKAGE/debian/control" ]]; then + CONTROL_DEPS=$(sed -n '/^Build-Depends:/,/^[A-Z]/p' "distro/debian/$PACKAGE/debian/control" | \ + sed '/^Build-Depends:/s/^Build-Depends: *//' | \ + sed '/^[A-Z]/d' | \ + tr '\n' ' ' | \ + sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/[[:space:]]\+/ /g') + if [[ -n "$CONTROL_DEPS" && "$CONTROL_DEPS" != "" ]]; then + BUILD_DEPS="$CONTROL_DEPS" + fi + fi + + cat > "$WORK_DIR/$PACKAGE.dsc" << EOF +Format: 3.0 (native) +Source: $PACKAGE +Binary: $PACKAGE +Architecture: any +Version: $VERSION +Maintainer: Avenge Media +Build-Depends: $BUILD_DEPS +Files: + $TARBALL_MD5 $TARBALL_SIZE $COMBINED_TARBALL +EOF + + echo " - Generated $PACKAGE.dsc for native format" + fi + else + # Quilt format (legacy) - for Debian only + if [[ "$UPLOAD_DEBIAN" == true ]]; then + # For quilt format, version can have revision + if [[ "$CHANGELOG_VERSION" == *"-"* ]]; then + VERSION="$CHANGELOG_VERSION" + else + VERSION="${CHANGELOG_VERSION}-1" + fi + + echo " - Quilt format detected: creating debian.tar.gz" + tar -czf "$WORK_DIR/debian.tar.gz" -C "distro/debian/$PACKAGE" debian/ + + echo " - Generating $PACKAGE.dsc for quilt format" + cat > "$WORK_DIR/$PACKAGE.dsc" << EOF +Format: 3.0 (quilt) +Source: $PACKAGE +Binary: $PACKAGE +Architecture: any +Version: $VERSION +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13), wget, gzip +DEBTRANSFORM-TAR: debian.tar.gz +Files: + 00000000000000000000000000000000 1 debian.tar.gz +EOF + fi + fi +fi + +# Change to working directory and commit +cd "$WORK_DIR" + +echo "==> Staging changes" +# List files to be uploaded +echo "Files to upload:" +# Only list files relevant to the selected upload type +if [[ "$UPLOAD_DEBIAN" == true ]] && [[ "$UPLOAD_OPENSUSE" == true ]]; then + ls -lh *.tar.gz *.tar.xz *.tar *.spec *.dsc _service 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' +elif [[ "$UPLOAD_DEBIAN" == true ]]; then + ls -lh *.tar.gz *.dsc _service 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' +elif [[ "$UPLOAD_OPENSUSE" == true ]]; then + ls -lh *.tar.gz *.tar.xz *.tar *.spec _service 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' +fi +echo "" + +osc addremove + +echo "==> Committing to OBS" +osc commit -m "$MESSAGE" + +echo "==> Checking build status" +osc results + +echo "" +echo "Upload complete! Monitor builds with:" +echo " cd $WORK_DIR && osc results" +echo " cd $WORK_DIR && osc buildlog " +echo "" + +# Don't cleanup - keep checkout for status checking +echo "" +echo "Upload complete! Build status:" +cd "$WORK_DIR" +osc results 2>&1 | head -10 +cd "$REPO_ROOT" + +echo "" +echo "To check detailed status:" +echo " cd $WORK_DIR && osc results" +echo " cd $WORK_DIR && osc remotebuildlog $OBS_PROJECT $PACKAGE Debian_13 x86_64" +echo "" +echo "NOTE: Checkout kept at $WORK_DIR for status checking" +echo "" +echo "✅ Upload complete!" +echo "" +echo "Check build status with:" +echo " ./distro/scripts/obs-status.sh $PACKAGE" diff --git a/distro/scripts/test-packaging.sh b/distro/scripts/test-packaging.sh new file mode 100755 index 00000000..05ac7568 --- /dev/null +++ b/distro/scripts/test-packaging.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# Manual testing script for DMS packaging +# Tests OBS (Debian/openSUSE) and PPA (Ubuntu) workflows +# Usage: ./distro/test-packaging.sh [obs|ppa|all] + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DISTRO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +REPO_ROOT="$(cd "$DISTRO_DIR/.." && pwd)" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +info() { echo -e "${BLUE}[INFO]${NC} $1"; } +success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } + +TEST_MODE="${1:-all}" + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "DMS Packaging Test Suite" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Test 1: OBS Upload (Debian + openSUSE) +if [[ "$TEST_MODE" == "obs" ]] || [[ "$TEST_MODE" == "all" ]]; then + echo "═══════════════════════════════════════════════════════════════════" + echo "TEST 1: OBS Upload (Debian + openSUSE)" + echo "═══════════════════════════════════════════════════════════════════" + echo "" + + OBS_SCRIPT="$SCRIPT_DIR/obs-upload.sh" + + if [[ ! -f "$OBS_SCRIPT" ]]; then + error "OBS script not found: $OBS_SCRIPT" + exit 1 + fi + + info "OBS script location: $OBS_SCRIPT" + info "Available packages: dms, dms-git" + echo "" + + warn "This will upload to OBS (home:AvengeMedia)" + read -p "Continue with OBS test? [y/N] " -n 1 -r + echo + + if [[ $REPLY =~ ^[Yy]$ ]]; then + info "Select package to test:" + echo " 1. dms (stable)" + echo " 2. dms-git (nightly)" + echo " 3. all (both packages)" + read -p "Choice [1]: " -n 1 -r PKG_CHOICE + echo + echo "" + + PKG_CHOICE="${PKG_CHOICE:-1}" + + cd "$REPO_ROOT" + + case "$PKG_CHOICE" in + 1) + info "Testing OBS upload for 'dms' package..." + bash "$OBS_SCRIPT" dms "Test packaging update" + ;; + 2) + info "Testing OBS upload for 'dms-git' package..." + bash "$OBS_SCRIPT" dms-git "Test packaging update" + ;; + 3) + info "Testing OBS upload for all packages..." + bash "$OBS_SCRIPT" all "Test packaging update" + ;; + *) + error "Invalid choice" + exit 1 + ;; + esac + + echo "" + success "OBS test completed" + echo "" + info "Check build status: https://build.opensuse.org/project/monitor/home:AvengeMedia" + else + warn "OBS test skipped" + fi + + echo "" +fi + +# Test 2: PPA Upload (Ubuntu) +if [[ "$TEST_MODE" == "ppa" ]] || [[ "$TEST_MODE" == "all" ]]; then + echo "═══════════════════════════════════════════════════════════════════" + echo "TEST 2: PPA Upload (Ubuntu)" + echo "═══════════════════════════════════════════════════════════════════" + echo "" + + PPA_SCRIPT="$DISTRO_DIR/ubuntu/ppa/create-and-upload.sh" + + if [[ ! -f "$PPA_SCRIPT" ]]; then + error "PPA script not found: $PPA_SCRIPT" + exit 1 + fi + + info "PPA script location: $PPA_SCRIPT" + info "Available PPAs: dms, dms-git" + info "Ubuntu series: questing (25.10)" + echo "" + + warn "This will upload to Launchpad PPA (ppa:avengemedia/dms)" + read -p "Continue with PPA test? [y/N] " -n 1 -r + echo + + if [[ $REPLY =~ ^[Yy]$ ]]; then + info "Select package to test:" + echo " 1. dms (stable)" + echo " 2. dms-git (nightly)" + read -p "Choice [1]: " -n 1 -r PKG_CHOICE + echo + echo "" + + PKG_CHOICE="${PKG_CHOICE:-1}" + + case "$PKG_CHOICE" in + 1) + info "Testing PPA upload for 'dms' package..." + DMS_PKG="$DISTRO_DIR/ubuntu/dms" + PPA_NAME="dms" + ;; + 2) + info "Testing PPA upload for 'dms-git' package..." + DMS_PKG="$DISTRO_DIR/ubuntu/dms-git" + PPA_NAME="dms-git" + ;; + *) + error "Invalid choice" + exit 1 + ;; + esac + + echo "" + + if [[ ! -d "$DMS_PKG" ]]; then + error "DMS package directory not found: $DMS_PKG" + exit 1 + fi + + bash "$PPA_SCRIPT" "$DMS_PKG" "$PPA_NAME" questing + + echo "" + success "PPA test completed" + echo "" + info "Check build status: https://launchpad.net/~avengemedia/+archive/ubuntu/dms/+packages" + else + warn "PPA test skipped" + fi + + echo "" +fi + +# Summary +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "Testing Summary" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" diff --git a/distro/ubuntu/danklinux/danksearch/debian/changelog b/distro/ubuntu/danklinux/danksearch/debian/changelog new file mode 100644 index 00000000..10746dea --- /dev/null +++ b/distro/ubuntu/danklinux/danksearch/debian/changelog @@ -0,0 +1,5 @@ +danksearch (0.0.7ppa3) questing; urgency=medium + + * Rebuild for packaging fixes (ppa3) + + -- Avenge Media Fri, 21 Nov 2025 14:19:58 -0500 diff --git a/distro/ubuntu/danklinux/danksearch/debian/control b/distro/ubuntu/danklinux/danksearch/debian/control new file mode 100644 index 00000000..03975eac --- /dev/null +++ b/distro/ubuntu/danklinux/danksearch/debian/control @@ -0,0 +1,24 @@ +Source: danksearch +Section: utils +Priority: optional +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 +Homepage: https://github.com/AvengeMedia/danksearch +Vcs-Browser: https://github.com/AvengeMedia/danksearch +Vcs-Git: https://github.com/AvengeMedia/danksearch.git + +Package: danksearch +Architecture: amd64 arm64 +Depends: ${misc:Depends} +Description: Fast file search utility for DMS + DankSearch is a fast file search utility designed for DankMaterialShell. + It provides efficient file and content search capabilities with minimal + dependencies. This package contains the pre-built binary from the official + GitHub release. + . + Features include: + - Fast file searching + - Lightweight and efficient + - Designed for DMS integration + - Minimal resource usage diff --git a/distro/ubuntu/danklinux/danksearch/debian/copyright b/distro/ubuntu/danklinux/danksearch/debian/copyright new file mode 100644 index 00000000..7c832574 --- /dev/null +++ b/distro/ubuntu/danklinux/danksearch/debian/copyright @@ -0,0 +1,24 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: danksearch +Upstream-Contact: Avenge Media LLC +Source: https://github.com/AvengeMedia/danksearch + +Files: * +Copyright: 2025 Avenge Media LLC +License: GPL-3.0-only + +License: GPL-3.0-only + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/distro/ubuntu/danklinux/danksearch/debian/files b/distro/ubuntu/danklinux/danksearch/debian/files new file mode 100644 index 00000000..ac634a6d --- /dev/null +++ b/distro/ubuntu/danklinux/danksearch/debian/files @@ -0,0 +1 @@ +danksearch_0.0.7ppa3_source.buildinfo utils optional diff --git a/distro/ubuntu/danklinux/danksearch/debian/rules b/distro/ubuntu/danklinux/danksearch/debian/rules new file mode 100755 index 00000000..a9c821e3 --- /dev/null +++ b/distro/ubuntu/danklinux/danksearch/debian/rules @@ -0,0 +1,33 @@ +#!/usr/bin/make -f + +export DH_VERBOSE = 1 + +# Detect architecture for selecting correct binary +DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) + +# Map Debian arch to binary filename +ifeq ($(DEB_HOST_ARCH),amd64) + BINARY_FILE := dsearch-amd64 +else ifeq ($(DEB_HOST_ARCH),arm64) + BINARY_FILE := dsearch-arm64 +else + $(error Unsupported architecture: $(DEB_HOST_ARCH)) +endif + +%: + dh $@ + +override_dh_auto_build: + # Binary is already included in source package (native format) + # Downloaded by build-source.sh before upload + # Just verify it exists and is executable + test -f $(BINARY_FILE) || (echo "ERROR: $(BINARY_FILE) not found!" && exit 1) + chmod +x $(BINARY_FILE) + +override_dh_auto_install: + # Install binary as danksearch + install -Dm755 $(BINARY_FILE) debian/danksearch/usr/bin/danksearch + +override_dh_auto_clean: + # Don't delete binaries - they're part of the source package (native format) + dh_auto_clean diff --git a/distro/ubuntu/danklinux/danksearch/debian/source/format b/distro/ubuntu/danklinux/danksearch/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/distro/ubuntu/danklinux/danksearch/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/distro/ubuntu/danklinux/danksearch/dsearch-amd64 b/distro/ubuntu/danklinux/danksearch/dsearch-amd64 new file mode 100755 index 00000000..e66bcbf7 Binary files /dev/null and b/distro/ubuntu/danklinux/danksearch/dsearch-amd64 differ diff --git a/distro/ubuntu/danklinux/danksearch/dsearch-arm64 b/distro/ubuntu/danklinux/danksearch/dsearch-arm64 new file mode 100755 index 00000000..fd6d1d66 Binary files /dev/null and b/distro/ubuntu/danklinux/danksearch/dsearch-arm64 differ diff --git a/distro/ubuntu/danklinux/dgop/debian/changelog b/distro/ubuntu/danklinux/dgop/debian/changelog new file mode 100644 index 00000000..43632cd9 --- /dev/null +++ b/distro/ubuntu/danklinux/dgop/debian/changelog @@ -0,0 +1,9 @@ +dgop (0.1.11ppa2) questing; urgency=medium + + * Rebuild for Questing (25.10) - Ubuntu 25.10+ only + * Stateless CPU/GPU monitoring tool + * Support for NVIDIA and AMD GPUs + * JSON output for integration + * Pre-built binary package for amd64 and arm64 + + -- Avenge Media Sun, 16 Nov 2025 22:50:00 -0500 diff --git a/distro/ubuntu/danklinux/dgop/debian/control b/distro/ubuntu/danklinux/dgop/debian/control new file mode 100644 index 00000000..f1dd4614 --- /dev/null +++ b/distro/ubuntu/danklinux/dgop/debian/control @@ -0,0 +1,27 @@ +Source: dgop +Section: utils +Priority: optional +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13), + wget, + gzip +Standards-Version: 4.6.2 +Homepage: https://github.com/AvengeMedia/dgop +Vcs-Browser: https://github.com/AvengeMedia/dgop +Vcs-Git: https://github.com/AvengeMedia/dgop.git + +Package: dgop +Architecture: amd64 arm64 +Depends: ${misc:Depends} +Description: Stateless CPU/GPU monitor for DankMaterialShell + 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. + . + Features: + - CPU usage monitoring + - GPU usage and temperature (NVIDIA, AMD) + - Memory and swap statistics + - Network traffic monitoring + - Zero-state design (no background processes) + - JSON output for easy integration diff --git a/distro/ubuntu/danklinux/dgop/debian/copyright b/distro/ubuntu/danklinux/dgop/debian/copyright new file mode 100644 index 00000000..f1f3b2dd --- /dev/null +++ b/distro/ubuntu/danklinux/dgop/debian/copyright @@ -0,0 +1,27 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dgop +Upstream-Contact: Avenge Media LLC +Source: https://github.com/AvengeMedia/dgop + +Files: * +Copyright: 2025 Avenge Media LLC +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/distro/ubuntu/danklinux/dgop/debian/files b/distro/ubuntu/danklinux/dgop/debian/files new file mode 100644 index 00000000..d4bb33d1 --- /dev/null +++ b/distro/ubuntu/danklinux/dgop/debian/files @@ -0,0 +1 @@ +dgop_0.1.11ppa2_source.buildinfo utils optional diff --git a/distro/ubuntu/danklinux/dgop/debian/rules b/distro/ubuntu/danklinux/dgop/debian/rules new file mode 100755 index 00000000..0af8b692 --- /dev/null +++ b/distro/ubuntu/danklinux/dgop/debian/rules @@ -0,0 +1,38 @@ +#!/usr/bin/make -f + +export DH_VERBOSE = 1 + +# Extract version from debian/changelog +DEB_VERSION := $(shell dpkg-parsechangelog -S Version) +# Get upstream version (strip -1ppa1 suffix) +UPSTREAM_VERSION := $(shell echo $(DEB_VERSION) | sed 's/-[^-]*$$//') + +# Detect architecture for downloading correct binary +DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) + +# Map Debian arch to GitHub release arch names +ifeq ($(DEB_HOST_ARCH),amd64) + GITHUB_ARCH := amd64 +else ifeq ($(DEB_HOST_ARCH),arm64) + GITHUB_ARCH := arm64 +else + $(error Unsupported architecture: $(DEB_HOST_ARCH)) +endif + +%: + dh $@ + +override_dh_auto_build: + # Binary is already included in source package (native format) + # Just verify it exists and is executable + test -f dgop || (echo "ERROR: dgop binary not found!" && exit 1) + chmod +x dgop + +override_dh_auto_install: + # Install binary + install -Dm755 dgop debian/dgop/usr/bin/dgop + +override_dh_auto_clean: + # Don't delete dgop binary - it's part of the source package (native format) + rm -f dgop.gz + dh_auto_clean diff --git a/distro/ubuntu/danklinux/dgop/debian/source/format b/distro/ubuntu/danklinux/dgop/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/distro/ubuntu/danklinux/dgop/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/distro/ubuntu/dms-git/debian/changelog b/distro/ubuntu/dms-git/debian/changelog new file mode 100644 index 00000000..6ed3a3ed --- /dev/null +++ b/distro/ubuntu/dms-git/debian/changelog @@ -0,0 +1,5 @@ +dms-git (0.6.2+git2094.6cc6e7c8ppa1) questing; urgency=medium + + * Git snapshot (commit 2094: 6cc6e7c8) + + -- Avenge Media Sun, 23 Nov 2025 00:43:28 -0500 diff --git a/distro/ubuntu/dms-git/debian/control b/distro/ubuntu/dms-git/debian/control new file mode 100644 index 00000000..e974f8c5 --- /dev/null +++ b/distro/ubuntu/dms-git/debian/control @@ -0,0 +1,50 @@ +Source: dms-git +Section: x11 +Priority: optional +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 +Homepage: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Browser: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Git: https://github.com/AvengeMedia/DankMaterialShell.git + +Package: dms-git +Architecture: amd64 +Depends: ${misc:Depends}, + quickshell-git | quickshell, + accountsservice, + cava, + cliphist, + danksearch, + dgop, + matugen, + qml6-module-qtcore, + qml6-module-qtmultimedia, + qml6-module-qtqml, + qml6-module-qtquick, + qml6-module-qtquick-controls, + qml6-module-qtquick-dialogs, + qml6-module-qtquick-effects, + qml6-module-qtquick-layouts, + qml6-module-qtquick-templates, + qml6-module-qtquick-window, + qt6ct, + wl-clipboard +Provides: dms +Conflicts: dms +Replaces: dms +Description: DankMaterialShell - Modern Wayland Desktop Shell (git nightly) + DMS (DankMaterialShell) is a feature-rich desktop shell built on + Quickshell, providing a modern and customizable user interface for + Wayland compositors like niri, hyprland, and sway. + . + This is the nightly/git version built from the latest master branch. + . + Features include: + - Material Design inspired UI + - Customizable themes and appearance + - Built-in application launcher + - System tray and notifications + - Network and Bluetooth management + - Audio controls + - Systemd integration diff --git a/distro/ubuntu/dms-git/debian/copyright b/distro/ubuntu/dms-git/debian/copyright new file mode 100644 index 00000000..1e7bce73 --- /dev/null +++ b/distro/ubuntu/dms-git/debian/copyright @@ -0,0 +1,27 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dms +Upstream-Contact: Avenge Media LLC +Source: https://github.com/AvengeMedia/DankMaterialShell + +Files: * +Copyright: 2025 Avenge Media LLC +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/distro/ubuntu/dms-git/debian/files b/distro/ubuntu/dms-git/debian/files new file mode 100644 index 00000000..10d74fb1 --- /dev/null +++ b/distro/ubuntu/dms-git/debian/files @@ -0,0 +1 @@ +dms-git_0.6.2+git2094.6cc6e7c8ppa1_source.buildinfo x11 optional diff --git a/distro/ubuntu/dms-git/debian/rules b/distro/ubuntu/dms-git/debian/rules new file mode 100755 index 00000000..9cd337c6 --- /dev/null +++ b/distro/ubuntu/dms-git/debian/rules @@ -0,0 +1,45 @@ +#!/usr/bin/make -f + +export DH_VERBOSE = 1 + +# Get git commit date for version +GIT_DATE := $(shell date +%Y%m%d) +GIT_COMMIT := HEAD + +%: + dh $@ + +override_dh_auto_build: + # Git source is already included in source package (cloned by build-source.sh) + # Launchpad build environment has no internet access + test -d dms-git-repo || (echo "ERROR: dms-git-repo directory not found!" && exit 1) + test -f dms-distropkg-amd64.gz || (echo "ERROR: dms-distropkg-amd64.gz not found!" && exit 1) + + # Extract pre-built binary from latest release + # Note: For git versions, we use the latest release binary + # The QML files come from git master + gunzip -c dms-distropkg-amd64.gz > dms + chmod +x dms + +override_dh_auto_install: + # Install binary + install -Dm755 dms debian/dms-git/usr/bin/dms + + # Install QML files from git clone + mkdir -p debian/dms-git/usr/share/quickshell/dms + cp -r dms-git-repo/* debian/dms-git/usr/share/quickshell/dms/ + + # Remove unnecessary directories + rm -rf debian/dms-git/usr/share/quickshell/dms/core + rm -rf debian/dms-git/usr/share/quickshell/dms/distro + + # Install systemd user service + install -Dm644 dms-git-repo/quickshell/assets/systemd/dms.service \ + debian/dms-git/usr/lib/systemd/user/dms.service + +override_dh_auto_clean: + # Don't delete dms-git-repo directory - it's part of the source package (native format) + # Clean up build artifacts (but keep dms-distropkg-amd64.gz for Launchpad) + rm -f dms + # Don't remove dms-distropkg-amd64.gz - it needs to be included in the source package for Launchpad builds + dh_auto_clean diff --git a/distro/ubuntu/dms-git/debian/source/format b/distro/ubuntu/dms-git/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/distro/ubuntu/dms-git/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/distro/ubuntu/dms-git/debian/source/include-binaries b/distro/ubuntu/dms-git/debian/source/include-binaries new file mode 100644 index 00000000..77d7423a --- /dev/null +++ b/distro/ubuntu/dms-git/debian/source/include-binaries @@ -0,0 +1 @@ +dms-distropkg-amd64.gz diff --git a/distro/ubuntu/dms-git/debian/source/options b/distro/ubuntu/dms-git/debian/source/options new file mode 100644 index 00000000..dc3f6a5a --- /dev/null +++ b/distro/ubuntu/dms-git/debian/source/options @@ -0,0 +1,4 @@ +# Include files that are normally excluded by .gitignore +# These are needed for the build process on Launchpad (which has no internet access) +tar-ignore = !dms-distropkg-amd64.gz +tar-ignore = !dms-git-repo diff --git a/distro/ubuntu/dms/debian/changelog b/distro/ubuntu/dms/debian/changelog new file mode 100644 index 00000000..634af4eb --- /dev/null +++ b/distro/ubuntu/dms/debian/changelog @@ -0,0 +1,5 @@ +dms (0.6.2ppa3) questing; urgency=medium + + * Rebuild for packaging fixes (ppa3) + + -- Avenge Media Sun, 23 Nov 2025 00:40:41 -0500 diff --git a/distro/ubuntu/dms/debian/control b/distro/ubuntu/dms/debian/control new file mode 100644 index 00000000..91e63601 --- /dev/null +++ b/distro/ubuntu/dms/debian/control @@ -0,0 +1,47 @@ +Source: dms +Section: x11 +Priority: optional +Maintainer: Avenge Media +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 +Homepage: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Browser: https://github.com/AvengeMedia/DankMaterialShell +Vcs-Git: https://github.com/AvengeMedia/DankMaterialShell.git + +Package: dms +Architecture: amd64 +Depends: ${misc:Depends}, + quickshell-git | quickshell, + accountsservice, + cava, + cliphist, + danksearch, + dgop, + matugen, + qml6-module-qtcore, + qml6-module-qtmultimedia, + qml6-module-qtqml, + qml6-module-qtquick, + qml6-module-qtquick-controls, + qml6-module-qtquick-dialogs, + qml6-module-qtquick-effects, + qml6-module-qtquick-layouts, + qml6-module-qtquick-templates, + qml6-module-qtquick-window, + qt6ct, + wl-clipboard +Conflicts: dms-git +Replaces: dms-git +Description: DankMaterialShell - Modern Wayland Desktop Shell + DMS (DankMaterialShell) is a feature-rich desktop shell built on + Quickshell, providing a modern and customizable user interface for + Wayland compositors like niri, hyprland, and sway. + . + Features include: + - Material Design inspired UI + - Customizable themes and appearance + - Built-in application launcher + - System tray and notifications + - Network and Bluetooth management + - Audio controls + - Systemd integration diff --git a/distro/ubuntu/dms/debian/copyright b/distro/ubuntu/dms/debian/copyright new file mode 100644 index 00000000..1e7bce73 --- /dev/null +++ b/distro/ubuntu/dms/debian/copyright @@ -0,0 +1,27 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dms +Upstream-Contact: Avenge Media LLC +Source: https://github.com/AvengeMedia/DankMaterialShell + +Files: * +Copyright: 2025 Avenge Media LLC +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/distro/ubuntu/dms/debian/files b/distro/ubuntu/dms/debian/files new file mode 100644 index 00000000..d527f9a1 --- /dev/null +++ b/distro/ubuntu/dms/debian/files @@ -0,0 +1 @@ +dms_0.6.2ppa3_source.buildinfo x11 optional diff --git a/distro/ubuntu/dms/debian/rules b/distro/ubuntu/dms/debian/rules new file mode 100755 index 00000000..73c3ce04 --- /dev/null +++ b/distro/ubuntu/dms/debian/rules @@ -0,0 +1,63 @@ +#!/usr/bin/make -f + +export DH_VERBOSE = 1 + +# Extract version from debian/changelog +DEB_VERSION := $(shell dpkg-parsechangelog -S Version) +# Get upstream version (strip -1ppa1 suffix) +UPSTREAM_VERSION := $(shell echo $(DEB_VERSION) | sed 's/-[^-]*$$//') +# Strip ppa suffix and handle git versions +# Examples: 0.5.2ppa9 -> 0.5.2, 0.5.2+git20251116 -> 0.5.2 +BASE_VERSION := $(shell echo $(UPSTREAM_VERSION) | sed 's/ppa[0-9]*$$//' | sed 's/+git.*//') + +%: + dh $@ + +override_dh_auto_build: + # All files are included in source package (downloaded by build-source.sh) + # Launchpad build environment has no internet access + test -f dms-distropkg-amd64.gz || (echo "ERROR: dms-distropkg-amd64.gz not found!" && exit 1) + test -f dms-source.tar.gz || (echo "ERROR: dms-source.tar.gz not found!" && exit 1) + + # Extract pre-built binary + gunzip -c dms-distropkg-amd64.gz > dms + chmod +x dms + + # Extract source tarball for QML files + tar -xzf dms-source.tar.gz + # Find the extracted directory (it might have various names) + # and create a symlink to expected name for consistent install + SOURCE_DIR=$$(find . -maxdepth 1 -type d -name "DankMaterialShell*" | head -n1); \ + if [ -n "$$SOURCE_DIR" ]; then \ + ln -sf $$SOURCE_DIR DankMaterialShell-$(BASE_VERSION); \ + fi + +override_dh_auto_install: + # Install binary + install -Dm755 dms debian/dms/usr/bin/dms + + # Install QML files from source tarball + mkdir -p debian/dms/usr/share/quickshell/dms + cp -r DankMaterialShell-$(BASE_VERSION)/* debian/dms/usr/share/quickshell/dms/ + + # Remove unnecessary directories + rm -rf debian/dms/usr/share/quickshell/dms/core + rm -rf debian/dms/usr/share/quickshell/dms/distro + + # Install systemd user service + install -Dm644 DankMaterialShell-$(BASE_VERSION)/quickshell/assets/systemd/dms.service \ + debian/dms/usr/lib/systemd/user/dms.service + + # Generate and install shell completions (if applicable) + # Uncomment if dms supports completion generation + # ./dms completion bash > dms.bash + # ./dms completion zsh > dms.zsh + # install -Dm644 dms.bash debian/dms/usr/share/bash-completion/completions/dms + # install -Dm644 dms.zsh debian/dms/usr/share/zsh/vendor-completions/_dms + +override_dh_auto_clean: + rm -f dms + rm -rf DankMaterialShell-* + # Don't remove dms-distropkg-amd64.gz and dms-source.tar.gz + # They need to be included in the source package for Launchpad builds + dh_auto_clean diff --git a/distro/ubuntu/dms/debian/source/format b/distro/ubuntu/dms/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/distro/ubuntu/dms/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/distro/ubuntu/dms/debian/source/include-binaries b/distro/ubuntu/dms/debian/source/include-binaries new file mode 100644 index 00000000..bac25ab7 --- /dev/null +++ b/distro/ubuntu/dms/debian/source/include-binaries @@ -0,0 +1,2 @@ +dms-distropkg-amd64.gz +dms-source.tar.gz diff --git a/distro/ubuntu/dms/debian/source/options b/distro/ubuntu/dms/debian/source/options new file mode 100644 index 00000000..ca1d9b05 --- /dev/null +++ b/distro/ubuntu/dms/debian/source/options @@ -0,0 +1,4 @@ +# Include files that are normally excluded by .gitignore +# These are needed for the build process on Launchpad (which has no internet access) +tar-ignore = !dms-distropkg-amd64.gz +tar-ignore = !dms-source.tar.gz diff --git a/distro/ubuntu/dput.cf.template b/distro/ubuntu/dput.cf.template new file mode 100644 index 00000000..275cc625 --- /dev/null +++ b/distro/ubuntu/dput.cf.template @@ -0,0 +1,44 @@ +# dput configuration for AvengeMedia DMS PPAs +# Copy this to ~/.dput.cf (or merge with existing ~/.dput.cf) +# +# Usage: +# dput ppa:avengemedia/dms ../package_version_source.changes +# dput ppa:avengemedia/dms-git ../package_version_source.changes + +# Stable DMS PPA - for release versions +[ppa:avengemedia/dms] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~avengemedia/ubuntu/dms/ +login = anonymous +allow_unsigned_uploads = 0 + +# Nightly/Git DMS PPA - for development builds +[ppa:avengemedia/dms-git] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~avengemedia/ubuntu/dms-git/ +login = anonymous +allow_unsigned_uploads = 0 + +# Alternative: Use HTTPS instead of FTP (more reliable through firewalls) +# Uncomment these if FTP doesn't work: +# +# [ppa:avengemedia/dms-https] +# fqdn = ppa.launchpad.net +# method = https +# incoming = ~avengemedia/ubuntu/dms/ +# login = anonymous +# allow_unsigned_uploads = 0 +# +# [ppa:avengemedia/dms-git-https] +# fqdn = ppa.launchpad.net +# method = https +# incoming = ~avengemedia/ubuntu/dms-git/ +# login = anonymous +# allow_unsigned_uploads = 0 + +# Notes: +# - allow_unsigned_uploads = 0 enforces GPG signing (required by Launchpad) +# - anonymous login is standard for PPA uploads +# - The incoming path must match your Launchpad username and PPA name diff --git a/distro/ubuntu/ppa/create-and-upload.sh b/distro/ubuntu/ppa/create-and-upload.sh new file mode 100755 index 00000000..1169d9d2 --- /dev/null +++ b/distro/ubuntu/ppa/create-and-upload.sh @@ -0,0 +1,246 @@ +#!/bin/bash +# Build and upload PPA package with automatic cleanup +# Usage: ./create-and-upload.sh [ubuntu-series] [--keep-builds] +# +# Example: +# ./create-and-upload.sh ../dms dms questing +# ./create-and-upload.sh ../danklinux/dgop danklinux questing --keep-builds + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +info() { echo -e "${BLUE}[INFO]${NC} $1"; } +success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# Parse arguments +KEEP_BUILDS=false +ARGS=() +for arg in "$@"; do + if [ "$arg" = "--keep-builds" ]; then + KEEP_BUILDS=true + else + ARGS+=("$arg") + fi +done + +if [ ${#ARGS[@]} -lt 2 ]; then + error "Usage: $0 [ubuntu-series] [--keep-builds]" + echo + echo "Arguments:" + echo " package-dir : Path to package directory (e.g., ../dms, ../danklinux/dgop)" + echo " ppa-name : PPA name (danklinux, dms, dms-git)" + echo " ubuntu-series : Ubuntu series (optional, default: questing)" + echo " Supported: questing (25.10) and newer only" + echo " Note: Requires Qt 6.6+ (quickshell requirement)" + echo " --keep-builds : Keep build artifacts after upload (optional)" + echo + echo "Examples:" + echo " $0 ../dms dms questing" + echo " $0 ../danklinux/dgop danklinux questing --keep-builds" + echo " $0 ../dms-git dms-git # Defaults to questing" + exit 1 +fi + +PACKAGE_DIR="${ARGS[0]}" +PPA_NAME="${ARGS[1]}" +UBUNTU_SERIES="${ARGS[2]:-questing}" + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +BUILD_SCRIPT="$SCRIPT_DIR/create-source.sh" +UPLOAD_SCRIPT="$SCRIPT_DIR/upload-ppa.sh" + +# Validate scripts exist +if [ ! -f "$BUILD_SCRIPT" ]; then + error "Build script not found: $BUILD_SCRIPT" + exit 1 +fi + +# Get absolute path +PACKAGE_DIR=$(cd "$PACKAGE_DIR" && pwd) +PACKAGE_NAME=$(basename "$PACKAGE_DIR") +PARENT_DIR=$(dirname "$PACKAGE_DIR") + +info "Building and uploading: $PACKAGE_NAME" +info "Package directory: $PACKAGE_DIR" +info "PPA: ppa:avengemedia/$PPA_NAME" +info "Ubuntu series: $UBUNTU_SERIES" +echo + +# Step 1: Build source package +info "Step 1: Building source package..." +if ! "$BUILD_SCRIPT" "$PACKAGE_DIR" "$UBUNTU_SERIES"; then + error "Build failed!" + exit 1 +fi + +# Find the changes file +CHANGES_FILE=$(find "$PARENT_DIR" -maxdepth 1 -name "${PACKAGE_NAME}_*_source.changes" -type f | sort -V | tail -1) + +if [ -z "$CHANGES_FILE" ]; then + error "Changes file not found in $PARENT_DIR" + exit 1 +fi + +info "Found changes file: $CHANGES_FILE" +echo + +# Step 2: Upload to PPA +info "Step 2: Uploading to PPA..." + +# Check if using lftp (for all PPAs) or dput +if [ "$PPA_NAME" = "danklinux" ] || [ "$PPA_NAME" = "dms" ] || [ "$PPA_NAME" = "dms-git" ]; then + warn "Using lftp for upload" + + # Extract version from changes file + VERSION=$(grep "^Version:" "$CHANGES_FILE" | awk '{print $2}') + SOURCE_NAME=$(grep "^Source:" "$CHANGES_FILE" | awk '{print $2}') + + # Find all files to upload + BUILD_DIR=$(dirname "$CHANGES_FILE") + CHANGES_BASENAME=$(basename "$CHANGES_FILE") + DSC_FILE="${CHANGES_BASENAME/_source.changes/.dsc}" + TARBALL="${CHANGES_BASENAME/_source.changes/.tar.xz}" + BUILDINFO="${CHANGES_BASENAME/_source.changes/_source.buildinfo}" + + # Check all files exist + MISSING_FILES=() + [ ! -f "$BUILD_DIR/$DSC_FILE" ] && MISSING_FILES+=("$DSC_FILE") + [ ! -f "$BUILD_DIR/$TARBALL" ] && MISSING_FILES+=("$TARBALL") + [ ! -f "$BUILD_DIR/$BUILDINFO" ] && MISSING_FILES+=("$BUILDINFO") + + if [ ${#MISSING_FILES[@]} -gt 0 ]; then + error "Missing required files:" + for file in "${MISSING_FILES[@]}"; do + error " - $file" + done + exit 1 + fi + + info "Uploading files:" + info " - $CHANGES_BASENAME" + info " - $DSC_FILE" + info " - $TARBALL" + info " - $BUILDINFO" + echo + + # lftp build dir change + LFTP_SCRIPT=$(mktemp) + cat > "$LFTP_SCRIPT" < [ubuntu-series] +# +# Example: +# ./create-source.sh ../dms questing +# ./create-source.sh ../dms-git questing + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +info() { echo -e "${BLUE}[INFO]${NC} $1"; } +success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; } + +if [ $# -lt 1 ]; then + error "Usage: $0 [ubuntu-series]" + echo + echo "Arguments:" + echo " package-dir : Path to package directory (e.g., ../dms)" + echo " ubuntu-series : Ubuntu series (optional, default: noble)" + echo " Options: noble, jammy, oracular, mantic" + echo + echo "Examples:" + echo " $0 ../dms questing" + echo " $0 ../dms-git questing" + exit 1 +fi + +PACKAGE_DIR="$1" +UBUNTU_SERIES="${2:-noble}" + +# Validate package directory +if [ ! -d "$PACKAGE_DIR" ]; then + error "Package directory not found: $PACKAGE_DIR" + exit 1 +fi + +if [ ! -d "$PACKAGE_DIR/debian" ]; then + error "No debian/ directory found in $PACKAGE_DIR" + exit 1 +fi + +# Get absolute path +PACKAGE_DIR=$(cd "$PACKAGE_DIR" && pwd) +PACKAGE_NAME=$(basename "$PACKAGE_DIR") + +info "Building source package for: $PACKAGE_NAME" +info "Package directory: $PACKAGE_DIR" +info "Target Ubuntu series: $UBUNTU_SERIES" + +# Check for required files +REQUIRED_FILES=( + "debian/control" + "debian/rules" + "debian/changelog" + "debian/copyright" + "debian/source/format" +) + +for file in "${REQUIRED_FILES[@]}"; do + if [ ! -f "$PACKAGE_DIR/$file" ]; then + error "Required file missing: $file" + exit 1 + fi +done + +# Verify GPG key is set up +info "Checking GPG key setup..." +if ! gpg --list-secret-keys &> /dev/null; then + error "No GPG secret keys found. Please set up GPG first!" + error "See GPG_SETUP.md for instructions" + exit 1 +fi + +success "GPG key found" + +# Check if debuild is installed +if ! command -v debuild &> /dev/null; then + error "debuild not found. Install devscripts:" + error " sudo dnf install devscripts" + exit 1 +fi + +# Extract package info from changelog +cd "$PACKAGE_DIR" +CHANGELOG_VERSION=$(dpkg-parsechangelog -S Version) +SOURCE_NAME=$(dpkg-parsechangelog -S Source) + +info "Source package: $SOURCE_NAME" +info "Version: $CHANGELOG_VERSION" + +# Check if version targets correct Ubuntu series +CHANGELOG_SERIES=$(dpkg-parsechangelog -S Distribution) +if [ "$CHANGELOG_SERIES" != "$UBUNTU_SERIES" ] && [ "$CHANGELOG_SERIES" != "UNRELEASED" ]; then + warn "Changelog targets '$CHANGELOG_SERIES' but building for '$UBUNTU_SERIES'" + warn "Consider updating changelog with: dch -r '' -D $UBUNTU_SERIES" +fi + +# Detect package type and update version automatically +cd "$PACKAGE_DIR" + +# Function to get latest tag from GitHub +get_latest_tag() { + local repo="$1" + # Try GitHub API first (faster) + if command -v curl &> /dev/null; then + LATEST_TAG=$(curl -s "https://api.github.com/repos/$repo/releases/latest" 2>/dev/null | grep '"tag_name":' | sed 's/.*"tag_name": "\(.*\)".*/\1/' | head -1) + if [ -n "$LATEST_TAG" ]; then + echo "$LATEST_TAG" | sed 's/^v//' + return + fi + fi + # Fallback: clone and get latest tag + TEMP_REPO=$(mktemp -d) + if git clone --depth=1 --quiet "https://github.com/$repo.git" "$TEMP_REPO" 2>/dev/null; then + LATEST_TAG=$(cd "$TEMP_REPO" && git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "") + rm -rf "$TEMP_REPO" + echo "$LATEST_TAG" + fi +} + +# Detect if package is git-based +IS_GIT_PACKAGE=false +GIT_REPO="" +SOURCE_DIR="" + +# Check package name for -git suffix +if [[ "$PACKAGE_NAME" == *"-git" ]]; then + IS_GIT_PACKAGE=true +fi + +# Check rules file for git clone patterns and extract repo +if grep -q "git clone" debian/rules 2>/dev/null; then + IS_GIT_PACKAGE=true + # Extract GitHub repo URL from rules + GIT_URL=$(grep -o "git clone.*https://github.com/[^/]*/[^/]*\.git" debian/rules 2>/dev/null | head -1 | sed 's/.*github\.com\///' | sed 's/\.git.*//' || echo "") + if [ -n "$GIT_URL" ]; then + GIT_REPO="$GIT_URL" + fi +fi + +# Special handling for known packages +case "$PACKAGE_NAME" in + dms-git) + IS_GIT_PACKAGE=true + GIT_REPO="AvengeMedia/DankMaterialShell" + SOURCE_DIR="dms-git-repo" + ;; + dms) + GIT_REPO="AvengeMedia/DankMaterialShell" + info "Downloading pre-built binaries and source for dms..." + # Get version from changelog (remove ppa suffix for both quilt and native formats) + # Native: 0.5.2ppa1 -> 0.5.2, Quilt: 0.5.2-1ppa1 -> 0.5.2 + VERSION=$(dpkg-parsechangelog -S Version | sed 's/-[^-]*$//' | sed 's/ppa[0-9]*$//') + + # Download amd64 binary (will be included in source package) + if [ ! -f "dms-distropkg-amd64.gz" ]; then + info "Downloading dms binary for amd64..." + if wget -O dms-distropkg-amd64.gz "https://github.com/AvengeMedia/DankMaterialShell/releases/download/v${VERSION}/dms-distropkg-amd64.gz"; then + success "amd64 binary downloaded" + else + error "Failed to download dms-distropkg-amd64.gz" + exit 1 + fi + fi + + # Download source tarball for QML files + if [ ! -f "dms-source.tar.gz" ]; then + info "Downloading dms source for QML files..." + if wget -O dms-source.tar.gz "https://github.com/AvengeMedia/DankMaterialShell/archive/refs/tags/v${VERSION}.tar.gz"; then + success "source tarball downloaded" + else + error "Failed to download dms-source.tar.gz" + exit 1 + fi + fi + ;; + danksearch) + # danksearch uses pre-built binary from releases, like dgop + GIT_REPO="AvengeMedia/danksearch" + ;; + dgop) + # dgop uses pre-built binary from releases + GIT_REPO="AvengeMedia/dgop" + ;; +esac + +# Handle git packages +if [ "$IS_GIT_PACKAGE" = true ] && [ -n "$GIT_REPO" ]; then + info "Detected git package: $PACKAGE_NAME" + + # Determine source directory name + if [ -z "$SOURCE_DIR" ]; then + # Default: use package name without -git suffix + -source or -repo + BASE_NAME=$(echo "$PACKAGE_NAME" | sed 's/-git$//') + if [ -d "${BASE_NAME}-source" ] 2>/dev/null; then + SOURCE_DIR="${BASE_NAME}-source" + elif [ -d "${BASE_NAME}-repo" ] 2>/dev/null; then + SOURCE_DIR="${BASE_NAME}-repo" + elif [ -d "$BASE_NAME" ] 2>/dev/null; then + SOURCE_DIR="$BASE_NAME" + else + SOURCE_DIR="${BASE_NAME}-source" + fi + fi + + # Always clone fresh source to get latest commit info + info "Cloning $GIT_REPO from GitHub (getting latest commit info)..." + TEMP_CLONE=$(mktemp -d) + if git clone "https://github.com/$GIT_REPO.git" "$TEMP_CLONE"; then + # Get git commit info from fresh clone + GIT_COMMIT_HASH=$(cd "$TEMP_CLONE" && git rev-parse --short HEAD) + GIT_COMMIT_COUNT=$(cd "$TEMP_CLONE" && git rev-list --count HEAD) + + # Get upstream version from latest git tag (e.g., 0.2.1) + # Sort all tags by version and get the latest one (not just the one reachable from HEAD) + UPSTREAM_VERSION=$(cd "$TEMP_CLONE" && git tag -l "v*" | sed 's/^v//' | sort -V | tail -1) + if [ -z "$UPSTREAM_VERSION" ]; then + # Fallback: try without v prefix + UPSTREAM_VERSION=$(cd "$TEMP_CLONE" && git tag -l | grep -E '^[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1) + fi + if [ -z "$UPSTREAM_VERSION" ]; then + # Last resort: use git describe + UPSTREAM_VERSION=$(cd "$TEMP_CLONE" && git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.0.1") + fi + + # Verify we got valid commit info + if [ -z "$GIT_COMMIT_COUNT" ] || [ "$GIT_COMMIT_COUNT" = "0" ]; then + error "Failed to get commit count from $GIT_REPO" + rm -rf "$TEMP_CLONE" + exit 1 + fi + + if [ -z "$GIT_COMMIT_HASH" ]; then + error "Failed to get commit hash from $GIT_REPO" + rm -rf "$TEMP_CLONE" + exit 1 + fi + + success "Got commit info: $GIT_COMMIT_COUNT ($GIT_COMMIT_HASH), upstream: $UPSTREAM_VERSION" + + # Update changelog with git commit info + info "Updating changelog with git commit info..." + # Format: 0.2.1+git705.fdbb86appa1 + # Check if we're rebuilding the same commit (increment PPA number if so) + BASE_VERSION="${UPSTREAM_VERSION}+git${GIT_COMMIT_COUNT}.${GIT_COMMIT_HASH}" + CURRENT_VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null || echo "") + PPA_NUM=1 + + # If current version matches the base version, increment PPA number + # Escape special regex characters in BASE_VERSION for pattern matching + ESCAPED_BASE=$(echo "$BASE_VERSION" | sed 's/\./\\./g' | sed 's/+/\\+/g') + if [[ "$CURRENT_VERSION" =~ ^${ESCAPED_BASE}ppa([0-9]+)$ ]]; then + PPA_NUM=$((BASH_REMATCH[1] + 1)) + info "Detected rebuild of same commit (current: $CURRENT_VERSION), incrementing PPA number to $PPA_NUM" + else + info "New commit or first build, using PPA number $PPA_NUM" + fi + + NEW_VERSION="${BASE_VERSION}ppa${PPA_NUM}" + + # Use sed to update changelog (non-interactive, faster) + # Get current changelog content - find the next package header line (starts with package name) + # Skip the first entry entirely by finding the second occurrence of the package name at start of line + OLD_ENTRY_START=$(grep -n "^${SOURCE_NAME} (" debian/changelog | sed -n '2p' | cut -d: -f1) + if [ -n "$OLD_ENTRY_START" ]; then + # Found second entry, use everything from there + CHANGELOG_CONTENT=$(tail -n +$OLD_ENTRY_START debian/changelog) + else + # No second entry found, changelog will only have new entry + CHANGELOG_CONTENT="" + fi + + # Create new changelog entry with proper format + CHANGELOG_ENTRY="${SOURCE_NAME} (${NEW_VERSION}) ${UBUNTU_SERIES}; urgency=medium + + * Git snapshot (commit ${GIT_COMMIT_COUNT}: ${GIT_COMMIT_HASH}) + + -- Avenge Media $(date -R)" + + # Write new changelog (new entry, blank line, then old entries) + echo "$CHANGELOG_ENTRY" > debian/changelog + if [ -n "$CHANGELOG_CONTENT" ]; then + echo "" >> debian/changelog + echo "$CHANGELOG_CONTENT" >> debian/changelog + fi + success "Version updated to $NEW_VERSION" + + # Now clone to source directory (without .git for inclusion in package) + rm -rf "$SOURCE_DIR" + cp -r "$TEMP_CLONE" "$SOURCE_DIR" + rm -rf "$SOURCE_DIR/.git" + rm -rf "$TEMP_CLONE" + + # Vendor Rust dependencies for packages that need it + if false; then + # No current packages need Rust vendoring + if [ -f "$SOURCE_DIR/Cargo.toml" ]; then + info "Vendoring Rust dependencies (Launchpad has no internet access)..." + cd "$SOURCE_DIR" + + # Clean up any existing vendor directory and .orig files + # (prevents cargo from including .orig files in checksums) + rm -rf vendor .cargo + find . -type f -name "*.orig" -exec rm -f {} + || true + + # Download all dependencies (crates.io + git repos) to vendor/ + # cargo vendor outputs the config to stderr, capture it + mkdir -p .cargo + cargo vendor 2>&1 | awk ' + /^\[source\.crates-io\]/ { printing=1 } + printing { print } + /^directory = "vendor"$/ { exit } + ' > .cargo/config.toml + + # Verify vendor directory was created + if [ ! -d "vendor" ]; then + error "Failed to vendor dependencies" + exit 1 + fi + + # Verify config was created + if [ ! -s .cargo/config.toml ]; then + error "Failed to create cargo config" + exit 1 + fi + + # CRITICAL: Remove ALL .orig files from vendor directory + # These break cargo checksums when dh_clean tries to use them + info "Cleaning .orig files from vendor directory..." + find vendor -type f -name "*.orig" -exec rm -fv {} + || true + find vendor -type f -name "*.rej" -exec rm -fv {} + || true + + # Verify no .orig files remain + ORIG_COUNT=$(find vendor -type f -name "*.orig" | wc -l) + if [ "$ORIG_COUNT" -gt 0 ]; then + warn "Found $ORIG_COUNT .orig files still in vendor directory" + fi + + success "Rust dependencies vendored (including git dependencies)" + cd "$PACKAGE_DIR" + fi + fi + + # Download pre-built binary for dms-git + # dms-git uses latest release binary with git master QML files + if [ "$PACKAGE_NAME" = "dms-git" ]; then + info "Downloading latest release binary for dms-git..." + if [ ! -f "dms-distropkg-amd64.gz" ]; then + if wget -O dms-distropkg-amd64.gz "https://github.com/AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-amd64.gz"; then + success "Latest release binary downloaded" + else + error "Failed to download dms-distropkg-amd64.gz" + exit 1 + fi + else + info "Release binary already downloaded" + fi + fi + + success "Source prepared for packaging" + else + error "Failed to clone $GIT_REPO" + rm -rf "$TEMP_CLONE" + exit 1 + fi +# Handle stable packages - get latest tag +elif [ -n "$GIT_REPO" ]; then + info "Detected stable package: $PACKAGE_NAME" + info "Fetching latest tag from $GIT_REPO..." + + LATEST_TAG=$(get_latest_tag "$GIT_REPO") + if [ -n "$LATEST_TAG" ]; then + # Check source format - native packages can't use dashes + SOURCE_FORMAT=$(cat debian/source/format 2>/dev/null | head -1 || echo "3.0 (quilt)") + + # Get current version to check if we need to increment PPA number + CURRENT_VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null || echo "") + PPA_NUM=1 + + if [[ "$SOURCE_FORMAT" == *"native"* ]]; then + # Native format: 0.2.1ppa1 (no dash, no revision) + BASE_VERSION="${LATEST_TAG}" + # Check if we're rebuilding the same version (increment PPA number if so) + if [[ "$CURRENT_VERSION" =~ ^${LATEST_TAG}ppa([0-9]+)$ ]]; then + PPA_NUM=$((BASH_REMATCH[1] + 1)) + info "Detected rebuild of same version (current: $CURRENT_VERSION), incrementing PPA number to $PPA_NUM" + else + info "New version or first build, using PPA number $PPA_NUM" + fi + NEW_VERSION="${BASE_VERSION}ppa${PPA_NUM}" + else + # Quilt format: 0.2.1-1ppa1 (with revision) + BASE_VERSION="${LATEST_TAG}-1" + # Check if we're rebuilding the same version (increment PPA number if so) + ESCAPED_BASE=$(echo "$BASE_VERSION" | sed 's/\./\\./g' | sed 's/-/\\-/g') + if [[ "$CURRENT_VERSION" =~ ^${ESCAPED_BASE}ppa([0-9]+)$ ]]; then + PPA_NUM=$((BASH_REMATCH[1] + 1)) + info "Detected rebuild of same version (current: $CURRENT_VERSION), incrementing PPA number to $PPA_NUM" + else + info "New version or first build, using PPA number $PPA_NUM" + fi + NEW_VERSION="${BASE_VERSION}ppa${PPA_NUM}" + fi + + # Check if version needs updating (either new version or PPA number changed) + if [ "$CURRENT_VERSION" != "$NEW_VERSION" ]; then + if [ "$PPA_NUM" -gt 1 ]; then + info "Updating changelog for rebuild (PPA number incremented to $PPA_NUM)" + else + info "Updating changelog to latest tag: $LATEST_TAG" + fi + # Use sed to update changelog (non-interactive) + # Get current changelog content - find the next package header line + OLD_ENTRY_START=$(grep -n "^${SOURCE_NAME} (" debian/changelog | sed -n '2p' | cut -d: -f1) + if [ -n "$OLD_ENTRY_START" ]; then + CHANGELOG_CONTENT=$(tail -n +$OLD_ENTRY_START debian/changelog) + else + CHANGELOG_CONTENT="" + fi + + # Create appropriate changelog message + if [ "$PPA_NUM" -gt 1 ]; then + CHANGELOG_MSG="Rebuild for packaging fixes (ppa${PPA_NUM})" + else + CHANGELOG_MSG="Upstream release ${LATEST_TAG}" + fi + + CHANGELOG_ENTRY="${SOURCE_NAME} (${NEW_VERSION}) ${UBUNTU_SERIES}; urgency=medium + + * ${CHANGELOG_MSG} + + -- Avenge Media $(date -R)" + echo "$CHANGELOG_ENTRY" > debian/changelog + if [ -n "$CHANGELOG_CONTENT" ]; then + echo "" >> debian/changelog + echo "$CHANGELOG_CONTENT" >> debian/changelog + fi + success "Version updated to $NEW_VERSION" + else + info "Version already at latest tag: $LATEST_TAG" + fi + else + warn "Could not determine latest tag for $GIT_REPO, using existing version" + fi +fi + +# Handle packages that need pre-built binaries downloaded +cd "$PACKAGE_DIR" +case "$PACKAGE_NAME" in + danksearch) + info "Downloading pre-built binaries for danksearch..." + # Get version from changelog (remove ppa suffix for both quilt and native formats) + # Native: 0.5.2ppa1 -> 0.5.2, Quilt: 0.5.2-1ppa1 -> 0.5.2 + VERSION=$(dpkg-parsechangelog -S Version | sed 's/-[^-]*$//' | sed 's/ppa[0-9]*$//') + + # Download both amd64 and arm64 binaries (will be included in source package) + # Launchpad can't download during build, so we include both architectures + if [ ! -f "dsearch-amd64" ]; then + info "Downloading dsearch binary for amd64..." + if wget -O dsearch-amd64.gz "https://github.com/AvengeMedia/danksearch/releases/download/v${VERSION}/dsearch-linux-amd64.gz"; then + gunzip dsearch-amd64.gz + chmod +x dsearch-amd64 + success "amd64 binary downloaded" + else + error "Failed to download dsearch-amd64.gz" + exit 1 + fi + fi + + if [ ! -f "dsearch-arm64" ]; then + info "Downloading dsearch binary for arm64..." + if wget -O dsearch-arm64.gz "https://github.com/AvengeMedia/danksearch/releases/download/v${VERSION}/dsearch-linux-arm64.gz"; then + gunzip dsearch-arm64.gz + chmod +x dsearch-arm64 + success "arm64 binary downloaded" + else + error "Failed to download dsearch-arm64.gz" + exit 1 + fi + fi + ;; + dgop) + # dgop binary should already be committed in the repo + if [ ! -f "dgop" ]; then + warn "dgop binary not found - should be committed to repo" + fi + ;; +esac + +cd - > /dev/null + +# Build source package +info "Building source package..." +echo + +# Use -S for source only, -sa to include original source +# -d skips dependency checking (we're building on Fedora, not Ubuntu) +# Pipe yes to automatically answer prompts (e.g., "continue anyway?") +if yes | DEBIAN_FRONTEND=noninteractive debuild -S -sa -d; then + echo + success "Source package built successfully!" + + # List generated files + info "Generated files in $(dirname "$PACKAGE_DIR"):" + ls -lh "$(dirname "$PACKAGE_DIR")"/${SOURCE_NAME}_${CHANGELOG_VERSION}* 2>/dev/null || true + + # Show what to do next + echo + info "Next steps:" + echo " 1. Review the source package:" + echo " cd $(dirname "$PACKAGE_DIR")" + echo " ls -lh ${SOURCE_NAME}_${CHANGELOG_VERSION}*" + echo + echo " 2. Upload to PPA (stable):" + echo " dput ppa:avengemedia/dms ${SOURCE_NAME}_${CHANGELOG_VERSION}_source.changes" + echo + echo " 3. Or upload to PPA (nightly):" + echo " dput ppa:avengemedia/dms-git ${SOURCE_NAME}_${CHANGELOG_VERSION}_source.changes" + echo + echo " 4. Or use the upload script:" + echo " ./upload-ppa.sh $(dirname "$PACKAGE_DIR")/${SOURCE_NAME}_${CHANGELOG_VERSION}_source.changes dms" + +else + error "Source package build failed!" + exit 1 +fi diff --git a/distro/ubuntu/ppa/upload-ppa.sh b/distro/ubuntu/ppa/upload-ppa.sh new file mode 100755 index 00000000..e7c99a16 --- /dev/null +++ b/distro/ubuntu/ppa/upload-ppa.sh @@ -0,0 +1,179 @@ +#!/bin/bash +# Generic PPA uploader for DMS packages +# Usage: ./upload-ppa.sh +# +# Example: +# ./upload-ppa.sh ../dms_0.5.2ppa1_source.changes dms +# ./upload-ppa.sh ../dms_0.5.2+git705.fdbb86appa1_source.changes dms-git + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +info() { echo -e "${BLUE}[INFO]${NC} $1"; } +success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; } + +if [ $# -lt 2 ]; then + error "Usage: $0 " + echo + echo "Arguments:" + echo " changes-file : Path to .changes file (e.g., ../dms_0.5.2ppa1_source.changes)" + echo " ppa-name : PPA to upload to (dms or dms-git)" + echo + echo "Examples:" + echo " $0 ../dms_0.5.2ppa1_source.changes dms" + echo " $0 ../dms_0.5.2+git705.fdbb86appa1_source.changes dms-git" + exit 1 +fi + +CHANGES_FILE="$1" +PPA_NAME="$2" + +# Validate changes file +if [ ! -f "$CHANGES_FILE" ]; then + error "Changes file not found: $CHANGES_FILE" + exit 1 +fi + +if [[ ! "$CHANGES_FILE" =~ \.changes$ ]]; then + error "File must be a .changes file" + exit 1 +fi + +# Validate PPA name +if [ "$PPA_NAME" != "dms" ] && [ "$PPA_NAME" != "dms-git" ] && [ "$PPA_NAME" != "danklinux" ]; then + error "PPA name must be 'dms', 'dms-git', or 'danklinux'" + exit 1 +fi + +# Get absolute path +CHANGES_FILE=$(realpath "$CHANGES_FILE") + +info "Uploading to PPA: ppa:avengemedia/$PPA_NAME" +info "Changes file: $CHANGES_FILE" + +# Check if dput or lftp is installed +UPLOAD_METHOD="" +if command -v dput &> /dev/null; then + UPLOAD_METHOD="dput" +elif command -v lftp &> /dev/null; then + UPLOAD_METHOD="lftp" + warn "dput not found, using lftp as fallback" +else + error "Neither dput nor lftp found. Install one with:" + error " sudo dnf install dput-ng # Preferred but broken on Fedora" + error " sudo dnf install lftp # Alternative upload method" + exit 1 +fi + +# Check if ~/.dput.cf exists +if [ ! -f "$HOME/.dput.cf" ]; then + error "~/.dput.cf not found!" + echo + info "Create it from template:" + echo " cp $(dirname "$0")/../dput.cf.template ~/.dput.cf" + echo + info "Or create it manually with:" + cat <<'EOF' +[ppa:avengemedia/dms] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~avengemedia/ubuntu/dms/ +login = anonymous +allow_unsigned_uploads = 0 + +[ppa:avengemedia/dms-git] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~avengemedia/ubuntu/dms-git/ +login = anonymous +allow_unsigned_uploads = 0 +EOF + exit 1 +fi + +# Check if PPA is configured in dput.cf +if ! grep -q "^\[ppa:avengemedia/$PPA_NAME\]" "$HOME/.dput.cf"; then + error "PPA 'ppa:avengemedia/$PPA_NAME' not found in ~/.dput.cf" + echo + info "Add this to ~/.dput.cf:" + cat </dev/null; then + success "GPG signature valid" +else + error "GPG signature verification failed!" + error "The .changes file must be signed with your GPG key" + exit 1 +fi + +# Ask for confirmation +echo +warn "About to upload to: ppa:avengemedia/$PPA_NAME" +read -p "Continue? (y/N) " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + info "Upload cancelled" + exit 0 +fi + +# Upload to PPA +info "Uploading to Launchpad..." +echo + +if dput "ppa:avengemedia/$PPA_NAME" "$CHANGES_FILE"; then + echo + success "Upload successful!" + echo + info "Monitor build progress at:" + echo " https://launchpad.net/~avengemedia/+archive/ubuntu/$PPA_NAME/+packages" + echo + info "Builds typically take 5-30 minutes depending on:" + echo " - Build queue length" + echo " - Package complexity" + echo " - Number of target Ubuntu series" + echo + info "Once built, users can install with:" + echo " sudo add-apt-repository ppa:avengemedia/$PPA_NAME" + echo " sudo apt update" + echo " sudo apt install $PACKAGE_NAME" + +else + error "Upload failed!" + echo + info "Common issues:" + echo " - GPG key not verified on Launchpad (check https://launchpad.net/~/+editpgpkeys)" + echo " - Version already uploaded (must increment version number)" + echo " - Network/firewall blocking FTP (try HTTPS method in dput.cf)" + echo " - Email in changelog doesn't match GPG key email" + exit 1 +fi