Skip to content

Instantly share code, notes, and snippets.

@AugustoCalaca
Last active October 16, 2023 19:18
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save AugustoCalaca/263c62f6b9f0b89ed25b446991dae3e3 to your computer and use it in GitHub Desktop.
Save AugustoCalaca/263c62f6b9f0b89ed25b446991dae3e3 to your computer and use it in GitHub Desktop.
example of workflow ci/cd for monorepo with github actions
name: CI/CD Monorepo
env:
AWS_REGION: us-east-1 # N. Virginia
on:
push:
branches:
- main
paths-ignore:
- '**.md'
jobs:
yarn:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- uses: actions/cache@v2
name: yarn-cache
id: yarn-cache
with:
path: |
**/node_modules
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn
- name: Yarn
if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --prefer-offline --non-interactive --ignore-scripts
gatekeeper-server:
runs-on: ubuntu-latest
outputs:
has-changed: ${{ steps.gatekeeper-cerberus.outputs.changed }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: marceloprado/has-changed-path@v1
id: gatekeeper-cerberus
with:
paths: packages/server packages/utils packages/connectors packages/entities packages/events
build-server:
needs: [yarn, gatekeeper-server]
if: needs.gatekeeper-cerberus.outputs.has-changed == 'true'
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- uses: actions/cache@v2
name: yarn-cache
id: yarn-cache
with:
path: |
**/node_modules
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn
- name: Build Server
run: yarn workspace @monorepo/server build
- name: Build Utils
run: yarn workspace @monorepo/utils build
- name: Build Connectors
run: yarn workspace @monorepo/connectors build
- name: Build Entities
run: yarn workspace @monorepo/entities build
- name: Build Events
run: yarn workspace @monorepo/events build
- name: Copy Dockerrun.aws.json
run: |
cp config/Dockerrun.aws.json Dockerrun.aws.json
- name: Generate Deployment Package
run: zip -r docker-multicontainer-v2.zip . --exclude '*.git*' '*node_modules*' '*.md' '*-web*' '*shared*' '*generators*'
- name: Upload Deploy Zip Artifact
uses: actions/upload-artifact@v2
with:
name: docker-multicontainer-v2.zip
path: docker-multicontainer-v2.zip
deploy-server:
needs: [build-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download Deploy Zip Artifact
uses: actions/download-artifact@v2
with:
name: docker-multicontainer-v2.zip
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
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: Get Current Date
id: get_date
run: echo "::set-output name=date::$(date +'%Y-%m-%d %H:%M:%S')"
- name: Deploy Server to ELB
uses: einaregilsson/beanstalk-deploy@v16
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: Awesome
environment_name: Awesome-Staging
region: ${{ env.AWS_REGION }}
version_label: aewsome-staging-${{ steps.get_date.outputs.date }}-${{ github.run_id }}-${{ github.run_number }}
version_description: awesome-server-build-${{ github.SHA }}
deployment_package: docker-multicontainer-v2.zip
- name: Deployed!
run: echo Server Deployed to ELB
gatekeeper-web-1:
runs-on: ubuntu-latest
outputs:
has-changed: ${{ steps.gatekeeper-web-1.outputs.changed }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: marceloprado/has-changed-path@v1
id: gatekeeper-deatheaters
with:
paths: packages/web-1 packages/shared packages/utils
deploy-web-1:
needs: [yarn, build-server, deploy-server, gatekeeper-web-1]
if: |
always() &&
needs.gatekeeper-web-1.outputs.has-changed == 'true' &&
(needs.build-server.result == 'success' || needs.build-server.result == 'skipped') &&
(needs.deploy-server.result == 'success' || needs.deploy-server.result == 'skipped')
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- uses: actions/cache@v2
name: yarn-cache
id: yarn-cache
with:
path: |
**/node_modules
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Build Utils
run: yarn workspace @monorepo/utils build
- name: Build Web 1
run: yarn workspace @monorepo/web-1 build
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
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 to S3 Bucket
run: |
cd packages/web-1/build
aws s3 cp . s3://awesome-bucket --recursive --exclude '*.txt'
- name: Invalidate Cache CloudFront
run: |
aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_WEB_1_ID }} --paths '/index.html'
gatekeeper-web-2:
runs-on: ubuntu-latest
outputs:
has-changed: ${{ steps.gatekeeper-web-2.outputs.changed }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: marceloprado/has-changed-path@v1
id: gatekeeper-diagonalley
with:
paths: packages/web-2 packages/shared packages/utils
deploy-web-2:
runs-on: ubuntu-latest
needs: [yarn, build-server, deploy-server, gatekeeper-web-2]
if: |
always() &&
needs.gatekeeper-web-2.outputs.has-changed == 'true' &&
(needs.build-server.result == 'success' || needs.build-server.result == 'skipped') &&
(needs.deploy-server.result == 'success' || needs.deploy-server.result == 'skipped')
strategy:
matrix:
node-version: [12]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- uses: actions/cache@v2
name: yarn-cache
id: yarn-cache
with:
path: |
**/node_modules
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Build Utils
run: yarn workspace @monorepo/utils build
- name: Build Web 2
run: yarn workspace @monorepo/web-2 build
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
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 to S3 Bucket
run: |
cd packages/web-2/build
aws s3 cp . s3://awesome-bucket-url --recursive --exclude '*.txt'
- name: Invalidate Cache CloudFront
run: |
aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_WEB_2_ID }} --paths '/index.html'
@AugustoCalaca
Copy link
Author

AugustoCalaca commented Jun 21, 2021

  • cache dependencies
  • deploy only if has changed
  • deploy server to elastic beanstalk with docker multicontainer
  • deploy web to s3
  • invalidate web cache on cloudfront

@MemphisMeng
Copy link

It doesn't seem to be necessary to use matrix strategy if your matrix/array has one value given.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment