| | name: FRED ML CI/CD Pipeline |
| |
|
| | on: |
| | push: |
| | branches: [ main, develop ] |
| | pull_request: |
| | branches: [ main ] |
| | schedule: |
| | |
| | - cron: '0 2 * * *' |
| |
|
| | env: |
| | AWS_REGION: us-west-2 |
| | S3_BUCKET: fredmlv1 |
| | LAMBDA_FUNCTION: fred-ml-processor |
| | PYTHON_VERSION: '3.9' |
| |
|
| | jobs: |
| | |
| | test: |
| | name: π§ͺ Test & Quality |
| | runs-on: ubuntu-latest |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Set up Python ${{ env.PYTHON_VERSION }} |
| | uses: actions/setup-python@v4 |
| | with: |
| | python-version: ${{ env.PYTHON_VERSION }} |
| | |
| | - name: Cache pip dependencies |
| | uses: actions/cache@v3 |
| | with: |
| | path: ~/.cache/pip |
| | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} |
| | restore-keys: | |
| | ${{ runner.os }}-pip- |
| | |
| | - name: Install dependencies |
| | run: | |
| | python -m pip install --upgrade pip |
| | pip install -r requirements.txt |
| | pip install pytest pytest-cov black flake8 mypy |
| | |
| | - name: Run linting |
| | run: | |
| | echo "π Running code linting..." |
| | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics |
| | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics |
| | |
| | - name: Run type checking |
| | run: | |
| | echo "π Running type checking..." |
| | mypy lambda/ frontend/ src/ --ignore-missing-imports |
| | |
| | - name: Run formatting check |
| | run: | |
| | echo "π¨ Checking code formatting..." |
| | black --check --diff . |
| | |
| | - name: Run unit tests |
| | run: | |
| | echo "π§ͺ Running unit tests..." |
| | pytest tests/unit/ -v --cov=lambda --cov=frontend --cov-report=xml |
| | |
| | - name: Upload coverage to Codecov |
| | uses: codecov/codecov-action@v3 |
| | with: |
| | file: ./coverage.xml |
| | flags: unittests |
| | name: codecov-umbrella |
| | fail_ci_if_error: false |
| |
|
| | |
| | integration: |
| | name: π Integration Tests |
| | runs-on: ubuntu-latest |
| | needs: test |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Set up Python ${{ env.PYTHON_VERSION }} |
| | uses: actions/setup-python@v4 |
| | with: |
| | python-version: ${{ env.PYTHON_VERSION }} |
| | |
| | - name: Install dependencies |
| | run: | |
| | python -m pip install --upgrade pip |
| | pip install -r requirements.txt |
| | |
| | - name: Configure AWS credentials |
| | uses: aws-actions/configure-aws-credentials@v4 |
| | with: |
| | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| | aws-region: ${{ env.AWS_REGION }} |
| | |
| | - name: Run integration tests |
| | run: | |
| | echo "π Running integration tests..." |
| | python scripts/test_complete_system.py --skip-e2e |
| | env: |
| | AWS_DEFAULT_REGION: ${{ env.AWS_REGION }} |
| | S3_BUCKET: ${{ env.S3_BUCKET }} |
| | LAMBDA_FUNCTION: ${{ env.LAMBDA_FUNCTION }} |
| |
|
| | |
| | e2e: |
| | name: π End-to-End Tests |
| | runs-on: ubuntu-latest |
| | needs: [test, integration] |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Set up Python ${{ env.PYTHON_VERSION }} |
| | uses: actions/setup-python@v4 |
| | with: |
| | python-version: ${{ env.PYTHON_VERSION }} |
| | |
| | - name: Install dependencies |
| | run: | |
| | python -m pip install --upgrade pip |
| | pip install -r requirements.txt |
| | |
| | - name: Configure AWS credentials |
| | uses: aws-actions/configure-aws-credentials@v4 |
| | with: |
| | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| | aws-region: ${{ env.AWS_REGION }} |
| | |
| | - name: Run end-to-end tests |
| | run: | |
| | echo "π Running end-to-end tests..." |
| | python scripts/test_complete_system.py |
| | env: |
| | AWS_DEFAULT_REGION: ${{ env.AWS_REGION }} |
| | S3_BUCKET: ${{ env.S3_BUCKET }} |
| | LAMBDA_FUNCTION: ${{ env.LAMBDA_FUNCTION }} |
| | |
| | - name: Upload test results |
| | uses: actions/upload-artifact@v3 |
| | if: always() |
| | with: |
| | name: test-results |
| | path: test_report.json |
| |
|
| | |
| | security: |
| | name: π Security Scan |
| | runs-on: ubuntu-latest |
| | needs: test |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Run Bandit security scan |
| | run: | |
| | echo "π Running security scan..." |
| | pip install bandit |
| | bandit -r lambda/ frontend/ src/ -f json -o bandit-report.json || true |
| | |
| | - name: Upload security report |
| | uses: actions/upload-artifact@v3 |
| | if: always() |
| | with: |
| | name: security-report |
| | path: bandit-report.json |
| |
|
| | |
| | deploy-lambda: |
| | name: β‘ Deploy Lambda |
| | runs-on: ubuntu-latest |
| | needs: [test, integration, e2e, security] |
| | if: github.ref == 'refs/heads/main' |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Set up Python ${{ env.PYTHON_VERSION }} |
| | uses: actions/setup-python@v4 |
| | with: |
| | python-version: ${{ env.PYTHON_VERSION }} |
| | |
| | - name: Configure AWS credentials |
| | uses: aws-actions/configure-aws-credentials@v4 |
| | with: |
| | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| | aws-region: ${{ env.AWS_REGION }} |
| | |
| | - name: Create Lambda deployment package |
| | run: | |
| | echo "π¦ Creating Lambda deployment package..." |
| | cd lambda |
| | pip install -r requirements.txt -t . |
| | zip -r ../lambda-deployment.zip . |
| | cd .. |
| | |
| | - name: Update Lambda function |
| | run: | |
| | echo "β‘ Updating Lambda function..." |
| | aws lambda update-function-code \ |
| | --function-name ${{ env.LAMBDA_FUNCTION }} \ |
| | --zip-file fileb://lambda-deployment.zip \ |
| | --region ${{ env.AWS_REGION }} |
| | |
| | - name: Update Lambda configuration |
| | run: | |
| | echo "βοΈ Updating Lambda configuration..." |
| | aws lambda update-function-configuration \ |
| | --function-name ${{ env.LAMBDA_FUNCTION }} \ |
| | --environment Variables="{S3_BUCKET=${{ env.S3_BUCKET }}}" \ |
| | --region ${{ env.AWS_REGION }} |
| | |
| | - name: Update SSM parameter |
| | run: | |
| | echo "π Updating FRED API key in SSM..." |
| | aws ssm put-parameter \ |
| | --name "/fred-ml/api-key" \ |
| | --value "${{ secrets.FRED_API_KEY }}" \ |
| | --type "SecureString" \ |
| | --overwrite \ |
| | --region ${{ env.AWS_REGION }} |
| | |
| | |
| | deploy-infrastructure: |
| | name: ποΈ Deploy Infrastructure |
| | runs-on: ubuntu-latest |
| | needs: [test, integration, e2e, security] |
| | if: github.ref == 'refs/heads/main' |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Configure AWS credentials |
| | uses: aws-actions/configure-aws-credentials@v4 |
| | with: |
| | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| | aws-region: ${{ env.AWS_REGION }} |
| | |
| | - name: Deploy S3 bucket |
| | run: | |
| | echo "π¦ Deploying S3 bucket..." |
| | aws cloudformation deploy \ |
| | --template-file infrastructure/s3/bucket.yaml \ |
| | --stack-name fredmlv1-s3-stack \ |
| | --parameter-overrides BucketName=${{ env.S3_BUCKET }} \ |
| | --capabilities CAPABILITY_NAMED_IAM \ |
| | --region ${{ env.AWS_REGION }} |
| | |
| | - name: Deploy EventBridge rule |
| | run: | |
| | echo "β° Deploying EventBridge rule..." |
| | aws cloudformation deploy \ |
| | --template-file infrastructure/eventbridge/quarterly-rule.yaml \ |
| | --stack-name fred-ml-processor-eventbridge-stack \ |
| | --parameter-overrides \ |
| | LambdaFunctionName=${{ env.LAMBDA_FUNCTION }} \ |
| | S3BucketName=${{ env.S3_BUCKET }} \ |
| | --capabilities CAPABILITY_NAMED_IAM \ |
| | --region ${{ env.AWS_REGION }} |
| | |
| | |
| | deploy-streamlit: |
| | name: π¨ Deploy to Streamlit Cloud |
| | runs-on: ubuntu-latest |
| | needs: [deploy-lambda, deploy-infrastructure] |
| | if: github.ref == 'refs/heads/main' |
| | |
| | steps: |
| | - name: Checkout code |
| | uses: actions/checkout@v4 |
| | |
| | - name: Deploy to Streamlit Cloud |
| | run: | |
| | echo "π¨ Deploying to Streamlit Cloud..." |
| | echo "Manual deployment required - follow instructions in docs/deployment/streamlit-cloud.md" |
| | echo "Repository is ready for Streamlit Cloud deployment" |
| | |
| | - name: Create deployment summary |
| | run: | |
| | echo "π Deployment Summary" > deployment-summary.md |
| | echo "===================" >> deployment-summary.md |
| | echo "" >> deployment-summary.md |
| | echo "β
Lambda function updated" >> deployment-summary.md |
| | echo "β
Infrastructure deployed" >> deployment-summary.md |
| | echo "π Streamlit Cloud deployment: Manual step required" >> deployment-summary.md |
| | echo "" >> deployment-summary.md |
| | echo "Next steps:" >> deployment-summary.md |
| | echo "1. Deploy to Streamlit Cloud using the web interface" >> deployment-summary.md |
| | echo "2. Configure environment variables in Streamlit Cloud" >> deployment-summary.md |
| | echo "3. Test the complete system" >> deployment-summary.md |
| | |
| | - name: Upload deployment summary |
| | uses: actions/upload-artifact@v3 |
| | with: |
| | name: deployment-summary |
| | path: deployment-summary.md |
| |
|
| | |
| | notify: |
| | name: π’ Notifications |
| | runs-on: ubuntu-latest |
| | needs: [deploy-streamlit] |
| | if: always() |
| | |
| | steps: |
| | - name: Download test results |
| | uses: actions/download-artifact@v3 |
| | with: |
| | name: test-results |
| | |
| | - name: Download deployment summary |
| | uses: actions/download-artifact@v3 |
| | with: |
| | name: deployment-summary |
| | |
| | - name: Send notification |
| | run: | |
| | echo "π’ Sending deployment notification..." |
| | if [ "${{ needs.deploy-streamlit.result }}" == "success" ]; then |
| | echo "β
Deployment completed successfully!" |
| | else |
| | echo "β Deployment failed!" |
| | fi |