Build Community Editions #14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |