#How to Hack-A-Thon ###The Savvy Coders Way
The Halfway Hack-A-Thon and Web Store Hack-A-Thon are both end-of-week, collaborative projects that give students an opportunity to design, plan, and execute projects in a team environment, much like they would see building any other type of product. The goal of each Hack-A-Thon is to foster the following skills through the product development experience:
- Understanding of the managed repository/GitHub workflow
- Collaboration and compromise between teammates, available tech, and project managers (you!)
- Product design from the ground up through user stories and feature sets.
- Modular design and execution (e.g. don't cause merge conflicts)
- All of the skills covered in class up to that point
It's your job as instructor to guide students through the design, planning, and execution of each product while managing the codebase and providing example code of your own. We'll go over each of these steps below.
###git and GitHub workflow
Each class will update a single codebase through pull requests in GitHub. It is the job of the instructor to review this process and manage all pull requests submitted by students. The model for this workflow is the "blessed repository" model (or maybe the "benevolent dictator" model) outlined in the graphic below:
This workflow is made up of two repositories for each team member and instructor. Each repository is represented in the diagram above, and are as follows:
- Blessed Repository: This repo is the "production" version of the codebase. It is located on the integration manager/instructor/benevolent dictator's public GitHub profile. This version of the code will be forked from the boilerplate version of the project repo hosted on Alex's GitHub profile (NAlexPear). All pull requests will be made to this repository, and all updates to individual codebases will be fetched from this repository.
- Integration Manager: This is the local version Blessed Repository, hosted on the instructor's local machine. This is the only repository with direct push access to the Blessed Repository. All pull requests will be merged in this repo if they can't be merged automatically through GitHub.
- Developer Public: Each dev/student on the team will have their own forked version of the Blessed Repository on their public GitHub profile. All pull requests to the Blessed Repository will originate from these publicly-hosted versions.
- Developer Private: Each dev/student on the team will have a local version of the project that they're currently working on. At any moment, the local repository should only be one commit ahead of their public repository (at most), and only one modular feature ahead of the Blessed Repository.
These components allow us to manage each project in a way that would approximate a larger-scale collaborative effort. If we combine the above structure with the following step-by-step workflow, we can also avoid having individual developers worry about branches or merging. The following workflow is also outlined in less detail in each Hack-A-Thon's instructions.md document.
- Initialize Blessed Repository: first, the integration manager will fork the boilerplate repository from NAlexPear to their own profile through GitHub.
- Fork to Developers: second, all students will fork the Blessed Repository to their own accounts through GitHub.
- Clone Public Repos: third, all developers (including the integration manager) will clone their personal copy of the Blessed Repository to their local machines using
git clone [https url of individual public repos]
. - Add remotes to Blessed Repository: fourth, students will need to set up the Blessed Repository as a remote from which the latest product version can be fetched. If a student runs
git remote -v
, they should see that they have automatically set up a remote named 'origin' to their own forked version of the codebase on GitHub. They will then need to add a new remote, named whatever they would like (in this example, 'blessed'), usinggit add remote blessed [https url of blessed repository]
. If that worked, then devs should be able to see that they have remotes named both 'origin' and 'blessed' when they type ingit remote
. - Stage and Commit Local Changes: If possible, all additions to the codebase should be written in a way that doesn't conflict with any other features. That means, for the most part, only additions to the codebase (rather than removal of someone else's code). All changes should be staged and committed locally using the following commands:
git add -A
git commit -m "[enter a good commit message here]"
Note: if someone just types
git commit
, they will be taken to their default text editor to write a commit message. If they're using a Mac, the default editor is usually vim. If someone does this, it's a good idea if you know the basics. Check out a quick tutorial here. To commit a message, though, just rememberEsc
+:wq
. Simple, right?
- Push Committed Changes to Developer's Public Repo: Once all feature-related changes have been committed locally, devs should push all commits up to their repos set to remote
origin
. That's as easy asgit push
(orgit push origin master
for the more loquacious version). - Submit Changes as Pull Request: Once a dev has pushed a feature to their public GitHub profile, their local and public repos should be exactly the same. No further changes should be made to the local repository from this point forward until the changes have been fully merged into the Blessed Repository! To submit their new feature for merging into the Blessed Repository, devs should use GitHub's pull request GUI from their public copy of the codebase to the master branch of the Blessed Repository.
- Merge Pull Request: Each pull request should be merged as quickly as possible, since any dev with an active pull request will be waiting patiently for the newly updated codebase and next feature assignment. Pull requests should be auto-merged by the integration manager when possible. Otherwise, follow the on-screen instructions for merging pull requests from the command line. Once the merged changes are pushed to the Blessed Repository, GitHub will automatically change the status of the pull request from 'active' to 'merged'.
- Fetch Updated Codebase: Once a dev's feature has been fully merged, they are ready to update their local repository directly from the Blessed Repository. Since multiple features are being pulled in at the same time, it's highly unlikely that a devs local and public repositories are up-to-date with the Blessed Repository, even if their feature was the last to be added to production. To avoid merging conflicts (that the integration manager has already resolved), devs will fetch code from the Blessed Repository and overwrite all of the files currently in their local directory. To do this, the dev will use the following commands:
git fetch --all
git reset --hard blessed/master
NOTE: this assumes that the remote for the Blessed Repository was named 'blessed'. It could, however, be anything
- Update Public Repository: Once the new version of the project has been downloaded, devs should go ahead and immediately update their public repo as well. To force the public repo to accept the new project structure without any fancy merging, use the
-f
flag. So the full command after resetting the local repository would begit push -f origin master
. - Update deployment: While steps 1-10 repeat ad nauseam, integration managers can deploy a prototype of the website using firebase. Just make sure that any firebase files (including
firebase.json
andfirebase-debug.log
) are hidden in the included.gitignore
file at the root of the directory. Make sure you share the deployment URL on Slack so that folks at home can follow along, and keep a tab open showing the product as it progresses to students through the projector.
###Collaboration and Teamwork
Features will be assigned by the instructor, and broken up into modular bits that can completed without creating merge conflicts (if possible). When students need to work with another student, they can do so in person (of course) or over Slack if that other person is sitting at home (as Alex might be doing).
###Product Design
The design phase should occur as a standing meeting. We've found it helpful to divide up features and tasks on a physical whiteboard, assigning tasks by having students initial them, and crossing off features and responsibilities as they are completed. In order to encourage modular development, projects are tackled first from the visual side, then from the programming/feature side. Tasks can be divided up like so:
What does the product look like? | What does the product do? (e.g. user stories: when a user does X, Y happens) |
---|---|
CONTENT (text and images... no HTML) | FEATURE #1 (initial pageload JavaScript) |
STRUCTURE (HTML document structure) | FEATURE #2 (initial user interaction event) |
STYLE (CSS in external stylesheet) | FEATURES #3+ (additional features) |
Make sure that every task has someone assigned to it, and avoid potential merge conflicts when you can! That usually means one person editing a document (HTML, CSS, or JS files) at a time. Managing the project structure is up to the integration manager.
And that should be it! Any questions, post them to Slack #admin, DM @nalexpear, or send an email to [email protected]. Good luck.