Part 4: Advanced Workflows and Optimization
Introduction
Reusable Workflows
Creating a Reusable Workflow
name: Reusable Node.js CI
on:
workflow_call:
inputs:
node-version:
description: 'Node.js version to use'
required: false
type: string
default: '18'
service-path:
description: 'Path to the service'
required: true
type: string
run-integration-tests:
description: 'Run integration tests'
required: false
type: boolean
default: true
secrets:
codecov-token:
description: 'Codecov token'
required: false
docker-username:
required: false
docker-password:
required: false
env:
NODE_VERSION: ${{ inputs.node-version }}
SERVICE_PATH: ${{ inputs.service-path }}
jobs:
lint:
name: Lint and Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: '${{ env.SERVICE_PATH }}/package-lock.json'
- name: Install dependencies
working-directory: ${{ env.SERVICE_PATH }}
run: npm ci
- name: Run linter
working-directory: ${{ env.SERVICE_PATH }}
run: npm run lint
- name: Type check
working-directory: ${{ env.SERVICE_PATH }}
run: npm run type-check
test:
name: Test
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: '${{ env.SERVICE_PATH }}/package-lock.json'
- name: Install dependencies
working-directory: ${{ env.SERVICE_PATH }}
run: npm ci
- name: Generate Prisma Client
working-directory: ${{ env.SERVICE_PATH }}
run: npx prisma generate
- name: Run migrations
if: inputs.run-integration-tests
working-directory: ${{ env.SERVICE_PATH }}
run: npx prisma migrate deploy
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
- name: Run tests
working-directory: ${{ env.SERVICE_PATH }}
run: npm test -- --coverage
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
REDIS_URL: redis://localhost:6379
- name: Upload coverage
if: ${{ secrets.codecov-token != '' }}
uses: codecov/codecov-action@v3
with:
files: ./${{ env.SERVICE_PATH }}/coverage/lcov.info
token: ${{ secrets.codecov-token }}
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: '${{ env.SERVICE_PATH }}/package-lock.json'
- name: Install dependencies
working-directory: ${{ env.SERVICE_PATH }}
run: npm ci
- name: Build
working-directory: ${{ env.SERVICE_PATH }}
run: npm run buildUsing the Reusable Workflow
Composite Actions
Creating a Composite Action
Using the Composite Action
Advanced Composite Action with Outputs
Concurrency Control
Artifacts and Caching
Uploading and Downloading Artifacts
Advanced Caching Strategy
Job Outputs
Dynamic Matrix from JSON
Conditional Workflows
Run Different Jobs Based on Conditions
Performance Optimization
Parallel Jobs
Split Tests Across Multiple Runners
Reduce Checkout Time
Self-Hosted Runners
Workflow Visualization
Advanced Debugging
Enable Debug Logging
Add Debug Step
SSH Debugging
Key Takeaways
PreviousPart 3: Building CI/CD Pipelines for TypeScript MicroservicesNextPart 5: Production Deployment and Best Practices
Last updated