name: Void Linux XBPS Repository on: schedule: - cron: "0 2,5,14,17,20,23 * * *" # 9am, 12pm, 3pm, 6pm, 9pm, 12am EST (UTC times shown) # release trigger disabled; dispatch manually after a release # release: # types: [published] workflow_dispatch: inputs: version: description: 'Stable release tag/version to build (e.g. v1.5.0 or 1.5.0). Leave blank to use the selected ref/template version' type: string required: false force_rebuild: description: 'Force rebuilding packages even if they already exist in the repository' type: boolean required: false default: false build_git: description: 'Build dms-git package' type: boolean required: false default: true build_dms: description: 'Build stable dms package' type: boolean required: false default: true build_greeter: description: 'Build stable dms-greeter package' type: boolean required: false default: true permissions: contents: read concurrency: group: void-xbps-${{ github.ref }} cancel-in-progress: false jobs: preflight: name: Check for unpublished changes runs-on: ubuntu-latest outputs: should_build: ${{ steps.check.outputs.should_build }} steps: - name: Check published commit id: check env: MANIFEST_URL: https://void.danklinux.com/dms/current/manifest.json run: | SHOULD_BUILD=true if [ "${{ github.event_name }}" = "schedule" ]; then PUBLISHED_COMMIT="$(curl -fsSL --retry 3 "$MANIFEST_URL" | jq -r '.source_commit // empty' 2>/dev/null || true)" if [ "$PUBLISHED_COMMIT" = "${{ github.sha }}" ]; then SHOULD_BUILD=false echo "${{ github.sha }} is already published; skipping the scheduled build." fi fi echo "should_build=$SHOULD_BUILD" >> "$GITHUB_OUTPUT" build-and-deploy: name: Build & Deploy XBPS packages runs-on: ubuntu-latest needs: preflight if: github.repository == 'AvengeMedia/DankMaterialShell' && needs.preflight.outputs.should_build == 'true' env: AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: auto AWS_EC2_METADATA_DISABLED: true R2_BUCKET: danklinux-void R2_ENDPOINT: https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com R2_PREFIX: dms REPOSITORY_DIR: ${{ github.workspace }}/r2-repo SOURCE_COMMIT: ${{ github.sha }} steps: - name: Checkout repository uses: actions/checkout@v6 with: ref: ${{ github.event.release.tag_name || (github.event.inputs.version && (startsWith(github.event.inputs.version, 'v') && github.event.inputs.version || format('v{0}', github.event.inputs.version))) || github.ref }} fetch-depth: 0 - name: Record checked-out source commit run: echo "SOURCE_COMMIT=$(git rev-parse HEAD)" >> "$GITHUB_ENV" - name: Download current R2 repository run: | aws --version bash .github/scripts/publish-void-r2.sh download - name: Install XBPS Static Utilities run: | mkdir -p ${{ github.workspace }}/xbps curl -s -L https://repo-default.voidlinux.org/static/xbps-static-latest.x86_64-musl.tar.xz | tar -xJ -C ${{ github.workspace }}/xbps echo "${{ github.workspace }}/xbps/usr/bin" >> $GITHUB_PATH - name: Clone void-packages run: | git clone --depth=1 https://github.com/void-linux/void-packages.git - name: Inject templates run: | cp -R distro/void/srcpkgs/dms void-packages/srcpkgs/ cp -R distro/void/srcpkgs/dms-greeter void-packages/srcpkgs/ cp -R distro/void/srcpkgs/dms-git void-packages/srcpkgs/ - name: Enable unprivileged user namespaces (Ubuntu 24.04) run: | sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true - name: Bootstrap xbps-src run: | cd void-packages ./xbps-src binary-bootstrap - name: Configure signing keys and trust run: | # Write private key; extract and register the public key echo "${{ secrets.XBPS_PRIVATE_KEY }}" > /tmp/xbps_privkey.pem chmod 600 /tmp/xbps_privkey.pem # Extract public key in PEM format openssl rsa -in /tmp/xbps_privkey.pem -pubout -out /tmp/dms-key.pub rm -f /tmp/xbps_privkey.pem # Compute MD5 fingerprint in colon-separated hex format FINGERPRINT=$(openssl rsa -pubin -in /tmp/dms-key.pub -outform DER 2>/dev/null | openssl dgst -md5 -c | tr '[:upper:]' '[:lower:]' | awk '{print $NF}') # Format key in XML property list (plist) format as expected by xbps mkdir -p /tmp/keys cat < "/tmp/keys/${FINGERPRINT}.plist" public-key $(base64 -w0 /tmp/dms-key.pub) public-key-size 4096 signature-by AvengeMedia EOF # Copy keys to all host and chroot trust stores sudo mkdir -p /var/db/xbps/keys sudo cp "/tmp/keys/${FINGERPRINT}.plist" "/var/db/xbps/keys/${FINGERPRINT}.plist" mkdir -p void-packages/masterdir/var/db/xbps/keys cp "/tmp/keys/${FINGERPRINT}.plist" "void-packages/masterdir/var/db/xbps/keys/${FINGERPRINT}.plist" mkdir -p void-packages/etc/xbps.d/keys cp "/tmp/keys/${FINGERPRINT}.plist" "void-packages/etc/xbps.d/keys/${FINGERPRINT}.plist" mkdir -p void-packages/common/repo-keys cp "/tmp/keys/${FINGERPRINT}.plist" "void-packages/common/repo-keys/${FINGERPRINT}.plist" rm -rf /tmp/keys /tmp/dms-key.pub - name: Configure repositories run: | # Append the repository to repos-remote templates so xbps-src translates it automatically echo "repository=https://void.danklinux.com/danklinux/current" >> void-packages/etc/xbps.d/repos-remote.conf echo "repository=https://void.danklinux.com/danklinux/current" >> void-packages/etc/xbps.d/repos-remote-x86_64-multilib.conf # Add any existing compiled packages to the build cache directory to avoid rebuilds if [ -d "r2-repo/current" ]; then mkdir -p void-packages/hostdir/binpkgs cp -L r2-repo/current/*.xbps void-packages/hostdir/binpkgs/ 2>/dev/null || true xbps-rindex -a void-packages/hostdir/binpkgs/*.xbps 2>/dev/null || true fi - name: Build packages run: | mkdir -p r2-repo/current BUILD_DMS="${{ github.event.inputs.build_dms || 'true' }}" BUILD_GREETER="${{ github.event.inputs.build_greeter || 'true' }}" BUILD_GIT="${{ github.event.inputs.build_git || 'true' }}" FORCE_REBUILD="${{ github.event.inputs.force_rebuild || 'false' }}" if [ "${{ github.event_name }}" = "schedule" ]; then BUILD_DMS="false" BUILD_GREETER="false" BUILD_GIT="true" fi if [ "${{ github.event_name }}" = "release" ]; then BUILD_DMS="true" BUILD_GREETER="true" BUILD_GIT="false" fi RELEASE_TAG="" if [ "${{ github.event_name }}" = "release" ]; then RELEASE_TAG="${{ github.event.release.tag_name }}" elif [ -n "${{ github.event.inputs.version || '' }}" ]; then RELEASE_TAG="${{ github.event.inputs.version }}" elif [ "${{ github.ref_type }}" = "tag" ]; then RELEASE_TAG="${{ github.ref_name }}" fi if [ -n "$RELEASE_TAG" ]; then RELEASE_VER="${RELEASE_TAG#v}" ARCHIVE_TAG="v${RELEASE_VER}" echo "Stable release tag: $ARCHIVE_TAG" else RELEASE_VER="" ARCHIVE_TAG="" echo "Stable release tag: (template version)" fi echo "=== Starting Builds ===" echo "DMS stable build enabled: $BUILD_DMS" echo "Greeter stable build enabled: $BUILD_GREETER" echo "Git build enabled: $BUILD_GIT" echo "Force rebuild: $FORCE_REBUILD" cd void-packages if [ -n "$RELEASE_VER" ] && { [ "$BUILD_DMS" = "true" ] || [ "$BUILD_GREETER" = "true" ]; }; then echo "🔧 Updating stable templates for $ARCHIVE_TAG" TARBALL="$(mktemp)" curl -fsSL -o "$TARBALL" "https://github.com/${{ github.repository }}/archive/refs/tags/${ARCHIVE_TAG}.tar.gz" RELEASE_CHECKSUM="$(sha256sum "$TARBALL" | cut -d' ' -f1)" rm -f "$TARBALL" for pkg in dms dms-greeter; do sed -i "s/^version=.*/version=${RELEASE_VER}/" "srcpkgs/${pkg}/template" sed -i "s/^checksum=.*/checksum=${RELEASE_CHECKSUM}/" "srcpkgs/${pkg}/template" done fi # 1. Build dms-git (development package) if [ "$BUILD_GIT" = "true" ]; then # Calculate dynamic git version (tag.commits.hash) GIT_VER=$(git -C .. describe --tags --always | sed 's/^v//; s/-/./g') echo "🔨 Preparing dms-git version $GIT_VER" # Stage source tarball in the xbps-src source cache. # --transform adds a top-level directory so xbps-src can extract # into $wrksrc (create_wrksrc=yes handles the rest). SRC_CACHE="hostdir/sources/dms-git-${GIT_VER}" mkdir -p "$SRC_CACHE" tar -czf "${SRC_CACHE}/dms-git-${GIT_VER}.tar.gz" \ --exclude=void-packages \ --exclude=r2-repo \ --exclude=.git \ --exclude=danklinux \ -C .. . CHECKSUM=$(sha256sum "${SRC_CACHE}/dms-git-${GIT_VER}.tar.gz" | cut -d' ' -f1) # Dynamically patch template version, checksum, and distfiles sed -i "s/^version=.*/version=${GIT_VER}/" srcpkgs/dms-git/template sed -i "s/^checksum=.*/checksum=${CHECKSUM}/" srcpkgs/dms-git/template sed -i "s|^distfiles=.*|distfiles=\"dms-git-${GIT_VER}.tar.gz\"|" srcpkgs/dms-git/template EXPECTED_GIT_FILE="dms-git-${GIT_VER}_1.x86_64.xbps" if [ -f "../r2-repo/current/$EXPECTED_GIT_FILE" ] && [ "$FORCE_REBUILD" != "true" ]; then echo "✅ $EXPECTED_GIT_FILE already exists, skipping build." else echo "🔨 Compiling dms-git..." ./xbps-src pkg dms-git rm -f "../r2-repo/current/${EXPECTED_GIT_FILE}" cp -L "hostdir/binpkgs/${EXPECTED_GIT_FILE}" ../r2-repo/current/ fi fi # 2. Build stable dms package if [ "$BUILD_DMS" = "true" ]; then STABLE_VER=$(grep -E '^version=' srcpkgs/dms/template | cut -d= -f2 | tr -d '"') STABLE_REV=$(grep -E '^revision=' srcpkgs/dms/template | cut -d= -f2 | tr -d '"') EXPECTED_DMS_FILE="dms-${STABLE_VER}_${STABLE_REV}.x86_64.xbps" if [ -f "../r2-repo/current/$EXPECTED_DMS_FILE" ] && [ "$FORCE_REBUILD" != "true" ]; then echo "✅ $EXPECTED_DMS_FILE already exists, skipping build." else echo "🔨 Compiling dms ($STABLE_VER)..." ./xbps-src pkg dms rm -f "../r2-repo/current/${EXPECTED_DMS_FILE}" cp -L hostdir/binpkgs/dms-${STABLE_VER}_${STABLE_REV}.x86_64.xbps ../r2-repo/current/ fi fi # 3. Build stable dms-greeter package if [ "$BUILD_GREETER" = "true" ]; then GREETER_VER=$(grep -E '^version=' srcpkgs/dms-greeter/template | cut -d= -f2 | tr -d '"') GREETER_REV=$(grep -E '^revision=' srcpkgs/dms-greeter/template | cut -d= -f2 | tr -d '"') EXPECTED_GREETER_FILE="dms-greeter-${GREETER_VER}_${GREETER_REV}.x86_64.xbps" if [ -f "../r2-repo/current/$EXPECTED_GREETER_FILE" ] && [ "$FORCE_REBUILD" != "true" ]; then echo "✅ $EXPECTED_GREETER_FILE already exists, skipping build." else echo "🔨 Compiling dms-greeter ($GREETER_VER)..." ./xbps-src pkg dms-greeter rm -f "../r2-repo/current/${EXPECTED_GREETER_FILE}" cp -L hostdir/binpkgs/dms-greeter-${GREETER_VER}_${GREETER_REV}.x86_64.xbps ../r2-repo/current/ fi fi - name: Index and sign repository run: | cd r2-repo/current rm -f *.sig # Guard: nothing to index if no .xbps files exist if ! ls *.xbps 1>/dev/null 2>&1; then echo "⚠️ No .xbps files found to index, skipping." exit 0 fi # Regenerate repo index xbps-rindex -a $(pwd)/*.xbps xbps-rindex --remove-obsoletes $(pwd) # Remove signatures left behind by obsolete packages. Signatures for # unchanged immutable packages are retained byte-for-byte. for sig in *.sig2; do [ -e "$sig" ] || break [ -f "${sig%.sig2}" ] || rm -f "$sig" done # Sign repository echo "${{ secrets.XBPS_PRIVATE_KEY }}" > /tmp/xbps_privkey.pem chmod 600 /tmp/xbps_privkey.pem xbps-rindex --sign --signedby "AvengeMedia " --privkey /tmp/xbps_privkey.pem $(pwd) xbps-rindex --sign-pkg --privkey /tmp/xbps_privkey.pem $(pwd)/*.xbps rm -f /tmp/xbps_privkey.pem - name: Publish repository to R2 run: bash .github/scripts/publish-void-r2.sh publish