Initial Due Date: 2025-03-25 9:45AM
Final Due Date: 2025-04-08 4:15PM
Today you will add a feature to the color picker to enable the user to enter the color component by number. As part of that process we will practice testing, CI and automated deployment. Check out a deployed version of the final result.
💻 git clone
(get the name of the repository from GitHub).💻 pnpm install
in the terminal.Changes in Node 22 are triggering deprecation warnings for the punycode
module. You can ignore this warning. We have tried to suppress this message but have only been partly successful doing so.
Before you make any changes, create a feature branch named “editable-number” to isolate your modifications from the main branch:
💻 git checkout -b editable-number
This should be the new default action that you take when working on your code to get you in the habit. When you start a feature, create a corresponding feature branch. Work until it is stable and only then merge it into the main branch.
GitHub actions allow us to execute a wide variety of actions in response to git events. If you are looking at the repository on Github, you will see there is an Actions tab, which will allow you to add a number of different actions designed by GitHub and the community. However, all these do is create a special configuration file in your repository, so we will do that directly.
At the top level of your package directory, you should have a .github directory with a workflows directory inside (if not, you should create them). Inside of workflows, create a new file called node.js.yml, i.e., .github/workflows/node.js.yml (the important part of the file name is the .yml on the end, but use the full name) with the contents shown below.
YAML (pronounced like “camel”) is a popular file format for text-based configuration files. It won’t be important to understand all of its ins and outs, for now the key thing to know is that like Python, indentation matters.
name: Node.js CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
HUSKY: 0
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Use Node.js 22.x
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'pnpm'
- run: pnpm install
- run: pnpm test
- run: pnpm run build
There are two main sections here: on
and jobs
. The on
section tells GitHub Actions when to execute this action (when we push to main or make a PR to main). The jobs
section describes the steps to carry out. In this case, it
pnpm install
to install all of the dependencies specified in the pnpm-lock.yaml filepnpm test
pnpm run build
to ensure a production version of your application will buildIf any of the commands fail, e.g., there are testing errors, GitHub actions will report the errors so we know we need to fix the pull request.
As you browse different repositories on GitHub, you may have seen flashy status badges in the README files that indicate that the tests are passing (or not). You can add one to your project as well.
As described in the documentation, the URL of the image is:
https://github.com/<OWNER>/<REPOSITORY>/actions/workflows/<WORKFLOW_FILE>/badge.svg
We need to put this into Markdown syntax to add an image. So for example, I might add the following line to the README.md to render the image. Do so in your README.md, but change the URL to point to your repository.

Let’s commit this change and push it to GitHub:
💻 git add .
💻 git commit -m "Add actions config file"
💻 git push -u origin editable-number
The last command tells git to find the local branch named editable-number
and push its contents to a branch named editable-number
in the remote origin
repository. Recall that origin
is the name automatically given to the repository we cloned from (on GitHub in this case).
Visit the repository on GitHub (reloading the page, if needed). There should be a yellow banner across the top notifying you of a change to a branch and asking if you would like to “Compare & pull request”. Do so. If you don’t see the banner, you can always create a new PR from the ‘Pull requests’ tab.
On the new page that comes up you will see a form for starting the PR. Make sure you are comparing branches, not forks, i.e., it shows the base as the main
branch and the compared as the editable-number
branch in your practical repository, not the skeleton. You should only see the one commit you just created included the PR. Type in a message and click the button to create the PR.
You will see a message that it is OK to merge with main. This is unsurprising since no one has done anything to main since you made a branch, so the merge just involved adding the changes in this branch on top of main. If you wait a moment (you may also need to reload), however, you will see a new message appear as GitHub Actions kicks off. Give it a moment to run, and then it should come back and tell you that the checks have failed. This is also unsurprising since you haven’t changed the code yet. If you click on “Details” you can see the run log and the output from running the tests.
Now let’s make our change the the ColorPicker. Start the development server (💻 pnpm run dev
) so you can see the effects of your changes. You should see the familiar ColorPicker appear in the web view. You can also run the tests with 💻 pnpm test
, and they should fail.
You are now ready to make the changes to the LabeledSlider
in src/components/LabeledSlider.js. Remove the current span
which reports the value (<span>{value}</span>
) and replace it with a number input element. The numerical input will be very similar to its slider counterpart. Its value should be controlled by the React state (so that all the elements that depend on or modify that value remain in sync), it should update the color component as specified, and have appropriate min
and max
values. The differences are it will be of type “number” and it will have an appropriate data-testid
, e.g.,
data-testid={`${label}_number`}
You should now see your new inputs at the end of the sliders, and the tests should all pass.
Now that you have working code, add, commit and push it on the same feature branch you have been working on, e.g., 💻 git push origin editable-number
Return to the PR page on GitHub. You should see your new commit added to the PR and after a moment you should see the action kick off again. This time you should get a message that “All checks have passed” (it may take a few minute the first time due to caching behavior). If not, make sure that the tests were passing locally and that the new code has actually been pushed to the branch.
Click the “Merge pull request” button. it should give you a chance to add a message to the merge and then you can click “Confirm merge”. After the merge is complete, it will give you a “Delete branch” button. Click the “Delete branch” button to remove the feature branch from GitHub.
Return to your terminal and switch back to the “main” branch (💻 git checkout main
). You now want to pull the changes from GitHub, pruning to delete remote tracking references (💻 git pull --prune
) and then delete your local branch (💻 git branch -d editable-number
).
To avoid mistakes when deleting branches, you can add the --dry-run
option to the pull --prune
command , e.g. 💻 git pull --prune --dry-run
to double check before actually pruning anything (note you will still need to run the actual command when you are sure it correct).
The full command sequence is:
💻 git checkout main
💻 git pull --prune
💻 git branch -d editable-number
To support deployment without requiring you to enter a credit card or running into limits on team sizes, etc. we have our own simple cloud deployment platform csci312.dev. Similar to Heroku or fly.io, you will push your code to a deployment repository at csci312.dev, which will then build and deploy your application at https://<project name>.csci312.dev
.
Before you deploy, I encourage you to test the production version of your application locally. You can do so with:
💻 pnpm run build
💻 pnpm run start
This will build the production version of your application and start it the same way the server will (e.g., setting the production
environment). If this doesn’t work locally, it is unlikely to work remotely!
deploy
via 💻 git remote add deploy git@csci312.dev:<midd username>-practical06
replacing <midd username>
with your Middlebury username, e.g., 💻 git remote add deploy git@csci312.dev:mlinderman-practical06
. Note that the name matters, it must be your Middlebury username followed by “-practical06”.main
branch to the deploy repository: 💻 git push deploy main
. This should automatically build and deploy your application at https://<midd username>-practical06.csci312.dev
. Note that the push will not complete until the application deploys, so it will take a minute or so. Any errors should (hopefully) be reported in the terminal as the push proceeds.💻 ssh git@csci312.dev logs <midd username>-practical06
. You can optionally add a --lines
argument, e.g., --line 50
to look at more lines.main
branch and push them to the deploy
remote as you did above. That will re-deploy your application automatically.When the deployment completes successfully, open https://<midd username>-practical06.csci312.dev
in the browser, e.g., https://mlinderman-practical06.csci312.dev, to see your application live! Note that these sites are visible to anyone (i.e., you can send your awesome color picker to friends, family or anyone you want impress😀).
There are some more features of this platform that we will use when we deploy our projects. For that process, we will follow these similar, but more detailed, instructions.
⚠️ This platform is home-rolled, and while adequate for the needs of 5 concurrent projects, I am not sure it will hold up to 30 simultaneous deployments. We will see how it goes...
Make sure all of the provided tests pass and you don’t have any lint errors. Commit any additional changes you may have made and then push your changes to GitHub. You should then submit your repository to Gradescope as described here.
If you attempt to push your changes to GitHub and get an error like the following, your repository on GitHub has commits that you local clone does not (as a result of how GitHub classroom seems to work, see details below). You will need to pull the changes you don’t have. In this case, you can safely and effectively use rebase to do so, i.e., execute 💻 git pull --rebase origin main
in the terminal. Then attempt to push again.
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:csci312a-s25/assignment01...'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
It appears that there can sometimes be a delay between when GitHub classroom creates your repository and when it finishes adding its automatic commits (for the due date, etc.). Thus is it possible (easy) to clone the repository before that process has completed and end up in a situation where the GitHub repository has commits your local clone does not.
Required functionality:
Recall that the Practical exercises are evaluated as “Satisfactory/Not yet satisfactory”. Your submission will need to implement all of the required functionality (i.e., pass all the tests) to be Satisfactory (2 points).