1. Create Github Actions workflow file

Create .github/workflows/deploy.yml file

In github repository .github/workflows/ directory is for Github Actions.

Save yml file in there, Github Actions will read the file as a workflow. Workflow trigger can be push, pr, issue, manual button and so on.

name: Our Company Lunch Build & Deploy

on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths-ignore:
      - 'README.md'
      - '.github/**'
      - 'doc/**'

env:
  CODE_DEPLOY_APPLICATION_NAME: our-company-lunch
  CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: our-company-lunch-deployment-group
  APPLICATION_YML: ./src/main/resources/application.yml
  SPRING_PROFILE: ec2
  FIREBASE_JSON: our-company-lunch-firebase-adminsdk.json

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Java JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'corretto'
          java-version: '21'
          architecture: x64
          cache: 'gradle'

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-2
          role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }}
          role-duration-seconds: 1800

      - name: Download configuration files from S3
        run: |
          aws s3 cp --region ap-northeast-2 s3://${{ vars.S3_BUCKET_NAME }}/application-${{ env.SPRING_PROFILE }}.yml ./src/main/resources/
          mkdir -p ./config
          aws s3 cp --region ap-northeast-2 s3://${{ vars.S3_BUCKET_NAME }}/${{ env.FIREBASE_JSON }} ./config/
      
      - name: Change spring profile to ${{ env.SPRING_PROFILE }}
        uses: microsoft/variable-substitution@v1
        with:
          files: ${{ env.APPLICATION_YML }}
        env:
          spring.profiles.active: ${{ env.SPRING_PROFILE }}

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4
        with:
          cache-disabled: true # Use setup-java caching

      - name: Build with Gradle
        run: ./gradlew build

      - name: Archive to a zip file
        run: |
          mv build/libs/*.jar .
          zip -r ./$GITHUB_SHA ./*.jar scripts/ config/ appspec.yml
        shell: bash

      - name: Upload to S3
        run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://${{ vars.S3_BUCKET_NAME }}/$GITHUB_SHA.zip

      - name: Run CodeDeploy
        run: |
          aws deploy create-deployment \
          --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
          --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
          --s3-location bucket=${{ vars.S3_BUCKET_NAME }},bundleType=zip,key=$GITHUB_SHA.zip
circle-info

Filename doesn't matter, but directory matters.

I can have several files for several workflows.

After push to main, I can see workflows in Github website Actions tab.

Workflow overview

This workflow is used at my toy project. https://github.com/marcel1315/our-company-lunch/arrow-up-right

I think this final workflow file explains most part of CI/CD flow.

  1. Triggered by manual button or push.

  2. In github provided builder(ubuntu-latest), setup java, gradle and aws credentials.

  3. Download config file for distribution from S3.

  4. Build jar in ubuntu machine.

  5. Archive a build file and config and script files into an artifact.

  6. Upload the artifact to S3.

  7. When CodeDeploy executed, it will find the right EC2 with a tag.

  8. By appspec.yml, download the artifact, unzip, and run script inside the EC2.

  9. The startup script will launch jar file.

Workflow triggers

These are triggers. "workflow_dispatch" is a keyword for showing manual button in Github Actions.

Push means triggered by push, too.

Last updated