81.1 Project 77: GitHub Actions CI for a Node.js app
Friends, Actions runs CI next to your code. Today we write a workflow YAML, install Node, run tests on every push and pull request, and read the Actions run log.
मित्रांनो, Actions code जवळ CI चालवते. आज workflow YAML, Node install, प्रत्येक push/PR वर tests, आणि Actions run log.
दोस्तों, Actions code के पास CI चलाता है. आज workflow YAML, Node install, हर push/PR पर tests, और Actions run log.
What you will build in this project
- Create .github/workflows/ci.yml.
- Set up Node with actions/setup-node.
- Run npm test on push and pull_request.
- Read a failed run and fix it.
1. Start from a real company story
At Freshworks in Chennai, Node tests ran only on laptops and a broken PR merged before anyone noticed.
Support tickets spiked. Rough cost: about ₹11 lakh that week.
Divya added an Actions workflow that blocks merge on red tests.
Today we write that workflow.
Ravindra Bagale's Tip
Students use npm install in CI and get floating dependency trees. Prefer npm ci with a committed lockfile. Keep that habit.
Students CI मध्ये npm install वापरतात. Lockfile सह npm ci वापरा. सवय ठेवा.
Students CI में npm install इस्तेमाल करते हैं. Lockfile के साथ npm ci इस्तेमाल करें. आदत रखिए.
2. Start and prepare
Step 1: Why Actions
Why: CI next to the repo. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: echo why. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 1: a1
Type this:
echo 'GitHub Actions = YAML workflows that run on forge events'
You will see:
GitHub Actions = YAML workflows that run on forge events
What it means: Why.
Example 2: a2
Type this:
mkdir -p /tmp/gha77/app/.github/workflows && ls /tmp/gha77/app/.github
You will see:
workflows
What it means: Folder.
Example 3: a3
Type this:
echo 'Today: ci.yml, setup-node, npm ci, npm test'
You will see:
Today: ci.yml, setup-node, npm ci, npm test
What it means: Scope.
Step 2: Sample Node app
Why: Tiny package. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf package.json. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 4: b1
Type this:
printf '%s\n' '{' ' "name": "shop-api",' ' "version": "1.0.0",' ' "scripts": { "test": "node test.js" },' ' "engines": { "node": "20.x" }' '}' > /tmp/gha77/app/package.json && cat /tmp/gha77/app/package.json
You will see:
"name": "shop-api",
What it means: package.
Example 5: b2
Type this:
printf '%s\n' 'const assert = require("assert");' 'assert.strictEqual(2+3, 5);' 'console.log("ok");' > /tmp/gha77/app/test.js && node /tmp/gha77/app/test.js
You will see:
ok
What it means: Local test.
Example 6: b3
Type this:
printf '%s\n' '{}' > /tmp/gha77/app/package-lock.json && echo 'Commit the real lockfile from npm install once locally'
You will see:
Commit the real lockfile from npm install once locally
What it means: Lock tip.
Step 3: Workflow skeleton
Why: name on and jobs. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf ci.yml. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 7: c1
Type this:
printf '%s\n' 'name: ci' 'on:' ' push:' ' branches: [ main ]' ' pull_request:' ' branches: [ main ]' 'jobs:' ' test:' ' runs-on: ubuntu-latest' ' steps:' ' - uses: actions/checkout@v4' > /tmp/gha77/app/.github/workflows/ci.yml && cat /tmp/gha77/app/.github/workflows/ci.yml
You will see:
name: ci
What it means: Skeleton.
Example 8: c2
Type this:
echo 'runs-on ubuntu-latest picks a hosted Linux runner'
You will see:
runs-on ubuntu-latest picks a hosted Linux runner
What it means: Runner.
Example 9: c3
Type this:
echo 'Pin action SHAs in regulated orgs; tags like @v4 are a start'
You will see:
Pin action SHAs in regulated orgs; tags like @v4 are a start
What it means: Pin tip.
3. Build the main pieces
Step 4: setup-node
Why: Pin the runtime. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: add step. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 10: d1
Type this:
printf '%s\n' ' - uses: actions/setup-node@v4' ' with:' ' node-version: \'20\'' ' cache: npm' >> /tmp/gha77/app/.github/workflows/ci.yml && tail -5 /tmp/gha77/app/.github/workflows/ci.yml
You will see:
- uses: actions/setup-node@v4
What it means: setup-node.
Example 11: d2
Type this:
echo 'cache: npm speeds installs using the lockfile hash'
You will see:
cache: npm speeds installs using the lockfile hash
What it means: Cache.
Example 12: d3
Type this:
echo 'Match engines.node in package.json to node-version'
You will see:
Match engines.node in package.json to node-version
What it means: Match.
Step 5: Install and test
Why: npm ci. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: add steps. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 13: e1
Type this:
printf '%s\n' ' - run: npm ci' ' - run: npm test' >> /tmp/gha77/app/.github/workflows/ci.yml && tail -4 /tmp/gha77/app/.github/workflows/ci.yml
You will see:
- run: npm ci
What it means: ci+test.
Example 14: e2
Type this:
echo 'npm ci fails if package-lock.json is missing or out of sync — good'
You will see:
npm ci fails if package-lock.json is missing or out of sync — good
What it means: Strict.
Example 15: e3
Type this:
echo 'Add npm run lint as another step when ready'
You will see:
Add npm run lint as another step when ready
What it means: Lint tip.
Step 6: Push and watch
Why: Actions tab. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: run tip. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 16: f1
Type this:
echo 'git add .github/workflows/ci.yml package.json test.js package-lock.json && git commit -m "ci: add node workflow" && git push'
You will see:
git add .github/workflows/ci.yml package.json test.js package-lock.json && git commit -m "ci: add node workflow" && git push
What it means: Push.
Example 17: f2
Type this:
echo 'Open the repo Actions tab and watch the test job'
You will see:
Open the repo Actions tab and watch the test job
What it means: UI.
Example 18: f3
Type this:
printf '%s\n' 'Acceptance: green check on the commit' > /tmp/gha77/ACCEPT.txt && cat /tmp/gha77/ACCEPT.txt
You will see:
Acceptance: green check on the commit
What it means: Gate.
4. Automate and verify
Step 7: Branch protection
Why: Require the check. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: settings tip. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 19: g1
Type this:
printf '%s\n' 'Repo Settings -> Branches -> Branch protection on main' 'Require status checks: ci / test' 'Do not allow bypass for admins in prod repos' > /tmp/gha77/PROTECT.txt && cat /tmp/gha77/PROTECT.txt
You will see:
Require status checks: ci / test
What it means: Protect.
Example 20: g2
Type this:
echo 'PR cannot merge while the check is red or pending'
You will see:
PR cannot merge while the check is red or pending
What it means: Gate.
Example 21: g3
Type this:
echo 'Name the job carefully — protection matches the check name'
You will see:
Name the job carefully — protection matches the check name
What it means: Name.
Step 8: Fail path
Why: Broken test. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: prove red. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 22: h1
Type this:
echo 'Change assert to 2+3===6, push, watch the job fail'
You will see:
Change assert to 2+3===6, push, watch the job fail
What it means: Break.
Example 23: h2
Type this:
echo 'Open the failed step log and read the assert message'
You will see:
Open the failed step log and read the assert message
What it means: Log.
Example 24: h3
Type this:
echo 'Revert before you leave the lab'
You will see:
Revert before you leave the lab
What it means: Revert.
Step 9: Secrets tip
Why: No tokens in YAML. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: secrets. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 25: i1
Type this:
echo 'Repo Settings -> Secrets and variables -> Actions'
You will see:
Repo Settings -> Secrets and variables -> Actions
What it means: Where.
Example 26: i2
Type this:
echo 'Reference as secrets.NPM_TOKEN in the workflow — never echo it'
You will see:
Reference as secrets.NPM_TOKEN in the workflow — never echo it
What it means: Use.
Example 27: i3
Type this:
echo 'Fork PRs do not get secrets by default — good'
You will see:
Fork PRs do not get secrets by default — good
What it means: Forks.
5. Harden and accept
Step 10: Story Freshworks
Why: Chennai laptop CI. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: story. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 28: j1
Type this:
printf '%s\n' 'At Freshworks in Chennai, Node tests ran only on laptops and a broken PR merged.' 'Divya added an Actions workflow that blocks merge on red tests.' > /tmp/gha77/STORY.txt && wc -l /tmp/gha77/STORY.txt
You will see:
2 /tmp/gha77/STORY.txt
What it means: Story.
Example 29: j2
Type this:
echo 'Rough cost: about ₹11 lakh that week'
You will see:
Rough cost: about ₹11 lakh that week
What it means: Cost.
Example 30: j3
Type this:
echo 'Divya: PASS'
You will see:
Divya: PASS
What it means: Sign-off.
Step 11: Proof
Why: Workflow exists. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: grep. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 31: k1
Type this:
grep -E 'npm ci|setup-node|pull_request' /tmp/gha77/app/.github/workflows/ci.yml
You will see:
pull_request:\n - uses: actions/setup-node@v4\n - run: npm ci
What it means: Lines.
Example 32: k2
Type this:
test -f /tmp/gha77/ACCEPT.txt && echo 'accept ok'
You will see:
accept ok
What it means: accept.
Example 33: k3
Type this:
echo 'Next: matrix builds project 78'
You will see:
Next: matrix builds project 78
What it means: Bridge.
Step 12: Acceptance
Why: Node CI green on push. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: final. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 34: z1
Type this:
echo 'ci.yml on push and pull_request'
You will see:
ci.yml on push and pull_request
What it means: Triggers.
Example 35: z2
Type this:
echo 'npm ci + npm test'
You will see:
npm ci + npm test
What it means: Steps.
Example 36: z3
Type this:
echo 'Red path proven'
You will see:
Red path proven
What it means: Fail.
Check yourself
Q1. Who fixed Freshworks laptop-only tests?
Divya
Q2. Workflow path?
.github/workflows
Q3. Install cmd?
npm ci
Q4. Setup action?
setup-node
Q5. Triggers?
push and pull_request
Q6. Floating deps?
no
Friends, you ran Node CI with GitHub Actions. Did you understand? Let us try it once more. Break a test on purpose, push, and prove the workflow goes red.
मित्रांनो, तुम्ही GitHub Actions ने Node CI चालवली. Test जाणूनबुजून मोडा, push करा, आणि workflow red होते हे सिद्ध करा.
दोस्तों, आपने GitHub Actions से Node CI चलाई. Test जानबूझकर तोड़ें, push करें, और workflow red हो, यह साबित करें.
Lab: try at home
- Write workflow YAML.
- Pin Node version.
- Run npm ci and test.
- Prove red path.
Recap
- Workflow as code.
- npm ci not install.
- Pin Node.
- PR + push triggers.
- Red blocks merge.