Skip to content

Instantly share code, notes, and snippets.

@tuanchauict
Created August 28, 2023 02:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuanchauict/4c416c2b2cb957b27670e8d3faea7812 to your computer and use it in GitHub Desktop.
Save tuanchauict/4c416c2b2cb957b27670e8d3faea7812 to your computer and use it in GitHub Desktop.
Created with MonoSketch
░██████╗░██╗████████╗██╗░░██╗██╗░░░██╗██████╗░    ░█████╗░░█████╗░████████╗██╗░█████╗░███╗░░██╗░██████╗
██╔════╝░██║╚══██╔══╝██║░░██║██║░░░██║██╔══██╗    ██╔══██╗██╔══██╗╚══██╔══╝██║██╔══██╗████╗░██║██╔════╝
██║░░██╗░██║░░░██║░░░███████║██║░░░██║██████╦╝    ███████║██║░░╚═╝░░░██║░░░██║██║░░██║██╔██╗██║╚█████╗░
██║░░╚██╗██║░░░██║░░░██╔══██║██║░░░██║██╔══██╗    ██╔══██║██║░░██╗░░░██║░░░██║██║░░██║██║╚████║░╚═══██╗
╚██████╔╝██║░░░██║░░░██║░░██║╚██████╔╝██████╦╝    ██║░░██║╚█████╔╝░░░██║░░░██║╚█████╔╝██║░╚███║██████╔╝
░╚═════╝░╚═╝░░░╚═╝░░░╚═╝░░╚═╝░╚═════╝░╚═════╝░    ╚═╝░░╚═╝░╚════╝░░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝╚═════╝░
█ █▄░█ ▀█▀ █▀█ █▀█ █▀▄ █░█ █▀▀ ▀█▀ █ █▀█ █▄░█
█ █░▀█ ░█░ █▀▄ █▄█ █▄▀ █▄█ █▄▄ ░█░ █ █▄█ █░▀█
GitHub Actions is an automation feature provided by GitHub that allows
developers to build, test, and deploy their software directly from their
repositories. It enables the creation of custom workflows that can be
triggered by various events, streamlining and enhancing the software
development process.
█▄▀ █▀▀ █▄█   █▀▀ █░░ █▀▀ █▀▄▀█ █▀▀ █▄░█ ▀█▀ █▀
█░█ ██▄ ░█░   ██▄ █▄▄ ██▄ █░▀░█ ██▄ █░▀█ ░█░ ▄█
3 main key components of GitHub Actions are: Workflow, Job,
Step, and all of them are attached to a repository
╔═════════════════════════════════════════════════════════════════════════════╗
║ Code repository ║ A repository may have 1 or more
║ ║ workflows.
║ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ ║
║ │ Workflow 1 │ │ Workflow 2 │ │ Workflow 3 │ ║ The same, a workflow may have 1 or more
║ │ │ │ │ │ │ ║ jobs. A job may have 1 or more steps.
║ │ ┏━━━━━━━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━━━━━━┓ │ ║
║ │ ┃ Job 1 ┃ │ │ ┃ Job 1 ┃ │ │ ┃ Job 1 ┃ │ ║
║ │ ┃╭──────────────╮┃ │ │ ┃╭──────────────╮┃ │ │ ┃╭──────────────╮┃ │ ║ Unlike steps which are run in sequence,
║ │ ┃│ Step 1 │┃ │ │ ┃│ Step 1 │┃ │ │ ┃│ Step 1 │┃ │ ║ by default, jobs and workflows are
║ │ ┃╰──────────────╯┃ │ │ ┃╰──────────────╯┃ │ │ ┃╰──────────────╯┃ │ ║ independent
║ │ ┃╭──────────────╮┃ │ │ ┃╭──────────────╮┃ │ │ ┗━━━━━━━━━━━━━━━━┛ │ ║
║ │ ┃│ Step 2 │┃ │ │ ┃│ Step 2 │┃ │ │ ┏━━━━━━━━━━━━━━━━┓ │ ║
║ │ ┃╰──────────────╯┃ │ │ ┃╰──────────────╯┃ │ │ ┃ Job 2 ┃ │ ║
║ │ ┗━━━━━━━━━━━━━━━━┛ │ │ ┃╭──────────────╮┃ │ │ ┃╭──────────────╮┃ │ ║
║ │ ┏━━━━━━━━━━━━━━━━┓ │ │ ┃│ Step 3 │┃ │ │ ┃│ Step 1 │┃ │ ║
║ │ ┃ Job 2 ┃ │ │ ┃╰──────────────╯┃ │ │ ┃╰──────────────╯┃ │ ║
║ │ ┃╭──────────────╮┃ │ │ ┃╭──────────────╮┃ │ │ ┗━━━━━━━━━━━━━━━━┛ │ ║
║ │ ┃│ Step 1 │┃ │ │ ┃│ Step 4 │┃ │ │ │ ║
║ │ ┃╰──────────────╯┃ │ │ ┃╰──────────────╯┃ │ │ │ ║
║ │ ┃╭──────────────╮┃ │ │ ┗━━━━━━━━━━━━━━━━┛ │ │ │ ║
║ │ ┃│ Step 2 │┃ │ │ │ │ │ ║
║ │ ┃╰──────────────╯┃ │ │ │ │ │ ║
║ │ ┗━━━━━━━━━━━━━━━━┛ │ │ │ │ │ ║
║ └────────────────────┘ └────────────────────┘ └────────────────────┘ ║
╚═════════════════════════════════════════════════════════════════════════════╝
╭ ─ ─ ─ ─ ─ ╮ ╭ ─ ─ ─ ─ ─ ╮ ╭ ─ ─ ─ ─ ─ ╮
Event Event Event
╰ ─ ─ ┬ ─ ─ ╯ ╰ ─ ─ ┬ ─ ─ ╯ ╰ ─ ─ ┬ ─ ─ ╯ A workflow is triggered by 1 or multiple events,
│ │ │ automatically or manually or scheduled
└──┐ ┌───┘ ┌───────────┘
│ │ │ See:
┌────────┴───────┴──────┴─────────────────┐ https://docs.github.com/en/actions/using-workflo
│ │ ws/events-that-trigger-workflows
│ Workflow │
│ │
└─────────────────────────────────────────┘
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ A job needs an environment to execute, just like
Execute ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓ a container of Docker.
│Environment ┃ Job ┃ │
┃ ┃ (Note: We can run docker on Github Actions)
│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛ │
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
Execute  ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓ By default, jobs are independent, may have
│Environment ┃ Job ┃ │ different environments, and run in parallel.
┃ ┃
│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ To make a job able to run after another and see
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ the output of the others, we need to explicitly
define the dependency
╭────────────────────────────────────────╮
│ Step │ A step consists of 1 or more commands and is executed in sequence
│ - command 1 │ from top to bottom.
│ - command 2 │
│ - command 3 │ If a step is failed, the consequence steps will be skipped unless
│ - ... │ it is explicitly defined to be run when error (`if: failure()`),
│ │ for example, unit test error report; or always be executed even if
│ │ error or not (`if: always()`), for example, clean up resources
│ │
│ │
│ │
│ │
╰────────────────────────────────────────╯
█▀ ▀█▀ █▀█ █░█ █▀▀ ▀█▀ █░█ █▀█ █▀▀   █▀█ █▀▀   ▄▀█   █░█░█ █▀█ █▀█ █▄▀ █▀▀ █░░ █▀█ █░█░█
▄█ ░█░ █▀▄ █▄█ █▄▄ ░█░ █▄█ █▀▄ ██▄   █▄█ █▀░   █▀█   ▀▄▀▄▀ █▄█ █▀▄ █░█ █▀░ █▄▄ █▄█ ▀▄▀▄▀
A workflow is a yml file under `.github/workflows` directory
┌──────────────────────────────────────────────────────────────────┐ In this example:
│name: My First Workflow │
│ │ - The workflow is named "My First Workflow".
│# This workflow is triggered on pushes to the repository. │
│on: [push] │ - The on: [push] line means the workflow is triggered
│ │ whenever a push is made to the repository.
│jobs: │
│  build: │ - The jobs: section defines a single job called
│    runs-on: ubuntu-latest │ "build".
│ │
│    steps: │ - The runs-on: ubuntu-latest line specifies that the
│    - name: Check out repository │ job runs on an Ubuntu runner.
│      uses: actions/checkout@v3 │
│ │ - The steps: section defines two steps that are run in
│    - name: Run a one-line script │ sequence:
│      run: echo Hello, world! │
│ │ - The first step uses the actions/checkout@v3 action
│    - name: Run multiple lines script │ to check out the repository.
│      run: | │
│        echo Good afternoon │ - The second step runs a one-line script that prints
│        echo こ ん に ち は │ "Hello, world!" to the console.
│        echo Chào buổi chiều │
│        echo bon après-midi │ - The 3rd step runs a multiple-line script. For
│        echo Guten Tag │ multiple lines, we need `|` character
└──────────────────────────────────────────────────────────────────┘
Let's see a more complicated workflow.
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ This is the actual workflow of MonoSketch: │
│ name: Code health check https://github.com/tuanchauict/MonoSketch/blob/main │
│ on: /.github/workflows/code-health-check.yml │
│   pull_request: ┃ Events: │
│   push: ┃ - pull request │
│     branches: ┃ - push on main branch │
│       - main ┃ │
│ jobs: │
│   unit_test: │
│     runs-on: ubuntu-latest │
│     steps: │
│       - uses: actions/checkout@v3 │
│       - uses: actions/setup-java@v3 ┃ │
│         with: ┃ Setup Java environment │
│           distribution: 'zulu' ┃ │
│           java-version: 17 ┃ │
│       - name: Cache local maven repository ┃ │
│         uses: actions/cache@v3 ┃ │
│         with: ┃ │
│           path: | ┃ │
│             ~/.gradle/caches ┃ Caching │
│             ~/.gradle/wrapper ┃ │
│           key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }} ┃ │
│           restore-keys: | ┃ │
│             ${{ runner.os }}-gradle- ┃ │
│ │
│       - run: ./gradlew test --continue │
│ │
│       - name: Clean up test result ┃ Prepare test report │
│         if: failure() ┃ Only run if the test fails │
│         run: sh tools/devops/remove_success_test_report ┃ │
│ │
│       - name: Publish test result ┃ │
│         uses: actions/upload-artifact@v3 ┃ Publish the test result │
│         if: failure() ┃ Only run if the test fails │
│         with: ┃ │
│           name: test-result ┃ │
│           path: | ┃ │
│             build/reports/tests/ ┃ │
│             app/build/reports/tests/ ┃ │
│             libs/**/reports/tests/ ┃ │
│ │
│   ktlint: │
│     runs-on: ubuntu-latest │
│     steps: │
│       - uses: actions/checkout@v3 │
│       - uses: actions/setup-java@v3 │
│         with: │
│           distribution: 'zulu' │
│           java-version: 17 │
│       - name: Cache local maven repository ┃ │
│         uses: actions/cache@v3 ┃ │
│         with: ┃ Caching again │
│           path: | ┃ (I really want to │
│             ~/.gradle/caches ┃ make this shorter, │
│             ~/.gradle/wrapper ┃ but...) │
│           key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }} ┃ │
│           restore-keys: | ┃ │
│             ${{ runner.os }}-gradle- ┃ │
│ │
│       - run: ./gradlew ktlint │
│ │
│   assemble: │
│     runs-on: ubuntu-latest │
│     steps: │
│       - uses: actions/checkout@v3 │
│       - uses: actions/setup-java@v3 │
│         with: │
│           distribution: 'zulu' │
│           java-version: 17 │
│       - name: Cache local maven repository │
│         uses: actions/cache@v3 │
│         with: │
│           path: | │
│             ~/.gradle/caches │
│             ~/.gradle/wrapper │
│           key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }} │
│           restore-keys: | │
│             ${{ runner.os }}-gradle- │
│              │
│       - run: ./gradlew assemble │
│ │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Reference: 
- Cache: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows
- Store artifact: https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts
█▀ ▄▀█ █▀▄▀█ █▀█ █░░ █▀▀
▄█ █▀█ █░▀░█ █▀▀ █▄▄ ██▄
Requirement
╭─────────────╮if fails ╭─────────────╮
│ ◆──────────────▶ Report ○─────┐
○─────┤ Test │ ╰─────────────╯ ┴
│ ○──────╮
╰─────────────╯ │
╭─────────────╮ │ ╭─────────────╮
○─────┤ │ ╭──┴───────▶ Deploy ○─────┐
│ Build ○───╯ ╰─────────────╯ ┴
│ │
╰─────────────╯
┌────────────────────────────────────────────────────────────────┐
│ │
│ name: Build, Test, Deploy, and Report │
│ │
│ on: [push] │
│ │
│ jobs: │
│   build: │
│     runs-on: ubuntu-latest │
│ │
│     steps: │
│     - name: Check out repository │
│       uses: actions/checkout@v3 │
│ │
│     - name: Build │
│       run: echo Running build script... │
│ │
│     - name: Upload build artifact │
│       uses: actions/upload-artifact@v2 │
│       with: │
│         name: my-artifact │
│         path: ./path/to/artifact │
│ │
│   test: │
│     runs-on: ubuntu-latest │
│ │
│     steps: │
│     - name: Check out repository │
│       uses: actions/checkout@v3 │
│ │
│     - name: Test │
│       run: echo Running test script... │
│ │
│   deploy: │
│     needs: [build, test] │
│     runs-on: ubuntu-latest │
│ │
│     steps: │
│     - name: Check out repository │
│       uses: actions/checkout@v3 │
│ │
│     - name: Download build artifact │
│       uses: actions/download-artifact@v3 │
│       with: │
│         name: my-artifact │
│         path: ./path/to/artifact │
│ │
│     - name: Deploy │
│       run: echo Running deploy script... │
│ │
│   report: │
│     needs: [test] │
│     runs-on: ubuntu-latest │
│     if: failure() │
│      │
│     steps: │
│     - name: Check out repository │
│       uses: actions/checkout@v3 │
│ │
│     - name: Report │
│       run: echo Running report script... │
│ │
│ │
└────────────────────────────────────────────────────────────────┘
█▀▄ █▀▀ █▀▄▀█ █▀█
█▄▀ ██▄ █░▀░█ █▄█
https://github.com/monosketchapp/sample-actions
┌──────────────────────────────────────┐
│ │
│ Simple Kotlin JS app │
│ │
└──────────────────┬───────────────────┘
┌──────────────────▼───────────────────┐
│ │
│ Add job to run unit test │
│ │┌────────────────────┐
└──────────────────┬───────────────────┘│ Try error test │
│ └────────────────────┘
┌──────────────────▼───────────────────┐
│ │
│ Add job to run build │
│ │
└──────────────────┬───────────────────┘
┌─────────────────▼────────────────────┐
│ │
│ Store artifact │
│ │
└─────────────────┬────────────────────┘
┌─────────────────▼────────────────────┐
│ │
│ Apply cache │
│ │
└──────────────────┬───────────────────┘
┌──────────────────▼───────────────────┐
│ │
│ Generate test fail report │
│ │
└──────────────────────────────────────┘
Small pick
How to run GitHub Actions locally:
- https://github.com/nektos/act
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment