๐Ÿ“… let's chat! explore the endless possibilities creating industries that don't exist. click here

evernote-deploy-integration

Deploy Evernote integrations to production environments. Use when deploying to cloud platforms, configuring production, or setting up deployment pipelines. Trigger with phrases like "deploy evernote", "evernote production deploy", "release evernote", "evernote cloud deployment". allowed-tools: Read, Write, Edit, Bash(npm:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>

Allowed Tools

No tools specified

Provided by Plugin

evernote-pack

Claude Code skill pack for Evernote (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the evernote-pack plugin:

/plugin install evernote-pack@claude-code-plugins-plus

Click to copy

Instructions

# Evernote Deploy Integration ## Overview Deploy Evernote integrations to production environments including cloud platforms, containerized deployments, and serverless architectures. ## Prerequisites - CI/CD pipeline configured - Production API credentials approved - Cloud platform account (AWS, GCP, Azure) - Docker installed (for containerized deployments) ## Instructions ### Step 1: Docker Deployment ```dockerfile # Dockerfile FROM node:20-alpine AS builder WORKDIR /app # Install dependencies COPY package*.json ./ RUN npm ci --only=production # Copy source COPY . . # Build if needed RUN npm run build --if-present # Production image FROM node:20-alpine AS production WORKDIR /app # Security: non-root user RUN addgroup -g 1001 -S appgroup && \ adduser -u 1001 -S appuser -G appgroup # Copy from builder COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules COPY --from=builder --chown=appuser:appgroup /app/dist ./dist COPY --from=builder --chown=appuser:appgroup /app/package.json ./ USER appuser # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1 EXPOSE 3000 CMD ["node", "dist/index.js"] ``` ```yaml # docker-compose.yml version: '3.8' services: app: build: . ports: - "3000:3000" environment: - NODE_ENV=production - EVERNOTE_CONSUMER_KEY=${EVERNOTE_CONSUMER_KEY} - EVERNOTE_CONSUMER_SECRET=${EVERNOTE_CONSUMER_SECRET} - EVERNOTE_SANDBOX=false - SESSION_SECRET=${SESSION_SECRET} - REDIS_URL=redis://redis:6379 depends_on: - redis restart: unless-stopped redis: image: redis:7-alpine volumes: - redis-data:/data restart: unless-stopped volumes: redis-data: ``` ### Step 2: AWS Deployment (ECS/Fargate) ```yaml # cloudformation/evernote-service.yml AWSTemplateFormatVersion: '2010-09-09' Description: Evernote Integration Service Parameters: Environment: Type: String AllowedValues: [staging, production] EvernoteConsumerKey: Type: String NoEcho: true EvernoteConsumerSecret: Type: String NoEcho: true Resources: # ECS Cluster Cluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Sub evernote-${Environment} # Task Definition TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub evernote-app-${Environment} Cpu: '256' Memory: '512' NetworkMode: awsvpc RequiresCompatibilities: - FARGATE ExecutionRoleArn: !GetAtt ExecutionRole.Arn TaskRoleArn: !GetAtt TaskRole.Arn ContainerDefinitions: - Name: app Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/evernote-app:latest PortMappings: - ContainerPort: 3000 Environment: - Name: NODE_ENV Value: production - Name: EVERNOTE_SANDBOX Value: 'false' Secrets: - Name: EVERNOTE_CONSUMER_KEY ValueFrom: !Ref ConsumerKeySecret - Name: EVERNOTE_CONSUMER_SECRET ValueFrom: !Ref ConsumerSecretSecret LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref LogGroup awslogs-region: !Ref AWS::Region awslogs-stream-prefix: ecs HealthCheck: Command: - CMD-SHELL - wget -q --spider http://localhost:3000/health || exit 1 Interval: 30 Timeout: 5 Retries: 3 StartPeriod: 60 # Secrets Manager ConsumerKeySecret: Type: AWS::SecretsManager::Secret Properties: Name: !Sub /evernote/${Environment}/consumer-key SecretString: !Ref EvernoteConsumerKey ConsumerSecretSecret: Type: AWS::SecretsManager::Secret Properties: Name: !Sub /evernote/${Environment}/consumer-secret SecretString: !Ref EvernoteConsumerSecret # ECS Service Service: Type: AWS::ECS::Service Properties: Cluster: !Ref Cluster ServiceName: !Sub evernote-app-${Environment} TaskDefinition: !Ref TaskDefinition DesiredCount: 2 LaunchType: FARGATE NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED SecurityGroups: - !Ref SecurityGroup Subnets: - !Ref PublicSubnet1 - !Ref PublicSubnet2 LoadBalancers: - ContainerName: app ContainerPort: 3000 TargetGroupArn: !Ref TargetGroup # Application Load Balancer LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: !Sub evernote-alb-${Environment} Scheme: internet-facing Type: application SecurityGroups: - !Ref ALBSecurityGroup Subnets: - !Ref PublicSubnet1 - !Ref PublicSubnet2 # CloudWatch Logs LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /ecs/evernote-app-${Environment} RetentionInDays: 30 ``` ### Step 3: GitHub Actions Deployment ```yaml # .github/workflows/deploy.yml name: Deploy to Production on: push: branches: [main] tags: ['v*'] env: AWS_REGION: us-east-1 ECR_REPOSITORY: evernote-app ECS_SERVICE: evernote-app-production ECS_CLUSTER: evernote-production jobs: deploy: runs-on: ubuntu-latest environment: production steps: - 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: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - name: Build and push Docker image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} IMAGE_TAG: ${{ github.sha }} run: | docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:latest . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest - name: Update ECS service run: | aws ecs update-service \ --cluster $ECS_CLUSTER \ --service $ECS_SERVICE \ --force-new-deployment - name: Wait for deployment run: | aws ecs wait services-stable \ --cluster $ECS_CLUSTER \ --services $ECS_SERVICE - name: Notify deployment if: always() uses: slackapi/slack-github-action@v1 with: payload: | { "text": "Evernote Integration deployed: ${{ job.status }}" } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} ``` ### Step 4: Google Cloud Run Deployment ```yaml # cloudbuild.yaml steps: # Build container - name: 'gcr.io/cloud-builders/docker' args: - 'build' - '-t' - 'gcr.io/$PROJECT_ID/evernote-app:$COMMIT_SHA' - '-t' - 'gcr.io/$PROJECT_ID/evernote-app:latest' - '.' # Push to Container Registry - name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/$PROJECT_ID/evernote-app:$COMMIT_SHA'] # Deploy to Cloud Run - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: gcloud args: - 'run' - 'deploy' - 'evernote-app' - '--image' - 'gcr.io/$PROJECT_ID/evernote-app:$COMMIT_SHA' - '--region' - 'us-central1' - '--platform' - 'managed' - '--allow-unauthenticated' - '--set-secrets' - 'EVERNOTE_CONSUMER_KEY=evernote-consumer-key:latest,EVERNOTE_CONSUMER_SECRET=evernote-consumer-secret:latest' - '--set-env-vars' - 'NODE_ENV=production,EVERNOTE_SANDBOX=false' images: - 'gcr.io/$PROJECT_ID/evernote-app:$COMMIT_SHA' - 'gcr.io/$PROJECT_ID/evernote-app:latest' ``` ### Step 5: Serverless Deployment (AWS Lambda) ```javascript // serverless.yml service: evernote-integration provider: name: aws runtime: nodejs20.x stage: ${opt:stage, 'dev'} region: us-east-1 environment: NODE_ENV: production EVERNOTE_SANDBOX: false iam: role: statements: - Effect: Allow Action: - secretsmanager:GetSecretValue Resource: - !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:evernote/* functions: oauth: handler: src/handlers/oauth.handler events: - http: path: /auth/evernote method: get - http: path: /auth/evernote/callback method: get createNote: handler: src/handlers/notes.create events: - http: path: /notes method: post authorizer: type: COGNITO_USER_POOLS authorizerId: !Ref ApiGatewayAuthorizer searchNotes: handler: src/handlers/notes.search events: - http: path: /notes/search method: get authorizer: type: COGNITO_USER_POOLS authorizerId: !Ref ApiGatewayAuthorizer plugins: - serverless-offline - serverless-prune-plugin custom: prune: automatic: true number: 3 ``` ### Step 6: Kubernetes Deployment ```yaml # k8s/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: evernote-app labels: app: evernote-app spec: replicas: 3 selector: matchLabels: app: evernote-app template: metadata: labels: app: evernote-app spec: containers: - name: app image: your-registry/evernote-app:latest ports: - containerPort: 3000 env: - name: NODE_ENV value: production - name: EVERNOTE_SANDBOX value: 'false' - name: EVERNOTE_CONSUMER_KEY valueFrom: secretKeyRef: name: evernote-secrets key: consumer-key - name: EVERNOTE_CONSUMER_SECRET valueFrom: secretKeyRef: name: evernote-secrets key: consumer-secret resources: requests: memory: '256Mi' cpu: '100m' limits: memory: '512Mi' cpu: '500m' livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: evernote-app spec: selector: app: evernote-app ports: - port: 80 targetPort: 3000 type: LoadBalancer --- apiVersion: v1 kind: Secret metadata: name: evernote-secrets type: Opaque stringData: consumer-key: ${EVERNOTE_CONSUMER_KEY} consumer-secret: ${EVERNOTE_CONSUMER_SECRET} ``` ### Step 7: Deployment Verification ```javascript // scripts/verify-deployment.js const https = require('https'); const checks = [ { name: 'Health Check', url: `${process.env.APP_URL}/health`, expectedStatus: 200 }, { name: 'OAuth Endpoint', url: `${process.env.APP_URL}/auth/evernote`, expectedStatus: 302 // Redirect } ]; async function verifyDeployment() { console.log('Verifying deployment...\n'); for (const check of checks) { try { const response = await fetch(check.url, { redirect: 'manual' }); if (response.status === check.expectedStatus) { console.log(`[PASS] ${check.name}`); } else { console.log(`[FAIL] ${check.name} - Expected ${check.expectedStatus}, got ${response.status}`); process.exit(1); } } catch (error) { console.log(`[FAIL] ${check.name} - ${error.message}`); process.exit(1); } } console.log('\nDeployment verification passed!'); } verifyDeployment(); ``` ## Output - Docker containerization setup - AWS ECS/Fargate deployment - GitHub Actions CI/CD pipeline - Google Cloud Run deployment - Serverless (Lambda) deployment - Kubernetes deployment - Deployment verification scripts ## Deployment Checklist ```markdown ## Pre-Deployment - [ ] All tests passing - [ ] Production API key configured - [ ] Secrets stored securely - [ ] Health check endpoint working - [ ] Logging configured ## Deployment - [ ] Container built and pushed - [ ] Infrastructure provisioned - [ ] Secrets mounted - [ ] Service deployed - [ ] Load balancer configured ## Post-Deployment - [ ] Verify health check - [ ] Test OAuth flow - [ ] Monitor error rates - [ ] Check metrics - [ ] Update documentation ``` ## Resources - [AWS ECS Documentation](https://docs.aws.amazon.com/ecs/) - [Google Cloud Run](https://cloud.google.com/run/docs) - [Kubernetes Documentation](https://kubernetes.io/docs/) - [Serverless Framework](https://www.serverless.com/framework/docs) ## Next Steps For webhook handling, see `evernote-webhooks-events`.

Skill file: plugins/saas-packs/evernote-pack/skills/evernote-deploy-integration/SKILL.md