1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

feat: Mult-Distro support - Debian, Ubuntu, OpenSuse

This commit is contained in:
purian23
2025-11-23 02:39:24 -05:00
parent 97c11a2482
commit 644384ce8b
62 changed files with 3339 additions and 0 deletions

View File

@@ -386,6 +386,68 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 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: copr-build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: release needs: release

108
.github/workflows/run-obs.yml vendored Normal file
View File

@@ -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|<param name=\"revision\">v[0-9.]*</param>|<param name=\"revision\">$VERSION</param>|" "$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

101
.github/workflows/run-ppa.yml vendored Normal file
View File

@@ -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

View File

@@ -0,0 +1,24 @@
<services>
<!-- Pull full git repository for master branch -->
<service name="tar_scm" mode="disabled">
<param name="scm">git</param>
<param name="url">https://github.com/AvengeMedia/DankMaterialShell.git</param>
<param name="revision">master</param>
<param name="filename">dms-git-source</param>
</service>
<service name="recompress" mode="disabled">
<param name="file">*.tar</param>
<param name="compression">gz</param>
</service>
<!-- Download pre-built binaries (fallback for Debian 13 with Go 1.22) -->
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-amd64.gz</param>
</service>
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-arm64.gz</param>
</service>
</services>

View File

@@ -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 <AvengeMedia.US@gmail.com> Fri, 22 Nov 2025 00:00:00 -0500

View File

@@ -0,0 +1,50 @@
Source: dms-git
Section: x11
Priority: optional
Maintainer: Avenge Media <AvengeMedia.US@gmail.com>
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

View File

@@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: dms
Upstream-Contact: Avenge Media LLC <AvengeMedia.US@gmail.com>
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.

View File

@@ -0,0 +1 @@
dms-git_0.6.0+git2061.5ddea836ppa1_source.buildinfo x11 optional

View File

@@ -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

View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -0,0 +1 @@
dms-distropkg-amd64.gz

View File

@@ -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

View File

@@ -0,0 +1,21 @@
<services>
<!-- Download source tarball from GitHub releases -->
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/archive/refs/tags/v0.6.2.tar.gz</param>
<param name="filename">dms-source.tar.gz</param>
</service>
<!-- Download amd64 binary -->
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/releases/download/v0.6.2/dms-distropkg-amd64.gz</param>
</service>
<!-- Download arm64 binary -->
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/releases/download/v0.6.2/dms-distropkg-arm64.gz</param>
</service>
</services>

View File

@@ -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 <AvengeMedia.US@gmail.com> Tue, 19 Nov 2025 10:00:00 -0500

View File

@@ -0,0 +1,47 @@
Source: dms
Section: x11
Priority: optional
Maintainer: Avenge Media <AvengeMedia.US@gmail.com>
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

View File

@@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: dms
Upstream-Contact: Avenge Media LLC <AvengeMedia.US@gmail.com>
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.

View File

@@ -0,0 +1 @@
dms_0.6.0ppa2_source.buildinfo x11 optional

64
distro/debian/dms/debian/rules Executable file
View File

@@ -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

View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -0,0 +1,2 @@
dms-distropkg-amd64.gz
dms-source.tar.gz

View File

@@ -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

24
distro/opensuse/_service Normal file
View File

@@ -0,0 +1,24 @@
<services>
<!-- Pull full git repository for master branch (QML code) -->
<service name="tar_scm">
<param name="scm">git</param>
<param name="url">https://github.com/AvengeMedia/DankMaterialShell.git</param>
<param name="revision">master</param>
<param name="filename">dms-git-source</param>
</service>
<service name="recompress">
<param name="file">*.tar</param>
<param name="compression">gz</param>
</service>
<!-- Download pre-built binaries -->
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-amd64.gz</param>
</service>
<service name="download_url">
<param name="protocol">https</param>
<param name="host">github.com</param>
<param name="path">/AvengeMedia/DankMaterialShell/releases/latest/download/dms-distropkg-arm64.gz</param>
</service>
</services>

View File

@@ -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 <maintainer@avengemedia.com> - 0.6.2+git-5
- Git nightly build from master branch
- Multi-arch support (x86_64, aarch64)

107
distro/opensuse/dms.spec Normal file
View File

@@ -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 <maintainer@avengemedia.com> - 0.6.2-1
- Stable release build with pre-built binaries
- Multi-arch support (x86_64, aarch64)

View File

@@ -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!"

View File

@@ -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] <package-name> [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 name="url">\(.*\)<\/param>.*/\1/')
GIT_REVISION=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "revision" | sed 's/.*<param name="revision">\(.*\)<\/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 name="url">\(.*\)<\/param>.*/\1/')
GIT_REVISION=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "revision" | sed 's/.*<param name="revision">\(.*\)<\/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 '<service name="download_url">' "distro/debian/$PACKAGE/_service" | \
grep '<param name="path">' | \
sed 's/.*<param name="path">\(.*\)<\/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" '
/<service name="download_url">/ { 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 name="protocol">\(.*\)<\/param>.*/\1/' | head -1)
URL_HOST=$(echo "$SOURCE_BLOCK" | grep "host" | sed 's/.*<param name="host">\(.*\)<\/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 name="url">\(.*\)<\/param>.*/\1/')
GIT_REVISION=$(grep -A 5 'name="tar_scm"' "distro/debian/$PACKAGE/_service" | grep "revision" | sed 's/.*<param name="revision">\(.*\)<\/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 '<service name="download_url">' "distro/debian/$PACKAGE/_service" | \
grep '<param name="path">' | \
sed 's/.*<param name="path">\(.*\)<\/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" '
/<service name="download_url">/ { 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 name="protocol">\(.*\)<\/param>.*/\1/' | head -1)
URL_HOST=$(echo "$SOURCE_BLOCK" | grep "host" | sed 's/.*<param name="host">\(.*\)<\/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 <AvengeMedia.US@gmail.com>
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 <AvengeMedia.US@gmail.com>
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 <repo> <arch>"
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"

169
distro/scripts/test-packaging.sh Executable file
View File

@@ -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 "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

View File

@@ -0,0 +1,5 @@
danksearch (0.0.7ppa3) questing; urgency=medium
* Rebuild for packaging fixes (ppa3)
-- Avenge Media <AvengeMedia.US@gmail.com> Fri, 21 Nov 2025 14:19:58 -0500

View File

@@ -0,0 +1,24 @@
Source: danksearch
Section: utils
Priority: optional
Maintainer: Avenge Media <AvengeMedia.US@gmail.com>
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

View File

@@ -0,0 +1,24 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: danksearch
Upstream-Contact: Avenge Media LLC <AvengeMedia.US@gmail.com>
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 <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".

View File

@@ -0,0 +1 @@
danksearch_0.0.7ppa3_source.buildinfo utils optional

View File

@@ -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

View File

@@ -0,0 +1 @@
3.0 (native)

Binary file not shown.

Binary file not shown.

View File

@@ -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 <AvengeMedia.US@gmail.com> Sun, 16 Nov 2025 22:50:00 -0500

View File

@@ -0,0 +1,27 @@
Source: dgop
Section: utils
Priority: optional
Maintainer: Avenge Media <AvengeMedia.US@gmail.com>
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

View File

@@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: dgop
Upstream-Contact: Avenge Media LLC <AvengeMedia.US@gmail.com>
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.

View File

@@ -0,0 +1 @@
dgop_0.1.11ppa2_source.buildinfo utils optional

View File

@@ -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

View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -0,0 +1,5 @@
dms-git (0.6.2+git2094.6cc6e7c8ppa1) questing; urgency=medium
* Git snapshot (commit 2094: 6cc6e7c8)
-- Avenge Media <AvengeMedia.US@gmail.com> Sun, 23 Nov 2025 00:43:28 -0500

View File

@@ -0,0 +1,50 @@
Source: dms-git
Section: x11
Priority: optional
Maintainer: Avenge Media <AvengeMedia.US@gmail.com>
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

View File

@@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: dms
Upstream-Contact: Avenge Media LLC <AvengeMedia.US@gmail.com>
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.

View File

@@ -0,0 +1 @@
dms-git_0.6.2+git2094.6cc6e7c8ppa1_source.buildinfo x11 optional

View File

@@ -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

View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -0,0 +1 @@
dms-distropkg-amd64.gz

View File

@@ -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

View File

@@ -0,0 +1,5 @@
dms (0.6.2ppa3) questing; urgency=medium
* Rebuild for packaging fixes (ppa3)
-- Avenge Media <AvengeMedia.US@gmail.com> Sun, 23 Nov 2025 00:40:41 -0500

View File

@@ -0,0 +1,47 @@
Source: dms
Section: x11
Priority: optional
Maintainer: Avenge Media <AvengeMedia.US@gmail.com>
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

View File

@@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: dms
Upstream-Contact: Avenge Media LLC <AvengeMedia.US@gmail.com>
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.

View File

@@ -0,0 +1 @@
dms_0.6.2ppa3_source.buildinfo x11 optional

63
distro/ubuntu/dms/debian/rules Executable file
View File

@@ -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

View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -0,0 +1,2 @@
dms-distropkg-amd64.gz
dms-source.tar.gz

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,246 @@
#!/bin/bash
# Build and upload PPA package with automatic cleanup
# Usage: ./create-and-upload.sh <package-dir> <ppa-name> [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 <package-dir> <ppa-name> [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" <<EOF
cd ~avengemedia/ubuntu/$PPA_NAME/
lcd $BUILD_DIR
mput $CHANGES_BASENAME
mput $DSC_FILE
mput $TARBALL
mput $BUILDINFO
bye
EOF
if lftp -d ftp://anonymous:@ppa.launchpad.net < "$LFTP_SCRIPT"; then
success "Upload successful!"
rm -f "$LFTP_SCRIPT"
else
error "Upload failed!"
rm -f "$LFTP_SCRIPT"
exit 1
fi
else
# Use dput for other PPAs
if [ ! -f "$UPLOAD_SCRIPT" ]; then
error "Upload script not found: $UPLOAD_SCRIPT"
exit 1
fi
# Auto-confirm upload (pipe 'y' to the confirmation prompt)
if ! echo "y" | "$UPLOAD_SCRIPT" "$CHANGES_FILE" "$PPA_NAME"; then
error "Upload failed!"
exit 1
fi
fi
echo
success "Package uploaded successfully!"
info "Monitor build progress at:"
echo " https://launchpad.net/~avengemedia/+archive/ubuntu/$PPA_NAME/+packages"
echo
# Step 3: Cleanup (unless --keep-builds is specified)
if [ "$KEEP_BUILDS" = "false" ]; then
info "Step 3: Cleaning up build artifacts..."
# Find all build artifacts in parent directory
ARTIFACTS=(
"${PACKAGE_NAME}_*.dsc"
"${PACKAGE_NAME}_*.tar.xz"
"${PACKAGE_NAME}_*.tar.gz"
"${PACKAGE_NAME}_*_source.changes"
"${PACKAGE_NAME}_*_source.buildinfo"
"${PACKAGE_NAME}_*_source.build"
)
REMOVED=0
for pattern in "${ARTIFACTS[@]}"; do
for file in "$PARENT_DIR"/$pattern; do
if [ -f "$file" ]; then
rm -f "$file"
REMOVED=$((REMOVED + 1))
fi
done
done
# Clean up downloaded binaries in package directory
case "$PACKAGE_NAME" in
danksearch)
if [ -f "$PACKAGE_DIR/dsearch-amd64" ]; then
rm -f "$PACKAGE_DIR/dsearch-amd64"
REMOVED=$((REMOVED + 1))
fi
if [ -f "$PACKAGE_DIR/dsearch-arm64" ]; then
rm -f "$PACKAGE_DIR/dsearch-arm64"
REMOVED=$((REMOVED + 1))
fi
;;
dms)
# Remove downloaded binaries and source
if [ -f "$PACKAGE_DIR/dms-distropkg-amd64.gz" ]; then
rm -f "$PACKAGE_DIR/dms-distropkg-amd64.gz"
REMOVED=$((REMOVED + 1))
fi
if [ -f "$PACKAGE_DIR/dms-source.tar.gz" ]; then
rm -f "$PACKAGE_DIR/dms-source.tar.gz"
REMOVED=$((REMOVED + 1))
fi
;;
dms-git)
# Remove downloaded binary
if [ -f "$PACKAGE_DIR/dms-distropkg-amd64.gz" ]; then
rm -f "$PACKAGE_DIR/dms-distropkg-amd64.gz"
REMOVED=$((REMOVED + 1))
fi
# Remove git source directory
if [ -d "$PACKAGE_DIR/dms-git-repo" ]; then
rm -rf "$PACKAGE_DIR/dms-git-repo"
REMOVED=$((REMOVED + 1))
fi
;;
esac
if [ $REMOVED -gt 0 ]; then
success "Removed $REMOVED build artifact(s)"
else
info "No build artifacts to clean up"
fi
else
info "Keeping build artifacts (--keep-builds specified)"
info "Build artifacts in: $PARENT_DIR"
fi
echo
success "Done!"

View File

@@ -0,0 +1,534 @@
#!/bin/bash
# Generic source package builder for DMS PPA packages
# Usage: ./create-source.sh <package-dir> [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 <package-dir> [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 <AvengeMedia.US@gmail.com> $(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 <AvengeMedia.US@gmail.com> $(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

179
distro/ubuntu/ppa/upload-ppa.sh Executable file
View File

@@ -0,0 +1,179 @@
#!/bin/bash
# Generic PPA uploader for DMS packages
# Usage: ./upload-ppa.sh <changes-file> <ppa-name>
#
# 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 <changes-file> <ppa-name>"
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 <<EOF
[ppa:avengemedia/$PPA_NAME]
fqdn = ppa.launchpad.net
method = ftp
incoming = ~avengemedia/ubuntu/$PPA_NAME/
login = anonymous
allow_unsigned_uploads = 0
EOF
exit 1
fi
# Extract package info from changes file
PACKAGE_NAME=$(grep "^Source:" "$CHANGES_FILE" | awk '{print $2}')
VERSION=$(grep "^Version:" "$CHANGES_FILE" | awk '{print $2}')
info "Package: $PACKAGE_NAME"
info "Version: $VERSION"
# Show files that will be uploaded
echo
info "Files to be uploaded:"
grep "^ [a-f0-9]" "$CHANGES_FILE" | awk '{print " - " $5}' || true
# Verify GPG signature
info "Verifying GPG signature..."
if gpg --verify "$CHANGES_FILE" 2>/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