Merge pull request #13 from umar11b/feature/frontend #59
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: Deploy BlockchainCore | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| AWS_REGION: us-east-1 | |
| PYTHON_VERSION: "3.9" | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - 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 | |
| - name: Run linting | |
| run: | | |
| chmod +x scripts/lint.sh | |
| ./scripts/lint.sh --check-only | |
| - name: Run type checking | |
| run: | | |
| mypy src/ | |
| - name: Run tests | |
| run: | | |
| pytest tests/ -v --cov=src --cov-report=xml | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| build-lambda: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - 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: Clear previous artifacts | |
| run: | | |
| echo "π§Ή Clearing any previous build artifacts..." | |
| rm -rf src/lambda/processor/build src/lambda/processor/processor.zip | |
| rm -rf src/lambda/anomaly/build src/lambda/anomaly/anomaly.zip | |
| rm -rf .github/workflows/artifacts | |
| # Force clear any cached packages | |
| find . -name "*.zip" -delete | |
| find . -name "build" -type d -exec rm -rf {} + 2>/dev/null || true | |
| - name: Build processor Lambda package | |
| run: | | |
| # Clean up any existing build artifacts | |
| rm -rf src/lambda/processor/build src/lambda/processor/processor.zip | |
| mkdir -p src/lambda/processor/build | |
| cp src/lambda/processor/processor.py src/lambda/processor/build/ | |
| cd src/lambda/processor/build | |
| zip -r ../processor.zip . | |
| cd ../../../.. | |
| echo "π¦ Built processor package: $(ls -lh src/lambda/processor/processor.zip)" | |
| echo "π Package contents:" | |
| unzip -l src/lambda/processor/processor.zip | |
| - name: Build anomaly detector Lambda package | |
| run: | | |
| # Clean up any existing build artifacts | |
| rm -rf src/lambda/anomaly/build src/lambda/anomaly/anomaly.zip | |
| mkdir -p src/lambda/anomaly/build | |
| cp src/lambda/anomaly/detector.py src/lambda/anomaly/build/ | |
| cd src/lambda/anomaly/build | |
| zip -r ../anomaly.zip . | |
| cd ../../../.. | |
| echo "π¦ Built anomaly package: $(ls -lh src/lambda/anomaly/anomaly.zip)" | |
| echo "π Package contents:" | |
| unzip -l src/lambda/anomaly/anomaly.zip | |
| - name: Verify package sizes and locations | |
| run: | | |
| echo "π¦ Verifying Lambda package sizes and locations..." | |
| echo "Processor package:" | |
| ls -lh src/lambda/processor/processor.zip | |
| echo "Anomaly package:" | |
| ls -lh src/lambda/anomaly/anomaly.zip | |
| echo "β Package verification complete" | |
| # Verify Terraform can find the packages | |
| echo "π Checking Terraform paths..." | |
| ls -la terraform/ | |
| echo "β Terraform directory structure verified" | |
| - name: Upload Lambda artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lambda-packages | |
| path: | | |
| src/lambda/processor/processor.zip | |
| src/lambda/anomaly/anomaly.zip | |
| deploy-infrastructure: | |
| needs: build-lambda | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - name: Download Lambda artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lambda-packages | |
| path: src/lambda/ | |
| - 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 }} | |
| role-duration-seconds: 1200 | |
| - name: Debug AWS credentials | |
| run: | | |
| echo "Checking AWS credentials..." | |
| aws sts get-caller-identity || echo "AWS credentials not configured" | |
| echo "AWS region: $AWS_DEFAULT_REGION" | |
| - name: Clean up orphaned resources | |
| run: | | |
| echo "π§Ή Cleaning up any orphaned resources..." | |
| # Clean up Lambda functions FIRST (most important) | |
| echo "π Checking for existing Lambda functions..." | |
| LAMBDA_FUNCTIONS=$(aws lambda list-functions --query 'Functions[?contains(FunctionName, `blockchain-core`)].FunctionName' --output text) | |
| if [ -n "$LAMBDA_FUNCTIONS" ]; then | |
| echo "Found Lambda functions: $LAMBDA_FUNCTIONS" | |
| for function in $LAMBDA_FUNCTIONS; do | |
| echo "Deleting Lambda function: $function" | |
| aws lambda delete-function --function-name "$function" | |
| echo "β Deleted Lambda function: $function" | |
| done | |
| else | |
| echo "No Lambda functions found to clean up" | |
| fi | |
| # Clean up DynamoDB tables | |
| echo "π Checking for existing DynamoDB tables..." | |
| DYNAMODB_TABLES=$(aws dynamodb list-tables --query 'TableNames[?contains(@, `blockchain-core`)]' --output text) | |
| if [ -n "$DYNAMODB_TABLES" ]; then | |
| echo "Found DynamoDB tables: $DYNAMODB_TABLES" | |
| for table in $DYNAMODB_TABLES; do | |
| echo "Deleting DynamoDB table: $table" | |
| aws dynamodb delete-table --table-name "$table" | |
| echo "β Deleted DynamoDB table: $table" | |
| done | |
| else | |
| echo "No DynamoDB tables found to clean up" | |
| fi | |
| # Clean up IAM roles | |
| echo "π Checking for existing IAM roles..." | |
| IAM_ROLES=$(aws iam list-roles --query 'Roles[?contains(RoleName, `blockchain-core`)].RoleName' --output text) | |
| if [ -n "$IAM_ROLES" ]; then | |
| echo "Found IAM roles: $IAM_ROLES" | |
| for role in $IAM_ROLES; do | |
| echo "Cleaning up IAM role: $role" | |
| # Detach attached policies | |
| ATTACHED_POLICIES=$(aws iam list-attached-role-policies --role-name "$role" --query 'AttachedPolicies[].PolicyArn' --output text) | |
| for policy in $ATTACHED_POLICIES; do | |
| echo "Detaching policy: $policy from role: $role" | |
| aws iam detach-role-policy --role-name "$role" --policy-arn "$policy" | |
| done | |
| # Delete inline policies | |
| INLINE_POLICIES=$(aws iam list-role-policies --role-name "$role" --query 'PolicyNames[]' --output text) | |
| for policy in $INLINE_POLICIES; do | |
| echo "Deleting inline policy: $policy from role: $role" | |
| aws iam delete-role-policy --role-name "$role" --policy-name "$policy" | |
| done | |
| # Delete the role | |
| aws iam delete-role --role-name "$role" | |
| echo "β Deleted IAM role: $role" | |
| done | |
| else | |
| echo "No IAM roles found to clean up" | |
| fi | |
| # Clean up Lambda Event Source Mappings | |
| echo "π Checking for existing Lambda Event Source Mappings..." | |
| EVENT_MAPPINGS=$(aws lambda list-event-source-mappings --query 'EventSourceMappings[?contains(FunctionArn, `blockchain-core`)].UUID' --output text 2>/dev/null || echo "") | |
| if [ -n "$EVENT_MAPPINGS" ] && [ "$EVENT_MAPPINGS" != "null" ]; then | |
| echo "Found Event Source Mappings: $EVENT_MAPPINGS" | |
| for mapping in $EVENT_MAPPINGS; do | |
| echo "Deleting Event Source Mapping: $mapping" | |
| aws lambda delete-event-source-mapping --uuid "$mapping" | |
| echo "β Deleted Event Source Mapping: $mapping" | |
| done | |
| else | |
| echo "No Event Source Mappings found to clean up" | |
| fi | |
| # Clean up CloudWatch Log Groups | |
| echo "π Checking for existing CloudWatch Log Groups..." | |
| LOG_GROUPS=$(aws logs describe-log-groups --query 'logGroups[?contains(logGroupName, `blockchain-core`)].logGroupName' --output text 2>/dev/null || echo "") | |
| if [ -n "$LOG_GROUPS" ] && [ "$LOG_GROUPS" != "null" ]; then | |
| echo "Found Log Groups: $LOG_GROUPS" | |
| for log_group in $LOG_GROUPS; do | |
| echo "Deleting Log Group: $log_group" | |
| aws logs delete-log-group --log-group-name "$log_group" | |
| echo "β Deleted Log Group: $log_group" | |
| done | |
| else | |
| echo "No Log Groups found to clean up" | |
| fi | |
| echo "β Orphaned resources cleanup completed" | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: "1.0" | |
| - name: Verify Lambda packages for Terraform | |
| run: | | |
| echo "π Verifying Lambda packages are accessible to Terraform..." | |
| echo "Current directory: $(pwd)" | |
| echo "Terraform expects: ../src/lambda/processor/processor.zip" | |
| ls -lh src/lambda/processor/processor.zip | |
| echo "Terraform expects: ../src/lambda/anomaly/anomaly.zip" | |
| ls -lh src/lambda/anomaly/anomaly.zip | |
| echo "β Lambda packages verified for Terraform" | |
| - name: Terraform Init | |
| run: | | |
| cd terraform | |
| terraform init | |
| - name: Terraform Plan | |
| run: | | |
| cd terraform | |
| terraform plan -out=tfplan | |
| env: | |
| TF_VAR_environment: ${{ github.ref == 'refs/heads/main' && 'prod' || 'dev' }} | |
| - name: Terraform Apply | |
| run: | | |
| cd terraform | |
| terraform apply -auto-approve tfplan | |
| env: | |
| TF_VAR_environment: ${{ github.ref == 'refs/heads/main' && 'prod' || 'dev' }} | |
| deploy-lambda: | |
| needs: deploy-infrastructure | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - name: Download Lambda artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lambda-packages | |
| path: src/lambda/ | |
| - 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 }} | |
| role-duration-seconds: 1200 | |
| - name: Update Lambda functions | |
| run: | | |
| aws lambda update-function-code \ | |
| --function-name blockchain-core-processor \ | |
| --zip-file fileb://src/lambda/processor/processor.zip | |
| aws lambda update-function-code \ | |
| --function-name blockchain-core-anomaly-detector \ | |
| --zip-file fileb://src/lambda/anomaly/anomaly.zip | |
| # notify: | |
| # needs: [deploy-infrastructure, deploy-lambda] | |
| # runs-on: ubuntu-latest | |
| # if: always() && github.ref == 'refs/heads/main' | |
| # steps: | |
| # - name: Notify deployment status | |
| # uses: 8398a7/action-slack@v3 | |
| # with: | |
| # status: ${{ job.status }} | |
| # channel: "#deployments" | |
| # env: | |
| # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| # if: always() |