diff --git a/.github/workflows/build-check.yaml b/.github/workflows/build-check.yaml deleted file mode 100644 index 8e148337..00000000 --- a/.github/workflows/build-check.yaml +++ /dev/null @@ -1,109 +0,0 @@ -name: Validate and Test Build - -on: - pull_request: - branches: - - main - - dev - workflow_dispatch: - schedule: - - cron: '0 0 * * *' - -env: - DOCKER_BUILDKIT: 1 - PACMAN_CACHE: /tmp/pacman-cache - WORKSPACE: /workdir - BUILD_DIR: /workdir/workdir - OUTPUT_DIR: /workdir/out - -jobs: - test-build: - runs-on: ubuntu-latest - timeout-minutes: 120 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set up Arch Linux Container - run: | - mkdir -p ${{ env.PACMAN_CACHE }} - docker run --privileged --name arch-container -d \ - -v ${{ github.workspace }}:${{ env.WORKSPACE }} \ - -v ${{ env.PACMAN_CACHE }}:/var/cache/pacman/pkg \ - archlinux:latest sleep infinity - - - name: Install Dependencies - run: | - docker exec arch-container bash -c " - set -euo pipefail - pacman -Syu --noconfirm - pacman -S --noconfirm --needed git archiso grub qemu - " - - - name: Test Build - id: build - run: | - docker exec arch-container bash -c " - set -euo pipefail - cd ${{ env.WORKSPACE }} - rm -rf ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }} - mkdir -p ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }} - mkarchiso -v -w ${{ env.BUILD_DIR }} -o ${{ env.OUTPUT_DIR }} . - " - - - name: Verify ISO - run: | - docker exec arch-container bash -c " - set -euo pipefail - cd ${{ env.OUTPUT_DIR }} - - # Check if ISO exists - iso_count=\$(ls -1 *.iso 2>/dev/null | wc -l) - if [ \$iso_count -eq 0 ]; then - echo '::error::No ISO file found' - exit 1 - elif [ \$iso_count -gt 1 ]; then - echo '::error::Multiple ISO files found' - exit 1 - fi - - iso_file=\$(ls *.iso) - - # Check ISO size (minimum 500MB) - size=\$(stat -c%s \"\$iso_file\") - if [ \$size -lt 524288000 ]; then - echo \"::error::ISO file too small: \$((\$size / 1024 / 1024))MB\" - exit 1 - fi - - # Verify ISO checksum - sha256sum \"\$iso_file\" > checksum.sha256 - sha256sum -c checksum.sha256 || { - echo '::error::ISO checksum verification failed' - exit 1 - } - - # Generate additional checksums - md5sum \"\$iso_file\" > checksum.md5 - sha1sum \"\$iso_file\" > checksum.sha1 - " - - - name: Clean Up - if: always() - run: | - if docker ps -a | grep -q arch-container; then - docker stop arch-container || true - docker rm -f arch-container || true - fi - sudo rm -rf ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }} - - - name: Report Status - if: always() - run: | - if [ "${{ job.status }}" = "success" ]; then - echo "✅ Build check passed successfully" - else - echo "❌ Build check failed" - exit 1 - fi diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index 2a069d4b..00000000 --- a/.github/workflows/build.yaml +++ /dev/null @@ -1,335 +0,0 @@ -name: Build ISO - -on: - workflow_dispatch: - schedule: - - cron: '0 0 * * *' # Run the workflow every day at midnight - push: - branches: - - main - - dev - paths-ignore: - - '**.md' - - '.gitignore' - -# Add permissions needed for creating and managing releases -permissions: - contents: write - packages: read - issues: read - pull-requests: read - -env: - DOCKER_BUILDKIT: 1 - ISO_FILENAME: Arch.iso - WORKSPACE: ${{ github.workspace }} - -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 120 # Set a timeout to prevent hung builds - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set up environment variables - id: env - run: | - echo "DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - echo "VERSION=$(date +'%Y.%m.%d')" >> $GITHUB_ENV - - - name: Set up Arch Linux Container - run: | - docker run --privileged --name arch-container -d \ - -v ${WORKSPACE}:/workdir \ - -v /tmp/pacman-cache:/var/cache/pacman/pkg \ - archlinux:latest sleep infinity - - - name: Initialize Container - run: | - docker exec arch-container bash -c " - set -euo pipefail - - # Update package database and system - pacman -Syu --noconfirm - - # Install required packages - pacman -S --noconfirm --needed \ - git \ - archiso \ - grub \ - curl \ - jq \ - gnupg \ - make \ - sudo - - # Verify installation - command -v mkarchiso >/dev/null 2>&1 || { - echo '::error::mkarchiso not found' - exit 1 - } - " - - - name: Download previous package versions - if: github.ref == 'refs/heads/main' - continue-on-error: true - run: | - mkdir -p /tmp/package-versions - # Try to download the package versions file from the previous release - if ! gh release download --pattern "package_versions.txt" --dir "/tmp/package-versions" 2>/dev/null; then - echo "No previous package_versions.txt found, will create new one." - else - echo "Downloaded previous package versions file." - mv /tmp/package-versions/package_versions.txt /tmp/package-versions/previous_versions.txt - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Build ISO - id: build - run: | - docker exec arch-container bash -c " - set -euo pipefail - cd /workdir - - # Cleanup any previous builds - rm -rf workdir/ out/ - mkdir -p out/ - - # Fix the profiledef.sh file to ensure correct SquashFS options - sed -i 's/-threads/-Xcompression-threads/' profiledef.sh || true - - # Verify SquashFS options - echo '=== Checking SquashFS options in profiledef.sh ===' - grep 'airootfs_image_tool_options' profiledef.sh - - # Build the ISO with verbose output - mkarchiso -v -w workdir/ -o out/ . 2>&1 | tee build.log || { - echo '::error::ISO build failed!' - tail -n 50 build.log - exit 1 - } - - # Verify ISO was created - [ -f out/*.iso ] || { - echo '::error::ISO file not found after build' - exit 1 - } - " - - - name: Generate Package Updates - id: package_updates - run: | - docker exec arch-container bash -c " - set -euo pipefail - cd /workdir - - # Make package tracking script executable - chmod +x scripts/package_tracking/track_package_updates.sh - - # Run the package tracking script - ./scripts/package_tracking/track_package_updates.sh - - # Copy current version file for next build - cp /tmp/package-versions/current_versions.txt /workdir/out/package_versions.txt - " - - - name: Generate Checksums - run: | - docker exec arch-container bash -c " - set -euo pipefail - cd /workdir/out - - # Generate checksums - for iso in *.iso; do - sha256sum \"\$iso\" > \"\${iso}.sha256sum\" - sha512sum \"\$iso\" > \"\${iso}.sha512sum\" - done - " - - - name: Rename and Move ISO - run: | - docker exec arch-container bash -c " - set -euo pipefail - cd /workdir/out - - for f in *.iso; do - newname=\"arch-linux-no-beeps-${{ env.VERSION }}.iso\" - mv \"\$f\" \"\$newname\" - mv \"\$f.sha256sum\" \"\$newname.sha256sum\" - mv \"\$f.sha512sum\" \"\$newname.sha512sum\" - done - " - - - name: Generate Release Notes - id: release_notes - run: | - # Create a temporary file for release notes - TEMP_RELEASE_NOTES=$(mktemp) - - # Generate header for release notes - echo "🚀 Arch Linux ISO without system beeps (build ${{ env.DATE }})" > $TEMP_RELEASE_NOTES - echo "" >> $TEMP_RELEASE_NOTES - - # Get release notes from GitHub action - gh api \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/${GITHUB_REPOSITORY}/releases/generate-notes \ - -F tag_name="v${{ env.VERSION }}" \ - -F target_commitish="${GITHUB_SHA}" \ - -F previous_tag_name="$(git describe --tags --abbrev=0 2>/dev/null || echo '')" \ - | jq -r '.body' >> $TEMP_RELEASE_NOTES - - # Include package updates in release notes if they exist - if [ -f "/tmp/package-versions/package_updates.md" ]; then - echo "" >> $TEMP_RELEASE_NOTES - cat "/tmp/package-versions/package_updates.md" >> $TEMP_RELEASE_NOTES - fi - - # Add standard information - { - echo "" - echo "### Download" - echo "- Download the ISO and verify checksums before use" - echo "" - echo "### Checksums" - echo "SHA256 and SHA512 checksums are available in the uploaded files." - } >> $TEMP_RELEASE_NOTES - - # Set the release notes in GITHUB_ENV - echo "RELEASE_NOTES<> $GITHUB_ENV - cat $TEMP_RELEASE_NOTES >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - # Cleanup - rm -f $TEMP_RELEASE_NOTES - - - name: Create Release - id: create_release - uses: softprops/action-gh-release@v2 - if: github.ref == 'refs/heads/main' - env: - FAIL_COMMENT_NAME: "Create Release" - FAIL_COMMENT_MESSAGE: "An error occurred during the release creation process." - FAIL_COMMENT_CONTEXT: "GitHub Actions Workflow" - FAIL_COMMENT_DETAILS: "Check the logs for more details." - with: - tag_name: v${{ env.VERSION }} - name: "Arch Linux No Beeps v${{ env.VERSION }}" - body: ${{ env.RELEASE_NOTES }} - draft: false - prerelease: false - files: | - ${{ env.WORKSPACE }}/out/*.iso - ${{ env.WORKSPACE }}/out/*.sha*sum - ${{ env.WORKSPACE }}/out/package_versions.txt - - - - name: Set up GitHub CLI - run: | - type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y) - curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ - && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ - && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ - && sudo apt update \ - && sudo apt install gh -y - - - name: Delete old releases - # This step runs after the GitHub CLI setup and release creation - if: github.ref == 'refs/heads/main' && success() - env: - # Don't set GITHUB_TOKEN here as it conflicts with gh auth - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - set +e # Don't exit on error - - echo "::group::Release Cleanup" - - # Get current release tag we're creating - current_tag="v${{ env.VERSION }}" - echo "â„šī¸ Current release tag: $current_tag" - - # GitHub CLI uses GH_TOKEN environment variable automatically - # No need to explicitly authenticate - - # List all releases - echo "â„šī¸ Listing existing releases..." - - # Use simple list format first to check if releases exist - if ! release_count=$(gh release list | wc -l); then - echo "::warning::Failed to list releases. Skipping cleanup." - echo "::endgroup::" - exit 0 - fi - - if [ "$release_count" -eq 0 ]; then - echo "â„šī¸ No existing releases found. Nothing to clean up." - echo "::endgroup::" - exit 0 - fi - - echo "â„šī¸ Found $release_count releases in total" - - # Get detailed release info with JSON - if ! releases=$(gh release list --limit 100 --json tagName,createdAt 2>/dev/null); then - echo "::warning::Unable to get detailed release information. Skipping cleanup." - echo "::endgroup::" - exit 0 - fi - - # Check if jq command is available - if ! command -v jq &> /dev/null; then - echo "::warning::jq command not found. Installing jq..." - sudo apt-get update && sudo apt-get install -y jq - fi - - # Parse releases, handling potential JSON parsing errors - if ! old_releases=($(echo "$releases" | jq -r 'sort_by(.createdAt) | .[].tagName' 2>/dev/null)); then - echo "::warning::Failed to parse release information. Skipping cleanup." - echo "::endgroup::" - exit 0 - fi - - # Number of releases to keep (0 means delete all old releases) - keep=0 - count=0 - total=${#old_releases[@]} - - echo "â„šī¸ Found $total releases after parsing" - - # Delete all releases except the most recent 'keep' number and current release - for tag in "${old_releases[@]}"; do - # Skip the current release - if [[ "$tag" == "$current_tag" ]]; then - echo "â„šī¸ Skipping current release: $tag" - continue - fi - - ((count++)) - if ((count > keep)); then - echo "đŸ—‘ī¸ Attempting to delete release: $tag" - - # Try to delete the release with a timeout - if timeout 30s gh release delete "$tag" --yes; then - echo "✅ Successfully deleted release: $tag" - else - deletion_status=$? - echo "::warning::Failed to delete release $tag (exit code: $deletion_status) - continuing with next release" - fi - - # Small delay to avoid rate limiting - sleep 1 - else - echo "🔒 Keeping release: $tag (within keep limit)" - fi - done - - echo "🏁 Release cleanup completed" - echo "::endgroup::" - - # Always return success to avoid workflow failures - exit 0 - diff --git a/.github/workflows/dockerfile-check.yaml b/.github/workflows/dockerfile-check.yaml deleted file mode 100644 index af0832bc..00000000 --- a/.github/workflows/dockerfile-check.yaml +++ /dev/null @@ -1,62 +0,0 @@ -name: Check to make sure Dockerfile works - -on: - pull_request: - branches: [ "main" ] - workflow_dispatch: - schedule: - # Run the workflow on the 1st of every month at midnight - - cron: '0 0 1 * *' - -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 120 # Add a timeout to prevent hung builds - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set up Environment - run: | - echo "Setting up environment..." - mkdir -p out - chmod +x scripts/entrypoint.sh - chmod +x scripts/select-mirrors.sh - chmod +x profiledef.sh - - - name: Build Docker Image - run: | - echo "Building Docker image..." - docker build -t arch-iso-builder . || { - echo "::error::Docker build failed" - exit 1 - } - - - name: Validate Configuration - run: | - echo "Validating configuration..." - docker run --rm -v "$(pwd)":/workdir arch-iso-builder validate || { - echo "::error::Configuration validation failed" - exit 1 - } - - - name: Build ISO - run: | - echo "Building ISO..." - # Create a small-scale test build with output to verify the process works - docker run --rm --privileged \ - -v "$(pwd)":/workdir \ - arch-iso-builder build out work || { - echo "::error::ISO build failed" - exit 1 - } - - # Verify that output directory contains files - if [ ! -d "out" ] || [ -z "$(ls -A out 2>/dev/null)" ]; then - echo "::error::Output directory is empty or does not exist" - exit 1 - else - echo "ISO build process completed successfully!" - ls -la out - fi diff --git a/.github/workflows/validate-build.yaml b/.github/workflows/validate-build.yaml new file mode 100644 index 00000000..c21dbfb0 --- /dev/null +++ b/.github/workflows/validate-build.yaml @@ -0,0 +1,179 @@ +name: Validate and Test Build + +on: + pull_request: + branches: + - main + - dev + workflow_dispatch: + schedule: + - cron: '0 0 * * *' # Run daily checks + +env: + DOCKER_BUILDKIT: 1 + PACMAN_CACHE: /tmp/pacman-cache + WORKSPACE: /workdir + BUILD_DIR: /workdir/workdir + OUTPUT_DIR: /workdir/out + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 120 # Set timeout to prevent hung builds + + strategy: + matrix: + test-type: ['direct-build', 'dockerfile-build'] + fail-fast: false # Continue with other tests if one fails + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + # Common setup for all test types + - name: Set up Environment + run: | + echo "Setting up environment for ${{ matrix.test-type }}..." + mkdir -p out + chmod +x scripts/entrypoint.sh scripts/select-mirrors.sh profiledef.sh + + ####################################### + # Steps specific to direct build method + ####################################### + - name: Set up Arch Linux Container + if: matrix.test-type == 'direct-build' + run: | + mkdir -p ${{ env.PACMAN_CACHE }} + docker run --privileged --name arch-container -d \ + -v ${{ github.workspace }}:${{ env.WORKSPACE }} \ + -v ${{ env.PACMAN_CACHE }}:/var/cache/pacman/pkg \ + archlinux:latest sleep infinity + + - name: Install Dependencies (Direct Build) + if: matrix.test-type == 'direct-build' + run: | + docker exec arch-container bash -c " + set -euo pipefail + pacman -Syu --noconfirm + pacman -S --noconfirm --needed git archiso grub qemu + " + + - name: Test Direct Build + id: direct-build + if: matrix.test-type == 'direct-build' + run: | + docker exec arch-container bash -c " + set -euo pipefail + cd ${{ env.WORKSPACE }} + rm -rf ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }} + mkdir -p ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }} + mkarchiso -v -w ${{ env.BUILD_DIR }} -o ${{ env.OUTPUT_DIR }} . + " + + - name: Verify ISO (Direct Build) + if: matrix.test-type == 'direct-build' + run: | + docker exec arch-container bash -c " + set -euo pipefail + cd ${{ env.OUTPUT_DIR }} + + # Check if ISO exists + iso_count=\$(ls -1 *.iso 2>/dev/null | wc -l) + if [ \$iso_count -eq 0 ]; then + echo '::error::No ISO file found' + exit 1 + elif [ \$iso_count -gt 1 ]; then + echo '::error::Multiple ISO files found' + exit 1 + fi + + iso_file=\$(ls *.iso) + + # Check ISO size (minimum 500MB) + size=\$(stat -c%s \"\$iso_file\") + if [ \$size -lt 524288000 ]; then + echo \"::error::ISO file too small: \$((\$size / 1024 / 1024))MB\" + exit 1 + fi + + # Verify ISO checksum + sha256sum \"\$iso_file\" > checksum.sha256 + sha256sum -c checksum.sha256 || { + echo '::error::ISO checksum verification failed' + exit 1 + } + + # Generate additional checksums + md5sum \"\$iso_file\" > checksum.md5 + sha1sum \"\$iso_file\" > checksum.sha1 + " + + - name: Clean Up Direct Build + if: matrix.test-type == 'direct-build' && always() + run: | + if docker ps -a | grep -q arch-container; then + docker stop arch-container || true + docker rm -f arch-container || true + fi + sudo rm -rf ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }} + + ######################################### + # Steps specific to dockerfile build method + ######################################### + - name: Build Docker Image + if: matrix.test-type == 'dockerfile-build' + run: | + echo "Building Docker image..." + docker build -t arch-iso-builder . || { + echo "::error::Docker build failed" + exit 1 + } + + - name: Validate Configuration + if: matrix.test-type == 'dockerfile-build' + run: | + echo "Validating configuration..." + docker run --rm -v "$(pwd)":/workdir arch-iso-builder validate || { + echo "::error::Configuration validation failed" + exit 1 + } + + - name: Build ISO with Dockerfile + if: matrix.test-type == 'dockerfile-build' + id: dockerfile-build + run: | + echo "Building ISO using Dockerfile method..." + # Create a test build with output to verify the process works + docker run --rm --privileged \ + -v "$(pwd)":/workdir \ + arch-iso-builder build out work || { + echo "::error::ISO build failed" + exit 1 + } + + # Verify that output directory contains files + if [ ! -d "out" ] || [ -z "$(ls -A out 2>/dev/null)" ]; then + echo "::error::Output directory is empty or does not exist" + exit 1 + else + echo "ISO build process completed successfully!" + ls -la out + fi + + # Cleanup for Dockerfile build + - name: Clean Up Dockerfile Build + if: matrix.test-type == 'dockerfile-build' && always() + run: | + sudo rm -rf out/ work/ + docker image rm arch-iso-builder || true + + # Common final step for all test types + - name: Report Status + if: always() + run: | + if [ "${{ job.status }}" = "success" ]; then + echo "✅ ${{ matrix.test-type }} test passed successfully" + else + echo "❌ ${{ matrix.test-type }} test failed" + exit 1 + fi \ No newline at end of file