Add infinite-scroll pagination to home page and publish new blog posts
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: "CI/CD Patterns with GitHub Actions"
|
||||
date: 2026-05-15T09:00:00+08:00
|
||||
draft: false
|
||||
description: "Build matrices, caching strategies, environment-specific deployments, and reusable workflows. Patterns that scale from solo projects to team repos."
|
||||
tags:
|
||||
- CI/CD
|
||||
- GitHub
|
||||
- DevOps
|
||||
---
|
||||
|
||||
GitHub Actions is now the default CI for most open-source projects. Build matrices save config lines, caching `node_modules` and Go modules saves minutes per run. Reusable workflows keep things DRY across repos.
|
||||
|
||||
## Build Matrices
|
||||
|
||||
Don't copy-paste job definitions for different Node versions or OS targets. Use a matrix:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
node: [18, 20, 22]
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
This single definition expands to 6 parallel jobs. Add `fail-fast: false` if you want all runs to complete even when one fails — helpful for catching platform-specific bugs in one CI run.
|
||||
|
||||
## Smart Caching
|
||||
|
||||
Caching is the easiest way to cut CI minutes:
|
||||
|
||||
```yaml
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: npm-${{ runner.os }}-
|
||||
```
|
||||
|
||||
The `restore-keys` fallback is important: even a partial cache hit saves time. For Go modules, cache `~/go/pkg/mod`. For Docker builds, use BuildKit's registry cache (`--cache-from type=registry`) for layer caching across CI runs.
|
||||
|
||||
## Environment-Specific Deployments
|
||||
|
||||
Use environments to gate production deploys:
|
||||
|
||||
```yaml
|
||||
deploy-prod:
|
||||
needs: [test, build]
|
||||
environment: production
|
||||
steps:
|
||||
- run: ./deploy.sh production
|
||||
```
|
||||
|
||||
The `environment: production` lets you set required reviewers, wait timers, and environment-specific secrets in the GitHub UI. No more accidentally deploying to prod from a feature branch.
|
||||
|
||||
## Reusable Workflows
|
||||
|
||||
When you maintain multiple repos, reusable workflows prevent drift:
|
||||
|
||||
```yaml
|
||||
# .github/workflows/deploy.yml in a shared repo
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
environment:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
AWS_ROLE:
|
||||
required: true
|
||||
```
|
||||
|
||||
Call it from any repo:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
uses: org/shared-workflows/.github/workflows/deploy.yml@main
|
||||
with:
|
||||
environment: staging
|
||||
secrets:
|
||||
AWS_ROLE: ${{ secrets.AWS_ROLE }}
|
||||
```
|
||||
|
||||
Update the shared workflow once, and every repo benefits. This pattern scales well for orgs with 10+ services.
|
||||
|
||||
## Practical Tips
|
||||
|
||||
- Set `timeout-minutes` on every job — the default is 360 minutes, and you don't want a hung test burning your quota.
|
||||
- Use `concurrency` to cancel redundant runs when pushing to the same PR multiple times.
|
||||
- Pin action versions to SHA hashes for supply-chain security, not just tags.
|
||||
Reference in New Issue
Block a user