Automation Isn't About Tools, It's About Mindset: Why You're Still Doing the Same Thing Repeatedly
6 months of manual project setup 45 minutes every Monday. Friend wrote 1 20-line script, became 30 seconds. 18 hours a year lost. Automation isn't about bash scripting, it's about noticing friction and having the instinct to say "this must be automated."
0xNN · · 9 min read
I used to do the same thing every Monday morning. Pull 5 repos, install dependencies, run database migrations, start 4 services. 45 minutes. I thought "normal, the project is complex, setup takes time." Ran for 6 months. Then a friend watched and said: "you're still doing this manually?"
He wrote 1 script, 20 lines. Monday morning next week, I ran ./bootstrap.sh. 30 seconds. All services running, all migrations applied, all repos updated. 45 minutes to 30 seconds. I felt stupid - 6 months * 45 minutes * 4 weeks = 18 hours a year. One year of work, 18 hours lost just to repetitive setup.
That was the moment I realized: automation isn't about tools. Not about "learning bash scripting" or "learning Makefile." Automation is about mindset - noticing when you're doing the same thing repeatedly, and having the instinct to say "this must be automated."
---
The "If You Do It Twice, Automate It" Philosophy
The simple rule I hold now: if you do the same thing twice, automate it. Not 3 times, not 10 times. 2.
Why 2? Because:
• First time: you learn. You understand the friction, the steps, the errors.
• Second time: you repeat. The friction is the same. The steps are the same. The errors (probably) the same. This is a signal: you'll do this again.
• Third time onwards: you already automated at the second time, so just run.
Devs who postpone automation say "later, I'm busy now." But 10 manual times = 10x time lost. 1x time writing the script = 1x investment. Different mindset.
But there's nuance. Automation has costs:
• Time to write the script
• Maintenance time when the script breaks
• Cognitive overhead - scripts can become black boxes, people forget how to do it manually
What must be automated: repetitive, predictable, low-risk. What shouldn't: one-offs, experimental, high-risk (production data migration, merge conflict resolution).
---
What I Automate (Not a Listicle, But Philosophy)
I don't have "X tools I use." I have categories of automation, and each category has its own pattern.
Project bootstrap. Every new project needs: init git, install deps, setup linting, setup testing, create folder structure. Used to be 30 minutes manual. Now 1 script:
#!/bin/bash
bootstrap.sh - used every time I start a new project
PROJECT=$1
mkdir -p $PROJECT/{src,tests,docs}
cd $PROJECT
git init
npm init -y
npm install -D typescript eslint prettier vitest @types/node
npx tsc --init
npx eslint --init
Template files
cat > .gitignore README.md /dev/null; then
echo "✓ Deploy successful, health check passed"
else
echo "✗ Health check failed - investigate"
# Could auto-rollback here
exit 1
fi
Not an enterprise CI/CD pipeline. But 25 lines that reduce 15 minutes of manual work to 1 command + 10 seconds of verification. Value from automation doesn't have to be sophisticated. The value is consistency.
Report generation. Every Friday I had to make a "what I worked on this week" report. Used to scan git log, copy paste commit messages, format manually. 20 minutes. Now:
#!/bin/bash
weekly-report.sh - generate weekly summary from git log
SINCE=$(date -d 'last monday' +%Y-%m-%d 2>/dev/null || date -v -mon +%Y-%m-%d)
PROJECTS=("$HOME/dev/blog" "$HOME/dev/api" "$HOME/dev/scripts")
echo "# Weekly Report - $(date +'%Y-%m-%d')"
echo ""
for proj in "${PROJECTS[@]}"; do
if [ -d "$proj/.git" ]; then
commits=$(cd $proj && git log --since="$SINCE" --oneline --author="$(git config user.email)" 2>/dev/null)
if [ -n "$commits" ]; then
echo "## $(basename $proj)"
echo "$commits" | sed 's/^/- /'
echo ""
fi
fi
done
5 minutes to write the script. 20 minutes manual became 5 seconds. Every Friday. Incredible ROI.
---
Shell Script vs Python vs Makefile: When to Use What
Not about "which is best." About the complexity of the task:
Shell script (bash/zsh). For: file operations, system commands, chaining CLI tools. Glue language for things you already do in the terminal. Example: project bootstrap, deploy script, log parsing.
Shell wins when: you're just chaining existing commands
git log --since="1 week ago" --pretty=format:"%h %s" | grep "fix:" | wc -l
Python. For: complex logic, data processing, API calls, convoluted conditionals. If your script starts hitting 100+ lines of bash with nested ifs, switch to Python. More readable, more maintainable.
Python wins when: there's complex logic
import subprocess, json, requests
from datetime import datetime, timedelta
since = (datetime.now() - timedelta(days=7)).isoformat()
repos = ["blog", "api", "scripts"]
for repo in repos:
log = subprocess.run(
["git", "-C", f"~/dev/{repo}", "log", "--since", since, "--pretty=format:%h %s"],
capture_output=True, text=True
)
commits = log.stdout.strip().split("\n") if log.stdout.strip() else []
fix_commits = [c for c in commits if "fix:" in c]
print(f"{repo}: {len(fix_commits)} fixes this week")
Makefile. For: project-specific tasks used by the team. make test, make build, make deploy. Declarative, standard, every dev knows make .
Makefile - project tasks
.PHONY: test build deploy lint
test:
npm test
build:
npm run build
deploy: test build
./scripts/deploy.sh production
lint:
npx eslint src/ --fix
Not "Makefile is more powerful." Makefile has its place: project tasks used by others. If the script is just for you, shell is enough. If the team uses it, Makefile provides a standard interface.
Philosophy: choose the tool based on complexity, not hype. I've seen people wrap 5 lines of bash in 50 lines of Python "to be typed." Over-engineering. I've also seen 500 lines of bash that should use Python but was maintained "to avoid installing Python." Wrong trade-off.
---
What I Don't Automate
Not everything should be automated. What I avoid:
One-off tasks. A one-time migration script? If you only run it once, writing the script may take longer than doing it manually. Unless the task is high-risk and the script makes it safer (atomic transaction, rollback).
Things that change every time. If the task is different each time (deploying to a new client with a different setup), automation = brittle. You spend more time maintaining the script than the time you save. Better: document a checklist, do it manually.
Things that need human judgment. Code review, merge conflict resolution, architecture decisions. Tools can help (linting, formatting, tests), but decisions remain human. Don't automate what needs taste.
Experimental workflow. You don't know the right workflow yet. Automating early = lock-in to a workflow that may be wrong. Stabilize the workflow first, then automate.
---
What I Learned About Mindset
Automation isn't about "knowing bash scripting." Many devs know bash but never automate anything. The mindset is what's different:
Noticing friction. When you do something tedious, my old default response was: "that's just how it is." Now: "this is tedious, there must be a faster way." Friction is a signal, not normal.
Quantifying time. "Just 5 minutes" sounds small. But 5 minutes * 5 times a week * 52 weeks = 21.6 hours a year. Half a work day, gone. Every "small" thing repeated = big in the long-term.
Investment vs expense. 1 hour writing a script = expense now. But that script runs 100x a year = 100x return. Automation is an investment that compounds. Unlike watching Netflix (expense that doesn't compound).
Default to automation. Now every time I do the same thing twice, an alarm goes off in my head: "automate." Not "later." Not "I'm busy now." Now. 2x = signal, don't wait for 10x.
---
Common Misconceptions
"Automation is only for DevOps." - Wrong. A frontend dev who uses a script to generate component boilerplate? That's automation. A backend dev who makes a seed data script? Automation. A mobile dev who scripts screenshot generation for store listing? Automation. Every dev has repetitive tasks, every dev benefits from automation.
"You must use sophisticated tools (Ansible, Terraform, etc)." - No. A 20-line shell script solves 80% of problems. Sophisticated infrastructure-as-code tools aren't the starting point, they're the endpoint when you manage 100 servers.
"Automation makes you forget how to do it manually." - True, and that's a feature, not a bug. You shouldn't have to remember 20 deploy steps. You should remember 1 command. Your brain is for more important things.
"Writing scripts is a hassle." - 20 lines of bash = 5 minutes to write. 5 minutes vs 18 hours a year. If you say "hassle," you're not doing the math.
---
An Honest Closing
Automation isn't about tools. I use shell scripts for 90% of cases, Python for complex ones, Makefile for project tasks. The tool doesn't matter. What matters: the mindset of noticing friction, and the instinct to say "this must be automated."
The philosophy I learned: "if you do it twice, automate it." Not because I'm lazy. Because my time is more valuable for things that need human judgment - design, architecture, code review. Not for repeating 20 steps 100x.
If you've never written a script to automate anything, try starting with 1 thing you do manually every week. Deploy, report, setup, whatever. 5 minutes writing a bash script, returns compound forever. When you run it the first time and realize "wow, this is just 1 command," you'll feel "ah, so that's how." That moment changes how you see repetitive work.
I still automate new things every week. Every time I find friction, I ask "can this be automated?" 80% of the time the answer is yes. 20% the answer is "no, this needs judgment." Automate the 80%, focus on the 20% that needs your brain.