Skip to content

Build Community Editions #14

Build Community Editions

Build Community Editions #14

name: Build Community Editions
on:
schedule:
- cron: '0 6 * * 1' # weekly Monday 6am UTC
workflow_dispatch:
permissions:
contents: read
concurrency:
group: build-community-${{ github.sha }}
cancel-in-progress: false
jobs:
build:
strategy:
fail-fast: false
max-parallel: 2
matrix:
edition:
- slug: gnome
repo: spivanatalie64/acreetionos-gnome
desktop: GNOME
display: Wayland
arch: x86_64
- slug: plasma
repo: spivanatalie64/acreetionos-plasma
desktop: KDE Plasma
display: Wayland
arch: x86_64
- slug: xfce
repo: spivanatalie64/acreetionos-xfce
desktop: XFCE
display: XLibre
arch: x86_64
- slug: i3
repo: spivanatalie64/acreetionos-i3
desktop: i3
display: X11
arch: x86_64
- slug: sway
repo: spivanatalie64/acreetionos-sway
desktop: Sway
display: Wayland
arch: x86_64
- slug: mate
repo: spivanatalie64/acreetionos-mate
desktop: MATE
display: XLibre
arch: x86_64
- slug: openbox
repo: spivanatalie64/acreetionos-openbox
desktop: Openbox
display: XLibre
arch: x86_64
- slug: hyprland
repo: spivanatalie64/acreetionos-hyprland
desktop: Hyprland
display: Wayland
arch: x86_64
- slug: 32bit
repo: spivanatalie64/acreetionos32
desktop: Cinnamon
display: XLibre
arch: i686
- slug: immutable
repo: spivanatalie64/immutable
desktop: Immutable
display: Read-only
arch: x86_64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkout edition repo
uses: actions/checkout@v4
with:
repository: ${{ matrix.edition.repo }}
path: src
- name: Apply branding
run: |
sed -i 's/sudo //g' src/build.sh 2>/dev/null || true
sed -i 's/iso_label=.*/iso_label="AcreetionOS ${{ matrix.edition.desktop }}"/' src/profiledef.sh 2>/dev/null || true
sed -i 's/iso_publisher=.*/iso_publisher="AcreetionOS Project <https:\/\/acreetionos.org>"/' src/profiledef.sh 2>/dev/null || true
sed -i 's/iso_application=.*/iso_application="AcreetionOS Linux Distribution"/' src/profiledef.sh 2>/dev/null || true
- name: Emit build metadata
id: meta
run: |
echo "slug=${{ matrix.edition.slug }}" >> $GITHUB_OUTPUT
echo "date_tag=$(date +%Y%m%d)" >> $GITHUB_OUTPUT
echo "iso_name=${{ matrix.edition.slug }}-$(date +%Y%m%d).iso" >> $GITHUB_OUTPUT
- name: Write building status to R2
env:
CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
STATUS='{"edition":"${{ matrix.edition.desktop }}","slug":"${{ steps.meta.outputs.slug }}","status":"building","started":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","run_url":"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}","iso_name":"${{ steps.meta.outputs.iso_name }}","desktop":"${{ matrix.edition.desktop }}","display":"${{ matrix.edition.display }}","arch":"${{ matrix.edition.arch }}"}'
echo "$STATUS" > /tmp/status.json
curl -s -X PUT "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects/${{ steps.meta.outputs.slug }}-status.json" \
-H "Authorization: Bearer $CF_TOKEN" \
--data-binary @/tmp/status.json \
-H "Content-Type: application/json" || echo "Status write skipped"
- name: Build ISO in Docker
id: build
run: |
mkdir -p /tmp/iso
docker run --privileged --rm \
-v $PWD/src:/workspace \
archlinux@sha256:fb47d15e0fd28369c700edcfa46dd44e234d8ab6fee9627ee5f1ead5f1fc6c21 \
bash -c '
pacman -Syu --noconfirm archiso grub && \
cd /workspace && \
chmod +x *.sh 2>/dev/null; \
bash build.sh 2>&1 || { echo "BUILD_FAILED"; exit 1; }
' 2>&1 | tee /tmp/build.log
ls -la src/out/ 2>/dev/null && cp src/out/*.iso /tmp/iso/ 2>/dev/null || true
if [ -z "$(ls /tmp/iso/*.iso 2>/dev/null)" ]; then
echo "build_ok=false" >> $GITHUB_OUTPUT
else
echo "build_ok=true" >> $GITHUB_OUTPUT
fi
- name: Upload build log
if: always()
env:
CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
if [ -f /tmp/build.log ]; then
curl -s -X PUT "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects/${{ steps.meta.outputs.slug }}-build.log" \
-H "Authorization: Bearer $CF_TOKEN" \
--data-binary @/tmp/build.log \
-H "Content-Type: text/plain" || echo "Log upload skipped"
fi
- name: Prepare ISO for upload
id: iso
if: steps.build.outputs.build_ok == 'true'
run: |
ISO=$(ls /tmp/iso/*.iso 2>/dev/null | head -1)
if [ -n "$ISO" ]; then
cp "$ISO" "/tmp/${{ steps.meta.outputs.iso_name }}"
echo "iso_path=/tmp/${{ steps.meta.outputs.iso_name }}" >> $GITHUB_OUTPUT
echo "iso_name=${{ steps.meta.outputs.iso_name }}" >> $GITHUB_OUTPUT
echo "ok=true" >> $GITHUB_OUTPUT
else
echo "ok=false" >> $GITHUB_OUTPUT
fi
- name: Upload ISO to R2
if: steps.iso.outputs.ok == 'true'
env:
CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
# Upload to R2 using Cloudflare API
echo "Uploading ${{ steps.meta.outputs.iso_name }} to R2..."
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects/${{ steps.meta.outputs.iso_name }}" \
-H "Authorization: Bearer $CF_TOKEN" \
--data-binary @"${{ steps.iso.outputs.iso_path }}" \
-H "Content-Type: application/octet-stream" && echo "Uploaded: ${{ steps.meta.outputs.iso_name }}" || echo "R2 upload failed"
# Upload as latest too
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects/${{ steps.meta.outputs.slug }}-latest.iso" \
-H "Authorization: Bearer $CF_TOKEN" \
--data-binary @"${{ steps.iso.outputs.iso_path }}" \
-H "Content-Type: application/octet-stream" && echo "Uploaded: ${{ steps.meta.outputs.slug }}-latest.iso" || echo "Latest upload failed"
# Try S3-compatible upload via direct curl (no Python needed)
echo "Also trying S3-compatible upload..."
S3_URL="https://$CF_ACCOUNT.r2.cloudflarestorage.com/acreetionos-isos/${{ steps.meta.outputs.iso_name }}"
curl -s -X PUT "$S3_URL" \
-H "Authorization: Bearer $CF_TOKEN" \
--data-binary @"${{ steps.iso.outputs.iso_path }}" || echo "S3 upload skipped"
- name: Update build status
if: always()
env:
CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
if [ "${{ steps.iso.outputs.ok }}" = "true" ]; then
STATUS='{"edition":"${{ matrix.edition.desktop }}","slug":"${{ steps.meta.outputs.slug }}","status":"success","finished":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","run_url":"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}","iso_name":"${{ steps.meta.outputs.iso_name }}","download_url":"https://pub-173a1f638a3b4c95b5f58b09c0b968aa.r2.dev/acreetionos-isos/${{ steps.meta.outputs.iso_name }}"}'
else
STATUS='{"edition":"${{ matrix.edition.desktop }}","slug":"${{ steps.meta.outputs.slug }}","status":"failed","finished":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","run_url":"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}","desktop":"${{ matrix.edition.desktop }}","display":"${{ matrix.edition.display }}","arch":"${{ matrix.edition.arch }}"}'
fi
echo "$STATUS" > /tmp/status.json
curl -s -X PUT "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects/${{ steps.meta.outputs.slug }}-status.json" \
-H "Authorization: Bearer $CF_TOKEN" \
--data-binary @/tmp/status.json \
-H "Content-Type: application/json" || echo "Status update skipped"
cleanup:
needs: build
runs-on: ubuntu-latest
if: always()
steps:
- name: Delete old ISOs
env:
CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
echo "Cleaning up old ISOs..."
OBJECTS=$(curl -s "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects" \
-H "Authorization: Bearer $CF_TOKEN")
# Delete old ISOs (keep latest, status, logs)
# Use piped curl + jq instead of Python
curl -s "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects" \
-H "Authorization: Bearer $CF_TOKEN" | \
jq -r '.result.objects[] | select(.key | test("latest|status|build\\.log") | not) | .key + "|" + .uploaded' 2>/dev/null | \
while IFS='|' read -r key uploaded; do
TS=$(date -d "$uploaded" +%s 2>/dev/null)
CUTOFF=$(date -d "30 days ago" +%s)
if [ -n "$TS" ] && [ "$TS" -lt "$CUTOFF" ] 2>/dev/null; then
curl -s -X DELETE "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/r2/buckets/acreetionos-isos/objects/$key" \
-H "Authorization: Bearer $CF_TOKEN" && echo "Deleted $key"
fi
done || echo "Cleanup skipped"