name: Release Workflow on: workflow_dispatch: inputs: tag: description: 'Tag to create release with (e.g., v2.0.10)' required: true fork_owner: description: 'GitHub username of the fork owner' required: true default: 'tosin2013' jobs: test-ubuntu: strategy: matrix: os: [ubuntu-22.04, ubuntu-24.04] framework: ['crewai', 'autogen'] fail-fast: false runs-on: ${{ matrix.os }} timeout-minutes: 90 steps: # First checkout the upstream repo at the specified tag - name: Checkout upstream repo uses: actions/checkout@v4 with: persist-credentials: false with: persist-credentials: false with: repository: MervinPraison/PraisonAI ref: ${{ github.event.inputs.tag }} fetch-depth: 0 # Get the commit hash from the tag - name: Get commit hash id: get_commit env: INPUT_TAG: ${{ github.event.inputs.tag }} run: | COMMIT_HASH=$(git rev-parse HEAD) echo "commit_hash=$COMMIT_HASH" >> $GITHUB_OUTPUT echo "Found commit: $COMMIT_HASH for tag $INPUT_TAG" # Now checkout the fork at main branch - name: Checkout fork uses: actions/checkout@v4 with: persist-credentials: false with: persist-credentials: false with: repository: ${{ github.event.inputs.fork_owner }}/PraisonAI ref: main fetch-depth: 0 clean: true # Sync with upstream commit - name: Sync with upstream run: | git config --global user.name "MervinPraison" git config --global user.email "454862+MervinPraison@users.noreply.github.com" # Add upstream remote git remote add upstream https://github.com/MervinPraison/PraisonAI.git # Fetch from upstream git fetch upstream --tags --force - name: Hard reset to tag commit env: COMMIT_HASH: ${{ steps.get_commit.outputs.commit_hash }} run: | git reset --hard $COMMIT_HASH - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - name: Install Poetry run: | curl -sSL https://install.python-poetry.org | python3 - echo "$HOME/.local/bin" >> $GITHUB_PATH poetry config virtualenvs.in-project true poetry config virtualenvs.create true poetry --version poetry config --list - name: Install Dependencies run: | poetry lock #--no-update poetry install --all-extras poetry env info # Verify venv exists test -d .venv || { echo "Virtual environment not created!"; exit 1; } test -f .venv/bin/activate || { echo "Activation script not found!"; exit 1; } - name: Run setup script timeout-minutes: 20 run: | set -e # Exit on any error curl -OL https://raw.githubusercontent.com/tosin2013/PraisonAI/refs/heads/main/setup.sh chmod +x setup.sh ./setup.sh --all --cicd || { echo "Setup script failed"; exit 1; } env: OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }} GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} OPENAI_MODEL_NAME: "llama-3.3-70b-versatile" OPENAI_API_BASE: "https://api.groq.com/openai/v1/" OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/" PRAISONAI_NON_INTERACTIVE: "true" - name: Test Basic Functionality run: | set -e # Exit on any error # Random sleep between 60-120 seconds to avoid API rate limits SLEEP_TIME=$((RANDOM % 61 + 60)) echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..." sleep $SLEEP_TIME lsof -ti:8084 | xargs -r kill -9 || true source .venv/bin/activate || { echo "Failed to activate virtual environment"; exit 1; } mkdir -p test_output || { echo "Failed to create test_output directory"; exit 1; } echo "Testing basic CLI functionality..." # Test auto generation with explicit framework praisonai --framework ${{ matrix.framework }} --auto "create a short test script" 2>&1 | tee test_output/auto_test.log # Verify the output file exists and has content if [[ ! -s test_output/auto_test.log ]]; then echo "Error: No output generated from auto test" exit 1 fi # Test auto generation without framework echo "Basic functionality tests passed!" env: OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }} GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} OPENAI_MODEL_NAME: "llama-3.3-70b-versatile" OPENAI_API_BASE: "https://api.groq.com/openai/v1/" OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/" LOGLEVEL: "debug" PRAISONAI_NON_INTERACTIVE: "true" - name: Test Framework-specific Features continue-on-error: false run: | source .venv/bin/activate # Random sleep between 60-120 seconds to avoid API rate limits SLEEP_TIME=$((RANDOM % 61 + 60)) echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..." sleep $SLEEP_TIME lsof -ti:8084 | xargs -r kill -9 || true praisonai --framework ${{ matrix.framework }} --auto "create a movie script about Robots in Mars" 2>&1 | tee test_output/framework_output.txt || echo "Framework-specific test failed" >> test_output/errors.log env: OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }} GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} OPENAI_MODEL_NAME: "llama-3.3-70b-versatile" OPENAI_API_BASE: "https://api.groq.com/openai/v1/" OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/" PRAISONAI_NON_INTERACTIVE: "true" - name: Test Core Functionality continue-on-error: false run: | source .venv/bin/activate # Random sleep between 60-120 seconds to avoid API rate limits SLEEP_TIME=$((RANDOM % 61 + 60)) echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..." sleep $SLEEP_TIME echo "Testing core functionality..." # Test package imports python3 -c "from praisonai.cli import PraisonAI; from praisonai.auto import AutoGenerator; from praisonai.agents_generator import AgentsGenerator" || exit 1 # Test configuration loading python3 -c "from praisonai.inc.config import generate_config; print(generate_config())" || exit 1 # Test tools loading python3 -c "from praisonai.inbuilt_tools import *" || exit 1 echo "Core functionality tests passed!" env: OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }} GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} OPENAI_MODEL_NAME: "llama-3.3-70b-versatile" OPENAI_API_BASE: "https://api.groq.com/openai/v1/" OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/" LOGLEVEL: "debug" PRAISONAI_NON_INTERACTIVE: "true" - name: Test Agent Generation continue-on-error: false run: | source .venv/bin/activate # Random sleep between 60-120 seconds to avoid API rate limits SLEEP_TIME=$((RANDOM % 61 + 60)) echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..." sleep $SLEEP_TIME echo "Testing agent generation..." # Create a test YAML file cat > test_agents.yaml < test_tool.py < test_agents.py <&1 | tee test_output/agents_test.log # Verify the output if [[ ! -s test_output/agents_test.log ]]; then echo "Error: No output generated from agents test" exit 1 fi echo "Agents configuration tests passed!" env: OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }} GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} OPENAI_MODEL_NAME: "llama-3.3-70b-versatile" OPENAI_API_BASE: "https://api.groq.com/openai/v1/" OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/" LOGLEVEL: "debug" PRAISONAI_NON_INTERACTIVE: "true" - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 with: name: praisonai-output-${{ matrix.os }}-${{ matrix.framework }} path: test_output/ retention-days: 14 create-release: needs: [test-ubuntu] runs-on: ubuntu-latest if: success() steps: # First checkout the fork's main branch - name: Checkout fork repo uses: actions/checkout@v4 with: persist-credentials: false with: persist-credentials: false with: fetch-depth: 0 token: ${{ secrets.PAT_TOKEN }} repository: ${{ github.event.inputs.fork_owner }}/PraisonAI ref: main # Add upstream and get commit from tag - name: Get upstream tag commit id: get_upstream_commit env: INPUT_TAG: ${{ github.event.inputs.tag }} run: | # Add upstream remote git remote add upstream https://github.com/MervinPraison/PraisonAI.git # Delete local tag if it exists git tag -d "$INPUT_TAG" || true # Fetch from upstream including tags with force git fetch upstream --tags --force # Verify tag exists in upstream if ! git ls-remote --tags upstream | grep -q "refs/tags/$INPUT_TAG$"; then echo "::error::Tag $INPUT_TAG not found in upstream repository" exit 1 fi # Get the commit hash from the upstream tag UPSTREAM_COMMIT=$(git rev-list -n 1 refs/tags/"$INPUT_TAG") if [ -z "$UPSTREAM_COMMIT" ]; then echo "::error::Could not find commit for tag $INPUT_TAG" exit 1 fi echo "upstream_commit=$UPSTREAM_COMMIT" >> $GITHUB_OUTPUT echo "Found commit: $UPSTREAM_COMMIT for tag $INPUT_TAG" # Create tag at the same commit - name: Create tag at commit env: GIT_ASKPASS: /bin/echo PAT_TOKEN: ${{ secrets.PAT_TOKEN }} INPUT_TAG: ${{ github.event.inputs.tag }} run: | git config --global user.name "MervinPraison" git config --global user.email "454862+MervinPraison@users.noreply.github.com" # Remove tag if it exists locally git tag -d "$INPUT_TAG" || true # Remove tag if it exists remotely git push origin :refs/tags/"$INPUT_TAG" || true - name: Fetch tag from upstream env: UPSTREAM_COMMIT: ${{ steps.get_upstream_commit.outputs.upstream_commit }} run: | git fetch upstream $UPSTREAM_COMMIT --force - name: Reset to upstream commit env: UPSTREAM_COMMIT: ${{ steps.get_upstream_commit.outputs.upstream_commit }} run: | git reset --hard $UPSTREAM_COMMIT # Create and push tag git tag -a "$INPUT_TAG" -m "Release $INPUT_TAG (synced from upstream MervinPraison/PraisonAI@$INPUT_TAG)" git push origin "$INPUT_TAG" # Create the release - name: Create Release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }} with: tag_name: ${{ github.event.inputs.tag }} release_name: Release ${{ github.event.inputs.tag }} draft: false prerelease: false body: | Release ${{ github.event.inputs.tag }} (synced from upstream) This release is synchronized with MervinPraison/PraisonAI@${{ github.event.inputs.tag }} Commit: ${{ steps.get_upstream_commit.outputs.upstream_commit }} For installation: ```bash pip install praisonai ``` Changes from upstream v2.0.10: - Updated agent configuration tests - Added rate limiting protection - Improved test reliability Forked from: MervinPraison/PraisonAI