Weekend Challenges
These challenges extend what you practised during the week. Each one is self-contained — pick any order, or attempt all of them.
Challenge 1 — Expand Your Custom Commands
You added ~/bin/hello to your PATH on Day 2. Now build it out into something useful.
Write a command ~/bin/mkproject that accepts a project name as its first argument and:
- Creates a directory
~/projects/<name> - Initialises a Git repo inside it
- Creates a
README.mdwith the project name as the heading - Creates a
.env.examplewithAPP_ENV=localandAPP_VERSION=0.1.0 - Creates a
.gitignorecontaining.env - Makes an initial commit:
chore: initialise project
mkproject my-new-app
# should produce ~/projects/my-new-app with a git history of one commit
Handle the case where no argument is given — print a usage message and exit with a non-zero status code.
Challenge 2 — Multi-Environment Configuration Script
Extend the deploy-info script from Day 3 so it validates its inputs and produces a more complete configuration report.
Requirements:
- Read at least five environment variables:
APP_ENV,APP_VERSION,DB_HOST,DB_PORT,LOG_LEVEL - If
APP_ENVis not one oflocal,dev,staging,production— print an error and exit with status1 - If
APP_VERSIONis not set andAPP_ENVisproduction— print an error and exit with status1(a production deploy must have an explicit version) - Print a formatted config report showing all values
- Write a matching
.env.examplethat documents each variable
Test it by running it under each environment and deliberately triggering each error condition.
Challenge 3 — Branch and Merge Practice
In your envar-demo repository from Day 5, practise all three merge strategies back to back on real changes:
-
Create
feat/add-timestamp— add a line tobin/app-infothat prints the current date with$(date). Merge intomainusing a merge commit (--no-ff). -
Create
feat/add-hostname— add a line that prints the machine hostname with$(hostname). Merge intomainusing squash merge, writing a single clean Conventional Commit. -
Create
feat/add-uptime— add a line that prints uptime with$(uptime). Rebase ontomainbefore merging, then fast-forward.
After all three merges, run git log --oneline --graph and compare the shape of the history each strategy produced.
Challenge 4 — Extend the GitHub Actions Workflow
Add a second job to the run-app-info.yml workflow in envar-demo.
The new job should:
- Run only after the first job succeeds (
needs: run) - Print each environment variable on a separate line using
echo "KEY: $VALUE"forAPP_ENV,APP_VERSION, andGREETING - Use a different value for
APP_ENVthan the first job (staginginstead ofproduction) - Use
workflow_dispatchinputs so the workflow can be triggered manually with a customGREETINGvalue from the GitHub UI
Push the changes on a branch, open a pull request, and trigger the workflow both from the push and manually using the Run workflow button in the Actions tab.
Challenge 5 — Dotfiles Repository
Your shell configuration files (~/.zshrc, ~/.zprofile) and your ~/bin scripts are valuable — they represent your working environment. Back them up with Git.
-
Create a new repository called
dotfileson GitHub -
Create
~/.dotfileslocally and initialise it as a Git repo -
Move your
~/.zshrc(or~/.bashrc) into~/.dotfiles/zshrcand create a symlink back:mv ~/.zshrc ~/.dotfiles/zshrc ln -s ~/.dotfiles/zshrc ~/.zshrc -
Copy your
~/binscripts into~/.dotfiles/bin/ -
Commit everything with meaningful Conventional Commit messages
-
Push to GitHub — verify that cloning the repo and running
ln -srestores your environment
The goal is that on a fresh machine you can clone this repo and be productive in minutes.
Reflection
Answer these in a notes file or discuss with a peer:
- On Day 2 you added
~/binto your PATH in both~/.zshrcand~/.zprofile. What is the difference between those two files, and what would happen if you only set it in one of them? - You used
${VAR:-"default"}in your scripts. What does that syntax do, and what would happen if you used$VARalone when the variable is unset? - You used three merge strategies this week: merge commit, squash, and rebase. Which would you choose for a team working on a shared repository, and why?
- Your
.envfile is in.gitignorebut.env.exampleis committed. Explain why each decision is correct. - Look at the commit history of
envar-demo. Would a colleague understand what changed in each commit without reading the diff? Revise any commits that don't meet the Conventional Commits standard.