Sample output
Made on 27 October 2026
name: CI and Staging Deploy
on: pull_request: push: branches: - dev
Prevent older runs for the same branch or pull request from wasting resources.
concurrency: group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true
Use least-privilege defaults; individual jobs can add permissions if needed.
permissions: contents: read
env: NODE_VERSION: "22" PNPM_VERSION: "10"
jobs: install: name: Install dependencies runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v4
# Pin pnpm so local and CI dependency resolution remain consistent.
- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
- name: Set up Node.js with pnpm cache
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
# The lockfile is the cache key source for the whole workspace.
cache-dependency-path: pnpm-lock.yaml
# Enforce the committed lockfile and fail if it is out of date.
- name: Install dependencies
run: pnpm install --frozen-lockfile
# Reuse the exact installed dependency tree across downstream jobs.
- name: Upload installed dependencies
uses: actions/upload-artifact@v4
with:
name: workspace-node-modules
path: |
node_modules
packages/*/node_modules
apps/*/node_modules
# Dependency artifacts are only needed during this workflow run.
retention-days: 1
# Some workspaces may not contain both packages/ and apps/.
if-no-files-found: warn
# pnpm links compress poorly, so skipping compression speeds transfers.
compression-level: 0
include-hidden-files: true
lint: name: Lint runs-on: ubuntu-latest