serverforge 0.1.3

ServerForge - A robust server setup and maintenance tool
Documentation
name: Rust CI/CD

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  release:
    types: [created]

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  check:
    name: Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo check

  test:
    name: Test Suite
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo test --all-features -- --nocapture

  fmt:
    name: Rustfmt
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt
      - run: cargo fmt --all -- --check

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2
      - run: cargo clippy -- -D warnings

  docs:
    name: Documentation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Install mdBook
        run: cargo install mdbook
      - name: Setup mdBook
        run: |
          if [ ! -d "docs" ]; then
            mkdir docs
            cd docs
            mdbook init
            echo "# ServerForge" > src/chapter_1.md
            echo "# Summary" > src/SUMMARY.md
            echo "" >> src/SUMMARY.md
            echo "- [Chapter 1](./chapter_1.md)" >> src/SUMMARY.md
          fi
      - name: Build API docs
        run: cargo doc --no-deps --all-features
      - name: Build mdBook docs
        run: mdbook build docs
      - name: Combine docs
        run: |
          mkdir -p ./public
          cp -r ./target/doc ./public/api
          cp -r ./docs/book ./public/guide
          echo '<meta http-equiv="refresh" content="0; url=serverforge/index.html">' > ./public/index.html
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        if: github.ref == 'refs/heads/main'
        with:
          github_token: ${{ secrets.TOKEN }}
          publish_dir: ./public
          force_orphan: true

  publish-dry-run:
    name: Publish Dry Run
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo publish --dry-run

  release:
    name: Release
    needs: [check, fmt, docs, publish-dry-run]
    if: github.event_name == 'release' && github.event.action == 'created'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-unknown-linux-gnu
      - uses: Swatinem/rust-cache@v2
      - name: Build
        run: cargo build --release --target x86_64-unknown-linux-gnu
      - name: Package
        run: |
          cd target/x86_64-unknown-linux-gnu/release
          BINARY_NAME="server_forge"
          ARCHIVE_NAME="server_forge-x86_64-unknown-linux-gnu.tar.gz"
          tar czvf "../../../$ARCHIVE_NAME" "$BINARY_NAME"
      - name: Create install script
        run: |
          cat << EOF > install.sh
          #!/bin/bash
          set -e
          
          # Detect OS and architecture
          OS=$(uname -s | tr '[:upper:]' '[:lower:]')
          ARCH=$(uname -m)
          
          if [ "$OS" != "linux" ] || [ "$ARCH" != "x86_64" ]; then
            echo "Unsupported OS or architecture. This script is for Linux x86_64 only."
            exit 1
          fi
          
          # Download the latest release
          LATEST_RELEASE_URL=$(curl -s https://api.github.com/repos/doziestar/serverforge/releases/latest | grep "browser_download_url.*tar.gz" | cut -d : -f 2,3 | tr -d \")
          curl -L -o server_forge.tar.gz $LATEST_RELEASE_URL
          
          # Extract the binary
          tar -xzvf server_forge.tar.gz
          
          # Install the binary
          sudo mv server_forge /usr/local/bin/
          sudo chmod +x /usr/local/bin/server_forge
          
          # Clean up
          rm server_forge.tar.gz
          
          echo "ServerForge has been installed successfully!"
          EOF
      - name: Upload binary to release
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.TOKEN }}
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: ./server_forge-x86_64-unknown-linux-gnu.tar.gz
          asset_name: server_forge-x86_64-unknown-linux-gnu.tar.gz
          asset_content_type: application/gzip
      - name: Upload Build Artifact
        uses: actions/upload-artifact@v3
        with:
          name: server_forge-x86_64-unknown-linux-gnu
          path: server_forge-x86_64-unknown-linux-gnu.tar.gz

  publish-crates-io:
    name: Publish to crates.io
    needs: [release]
    if: github.event_name == 'release' && github.event.action == 'created'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}

  linux-packages:
    name: Create Linux Packages
    needs: [ release ]
    if: github.event_name == 'release' && github.event.action == 'created'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: sudo apt-get update && sudo apt-get install -y rpm
      - name: Set version
        run: echo "VERSION=${GITHUB_REF_NAME#refs/tags/v}" >> $GITHUB_ENV
      - name: Download release artifact
        uses: actions/download-artifact@v3
        with:
          name: server_forge-x86_64-unknown-linux-gnu
          path: ./
      - name: Extract release artifact
        run: tar -xzvf server_forge-x86_64-unknown-linux-gnu.tar.gz
      - name: Create DEB package
        run: |
          # Get the version from the environment file
          VERSION="${{ env.VERSION }}"

          mkdir -p serverforge_${VERSION}_amd64/DEBIAN
          echo "Package: serverforge
          Version: ${VERSION}
          Architecture: amd64
          Maintainer: Chidozie C. Okafor <chidosiky2015@gmail.com>
          Description: ServerForge - A robust server setup and maintenance tool" > serverforge_${VERSION}_amd64/DEBIAN/control
          mkdir -p serverforge_${VERSION}_amd64/usr/local/bin
          cp server_forge serverforge_${VERSION}_amd64/usr/local/bin/
          dpkg-deb --build serverforge_${VERSION}_amd64
      - name: Create RPM package
        run: |
          # Get the version from the environment file
          VERSION="${{ env.VERSION }}"

          mkdir -p ~/rpmbuild/{SPECS,SOURCES,BUILD,RPMS,SRPMS}
          cp server_forge ~/rpmbuild/SOURCES/
          echo "Name: serverforge
          Version: ${VERSION}
          Release: 1
          Summary: ServerForge - A robust server setup and maintenance tool
          License: MIT

          %description
          ServerForge is a robust server setup and maintenance tool.

          %install
          mkdir -p %{buildroot}/usr/local/bin
          cp %{_sourcedir}/server_forge %{buildroot}/usr/local/bin/

          %files
          /usr/local/bin/server_forge

          %clean
          rm -rf %{buildroot}" > ~/rpmbuild/SPECS/serverforge.spec
          rpmbuild -ba ~/rpmbuild/SPECS/serverforge.spec
      - name: Upload DEB package
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.TOKEN }}
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: ./serverforge_${{ env.VERSION }}_amd64.deb
          asset_name: serverforge_${{ env.VERSION }}_amd64.deb
          asset_content_type: application/octet-stream
      - name: Upload RPM package
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.TOKEN }}
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: ~/rpmbuild/RPMS/x86_64/serverforge-${{ env.VERSION }}-1.x86_64.rpm
          asset_name: serverforge-${{ env.VERSION }}-1.x86_64.rpm
          asset_content_type: application/octet-stream