Skip to content
CodeSook
CodeSook

14. Caching


Caching

GitHub Actions Caching เป็นฟีเจอร์ที่ช่วยเก็บ dependencies และ build artifacts เพื่อลดเวลาในการ build และประหยัด bandwidth

ใช้งานเมื่อไร?

  • เมื่อต้องการลดเวลา CI/CD
  • เมื่อมี dependencies ที่ไม่เปลี่ยนแปลงบ่อย
  • เมื่อต้องการประหยัดทรัพยากร

ตัวอย่างการใช้งาน

1. React CSR (Vite & Bun)

name: React Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
- name: Install dependencies
run: bun install
- name: Build
run: bun run build

2. ElysiaJS (Backend, Bun)

name: ElysiaJS Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
- name: Install dependencies
run: bun install
- name: Run tests
run: bun test

3. Go (Echo)

name: Go Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: "1.21"
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
- name: Download dependencies
run: go mod download
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...

4. Rust (Ntex)

name: Rust Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build
run: cargo build --release
- name: Test
run: cargo test

Key Points

  • key: ใช้ hash ของ lock files เป็นหลัก
  • restore-keys: fallback เมื่อไม่มี exact match
  • path: ระบุ directory ที่ต้องการ cache
  • ประหยัดเวลาได้เยอะ ในการ install dependencies

มาลองลงมือทำกันเลย

จาก project เดิมของเรา

workflows/deploy.yaml
deploy.yaml
name: Deploy Project
24 collapsed lines
on:
push:
workflow_dispatch:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
outputs:
build-time: ${{ steps.build-info.outputs.timestamp }}
build-hash: ${{ steps.build-info.outputs.hash }}
build-status: ${{ steps.build-info.outputs.status }}
package-version: ${{ steps.version.outputs.version }}
steps:
- name: Get Code
uses: actions/checkout@v4
- name: Get Package Version
id: version
run: |
VERSION=$(cat package.json | jq -r '.version')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Install Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.18
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
- name: Install Dependencies
run: bun i
41 collapsed lines
- name: Build
run: bun run build
- name: Get Build Info
id: build-info
run: |
echo "timestamp=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
echo "hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "status=success" >> $GITHUB_OUTPUT
- name: upload dist folder
uses: actions/upload-artifact@v4
with:
name: dist
path: |
dist
public
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Show Build Info
run: |
echo "🚀 Deploying version: ${{ needs.build.outputs.package-version }}"
echo "📦 Build hash: ${{ needs.build.outputs.build-hash }}"
echo "⏰ Built at: ${{ needs.build.outputs.build-time }}"
echo "✅ Build status: ${{ needs.build.outputs.build-status }}"
- name: download dist folder
uses: actions/download-artifact@v4
with:
name: dist
- name: List all files
run: ls -R
- name: Deploy
run: |
echo "Deploying version ${{ needs.build.outputs.package-version }}..."
echo "Commit: ${{ needs.build.outputs.build-hash }}"

จะทำที่ lint workflow ด้วยก็ได้

workflows/lint.yaml
lint.yaml
name: ESLint
14 collapsed lines
on:
pull_request:
types:
- opened
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Get Code
uses: actions/checkout@v4
- name: Install Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.8
- name: Install Dependencies
run: bun i
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
- name: Run ESLint
run: bun run lint

ลอง push code แล้วมาดูกัน

รอบแรกจะไม่มี cache

แต่พอ workflow ทำงานเสร็จแล้วมันจะส่ง files ไป cache ทีหลัง

ลองกด run workflow แบบ manual ดู

รอบนี้มี cache แล้ว